From aabc1e9af8759847723703cb1ad7fbde770a8960 Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Wed, 22 Oct 2025 11:39:55 +0530 Subject: [PATCH 01/22] services added --- .github/workflows/ci.yml | 28 + .gitignore | 2 + .prettierrc.js | 51 + .vscode/extensions.json | 7 + .vscode/launch.json | 12 + CHANGELOG.md | 0 CODE_OF_CONDUCT.md | 76 + LICENSE.md | 19 + README_TEMPLATE.md | 48 + credentials/SecloreProtect.credentials.ts | 0 eslint.config.mjs | 3 + icons/github.dark.svg | 3 + icons/github.svg | 3 + nodes/SecloreProtect/SecloreProtect.node.json | 0 nodes/SecloreProtect/SecloreProtect.node.ts | 1 + nodes/SecloreProtect/SecloreProtect.svg | 11 + .../Services/Interfaces/ErrorInterfaces.ts | 4 + .../Interfaces/FileStorageInterfaces.ts | 9 + .../Services/Interfaces/LoginInterfaces.ts | 13 + .../Services/Interfaces/ProtectInterfaces.ts | 37 + .../Interfaces/UnprotectInterfaces.ts | 7 + .../Services/SecloreDRMApiService.ts | 384 + package-lock.json | 7226 +++++++++++++++++ package.json | 50 + tsconfig.json | 25 + 25 files changed, 8019 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 .prettierrc.js create mode 100644 .vscode/extensions.json create mode 100644 .vscode/launch.json create mode 100644 CHANGELOG.md create mode 100644 CODE_OF_CONDUCT.md create mode 100644 LICENSE.md create mode 100644 README_TEMPLATE.md create mode 100644 credentials/SecloreProtect.credentials.ts create mode 100644 eslint.config.mjs create mode 100644 icons/github.dark.svg create mode 100644 icons/github.svg create mode 100644 nodes/SecloreProtect/SecloreProtect.node.json create mode 100644 nodes/SecloreProtect/SecloreProtect.node.ts create mode 100644 nodes/SecloreProtect/SecloreProtect.svg create mode 100644 nodes/SecloreProtect/Services/Interfaces/ErrorInterfaces.ts create mode 100644 nodes/SecloreProtect/Services/Interfaces/FileStorageInterfaces.ts create mode 100644 nodes/SecloreProtect/Services/Interfaces/LoginInterfaces.ts create mode 100644 nodes/SecloreProtect/Services/Interfaces/ProtectInterfaces.ts create mode 100644 nodes/SecloreProtect/Services/Interfaces/UnprotectInterfaces.ts create mode 100644 nodes/SecloreProtect/Services/SecloreDRMApiService.ts create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 tsconfig.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..7cab9aa --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,28 @@ +name: CI + +on: + pull_request: + push: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Install dependencies + run: 'npm ci' + + - name: Run lint + run: 'npm run lint' + + - name: Run build + run: 'npm run build' diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..de4d1f0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +dist +node_modules diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..ebf28d8 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,51 @@ +module.exports = { + /** + * https://prettier.io/docs/en/options.html#semicolons + */ + semi: true, + + /** + * https://prettier.io/docs/en/options.html#trailing-commas + */ + trailingComma: 'all', + + /** + * https://prettier.io/docs/en/options.html#bracket-spacing + */ + bracketSpacing: true, + + /** + * https://prettier.io/docs/en/options.html#tabs + */ + useTabs: true, + + /** + * https://prettier.io/docs/en/options.html#tab-width + */ + tabWidth: 2, + + /** + * https://prettier.io/docs/en/options.html#arrow-function-parentheses + */ + arrowParens: 'always', + + /** + * https://prettier.io/docs/en/options.html#quotes + */ + singleQuote: true, + + /** + * https://prettier.io/docs/en/options.html#quote-props + */ + quoteProps: 'as-needed', + + /** + * https://prettier.io/docs/en/options.html#end-of-line + */ + endOfLine: 'lf', + + /** + * https://prettier.io/docs/en/options.html#print-width + */ + printWidth: 100, +}; diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..306a6af --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + "dbaeumer.vscode-eslint", + "EditorConfig.EditorConfig", + "esbenp.prettier-vscode", + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..ed1a625 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,12 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Attach to running n8n", + "processId": "${command:PickProcess}", + "request": "attach", + "skipFiles": ["/**"], + "type": "node" + } + ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e69de29 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..3b0de04 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at jan@n8n.io. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..1e4b3a6 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,19 @@ +Copyright 2022 n8n + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README_TEMPLATE.md b/README_TEMPLATE.md new file mode 100644 index 0000000..a8d7860 --- /dev/null +++ b/README_TEMPLATE.md @@ -0,0 +1,48 @@ +# n8n-nodes-_node-name_ + +This is an n8n community node. It lets you use _app/service name_ in your n8n workflows. + +_App/service name_ is _one or two sentences describing the service this node integrates with_. + +[n8n](https://n8n.io/) is a [fair-code licensed](https://docs.n8n.io/reference/license/) workflow automation platform. + +[Installation](#installation) +[Operations](#operations) +[Credentials](#credentials) +[Compatibility](#compatibility) +[Usage](#usage) +[Resources](#resources) +[Version history](#version-history) + +## Installation + +Follow the [installation guide](https://docs.n8n.io/integrations/community-nodes/installation/) in the n8n community nodes documentation. + +## Operations + +_List the operations supported by your node._ + +## Credentials + +_If users need to authenticate with the app/service, provide details here. You should include prerequisites (such as signing up with the service), available authentication methods, and how to set them up._ + +## Compatibility + +_State the minimum n8n version, as well as which versions you test against. You can also include any known version incompatibility issues._ + +## Usage + +_This is an optional section. Use it to help users with any difficult or confusing aspects of the node._ + +_By the time users are looking for community nodes, they probably already know n8n basics. But if you expect new users, you can link to the [Try it out](https://docs.n8n.io/try-it-out/) documentation to help them get started._ + +## Resources + +* [n8n community nodes documentation](https://docs.n8n.io/integrations/#community-nodes) +* _Link to app/service documentation._ + +## Version history + +_This is another optional section. If your node has multiple versions, include a short description of available versions and what changed, as well as any compatibility impact._ + + diff --git a/credentials/SecloreProtect.credentials.ts b/credentials/SecloreProtect.credentials.ts new file mode 100644 index 0000000..e69de29 diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..ad811a0 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,3 @@ +import { config } from '@n8n/node-cli/eslint'; + +export default config; diff --git a/icons/github.dark.svg b/icons/github.dark.svg new file mode 100644 index 0000000..0366b08 --- /dev/null +++ b/icons/github.dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/icons/github.svg b/icons/github.svg new file mode 100644 index 0000000..fe1ac05 --- /dev/null +++ b/icons/github.svg @@ -0,0 +1,3 @@ + + + diff --git a/nodes/SecloreProtect/SecloreProtect.node.json b/nodes/SecloreProtect/SecloreProtect.node.json new file mode 100644 index 0000000..e69de29 diff --git a/nodes/SecloreProtect/SecloreProtect.node.ts b/nodes/SecloreProtect/SecloreProtect.node.ts new file mode 100644 index 0000000..30713a9 --- /dev/null +++ b/nodes/SecloreProtect/SecloreProtect.node.ts @@ -0,0 +1 @@ +import { IDataObject, INodeExecutionData, IExecuteFunctions } from 'n8n-workflow'; diff --git a/nodes/SecloreProtect/SecloreProtect.svg b/nodes/SecloreProtect/SecloreProtect.svg new file mode 100644 index 0000000..58541ba --- /dev/null +++ b/nodes/SecloreProtect/SecloreProtect.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/nodes/SecloreProtect/Services/Interfaces/ErrorInterfaces.ts b/nodes/SecloreProtect/Services/Interfaces/ErrorInterfaces.ts new file mode 100644 index 0000000..b77ee0d --- /dev/null +++ b/nodes/SecloreProtect/Services/Interfaces/ErrorInterfaces.ts @@ -0,0 +1,4 @@ +export interface IErrorResponse { + errorCode: string; + errorMessage: string; +} \ No newline at end of file diff --git a/nodes/SecloreProtect/Services/Interfaces/FileStorageInterfaces.ts b/nodes/SecloreProtect/Services/Interfaces/FileStorageInterfaces.ts new file mode 100644 index 0000000..3df394f --- /dev/null +++ b/nodes/SecloreProtect/Services/Interfaces/FileStorageInterfaces.ts @@ -0,0 +1,9 @@ +export interface IFileUploadResponse { + fileStorageId: string; + fileName: string; + downloadUrl: string; + fileType: string; + fileSize: number; + secloreFileId: string; + protected: boolean; +} diff --git a/nodes/SecloreProtect/Services/Interfaces/LoginInterfaces.ts b/nodes/SecloreProtect/Services/Interfaces/LoginInterfaces.ts new file mode 100644 index 0000000..d971879 --- /dev/null +++ b/nodes/SecloreProtect/Services/Interfaces/LoginInterfaces.ts @@ -0,0 +1,13 @@ +export interface ILoginRequest { + tenantId: string; + tenantSecret: string; +} + +export interface ILoginResponse { + accessToken: string; + refreshToken: string; +} + +export interface IRefreshTokenRequest { + refreshToken: string; +} diff --git a/nodes/SecloreProtect/Services/Interfaces/ProtectInterfaces.ts b/nodes/SecloreProtect/Services/Interfaces/ProtectInterfaces.ts new file mode 100644 index 0000000..e9cb61b --- /dev/null +++ b/nodes/SecloreProtect/Services/Interfaces/ProtectInterfaces.ts @@ -0,0 +1,37 @@ +export interface IExtRefProtectionDetail { + externalReferenceId: string; + externalReferenceName?: string; + externalReferenceData?: string; + externalAppId?: string; +} + +export interface IProtectWithExternalRefIdRequest { + hotfolderExternalReference: IExtRefProtectionDetail; + fileExternalReference?: IExtRefProtectionDetail; + fileStorageId: string; +} + +export interface IProtectWithExternalRefIdResponse { + fileStorageId: string; + secloreFileId: string; +} + +export interface IProtectWithFileIdRequest { + existingProtectedFileId: string; + fileStorageId: string; +} + +export interface IProtectWithFileIdResponse { + fileStorageId: string; + secloreFileId: string; +} + +export interface IProtectWithHotFolderRequest { + hotfolderId: string; + fileStorageId: string; +} + +export interface IProtectWithHotFolderResponse { + fileStorageId: string; + secloreFileId: string; +} diff --git a/nodes/SecloreProtect/Services/Interfaces/UnprotectInterfaces.ts b/nodes/SecloreProtect/Services/Interfaces/UnprotectInterfaces.ts new file mode 100644 index 0000000..51c2b0e --- /dev/null +++ b/nodes/SecloreProtect/Services/Interfaces/UnprotectInterfaces.ts @@ -0,0 +1,7 @@ +export interface IUnprotectRequest { + fileStorageId: string; +} + +export interface IUnprotectResponse { + fileStorageId: string; +} diff --git a/nodes/SecloreProtect/Services/SecloreDRMApiService.ts b/nodes/SecloreProtect/Services/SecloreDRMApiService.ts new file mode 100644 index 0000000..26e9d5b --- /dev/null +++ b/nodes/SecloreProtect/Services/SecloreDRMApiService.ts @@ -0,0 +1,384 @@ +import { IExecuteFunctions, IHttpRequestOptions } from 'n8n-workflow'; +import { ILoginRequest, ILoginResponse, IRefreshTokenRequest } from './Interfaces/LoginInterfaces'; +import { IErrorResponse } from './Interfaces/ErrorInterfaces'; +import { IProtectWithExternalRefIdRequest, IProtectWithExternalRefIdResponse, IProtectWithFileIdRequest, IProtectWithFileIdResponse, IProtectWithHotFolderRequest, IProtectWithHotFolderResponse } from './Interfaces/ProtectInterfaces'; +import FormData from 'form-data'; +import { IUnprotectRequest, IUnprotectResponse } from './Interfaces/UnprotectInterfaces'; +import { IFileUploadResponse } from './Interfaces/FileStorageInterfaces'; + +export class SecloreDRMApiService { + private baseUrl: string; + + constructor(private context: IExecuteFunctions, baseUrl: string) { + this.baseUrl = baseUrl; + } + + /** + * Login Endpoint to generate Access Token and Refresh Token for JWT Authorization. + * Upon successful login, all the existing previous tokens for that tenant will be invalidated. + * + * @param tenantId - The tenant ID + * @param tenantSecret - The tenant secret + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - Access token and refresh token + * @throws Error on authentication failure or server error + */ + async login(tenantId: string, tenantSecret: string, correlationId?: string): Promise { + const requestBody: ILoginRequest = { + tenantId, + tenantSecret, + }; + + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/auth/login`, + headers, + body: requestBody, + json: true, + }; + + try { + const response = await this.context.helpers.httpRequest(options); + return response as ILoginResponse; + } catch (error: any) { + // Handle specific HTTP error responses + if (error.statusCode === 401) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid credentials'}`); + } else if (error.statusCode === 500) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); + } + // Re-throw other errors + throw error; + } + } + + /** + * Endpoint for generating new Access Token and Refresh Token using an existing valid Refresh Token. + * Upon successful response, all the previous existing Access Tokens and Refresh Tokens of that tenant will be invalidated. + * + * @param refreshToken - The existing valid refresh token + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - New access token and refresh token + * @throws Error on authentication failure or server error + */ + async refreshToken(refreshToken: string, correlationId?: string): Promise { + const requestBody: IRefreshTokenRequest = { + refreshToken, + }; + + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/auth/refresh`, + headers, + body: requestBody, + json: true, + }; + + try { + const response = await this.context.helpers.httpRequest(options); + return response as ILoginResponse; + } catch (error: any) { + // Handle specific HTTP error responses + if (error.statusCode === 401) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid refresh token'}`); + } else if (error.statusCode === 500) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); + } + + // Re-throw other errors + throw error; + } + } + + /** + * Protect file using external identifier of protected File and HotFolder with PS configured against the logged in Tenant in application. + * + * @param protectRequest - The protection request details + * @param accessToken - JWT access token for authorization + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - File storage ID and Seclore file ID + * @throws Error on bad request, authentication failure or server error + */ + async protectWithExternalRefId( + protectRequest: IProtectWithExternalRefIdRequest, + accessToken: string, + correlationId?: string + ): Promise { + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${accessToken}`, + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/protect/externalref`, + headers, + body: protectRequest, + json: true, + }; + + try { + const response = await this.context.helpers.httpRequest(options); + return response as IProtectWithExternalRefIdResponse; + } catch (error: any) { + // Handle specific HTTP error responses + if (error.statusCode === 400) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Bad Request: ${errorResponse?.errorMessage || 'Invalid request data'}`); + } else if (error.statusCode === 401) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid access token'}`); + } else if (error.statusCode === 500) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); + } + + // Re-throw other errors + throw error; + } + } + + /** + * Protects file using File ID of already protected file with PS configured against the logged in Tenant in application. + * + * @param protectRequest - The protection request details with existing protected file ID + * @param accessToken - JWT access token for authorization + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - File storage ID and Seclore file ID + * @throws Error on bad request, authentication failure or server error + */ + async protectWithFileId( + protectRequest: IProtectWithFileIdRequest, + accessToken: string, + correlationId?: string + ): Promise { + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${accessToken}`, + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/protect/fileid`, + headers, + body: protectRequest, + json: true, + }; + + try { + const response = await this.context.helpers.httpRequest(options); + return response as IProtectWithFileIdResponse; + } catch (error: any) { + // Handle specific HTTP error responses + if (error.statusCode === 400) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Bad Request: ${errorResponse?.errorMessage || 'Invalid request data'}`); + } else if (error.statusCode === 401) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid access token'}`); + } else if (error.statusCode === 500) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); + } + + // Re-throw other errors + throw error; + } + } + + /** + * Protects file using HotFolder ID with PS configured against the logged in Tenant in application. + * + * @param protectRequest - The protection request details with hotfolder ID + * @param accessToken - JWT access token for authorization + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - File storage ID and Seclore file ID + * @throws Error on bad request, authentication failure or server error + */ + async protectWithHotFolder( + protectRequest: IProtectWithHotFolderRequest, + accessToken: string, + correlationId?: string + ): Promise { + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${accessToken}`, + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/protect/hf`, + headers, + body: protectRequest, + json: true, + }; + + try { + const response = await this.context.helpers.httpRequest(options); + return response as IProtectWithHotFolderResponse; + } catch (error: any) { + // Handle specific HTTP error responses + if (error.statusCode === 400) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Bad Request: ${errorResponse?.errorMessage || 'Invalid request data'}`); + } else if (error.statusCode === 401) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid access token'}`); + } else if (error.statusCode === 500) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); + } + + // Re-throw other errors + throw error; + } + } + + /** + * Unprotects file with PS configured against the logged in Tenant in application. + * + * @param unprotectRequest - The unprotect request details with file storage ID + * @param accessToken - JWT access token for authorization + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - File storage ID of unprotected file + * @throws Error on bad request, authentication failure or server error + */ + async unprotect( + unprotectRequest: IUnprotectRequest, + accessToken: string, + correlationId?: string + ): Promise { + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${accessToken}`, + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/unprotect`, + headers, + body: unprotectRequest, + json: true, + }; + + try { + const response = await this.context.helpers.httpRequest(options); + return response as IUnprotectResponse; + } catch (error: any) { + // Handle specific HTTP error responses + if (error.statusCode === 400) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Bad Request: ${errorResponse?.errorMessage || 'Invalid request data'}`); + } else if (error.statusCode === 401) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid access token'}`); + } else if (error.statusCode === 500) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); + } + + // Re-throw other errors + throw error; + } + } + + /** + * Adds a new file to the file storage for currently logged in Tenant. + * + * @param fileBuffer - The file buffer data + * @param fileName - The name of the file + * @param accessToken - JWT access token for authorization + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - File storage details including file ID and metadata + * @throws Error on authentication failure, payload too large, or server error + */ + async uploadFile( + fileBuffer: Uint8Array, + fileName: string, + accessToken: string, + correlationId?: string + ): Promise { + const headers: { [key: string]: string } = { + 'Authorization': `Bearer ${accessToken}`, + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + // Create FormData for multipart/form-data upload + const formData = new FormData(); + formData.append('file', fileBuffer, fileName); + + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/filestorage/1.0/upload`, + headers, + body: formData, + }; + + try { + const response = await this.context.helpers.httpRequest(options); + return response as IFileUploadResponse; + } catch (error: any) { + // Handle specific HTTP error responses + if (error.statusCode === 401) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid access token'}`); + } else if (error.statusCode === 413) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Payload Too Large: ${errorResponse?.errorMessage || 'File size exceeds limit'}`); + } else if (error.statusCode === 500) { + const errorResponse = error.response?.body as IErrorResponse; + throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); + } + + // Re-throw other errors + throw error; + } + } + +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..aeff92d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,7226 @@ +{ + "name": "n8n-nodes-secloreprotect", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "n8n-nodes-secloreprotect", + "version": "0.1.0", + "license": "MIT", + "devDependencies": { + "@n8n/node-cli": "*", + "eslint": "9.32.0", + "prettier": "3.6.2", + "release-it": "^19.0.4", + "typescript": "5.9.2" + }, + "peerDependencies": { + "n8n-workflow": "*" + } + }, + "node_modules/@clack/core": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.5.0.tgz", + "integrity": "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "sisteransi": "^1.0.5" + } + }, + "node_modules/@clack/prompts": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.11.0.tgz", + "integrity": "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@clack/core": "0.5.0", + "picocolors": "^1.0.0", + "sisteransi": "^1.0.5" + } + }, + "node_modules/@emnapi/core": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.5.0.tgz", + "integrity": "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.5.0.tgz", + "integrity": "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", + "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", + "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz", + "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", + "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.15.2", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@inquirer/ansi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.1.tgz", + "integrity": "sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.0.tgz", + "integrity": "sha512-5+Q3PKH35YsnoPTh75LucALdAxom6xh5D1oeY561x4cqBuH24ZFVyFREPe14xgnrtmGu3EEt1dIi60wRVSnGCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.1", + "@inquirer/core": "^10.3.0", + "@inquirer/figures": "^1.0.14", + "@inquirer/type": "^3.0.9", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.1.19", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.19.tgz", + "integrity": "sha512-wQNz9cfcxrtEnUyG5PndC8g3gZ7lGDBzmWiXZkX8ot3vfZ+/BLjR8EvyGX4YzQLeVqtAlY/YScZpW7CW8qMoDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.0.tgz", + "integrity": "sha512-Uv2aPPPSK5jeCplQmQ9xadnFx2Zhj9b5Dj7bU6ZeCdDNNY11nhYy4btcSdtDguHqCT2h5oNeQTcUNSGGLA7NTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.1", + "@inquirer/figures": "^1.0.14", + "@inquirer/type": "^3.0.9", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/core/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/core/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.21", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.21.tgz", + "integrity": "sha512-MjtjOGjr0Kh4BciaFShYpZ1s9400idOdvQ5D7u7lE6VztPFoyLcVNE5dXBmEEIQq5zi4B9h2kU+q7AVBxJMAkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.0", + "@inquirer/external-editor": "^1.0.2", + "@inquirer/type": "^3.0.9" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.21", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.21.tgz", + "integrity": "sha512-+mScLhIcbPFmuvU3tAGBed78XvYHSvCl6dBiYMlzCLhpr0bzGzd8tfivMMeqND6XZiaZ1tgusbUHJEfc6YzOdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.2.tgz", + "integrity": "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.0", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.14.tgz", + "integrity": "sha512-DbFgdt+9/OZYFM+19dbpXOSeAstPy884FPy1KjDu4anWwymZeOYhMY1mdFri172htv6mvc/uvIAAi7b7tvjJBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.2.5.tgz", + "integrity": "sha512-7GoWev7P6s7t0oJbenH0eQ0ThNdDJbEAEtVt9vsrYZ9FulIokvd823yLyhQlWHJPGce1wzP53ttfdCZmonMHyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.21.tgz", + "integrity": "sha512-5QWs0KGaNMlhbdhOSCFfKsW+/dcAVC2g4wT/z2MCiZM47uLgatC5N20kpkDQf7dHx+XFct/MJvvNGy6aYJn4Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.21", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.21.tgz", + "integrity": "sha512-xxeW1V5SbNFNig2pLfetsDb0svWlKuhmr7MPJZMYuDnCTkpVBI+X/doudg4pznc1/U+yYmWFFOi4hNvGgUo7EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.1", + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.9.0.tgz", + "integrity": "sha512-X7/+dG9SLpSzRkwgG5/xiIzW0oMrV3C0HOa7YHG1WnrLK+vCQHfte4k/T80059YBdei29RBC3s+pSMvPJDU9/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.3.0", + "@inquirer/confirm": "^5.1.19", + "@inquirer/editor": "^4.2.21", + "@inquirer/expand": "^4.0.21", + "@inquirer/input": "^4.2.5", + "@inquirer/number": "^3.0.21", + "@inquirer/password": "^4.0.21", + "@inquirer/rawlist": "^4.1.9", + "@inquirer/search": "^3.2.0", + "@inquirer/select": "^4.4.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.9.tgz", + "integrity": "sha512-AWpxB7MuJrRiSfTKGJ7Y68imYt8P9N3Gaa7ySdkFj1iWjr6WfbGAhdZvw/UnhFXTHITJzxGUI9k8IX7akAEBCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.0.tgz", + "integrity": "sha512-a5SzB/qrXafDX1Z4AZW3CsVoiNxcIYCzYP7r9RzrfMpaLpB+yWi5U8BWagZyLmwR0pKbbL5umnGRd0RzGVI8bQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.0", + "@inquirer/figures": "^1.0.14", + "@inquirer/type": "^3.0.9", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.0.tgz", + "integrity": "sha512-kaC3FHsJZvVyIjYBs5Ih8y8Bj4P/QItQWrZW22WJax7zTN+ZPXVGuOM55vzbdCP9zKUiBd9iEJVdesujfF+cAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.1", + "@inquirer/core": "^10.3.0", + "@inquirer/figures": "^1.0.14", + "@inquirer/type": "^3.0.9", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.9.tgz", + "integrity": "sha512-QPaNt/nmE2bLGQa9b7wwyRJoLZ7pN6rcyXvzU0YCmivmJyq1BVo94G98tStRWkoD1RgDX5C+dPlhhHzNdu/W/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@n8n_io/riot-tmpl": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@n8n_io/riot-tmpl/-/riot-tmpl-4.0.1.tgz", + "integrity": "sha512-/zdRbEfTFjsm1NqnpPQHgZTkTdbp5v3VUxGeMA9098sps8jRCTraQkc3AQstJgHUm7ylBXJcIVhnVeLUMWAfwQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "eslint-config-riot": "^1.0.0" + } + }, + "node_modules/@n8n/errors": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@n8n/errors/-/errors-0.5.0.tgz", + "integrity": "sha512-0Vk1Eb3Uor+zeF/WVnuhFgJc51wEBTZNBlVQy3mvyr3sGmW86bP1jA7wmRsd0DZbswPwN0vNOl/TmkDTEopOtQ==", + "license": "SEE LICENSE IN LICENSE.md", + "peer": true, + "dependencies": { + "callsites": "3.1.0" + } + }, + "node_modules/@n8n/eslint-plugin-community-nodes": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@n8n/eslint-plugin-community-nodes/-/eslint-plugin-community-nodes-0.6.0.tgz", + "integrity": "sha512-VafBm+pHvOiO/DPZfdyYBHWS6ZEeu3jMwK3E1lxE7rXUbLlRoqW3YL4jnJ5R8JIChMVcZeoybGALt1lnuixyjA==", + "dev": true, + "license": "SEE LICENSE IN LICENSE.md", + "dependencies": { + "@typescript-eslint/utils": "^8.35.0", + "fastest-levenshtein": "1.0.16" + }, + "peerDependencies": { + "eslint": ">= 9" + } + }, + "node_modules/@n8n/node-cli": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@n8n/node-cli/-/node-cli-0.13.0.tgz", + "integrity": "sha512-4YRA1r3D2k+qA2psKNQHd+g077slvJpRunyRt3etgI5Kmbo445wQJSMF03+f4Els1EP3AO7eN7F6HSTz0AHtzA==", + "dev": true, + "license": "SEE LICENSE IN LICENSE.md", + "dependencies": { + "@clack/prompts": "^0.11.0", + "@n8n/eslint-plugin-community-nodes": "0.6.0", + "@oclif/core": "^4.5.2", + "change-case": "^5.4.4", + "eslint-import-resolver-typescript": "^4.4.3", + "eslint-plugin-import-x": "^4.15.2", + "eslint-plugin-n8n-nodes-base": "1.16.3", + "fast-glob": "3.2.12", + "handlebars": "4.7.8", + "picocolors": "1.0.1", + "prettier": "3.6.2", + "prompts": "^2.4.2", + "rimraf": "6.0.1", + "ts-morph": "^26.0.0", + "typescript-eslint": "^8.35.0" + }, + "bin": { + "n8n-node": "bin/n8n-node.mjs" + }, + "peerDependencies": { + "eslint": ">= 9" + } + }, + "node_modules/@n8n/tournament": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@n8n/tournament/-/tournament-1.0.6.tgz", + "integrity": "sha512-UGSxYXXVuOX0yL6HTLBStKYwLIa0+JmRKiSZSCMcM2s2Wax984KWT6XIA1TR/27i7yYpDk1MY14KsTPnuEp27A==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@n8n_io/riot-tmpl": "^4.0.1", + "ast-types": "^0.16.1", + "esprima-next": "^5.8.4", + "recast": "^0.22.0" + }, + "engines": { + "node": ">=20.15", + "pnpm": ">=9.5" + } + }, + "node_modules/@n8n/tournament/node_modules/ast-types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", + "license": "MIT", + "peer": true, + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodeutils/defaults-deep": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@nodeutils/defaults-deep/-/defaults-deep-1.1.0.tgz", + "integrity": "sha512-gG44cwQovaOFdSR02jR9IhVRpnDP64VN6JdjYJTfNz4J4fWn7TQnmrf22nSjRqlwlxPcW8PL/L3KbJg3tdwvpg==", + "dev": true, + "license": "ISC", + "dependencies": { + "lodash": "^4.15.0" + } + }, + "node_modules/@oclif/core": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-4.5.5.tgz", + "integrity": "sha512-iQzlaJQgPeUXrtrX71OzDwxPikQ7c2FhNd8U8rBB7BCtj2XYfmzBT/Hmbc+g9OKDIG/JkbJT0fXaWMMBrhi+1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.3.2", + "ansis": "^3.17.0", + "clean-stack": "^3.0.1", + "cli-spinners": "^2.9.2", + "debug": "^4.4.3", + "ejs": "^3.1.10", + "get-package-type": "^0.1.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "lilconfig": "^3.1.3", + "minimatch": "^9.0.5", + "semver": "^7.7.3", + "string-width": "^4.2.3", + "supports-color": "^8", + "tinyglobby": "^0.2.14", + "widest-line": "^3.1.0", + "wordwrap": "^1.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@octokit/auth-token": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", + "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/core": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.5.tgz", + "integrity": "sha512-t54CUOsFMappY1Jbzb7fetWeO0n6K0k/4+/ZpkS+3Joz8I4VcvY9OiEBFRYISqaI2fq5sCiPtAjRDOzVYG8m+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^6.0.0", + "@octokit/graphql": "^9.0.2", + "@octokit/request": "^10.0.4", + "@octokit/request-error": "^7.0.1", + "@octokit/types": "^15.0.0", + "before-after-hook": "^4.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/endpoint": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.1.tgz", + "integrity": "sha512-7P1dRAZxuWAOPI7kXfio88trNi/MegQ0IJD3vfgC3b+LZo1Qe6gRJc2v0mz2USWWJOKrB2h5spXCzGbw+fAdqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^15.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/graphql": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.2.tgz", + "integrity": "sha512-iz6KzZ7u95Fzy9Nt2L8cG88lGRMr/qy1Q36ih/XVzMIlPDMYwaNLE/ENhqmIzgPrlNWiYJkwmveEetvxAgFBJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request": "^10.0.4", + "@octokit/types": "^15.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-26.0.0.tgz", + "integrity": "sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-13.2.0.tgz", + "integrity": "sha512-YuAlyjR8o5QoRSOvMHxSJzPtogkNMgeMv2mpccrvdUGeC3MKyfi/hS+KiFwyH/iRKIKyx+eIMsDjbt3p9r2GYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^15.0.0" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-6.0.0.tgz", + "integrity": "sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-16.1.0.tgz", + "integrity": "sha512-nCsyiKoGRnhH5LkH8hJEZb9swpqOcsW+VXv1QoyUNQXJeVODG4+xM6UICEqyqe9XFr6LkL8BIiFCPev8zMDXPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^15.0.0" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/request": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.5.tgz", + "integrity": "sha512-TXnouHIYLtgDhKo+N6mXATnDBkV05VwbR0TtMWpgTHIoQdRQfCSzmy/LGqR1AbRMbijq/EckC/E3/ZNcU92NaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^11.0.1", + "@octokit/request-error": "^7.0.1", + "@octokit/types": "^15.0.0", + "fast-content-type-parse": "^3.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/request-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.0.1.tgz", + "integrity": "sha512-CZpFwV4+1uBrxu7Cw8E5NCXDWFNf18MSY23TdxCBgjw1tXXHvTrZVsXlW8hgFTOLw8RQR1BBrMvYRtuyaijHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^15.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/rest": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-22.0.0.tgz", + "integrity": "sha512-z6tmTu9BTnw51jYGulxrlernpsQYXpui1RK21vmXn8yF5bp6iX16yfTtJYGK5Mh1qDkvDOmp2n8sRMcQmR8jiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/core": "^7.0.2", + "@octokit/plugin-paginate-rest": "^13.0.1", + "@octokit/plugin-request-log": "^6.0.0", + "@octokit/plugin-rest-endpoint-methods": "^16.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/types": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-15.0.0.tgz", + "integrity": "sha512-8o6yDfmoGJUIeR9OfYU0/TUJTnMPG2r68+1yEdUeG2Fdqpj8Qetg0ziKIgcBm0RW/j29H41WP37CYCEhp6GoHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^26.0.0" + } + }, + "node_modules/@phun-ky/typeof": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@phun-ky/typeof/-/typeof-2.0.3.tgz", + "integrity": "sha512-oeQJs1aa8Ghke8JIK9yuq/+KjMiaYeDZ38jx7MhkXncXlUKjqQ3wEm2X3qCKyjo+ZZofZj+WsEEiqkTtRuE2xQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.9.0 || >=22.0.0", + "npm": ">=10.8.2" + }, + "funding": { + "url": "https://github.com/phun-ky/typeof?sponsor=1" + } + }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@ts-morph/common": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.27.0.tgz", + "integrity": "sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "^3.3.3", + "minimatch": "^10.0.1", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@ts-morph/common/node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@ts-morph/common/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@ts-morph/common/node_modules/minimatch": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/parse-path": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/parse-path/-/parse-path-7.0.3.tgz", + "integrity": "sha512-LriObC2+KYZD3FzCrgWGv/qufdUy4eXrxcLgQMfYXgPbLIecKIsVBaQgUPmxSSLcjmYbDTQbMgr6qr6l/eb7Bg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.1.tgz", + "integrity": "sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.46.1", + "@typescript-eslint/type-utils": "8.46.1", + "@typescript-eslint/utils": "8.46.1", + "@typescript-eslint/visitor-keys": "8.46.1", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.46.1", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.1.tgz", + "integrity": "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.46.1", + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/typescript-estree": "8.46.1", + "@typescript-eslint/visitor-keys": "8.46.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.1.tgz", + "integrity": "sha512-FOIaFVMHzRskXr5J4Jp8lFVV0gz5ngv3RHmn+E4HYxSJ3DgDzU7fVI1/M7Ijh1zf6S7HIoaIOtln1H5y8V+9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.1", + "@typescript-eslint/types": "^8.46.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.1.tgz", + "integrity": "sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/visitor-keys": "8.46.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.1.tgz", + "integrity": "sha512-X88+J/CwFvlJB+mK09VFqx5FE4H5cXD+H/Bdza2aEWkSb8hnWIQorNcscRl4IEo1Cz9VI/+/r/jnGWkbWPx54g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.1.tgz", + "integrity": "sha512-+BlmiHIiqufBxkVnOtFwjah/vrkF4MtKKvpXrKSPLCkCtAp8H01/VV43sfqA98Od7nJpDcFnkwgyfQbOG0AMvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/typescript-estree": "8.46.1", + "@typescript-eslint/utils": "8.46.1", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.1.tgz", + "integrity": "sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.1.tgz", + "integrity": "sha512-uIifjT4s8cQKFQ8ZBXXyoUODtRoAd7F7+G8MKmtzj17+1UbdzFl52AzRyZRyKqPHhgzvXunnSckVu36flGy8cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.46.1", + "@typescript-eslint/tsconfig-utils": "8.46.1", + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/visitor-keys": "8.46.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.1.tgz", + "integrity": "sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.1", + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/typescript-estree": "8.46.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.1.tgz", + "integrity": "sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.1", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", + "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "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" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansis": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-3.17.0.tgz", + "integrity": "sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/assert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" + } + }, + "node_modules/ast-types": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.15.2.tgz", + "integrity": "sha512-c27loCv9QkZinsa5ProX751khO9DJl/AcB5c2KNtA6NRvHKS0PgLfcftz72KVq504vB0Gku5s2kUZzDBvQWvHg==", + "license": "MIT", + "peer": true, + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "retry": "0.13.1" + } + }, + "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", + "peer": true + }, + "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", + "peer": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/before-after-hook": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", + "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/c12": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/c12/-/c12-3.3.0.tgz", + "integrity": "sha512-K9ZkuyeJQeqLEyqldbYLG3wjqwpw4BVaAqvmxq3GYKK0b1A/yYQdIcJxkzAOWcNVWhJpRXAPfZFueekiY/L8Dw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.3", + "confbox": "^0.2.2", + "defu": "^6.1.4", + "dotenv": "^17.2.2", + "exsolve": "^1.0.7", + "giget": "^2.0.0", + "jiti": "^2.5.1", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "perfect-debounce": "^2.0.0", + "pkg-types": "^2.3.0", + "rc9": "^2.1.2" + }, + "peerDependencies": { + "magicast": "^0.3.5" + }, + "peerDependenciesMeta": { + "magicast": { + "optional": true + } + } + }, + "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", + "peer": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "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==", + "license": "MIT", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/chardet": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.0.tgz", + "integrity": "sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ci-info": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", + "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/citty": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", + "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "consola": "^3.2.3" + } + }, + "node_modules/clean-stack": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", + "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "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", + "peer": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "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", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "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", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/code-block-writer": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz", + "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", + "dev": true, + "license": "MIT" + }, + "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" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "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", + "peer": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/confbox": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", + "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "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", + "peer": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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", + "peer": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "dev": true, + "license": "MIT" + }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/degenerator/node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "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", + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "dev": true, + "license": "MIT" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dotenv": { + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "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", + "peer": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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/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", + "peer": true, + "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", + "peer": true, + "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", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/eslint": { + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.32.0.tgz", + "integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.3.0", + "@eslint/core": "^0.15.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.32.0", + "@eslint/plugin-kit": "^0.3.4", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-riot": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-riot/-/eslint-config-riot-1.0.0.tgz", + "integrity": "sha512-NB/L/1Y30qyJcG5xZxCJKW/+bqyj+llbcCwo9DEz8bESIP0SLTOQ8T1DWCCFc+wJ61AMEstj4511PSScqMMfCw==", + "license": "MIT", + "peer": true + }, + "node_modules/eslint-import-context": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", + "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-tsconfig": "^4.10.1", + "stable-hash-x": "^0.2.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-context" + }, + "peerDependencies": { + "unrs-resolver": "^1.0.0" + }, + "peerDependenciesMeta": { + "unrs-resolver": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-4.4.4.tgz", + "integrity": "sha512-1iM2zeBvrYmUNTj2vSC/90JTHDth+dfOfiNKkxApWRsTJYNrc8rOdxxIf5vazX+BiAXTeOT0UvWpGI/7qIWQOw==", + "dev": true, + "license": "ISC", + "dependencies": { + "debug": "^4.4.1", + "eslint-import-context": "^0.1.8", + "get-tsconfig": "^4.10.1", + "is-bun-module": "^2.0.0", + "stable-hash-x": "^0.2.0", + "tinyglobby": "^0.2.14", + "unrs-resolver": "^1.7.11" + }, + "engines": { + "node": "^16.17.0 || >=18.6.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-import-x": { + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.16.1.tgz", + "integrity": "sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "^8.35.0", + "comment-parser": "^1.4.1", + "debug": "^4.4.1", + "eslint-import-context": "^0.1.9", + "is-glob": "^4.0.3", + "minimatch": "^9.0.3 || ^10.0.1", + "semver": "^7.7.2", + "stable-hash-x": "^0.2.0", + "unrs-resolver": "^1.9.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-import-x" + }, + "peerDependencies": { + "@typescript-eslint/utils": "^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", + "eslint-import-resolver-node": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/utils": { + "optional": true + }, + "eslint-import-resolver-node": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-local": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-local/-/eslint-plugin-local-1.0.0.tgz", + "integrity": "sha512-bcwcQnKL/Iw5Vi/F2lG1he5oKD2OGjhsLmrcctkWrWq5TujgiaYb0cj3pZgr3XI54inNVnneOFdAx1daLoYLJQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-plugin-n8n-nodes-base": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-n8n-nodes-base/-/eslint-plugin-n8n-nodes-base-1.16.3.tgz", + "integrity": "sha512-edLX42Vg4B+y0kzkitTVDmHZQrG5/wUZO874N5Z9leBuxt5TG1pqMY4zdr35RlpM4p4REr/T9x+6DpsQSL63WA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^6.21.0", + "camel-case": "^4.1.2", + "eslint-plugin-local": "^1.0.0", + "indefinite": "^2.5.1", + "pascal-case": "^3.1.2", + "pluralize": "^8.0.0", + "sentence-case": "^3.0.4", + "title-case": "^3.0.3" + }, + "engines": { + "node": ">=20.15", + "pnpm": ">=9.6" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/eslint-plugin-n8n-nodes-base/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima-next": { + "version": "5.8.4", + "resolved": "https://registry.npmjs.org/esprima-next/-/esprima-next-5.8.4.tgz", + "integrity": "sha512-8nYVZ4ioIH4Msjb/XmhnBdz5WRRBaYqevKa1cv9nGJdCehMbzZCPNEEnqfLCZVetUVrUPEcb5IYyu1GG4hFqgg==", + "license": "BSD-2-Clause", + "peer": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eta": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eta/-/eta-4.0.1.tgz", + "integrity": "sha512-0h0oBEsF6qAJU7eu9ztvJoTo8D2PAq/4FvXVIQA1fek3WOTe6KPsVJycekG1+g1N6mfpblkheoGwaUhMtnlH4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/bgub/eta?sponsor=1" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/exsolve": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", + "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-content-type-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", + "integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "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", + "peer": true, + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "license": "MIT", + "peer": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "peer": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "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", + "peer": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-tsconfig": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.12.0.tgz", + "integrity": "sha512-LScr2aNr2FbjAjZh2C6X6BxRx1/x+aTDExct/xyq2XKbYOiG5c0aK7pMsSuyc0brz3ibr/lbQiHD9jzt4lccJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/giget": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/giget/-/giget-2.0.0.tgz", + "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.0", + "defu": "^6.1.4", + "node-fetch-native": "^1.6.6", + "nypm": "^0.6.0", + "pathe": "^2.0.3" + }, + "bin": { + "giget": "dist/cli.mjs" + } + }, + "node_modules/git-up": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/git-up/-/git-up-8.1.1.tgz", + "integrity": "sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-ssh": "^1.4.0", + "parse-url": "^9.2.0" + } + }, + "node_modules/git-url-parse": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-16.1.0.tgz", + "integrity": "sha512-cPLz4HuK86wClEW7iDdeAKcCVlWXmrLpb2L+G9goW0Z1dtpNS6BXXSOckUTlJT/LDQViE1QZKstNORzHsLnobw==", + "dev": true, + "license": "MIT", + "dependencies": { + "git-up": "^8.1.0" + } + }, + "node_modules/glob": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", + "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.0.3", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "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-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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", + "peer": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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", + "peer": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", + "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indefinite": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/indefinite/-/indefinite-2.5.2.tgz", + "integrity": "sha512-J3ELLIk835hmgDMUfNltTCrHz9+CteTnSuXJqvxZT18wo1U2M9/QeeJMw99QdZwPEEr1DE2aBYda101Ojjdw5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC", + "peer": true + }, + "node_modules/inquirer": { + "version": "12.9.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-12.9.6.tgz", + "integrity": "sha512-603xXOgyfxhuis4nfnWaZrMaotNT0Km9XwwBNWUKbIDqeCY89jGr2F9YPEMiNhU6XjIP4VoWISMBFfcc5NgrTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.0", + "@inquirer/core": "^10.2.2", + "@inquirer/prompts": "^7.8.6", + "@inquirer/type": "^3.0.8", + "mute-stream": "^2.0.0", + "run-async": "^4.0.5", + "rxjs": "^7.8.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/ip-address": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", + "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "license": "MIT", + "peer": true + }, + "node_modules/is-bun-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, + "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", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "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", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ssh": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.1.tgz", + "integrity": "sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "protocols": "^2.0.1" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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", + "peer": true, + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/issue-parser": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-7.0.1.tgz", + "integrity": "sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.capitalize": "^4.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.uniqby": "^4.7.0" + }, + "engines": { + "node": "^18.17 || >=20.6.1" + } + }, + "node_modules/jackspeak": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/jmespath": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", + "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/js-base64": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz", + "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jssha": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.3.1.tgz", + "integrity": "sha512-VCMZj12FCFMQYcFLPRm/0lOBbLi8uM2BhXPTqw3U4YAfs4AZfiApOoBLoN8cQE60Z50m1MYMTQVCfgF/KaCVhQ==", + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.capitalize": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", + "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", + "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/luxon": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz", + "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/macos-release": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-3.4.0.tgz", + "integrity": "sha512-wpGPwyg/xrSp4H4Db4xYSeAr6+cFQGHfspHzDUdYxswDnUW0L5Ov63UuJiSr8NMSpyaChO4u1n0MXUvVPtrN6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 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" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "peer": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/n8n-workflow": { + "version": "1.113.0", + "resolved": "https://registry.npmjs.org/n8n-workflow/-/n8n-workflow-1.113.0.tgz", + "integrity": "sha512-WiNbm2Us/lSOTioKQZeNdLMGlbOuDMUFVuC0aMVIrQl4YarUmIAyxH7xHkpOoWrahXwbg7PrW27aPkjjAHiEgg==", + "license": "SEE LICENSE IN LICENSE.md", + "peer": true, + "dependencies": { + "@n8n/errors": "^0.5.0", + "@n8n/tournament": "1.0.6", + "ast-types": "0.15.2", + "callsites": "3.1.0", + "esprima-next": "5.8.4", + "form-data": "4.0.0", + "jmespath": "0.16.0", + "js-base64": "3.7.2", + "jssha": "3.3.1", + "lodash": "4.17.21", + "luxon": "3.4.4", + "md5": "2.3.0", + "recast": "0.22.0", + "title-case": "3.0.3", + "transliteration": "2.3.5", + "xml2js": "0.6.2", + "zod": "3.25.67" + } + }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/new-github-release-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/new-github-release-url/-/new-github-release-url-2.0.0.tgz", + "integrity": "sha512-NHDDGYudnvRutt/VhKFlX26IotXe1w0cmkDm6JGquh5bz/bDTw0LufSmH/GxTjEdpHEO+bVKFTwdrcGa/9XlKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^2.5.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/new-github-release-url/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nypm": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.2.tgz", + "integrity": "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==", + "dev": true, + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.2", + "pathe": "^2.0.3", + "pkg-types": "^2.3.0", + "tinyexec": "^1.0.1" + }, + "bin": { + "nypm": "dist/cli.mjs" + }, + "engines": { + "node": "^14.16.0 || >=16.10.0" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "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", + "peer": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-9.0.0.tgz", + "integrity": "sha512-m0pg2zscbYgWbqRR6ABga5c3sZdEon7bSgjnlXC64kxtxLOyjRcbbUkLj7HFyy/FTD+P2xdBWu8snGhYI0jc4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.6.2", + "cli-cursor": "^5.0.0", + "cli-spinners": "^3.2.0", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.1.0", + "log-symbols": "^7.0.1", + "stdin-discarder": "^0.2.2", + "string-width": "^8.1.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/cli-spinners": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.3.0.tgz", + "integrity": "sha512-/+40ljC3ONVnYIttjMWrlL51nItDAbBrq2upN8BPyvGU/2n5Oxw3tbNwORCaNuNqLJnxGqOfjUuhsv7l5Q4IsQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/string-width": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-name": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/os-name/-/os-name-6.1.0.tgz", + "integrity": "sha512-zBd1G8HkewNd2A8oQ8c6BN/f/c9EId7rSUueOLGu28govmUctXmM+3765GwsByv9nYUdrLqHphXlYIc86saYsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "macos-release": "^3.3.0", + "windows-release": "^6.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dev": true, + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-path": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.1.0.tgz", + "integrity": "sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "protocols": "^2.0.0" + } + }, + "node_modules/parse-url": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-9.2.0.tgz", + "integrity": "sha512-bCgsFI+GeGWPAvAiUv63ZorMeif3/U0zaXABGJbOWt5OH2KCaPHF6S+0ok4aqM9RuIPGyZdx9tR9l13PsW4AYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/parse-path": "^7.0.0", + "parse-path": "^7.0.0" + }, + "engines": { + "node": ">=14.13.0" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz", + "integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/perfect-debounce": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.0.0.tgz", + "integrity": "sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-types": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", + "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.2.2", + "exsolve": "^1.0.7", + "pathe": "^2.0.3" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/protocols": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.2.tgz", + "integrity": "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/rc9": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", + "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defu": "^6.1.4", + "destr": "^2.0.3" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/recast": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.22.0.tgz", + "integrity": "sha512-5AAx+mujtXijsEavc5lWXBPQqrM4+Dl5qNH96N2aNeuJFUzpiiToKPsxQD/zAIJHspz7zz0maX0PCtCTFVlixQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "assert": "^2.0.0", + "ast-types": "0.15.2", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/release-it": { + "version": "19.0.5", + "resolved": "https://registry.npmjs.org/release-it/-/release-it-19.0.5.tgz", + "integrity": "sha512-bYlUKC0TQroBKi8jQUeoxLHql4d9Fx/2EQLHPKUobXTNSiTS2WY8vlgdHZRhRjVEMyAWwyadJVKfFZnRJuRn4Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/webpro" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/webpro" + } + ], + "license": "MIT", + "dependencies": { + "@nodeutils/defaults-deep": "1.1.0", + "@octokit/rest": "22.0.0", + "@phun-ky/typeof": "2.0.3", + "async-retry": "1.3.3", + "c12": "3.3.0", + "ci-info": "^4.3.0", + "eta": "4.0.1", + "git-url-parse": "16.1.0", + "inquirer": "12.9.6", + "issue-parser": "7.0.1", + "lodash.merge": "4.6.2", + "mime-types": "3.0.1", + "new-github-release-url": "2.0.0", + "open": "10.2.0", + "ora": "9.0.0", + "os-name": "6.1.0", + "proxy-agent": "6.5.0", + "semver": "7.7.2", + "tinyglobby": "0.2.15", + "undici": "6.21.3", + "url-join": "5.0.0", + "wildcard-match": "5.1.4", + "yargs-parser": "21.1.1" + }, + "bin": { + "release-it": "bin/release-it.js" + }, + "engines": { + "node": "^20.12.0 || >=22.0.0" + } + }, + "node_modules/release-it/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/release-it/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/release-it/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", + "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^11.0.0", + "package-json-from-dist": "^1.0.0" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-async": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-4.0.6.tgz", + "integrity": "sha512-IoDlSLTs3Yq593mb3ZoKWKXMNu3UpObxhgA/Xuid5p4bbfi2jdY1Hj0m1K+0/tEuQTxIGMhQDqGjKb7RuxGpAQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "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", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "license": "ISC", + "peer": true + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sentence-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", + "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "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", + "peer": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stable-hash-x": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", + "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/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/string-width/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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/tinyexec": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", + "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/title-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", + "integrity": "sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "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" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/transliteration": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/transliteration/-/transliteration-2.3.5.tgz", + "integrity": "sha512-HAGI4Lq4Q9dZ3Utu2phaWgtm3vB6PkLUFqWAScg/UW+1eZ/Tg6Exo4oC0/3VUol/w4BlefLhUUSVBr/9/ZGQOw==", + "license": "MIT", + "peer": true, + "dependencies": { + "yargs": "^17.5.1" + }, + "bin": { + "slugify": "dist/bin/slugify", + "transliterate": "dist/bin/transliterate" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-morph": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-26.0.0.tgz", + "integrity": "sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ts-morph/common": "~0.27.0", + "code-block-writer": "^13.0.3" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.46.1.tgz", + "integrity": "sha512-VHgijW803JafdSsDO8I761r3SHrgk4T00IdyQ+/UsthtgPRsBWQLqoSxOolxTpxRKi1kGXK0bSz4CoAc9ObqJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.46.1", + "@typescript-eslint/parser": "8.46.1", + "@typescript-eslint/typescript-estree": "8.46.1", + "@typescript-eslint/utils": "8.46.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/undici": { + "version": "6.21.3", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz", + "integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/universal-user-agent": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", + "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==", + "dev": true, + "license": "ISC" + }, + "node_modules/unrs-resolver": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", + "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + } + }, + "node_modules/upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-join": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", + "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "license": "MIT", + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "license": "MIT", + "peer": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wildcard-match": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/wildcard-match/-/wildcard-match-5.1.4.tgz", + "integrity": "sha512-wldeCaczs8XXq7hj+5d/F38JE2r7EXgb6WQDM84RVwxy81T/sxB5e9+uZLK9Q9oNz1mlvjut+QtvgaOQFPVq/g==", + "dev": true, + "license": "ISC" + }, + "node_modules/windows-release": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-6.1.0.tgz", + "integrity": "sha512-1lOb3qdzw6OFmOzoY0nauhLG72TpWtb5qgYPiSh/62rjc1XidBSDio2qw0pwHh17VINF217ebIkZJdFLZFn9SA==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^8.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "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", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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/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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wsl-utils/node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "license": "MIT", + "peer": true, + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "peer": true, + "engines": { + "node": ">=10" + } + }, + "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", + "peer": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "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" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.67", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.67.tgz", + "integrity": "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..395533e --- /dev/null +++ b/package.json @@ -0,0 +1,50 @@ +{ + "name": "n8n-nodes-secloreprotect", + "version": "0.1.0", + "description": "", + "license": "MIT", + "homepage": "", + "keywords": [ + "n8n-community-node-package" + ], + "author": { + "name": "", + "email": "" + }, + "repository": { + "type": "git", + "url": "https://github.com/seclore/n8n-nodes-secloreprotect.git" + }, + "scripts": { + "build": "n8n-node build", + "build:watch": "tsc --watch", + "dev": "n8n-node dev", + "lint": "n8n-node lint", + "lint:fix": "n8n-node lint --fix", + "release": "n8n-node release", + "prepublishOnly": "n8n-node prerelease" + }, + "files": [ + "dist" + ], + "n8n": { + "n8nNodesApiVersion": 1, + "strict": true, + "credentials": [ + "dist/credentials/SecloreProtectApi.credentials.js" + ], + "nodes": [ + "dist/nodes/SecloreProtect/SecloreProtect.node.js" + ] + }, + "devDependencies": { + "@n8n/node-cli": "*", + "eslint": "9.32.0", + "prettier": "3.6.2", + "release-it": "^19.0.4", + "typescript": "5.9.2" + }, + "peerDependencies": { + "n8n-workflow": "*" + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..b73660f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "strict": true, + "module": "commonjs", + "moduleResolution": "node", + "target": "es2019", + "lib": ["es2019", "es2020", "es2022.error"], + "removeComments": true, + "useUnknownInCatchVariables": false, + "forceConsistentCasingInFileNames": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noUnusedLocals": true, + "strictNullChecks": true, + "preserveConstEnums": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "incremental": true, + "declaration": true, + "sourceMap": true, + "skipLibCheck": true, + "outDir": "./dist/" + }, + "include": ["credentials/**/*", "nodes/**/*", "nodes/**/*.json", "package.json"] +} -- 2.40.1 From 07c6b03e04937d1f1d34b2e8701f721768d9df65 Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Wed, 22 Oct 2025 12:00:14 +0530 Subject: [PATCH 02/22] minor modifications --- .../Services/SecloreDRMApiService.ts | 126 +++++------------- 1 file changed, 35 insertions(+), 91 deletions(-) diff --git a/nodes/SecloreProtect/Services/SecloreDRMApiService.ts b/nodes/SecloreProtect/Services/SecloreDRMApiService.ts index 26e9d5b..6322fff 100644 --- a/nodes/SecloreProtect/Services/SecloreDRMApiService.ts +++ b/nodes/SecloreProtect/Services/SecloreDRMApiService.ts @@ -13,6 +13,34 @@ export class SecloreDRMApiService { this.baseUrl = baseUrl; } + /** + * Common error handler for HTTP responses + * @param error - The error object from httpRequest + * @param customMessages - Optional custom error messages for specific status codes + */ + private handleHttpError(error: any, customMessages?: { [statusCode: number]: string }): never { + const statusCode = error.statusCode; + const errorResponse = error.response?.body as IErrorResponse; + + if (customMessages && customMessages[statusCode]) { + throw new Error(`${customMessages[statusCode]}: ${errorResponse?.errorMessage || 'Unknown error'}`); + } + + // Default error handling + switch (statusCode) { + case 400: + throw new Error(`Bad Request: ${errorResponse?.errorMessage || 'Invalid request data'}`); + case 401: + throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid credentials'}`); + case 413: + throw new Error(`Payload Too Large: ${errorResponse?.errorMessage || 'File size exceeds limit'}`); + case 500: + throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); + default: + throw error; + } + } + /** * Login Endpoint to generate Access Token and Refresh Token for JWT Authorization. * Upon successful login, all the existing previous tokens for that tenant will be invalidated. @@ -50,16 +78,7 @@ export class SecloreDRMApiService { const response = await this.context.helpers.httpRequest(options); return response as ILoginResponse; } catch (error: any) { - // Handle specific HTTP error responses - if (error.statusCode === 401) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid credentials'}`); - } else if (error.statusCode === 500) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); - } - // Re-throw other errors - throw error; + this.handleHttpError(error); } } @@ -98,17 +117,7 @@ export class SecloreDRMApiService { const response = await this.context.helpers.httpRequest(options); return response as ILoginResponse; } catch (error: any) { - // Handle specific HTTP error responses - if (error.statusCode === 401) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid refresh token'}`); - } else if (error.statusCode === 500) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); - } - - // Re-throw other errors - throw error; + this.handleHttpError(error, { 401: 'Unauthorized' }); } } @@ -148,20 +157,7 @@ export class SecloreDRMApiService { const response = await this.context.helpers.httpRequest(options); return response as IProtectWithExternalRefIdResponse; } catch (error: any) { - // Handle specific HTTP error responses - if (error.statusCode === 400) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Bad Request: ${errorResponse?.errorMessage || 'Invalid request data'}`); - } else if (error.statusCode === 401) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid access token'}`); - } else if (error.statusCode === 500) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); - } - - // Re-throw other errors - throw error; + this.handleHttpError(error); } } @@ -201,20 +197,7 @@ export class SecloreDRMApiService { const response = await this.context.helpers.httpRequest(options); return response as IProtectWithFileIdResponse; } catch (error: any) { - // Handle specific HTTP error responses - if (error.statusCode === 400) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Bad Request: ${errorResponse?.errorMessage || 'Invalid request data'}`); - } else if (error.statusCode === 401) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid access token'}`); - } else if (error.statusCode === 500) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); - } - - // Re-throw other errors - throw error; + this.handleHttpError(error); } } @@ -254,20 +237,7 @@ export class SecloreDRMApiService { const response = await this.context.helpers.httpRequest(options); return response as IProtectWithHotFolderResponse; } catch (error: any) { - // Handle specific HTTP error responses - if (error.statusCode === 400) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Bad Request: ${errorResponse?.errorMessage || 'Invalid request data'}`); - } else if (error.statusCode === 401) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid access token'}`); - } else if (error.statusCode === 500) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); - } - - // Re-throw other errors - throw error; + this.handleHttpError(error); } } @@ -307,20 +277,7 @@ export class SecloreDRMApiService { const response = await this.context.helpers.httpRequest(options); return response as IUnprotectResponse; } catch (error: any) { - // Handle specific HTTP error responses - if (error.statusCode === 400) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Bad Request: ${errorResponse?.errorMessage || 'Invalid request data'}`); - } else if (error.statusCode === 401) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid access token'}`); - } else if (error.statusCode === 500) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); - } - - // Re-throw other errors - throw error; + this.handleHttpError(error); } } @@ -364,20 +321,7 @@ export class SecloreDRMApiService { const response = await this.context.helpers.httpRequest(options); return response as IFileUploadResponse; } catch (error: any) { - // Handle specific HTTP error responses - if (error.statusCode === 401) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid access token'}`); - } else if (error.statusCode === 413) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Payload Too Large: ${errorResponse?.errorMessage || 'File size exceeds limit'}`); - } else if (error.statusCode === 500) { - const errorResponse = error.response?.body as IErrorResponse; - throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); - } - - // Re-throw other errors - throw error; + this.handleHttpError(error); } } -- 2.40.1 From 3e1c503f0162eff550f27e83f591bd821ae66fb2 Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Wed, 22 Oct 2025 14:39:02 +0530 Subject: [PATCH 03/22] drmfileservice added --- .../Services/SecloreDRMFileService.ts | 288 ++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 nodes/SecloreProtect/Services/SecloreDRMFileService.ts diff --git a/nodes/SecloreProtect/Services/SecloreDRMFileService.ts b/nodes/SecloreProtect/Services/SecloreDRMFileService.ts new file mode 100644 index 0000000..ae0b93d --- /dev/null +++ b/nodes/SecloreProtect/Services/SecloreDRMFileService.ts @@ -0,0 +1,288 @@ +import { IExecuteFunctions } from 'n8n-workflow'; +import { SecloreDRMApiService } from './SecloreDRMApiService'; +import { IProtectWithExternalRefIdRequest, IProtectWithExternalRefIdResponse, IProtectWithFileIdRequest, IProtectWithFileIdResponse, IProtectWithHotFolderRequest, IProtectWithHotFolderResponse } from './Interfaces/ProtectInterfaces'; +import { IUnprotectRequest, IUnprotectResponse } from './Interfaces/UnprotectInterfaces'; +import { IFileUploadResponse } from './Interfaces/FileStorageInterfaces'; + +export class SecloreDRMFileService { + private apiService: SecloreDRMApiService; + private tenantId: string; + private tenantSecret: string; + private accessToken?: string; + private refreshToken?: string; + private tokenExpiry?: Date; + private refreshPromise?: Promise; + private loginPromise?: Promise; + + constructor( + context: IExecuteFunctions, + baseUrl: string, + tenantId: string, + tenantSecret: string, + private defaultRetryCount: number = 3 + ) { + this.apiService = new SecloreDRMApiService(context, baseUrl); + this.tenantId = tenantId; + this.tenantSecret = tenantSecret; + } + + /** + * Ensures we have a valid access token, logging in if necessary + * @param correlationId - Optional correlation ID for logging + */ + private async ensureAuthenticated(correlationId?: string): Promise { + // If we don't have a token or it's expired, login + if (!this.accessToken || (this.tokenExpiry && new Date() >= this.tokenExpiry)) { + // If there's already a login in progress, wait for it + if (this.loginPromise) { + await this.loginPromise; + return; + } + + // Start login and store the promise + this.loginPromise = this.login(correlationId); + try { + await this.loginPromise; + } finally { + this.loginPromise = undefined; + } + } + } + + /** + * Performs login and stores tokens + * @param correlationId - Optional correlation ID for logging + */ + private async login(correlationId?: string): Promise { + try { + const loginResponse = await this.apiService.login( + this.tenantId, + this.tenantSecret, + correlationId + ); + + this.accessToken = loginResponse.accessToken; + this.refreshToken = loginResponse.refreshToken; + + // Set token expiry to 50 minutes from now (assuming 1 hour token life) + this.tokenExpiry = new Date(Date.now() + 50 * 60 * 1000); + } catch (error) { + this.clearTokens(); + throw error; + } + } + + /** + * Attempts to refresh the access token with concurrency protection + * @param correlationId - Optional correlation ID for logging + */ + private async refreshAccessToken(correlationId?: string): Promise { + // If there's already a refresh in progress, wait for it + if (this.refreshPromise) { + await this.refreshPromise; + return; + } + + if (!this.refreshToken) { + throw new Error('No refresh token available'); + } + + // Start refresh and store the promise + this.refreshPromise = this.performTokenRefresh(correlationId); + try { + await this.refreshPromise; + } finally { + this.refreshPromise = undefined; + } + } + + /** + * Performs the actual token refresh + * @param correlationId - Optional correlation ID for logging + */ + private async performTokenRefresh(correlationId?: string): Promise { + try { + const refreshResponse = await this.apiService.refreshToken( + this.refreshToken!, + correlationId + ); + + this.accessToken = refreshResponse.accessToken; + this.refreshToken = refreshResponse.refreshToken; + + // Set token expiry to 50 minutes from now + this.tokenExpiry = new Date(Date.now() + 50 * 60 * 1000); + } catch (error) { + this.clearTokens(); + throw error; + } + } + + /** + * Clears stored tokens and pending promises + */ + private clearTokens(): void { + this.accessToken = undefined; + this.refreshToken = undefined; + this.tokenExpiry = undefined; + this.refreshPromise = undefined; + this.loginPromise = undefined; + } + + /** + * Executes an API call with automatic authentication and retry logic + * @param apiCall - The API call function to execute + * @param retryCount - Number of retries (defaults to class default) + * @param correlationId - Optional correlation ID for logging + */ + private async executeWithRetry( + apiCall: (accessToken: string) => Promise, + retryCount: number = this.defaultRetryCount, + correlationId?: string + ): Promise { + let lastError: Error; + + for (let attempt = 0; attempt <= retryCount; attempt++) { + try { + // Ensure we have a valid token + await this.ensureAuthenticated(correlationId); + + if (!this.accessToken) { + throw new Error('Failed to obtain access token'); + } + + // Execute the API call + return await apiCall(this.accessToken); + + } catch (error: any) { + lastError = error; + + // If it's an authentication error and we have retries left, try to refresh token + if (error.message.includes('Unauthorized') && attempt < retryCount) { + try { + await this.refreshAccessToken(correlationId); + continue; // Retry with new token + } catch (refreshError) { + // If refresh fails, clear tokens and try full login on next attempt + this.clearTokens(); + } + } + + // If it's the last attempt or not an auth error, throw + if (attempt === retryCount) { + throw lastError; + } + + // Wait before retry (exponential backoff) + await new Promise(resolve => { + const delay = Math.pow(2, attempt) * 1000; + // Use a simple delay implementation + const start = Date.now(); + while (Date.now() - start < delay) { + // Busy wait for delay + } + resolve(undefined); + }); + } + } + + throw lastError!; + } + + /** + * Protect file using external identifier with automatic authentication and retry + */ + async protectWithExternalRefId( + protectRequest: IProtectWithExternalRefIdRequest, + correlationId?: string, + retryCount?: number + ): Promise { + return this.executeWithRetry( + (accessToken) => this.apiService.protectWithExternalRefId(protectRequest, accessToken, correlationId), + retryCount, + correlationId + ); + } + + /** + * Protect file using existing protected file ID with automatic authentication and retry + */ + async protectWithFileId( + protectRequest: IProtectWithFileIdRequest, + correlationId?: string, + retryCount?: number + ): Promise { + return this.executeWithRetry( + (accessToken) => this.apiService.protectWithFileId(protectRequest, accessToken, correlationId), + retryCount, + correlationId + ); + } + + /** + * Protect file using HotFolder ID with automatic authentication and retry + */ + async protectWithHotFolder( + protectRequest: IProtectWithHotFolderRequest, + correlationId?: string, + retryCount?: number + ): Promise { + return this.executeWithRetry( + (accessToken) => this.apiService.protectWithHotFolder(protectRequest, accessToken, correlationId), + retryCount, + correlationId + ); + } + + /** + * Unprotect file with automatic authentication and retry + */ + async unprotect( + unprotectRequest: IUnprotectRequest, + correlationId?: string, + retryCount?: number + ): Promise { + return this.executeWithRetry( + (accessToken) => this.apiService.unprotect(unprotectRequest, accessToken, correlationId), + retryCount, + correlationId + ); + } + + /** + * Upload file with automatic authentication and retry + */ + async uploadFile( + fileBuffer: Uint8Array, + fileName: string, + correlationId?: string, + retryCount?: number + ): Promise { + return this.executeWithRetry( + (accessToken) => this.apiService.uploadFile(fileBuffer, fileName, accessToken, correlationId), + retryCount, + correlationId + ); + } + + /** + * Get current access token (for debugging/monitoring) + */ + getAccessToken(): string | undefined { + return this.accessToken; + } + + /** + * Check if currently authenticated + */ + isAuthenticated(): boolean { + return !!this.accessToken && (!this.tokenExpiry || new Date() < this.tokenExpiry); + } + + /** + * Force logout (clears all tokens) + */ + logout(): void { + this.clearTokens(); + } +} -- 2.40.1 From 023fc238555fe5ed625a4f620423c789c5ac8d76 Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Wed, 22 Oct 2025 14:49:18 +0530 Subject: [PATCH 04/22] protect with hot folder draft --- credentials/SecloreProtect.credentials.ts | 58 +++++ nodes/SecloreProtect/SecloreProtect.node.json | 4 + nodes/SecloreProtect/SecloreProtect.node.ts | 230 +++++++++++++++++- .../Services/SecloreDRMApiService.ts | 39 +++ .../Services/SecloreDRMFileService.ts | 22 +- 5 files changed, 346 insertions(+), 7 deletions(-) diff --git a/credentials/SecloreProtect.credentials.ts b/credentials/SecloreProtect.credentials.ts index e69de29..f2c60bc 100644 --- a/credentials/SecloreProtect.credentials.ts +++ b/credentials/SecloreProtect.credentials.ts @@ -0,0 +1,58 @@ +import { + ICredentialTestRequest, + ICredentialType, + INodeProperties, +} from 'n8n-workflow'; + +export class SecloreProtectApi implements ICredentialType { + name = 'secloreProtectApi'; + displayName = 'Seclore Protect API'; + documentationUrl = 'https://docs.seclore.com/'; + properties: INodeProperties[] = [ + { + displayName: 'Base URL', + name: 'baseUrl', + type: 'string', + default: 'https://api.seclore.com', + placeholder: 'https://api.seclore.com', + description: 'The base URL of your Seclore API instance', + required: true, + }, + { + displayName: 'Tenant ID', + name: 'tenantId', + type: 'string', + default: '', + placeholder: 'your-tenant-id', + description: 'Your Seclore tenant ID', + required: true, + }, + { + displayName: 'Tenant Secret', + name: 'tenantSecret', + type: 'string', + typeOptions: { + password: true, + }, + default: '', + description: 'Your Seclore tenant secret', + required: true, + }, + ]; + + // Optional: Add credential test + test: ICredentialTestRequest = { + request: { + baseURL: '={{$credentials.baseUrl}}', + url: '/seclore/drm/1.0/auth/login', + method: 'POST', + body: { + tenantId: '={{$credentials.tenantId}}', + tenantSecret: '={{$credentials.tenantSecret}}', + }, + headers: { + 'Content-Type': 'application/json', + }, + }, + }; +} diff --git a/nodes/SecloreProtect/SecloreProtect.node.json b/nodes/SecloreProtect/SecloreProtect.node.json index e69de29..b88e26f 100644 --- a/nodes/SecloreProtect/SecloreProtect.node.json +++ b/nodes/SecloreProtect/SecloreProtect.node.json @@ -0,0 +1,4 @@ +{ + "node": "dist/nodes/SecloreProtect/SecloreProtect.node.js", + "credentials": "dist/credentials/SecloreProtectApi.credentials.js" +} diff --git a/nodes/SecloreProtect/SecloreProtect.node.ts b/nodes/SecloreProtect/SecloreProtect.node.ts index 30713a9..accc028 100644 --- a/nodes/SecloreProtect/SecloreProtect.node.ts +++ b/nodes/SecloreProtect/SecloreProtect.node.ts @@ -1 +1,229 @@ -import { IDataObject, INodeExecutionData, IExecuteFunctions } from 'n8n-workflow'; +import { + IExecuteFunctions, + INodeExecutionData, + INodeType, + INodeTypeDescription, + NodeOperationError, +} from 'n8n-workflow'; + +import { SecloreDRMFileService } from './Services/SecloreDRMFileService'; + +export class SecloreProtect implements INodeType { + description: INodeTypeDescription = { + displayName: 'Seclore Protect', + name: 'secloreProtect', + icon: 'file:SecloreProtect.svg', + group: ['transform'], + version: 1, + subtitle: '={{$parameter["operation"]}}', + description: 'Protect files using Seclore DRM with HotFolder configuration', + defaults: { + name: 'Seclore Protect', + }, + inputs: ['main'], + outputs: ['main'], + credentials: [ + { + name: 'secloreProtectApi', + required: true, + }, + ], + properties: [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + noDataExpression: true, + options: [ + { + name: 'Protect File with HotFolder', + value: 'protectWithHotFolder', + description: 'Protect a file using HotFolder ID configuration', + action: 'Protect file with HotFolder', + }, + ], + default: 'protectWithHotFolder', + }, + { + displayName: 'HotFolder ID', + name: 'hotfolderId', + type: 'string', + required: true, + default: '', + placeholder: 'e.g., hf-12345', + description: 'The ID of the HotFolder configuration to use for protection', + displayOptions: { + show: { + operation: ['protectWithHotFolder'], + }, + }, + }, + { + displayName: 'Input Binary Property', + name: 'binaryPropertyName', + type: 'string', + default: 'data', + required: true, + description: 'Name of the binary property that contains the file to protect', + displayOptions: { + show: { + operation: ['protectWithHotFolder'], + }, + }, + }, + { + displayName: 'Output Binary Property', + name: 'outputBinaryPropertyName', + type: 'string', + default: 'data', + required: true, + description: 'Name of the binary property where the protected file will be stored', + displayOptions: { + show: { + operation: ['protectWithHotFolder'], + }, + }, + }, + { + displayName: 'Correlation ID', + name: 'correlationId', + type: 'string', + default: '', + placeholder: 'e.g., req-12345', + description: 'Optional correlation ID for request tracking and logging', + displayOptions: { + show: { + operation: ['protectWithHotFolder'], + }, + }, + }, + { + displayName: 'Retry Count', + name: 'retryCount', + type: 'number', + default: 3, + description: 'Number of retry attempts for failed requests', + displayOptions: { + show: { + operation: ['protectWithHotFolder'], + }, + }, + }, + ], + }; + + async execute(this: IExecuteFunctions): Promise { + const items = this.getInputData(); + const returnData: INodeExecutionData[] = []; + + // Get credentials + const credentials = await this.getCredentials('secloreProtectApi'); + const baseUrl = credentials.baseUrl as string; + const tenantId = credentials.tenantId as string; + const tenantSecret = credentials.tenantSecret as string; + + // Initialize the file service + const fileService = new SecloreDRMFileService( + this, + baseUrl, + tenantId, + tenantSecret + ); + + // Get node parameters + const operation = this.getNodeParameter('operation', 0) as string; + + for (let i = 0; i < items.length; i++) { + try { + if (operation === 'protectWithHotFolder') { + // Get parameters for this item + const hotfolderId = this.getNodeParameter('hotfolderId', i) as string; + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; + const outputBinaryPropertyName = this.getNodeParameter('outputBinaryPropertyName', i) as string; + const correlationId = this.getNodeParameter('correlationId', i) as string; + const retryCount = this.getNodeParameter('retryCount', i) as number; + + // Validate required parameters + if (!hotfolderId) { + throw new NodeOperationError(this.getNode(), 'HotFolder ID is required', { + itemIndex: i, + }); + } + + // Get input binary data + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); + const fileBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); + + // Upload the file first + const uploadResult = await fileService.uploadFile( + new Uint8Array(fileBuffer), + binaryData.fileName || 'file', + correlationId || undefined, + retryCount + ); + + // Protect the uploaded file with HotFolder + const protectResult = await fileService.protectWithHotFolder( + { + hotfolderId, + fileStorageId: uploadResult.fileStorageId, + }, + correlationId || undefined, + retryCount + ); + + // Download the protected file + const protectedFileData = await fileService.downloadFile( + protectResult.fileStorageId, + correlationId || undefined, + retryCount + ); + + // Create output binary data + const outputBinaryData = await this.helpers.prepareBinaryData( + protectedFileData.buffer, + binaryData.fileName || 'protected_file', + binaryData.mimeType + ); + + // Create return item with binary data and metadata + const returnItem: INodeExecutionData = { + json: { + success: true, + originalFileStorageId: uploadResult.fileStorageId, + protectedFileStorageId: protectResult.fileStorageId, + secloreFileId: protectResult.secloreFileId, + hotfolderId, + fileName: binaryData.fileName, + fileSize: protectedFileData.length, + correlationId: correlationId || null, + }, + binary: { + [outputBinaryPropertyName]: outputBinaryData, + }, + }; + + returnData.push(returnItem); + } + } catch (error) { + // Handle errors gracefully + if (this.continueOnFail()) { + const returnItem: INodeExecutionData = { + json: { + success: false, + error: error.message, + itemIndex: i, + }, + }; + returnData.push(returnItem); + } else { + throw new NodeOperationError(this.getNode(), error.message, { + itemIndex: i, + }); + } + } + } + + return [returnData]; + } +} diff --git a/nodes/SecloreProtect/Services/SecloreDRMApiService.ts b/nodes/SecloreProtect/Services/SecloreDRMApiService.ts index 6322fff..9cfa37d 100644 --- a/nodes/SecloreProtect/Services/SecloreDRMApiService.ts +++ b/nodes/SecloreProtect/Services/SecloreDRMApiService.ts @@ -325,4 +325,43 @@ export class SecloreDRMApiService { } } + /** + * Downloads file with fileStorageId from file storage of currently logged in Tenant. + * NOTE: Files whose fileStorageId has 'DL_' prefix will be deleted from the file storage after download. + * + * @param fileStorageId - Storage ID of the file to be retrieved + * @param accessToken - JWT access token for authorization + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - The downloaded file data + * @throws Error on authentication failure or server error + */ + async downloadFile( + fileStorageId: string, + accessToken: string, + correlationId?: string + ): Promise { + const headers: { [key: string]: string } = { + 'Authorization': `Bearer ${accessToken}`, + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + const options: IHttpRequestOptions = { + method: 'GET', + url: `${this.baseUrl}/seclore/drm/filestorage/1.0/download/${fileStorageId}`, + headers, + encoding: 'arraybuffer', + }; + + try { + const response = await this.context.helpers.httpRequest(options); + return new Uint8Array(response as ArrayBuffer); + } catch (error: any) { + this.handleHttpError(error); + } + } + } diff --git a/nodes/SecloreProtect/Services/SecloreDRMFileService.ts b/nodes/SecloreProtect/Services/SecloreDRMFileService.ts index ae0b93d..ae078cc 100644 --- a/nodes/SecloreProtect/Services/SecloreDRMFileService.ts +++ b/nodes/SecloreProtect/Services/SecloreDRMFileService.ts @@ -265,6 +265,22 @@ export class SecloreDRMFileService { ); } + /** + * Download file with automatic authentication and retry + * NOTE: Files whose fileStorageId has 'DL_' prefix will be deleted from the file storage after download. + */ + async downloadFile( + fileStorageId: string, + correlationId?: string, + retryCount?: number + ): Promise { + return this.executeWithRetry( + (accessToken) => this.apiService.downloadFile(fileStorageId, accessToken, correlationId), + retryCount, + correlationId + ); + } + /** * Get current access token (for debugging/monitoring) */ @@ -279,10 +295,4 @@ export class SecloreDRMFileService { return !!this.accessToken && (!this.tokenExpiry || new Date() < this.tokenExpiry); } - /** - * Force logout (clears all tokens) - */ - logout(): void { - this.clearTokens(); - } } -- 2.40.1 From 0348021ab201fe22aebfacc2df6bf0120606b893 Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Wed, 22 Oct 2025 09:54:06 +0000 Subject: [PATCH 05/22] devcontainer added --- .devcontainer/Dockerfile | 43 +++++++++ .devcontainer/README.md | 158 ++++++++++++++++++++++++++++++ .devcontainer/devcontainer.json | 91 +++++++++++++++++ .devcontainer/docker-compose.yml | 37 +++++++ .devcontainer/post-create.sh | 161 +++++++++++++++++++++++++++++++ 5 files changed, 490 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/README.md create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/docker-compose.yml create mode 100644 .devcontainer/post-create.sh diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..25f7898 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,43 @@ +# Use the official Node.js development container as base +FROM mcr.microsoft.com/devcontainers/javascript-node:1-20-bullseye + +# Set the working directory +WORKDIR /workspaces + +# Install additional system dependencies that might be needed for n8n +RUN apt-get update && apt-get install -y \ + python3 \ + python3-pip \ + build-essential \ + curl \ + git \ + && rm -rf /var/lib/apt/lists/* + +# Switch to node user for security +USER node + +# Set up npm configuration for the node user +RUN npm config set prefix '/home/node/.npm-global' +ENV PATH=/home/node/.npm-global/bin:$PATH + +# Create necessary directories +RUN mkdir -p /home/node/.n8n \ + && mkdir -p /home/node/.npm-global + +# Pre-install some global packages to speed up container startup +RUN npm install -g npm@latest typescript ts-node nodemon + +# Set the default shell to bash for better development experience +SHELL ["/bin/bash", "-c"] + +# Expose the default n8n port +EXPOSE 5678 + +# Set environment variables for n8n +ENV N8N_HOST=0.0.0.0 +ENV N8N_PORT=5678 +ENV N8N_PROTOCOL=http +ENV NODE_ENV=development + +# Set the default command +CMD ["bash"] diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 0000000..9761db6 --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,158 @@ +# Seclore n8n Development Container + +This devcontainer provides a complete development environment for the Seclore n8n custom node project. + +## 🚀 Quick Start + +1. **Open in Container**: + - Open this project in VS Code + - Click "Reopen in Container" when prompted + - Or use Command Palette: `Dev Containers: Reopen in Container` + +2. **Wait for Setup**: + - The container will automatically install dependencies + - This may take a few minutes on first run + +3. **Start Development**: + ```bash + start_dev # Build and start n8n with custom nodes + ``` + +4. **Access n8n**: + - Open http://localhost:5678 in your browser + - Your custom Seclore Protect node will be available + +## 📦 What's Included + +### Software +- **Node.js 20.x** - Latest LTS version +- **npm** - Latest version +- **n8n** - Latest version (globally installed) +- **TypeScript** - For development +- **ts-node** - TypeScript execution +- **nodemon** - Auto-restart on changes + +### VS Code Extensions +- **TypeScript & JavaScript**: Enhanced language support +- **ESLint & Prettier**: Code formatting and linting +- **Node.js IntelliSense**: Smart completions for Node.js +- **npm IntelliSense**: Package import suggestions +- **Git Tools**: GitLens and Git Graph +- **REST Client**: API testing tools +- **Docker**: Container management + +### Development Tools +- **build_and_test**: Build project and run linter +- **start_dev**: Build and start n8n with custom nodes +- **watch_build**: Auto-rebuild on file changes +- **~/start-n8n.sh**: Direct n8n startup script + +## 🔧 Development Workflow + +### 1. Make Changes +Edit your TypeScript files in: +- `nodes/SecloreProtect/` - Main node logic +- `Services/` - API service classes +- `credentials/` - Credential definitions + +### 2. Build & Test +```bash +build_and_test # Compile TypeScript and run linter +``` + +### 3. Start n8n +```bash +start_dev # Build and start n8n +# OR +~/start-n8n.sh # Start n8n directly (after manual build) +``` + +### 4. Auto-rebuild (Optional) +```bash +watch_build # Watch for changes and auto-rebuild +``` + +## 🌐 Port Forwarding + +The container automatically forwards these ports: +- **5678**: n8n web interface +- **3000**: Development server +- **8080**: Alternative port + +## 📁 Volume Mounts + +- **Project Files**: `/workspaces/Seclore n8n` (your source code) +- **n8n Data**: `~/.n8n` (n8n configuration and data) +- **Node Modules**: Cached for faster rebuilds + +## 🔐 Environment Variables + +The container sets up these environment variables: +```bash +N8N_HOST=0.0.0.0 +N8N_PORT=5678 +N8N_PROTOCOL=http +NODE_ENV=development +N8N_LOG_LEVEL=debug +N8N_CUSTOM_EXTENSIONS=/workspaces/Seclore n8n +``` + +## 🛠️ Customization + +### Adding Extensions +Edit `.devcontainer/devcontainer.json` and add extension IDs to the `extensions` array. + +### Changing Ports +Modify the `forwardPorts` array in `devcontainer.json`. + +### Additional Software +Add installation commands to `.devcontainer/post-create.sh`. + +## 🐛 Troubleshooting + +### Container Won't Start +- Check Docker is running +- Ensure you have enough disk space +- Try rebuilding: `Dev Containers: Rebuild Container` + +### n8n Won't Start +- Check if port 5678 is available +- Verify the build completed successfully +- Check logs for error messages + +### Build Errors +- Run `npm install` to ensure dependencies are installed +- Check TypeScript compilation errors +- Verify all import paths are correct + +### Custom Node Not Visible +- Ensure the build completed successfully +- Check that `N8N_CUSTOM_EXTENSIONS` points to the correct path +- Restart n8n after making changes + +## 📚 Useful Commands + +```bash +# Development +npm run build # Build the project +npm run lint # Run ESLint +npm run lint:fix # Fix ESLint issues + +# n8n +n8n start # Start n8n manually +n8n --help # n8n help + +# Container +cat ~/welcome.txt # Show welcome message +source ~/dev-scripts.sh # Reload development functions +``` + +## 🎯 Tips + +1. **Use the integrated terminal** in VS Code for the best experience +2. **Enable auto-save** in VS Code for faster development cycles +3. **Use the REST Client extension** to test your APIs +4. **Check the n8n logs** in the terminal for debugging +5. **Use `watch_build`** during active development for auto-rebuilds + +Happy coding! 🚀 diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..afebf6e --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,91 @@ +{ + "name": "Seclore n8n Development", + "image": "mcr.microsoft.com/devcontainers/javascript-node:1-20-bullseye", + + "features": { + "ghcr.io/devcontainers/features/git:1": {}, + "ghcr.io/devcontainers/features/github-cli:1": {} + }, + + "customizations": { + "vscode": { + "extensions": [ + // TypeScript and JavaScript + "ms-vscode.vscode-typescript-next", + "bradlc.vscode-tailwindcss", + "esbenp.prettier-vscode", + "dbaeumer.vscode-eslint", + + // Node.js specific + "ms-vscode.vscode-node-azure-pack", + "christian-kohler.npm-intellisense", + "eg2.vscode-npm-script", + "leizongmin.node-module-intellisense", + + // General development + "ms-vscode.vscode-json", + "redhat.vscode-yaml", + "ms-vscode.hexdump", + "ms-vscode.vscode-markdown", + + // Git and version control + "mhutchie.git-graph", + "eamodio.gitlens", + + // API and REST + "humao.rest-client", + "rangav.vscode-thunder-client", + + // Utilities + "formulahendry.auto-rename-tag", + "streetsidesoftware.code-spell-checker", + "ms-vscode.vscode-todo-highlight", + "gruntfuggly.todo-tree", + + // Docker (for n8n) + "ms-azuretools.vscode-docker" + ], + + "settings": { + "typescript.preferences.includePackageJsonAutoImports": "on", + "typescript.suggest.autoImports": true, + "typescript.updateImportsOnFileMove.enabled": "always", + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit", + "source.organizeImports": "explicit" + }, + "files.associations": { + "*.json": "jsonc" + }, + "npm.enableScriptExplorer": true, + "npm.scriptExplorerAction": "run" + } + } + }, + + "forwardPorts": [5678, 3000, 8080], + "portsAttributes": { + "5678": { + "label": "n8n", + "onAutoForward": "notify" + }, + "3000": { + "label": "Development Server", + "onAutoForward": "notify" + }, + "8080": { + "label": "Alternative Port", + "onAutoForward": "ignore" + } + }, + + "postCreateCommand": ".devcontainer/post-create.sh", + + "remoteUser": "node", + + "mounts": [ + "source=${localWorkspaceFolder}/.n8n,target=/home/node/.n8n,type=bind,consistency=cached" + ] +} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml new file mode 100644 index 0000000..7bf8325 --- /dev/null +++ b/.devcontainer/docker-compose.yml @@ -0,0 +1,37 @@ +version: '3.8' + +services: + app: + build: + context: . + dockerfile: Dockerfile + + volumes: + - ../..:/workspaces:cached + - node_modules:/workspaces/Seclore\ n8n/node_modules + - n8n_data:/home/node/.n8n + + ports: + - "5678:5678" # n8n + - "3000:3000" # Development server + - "8080:8080" # Alternative port + + environment: + - N8N_HOST=0.0.0.0 + - N8N_PORT=5678 + - N8N_PROTOCOL=http + - NODE_ENV=development + - N8N_LOG_LEVEL=debug + + # Keep container running + command: sleep infinity + + # Use node user for security + user: node + + # Set working directory + working_dir: /workspaces/Seclore n8n + +volumes: + node_modules: + n8n_data: diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh new file mode 100644 index 0000000..c5f1de9 --- /dev/null +++ b/.devcontainer/post-create.sh @@ -0,0 +1,161 @@ +#!/bin/bash + +# Make script executable and set proper permissions +chmod +x /workspaces/*/devcontainer/post-create.sh + +echo "🚀 Setting up Seclore n8n Development Environment..." + +# Update npm to latest version +echo "📦 Updating npm..." +npm install -g npm@latest + +# Install n8n globally +echo "🔧 Installing n8n..." +npm install -g n8n + +# Install common development tools +echo "🛠️ Installing development tools..." +npm install -g typescript ts-node nodemon + +# Install project dependencies +echo "📋 Installing project dependencies..." +npm install + +# Create .n8n directory if it doesn't exist +mkdir -p ~/.n8n + +# Set up n8n environment variables +echo "⚙️ Setting up n8n configuration..." +cat > ~/.n8n/.env << EOF +# n8n Configuration +N8N_BASIC_AUTH_ACTIVE=false +N8N_HOST=0.0.0.0 +N8N_PORT=5678 +N8N_PROTOCOL=http + +# Development settings +NODE_ENV=development +N8N_LOG_LEVEL=debug + +# Custom nodes path +N8N_CUSTOM_EXTENSIONS=/workspaces/Seclore\ n8n +EOF + +# Create a startup script for n8n +echo "📝 Creating n8n startup script..." +cat > ~/start-n8n.sh << 'EOF' +#!/bin/bash +echo "🎯 Starting n8n with custom Seclore nodes..." +echo "📍 Custom nodes path: /workspaces/Seclore n8n" +echo "🌐 n8n will be available at: http://localhost:5678" +echo "" + +# Build the custom nodes first +cd "/workspaces/Seclore n8n" +npm run build + +# Start n8n with custom nodes +N8N_CUSTOM_EXTENSIONS="/workspaces/Seclore n8n" n8n start +EOF + +chmod +x ~/start-n8n.sh + +# Create development scripts +echo "📋 Creating development scripts..." +cat > ~/dev-scripts.sh << 'EOF' +#!/bin/bash + +# Function to build and test the custom node +build_and_test() { + echo "🔨 Building Seclore n8n nodes..." + cd "/workspaces/Seclore n8n" + npm run build + + if [ $? -eq 0 ]; then + echo "✅ Build successful!" + echo "🧪 Running linter..." + npm run lint + else + echo "❌ Build failed!" + return 1 + fi +} + +# Function to start n8n in development mode +start_dev() { + echo "🚀 Starting n8n in development mode..." + build_and_test && ~/start-n8n.sh +} + +# Function to watch for changes and rebuild +watch_build() { + echo "👀 Watching for changes..." + cd "/workspaces/Seclore n8n" + npm run build:watch +} + +# Export functions +export -f build_and_test +export -f start_dev +export -f watch_build + +echo "📚 Available commands:" +echo " build_and_test - Build and lint the project" +echo " start_dev - Build and start n8n with custom nodes" +echo " watch_build - Watch for changes and rebuild automatically" +echo " ~/start-n8n.sh - Start n8n directly (after manual build)" +EOF + +chmod +x ~/dev-scripts.sh + +# Add to bashrc for easy access +echo "source ~/dev-scripts.sh" >> ~/.bashrc + +# Create a welcome message +echo "📄 Creating welcome message..." +cat > ~/welcome.txt << 'EOF' +🎉 Seclore n8n Development Environment Ready! + +📁 Project Structure: + /workspaces/Seclore n8n/ + ├── nodes/SecloreProtect/ # Custom n8n node + ├── credentials/ # Credential types + └── Services/ # API services + +🚀 Quick Start: + 1. Run: start_dev # Build and start n8n + 2. Open: http://localhost:5678 # Access n8n interface + 3. Use: build_and_test # Build and test changes + +🔧 Development Commands: + - start_dev : Build project and start n8n + - build_and_test : Build project and run linter + - watch_build : Auto-rebuild on file changes + - ~/start-n8n.sh : Start n8n (manual build required) + +📦 Installed Tools: + - Node.js 20.x + - npm (latest) + - n8n (latest) + - TypeScript + - ts-node + - nodemon + +🔌 VS Code Extensions: + - TypeScript & JavaScript support + - ESLint & Prettier + - Node.js IntelliSense + - Git tools + - REST client for API testing + +Happy coding! 🎯 +EOF + +# Display welcome message +echo "" +echo "✅ Setup complete!" +echo "" +cat ~/welcome.txt +echo "" +echo "💡 Tip: Run 'cat ~/welcome.txt' anytime to see this guide again." +echo "" -- 2.40.1 From 23179f45132d44ef286bbd252685a05a247ed0b8 Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Wed, 22 Oct 2025 09:55:52 +0000 Subject: [PATCH 06/22] interfaces added --- .../Services/Interfaces/ErrorInterfaces.ts | 6 +- .../Interfaces/FileStorageInterfaces.ts | 18 ++--- .../Services/Interfaces/LoginInterfaces.ts | 26 +++---- .../Services/Interfaces/ProtectInterfaces.ts | 74 +++++++++---------- .../Interfaces/UnprotectInterfaces.ts | 14 ++-- 5 files changed, 69 insertions(+), 69 deletions(-) diff --git a/nodes/SecloreProtect/Services/Interfaces/ErrorInterfaces.ts b/nodes/SecloreProtect/Services/Interfaces/ErrorInterfaces.ts index b77ee0d..11200d2 100644 --- a/nodes/SecloreProtect/Services/Interfaces/ErrorInterfaces.ts +++ b/nodes/SecloreProtect/Services/Interfaces/ErrorInterfaces.ts @@ -1,4 +1,4 @@ -export interface IErrorResponse { - errorCode: string; - errorMessage: string; +export interface IErrorResponse { + errorCode: string; + errorMessage: string; } \ No newline at end of file diff --git a/nodes/SecloreProtect/Services/Interfaces/FileStorageInterfaces.ts b/nodes/SecloreProtect/Services/Interfaces/FileStorageInterfaces.ts index 3df394f..de8e3a3 100644 --- a/nodes/SecloreProtect/Services/Interfaces/FileStorageInterfaces.ts +++ b/nodes/SecloreProtect/Services/Interfaces/FileStorageInterfaces.ts @@ -1,9 +1,9 @@ -export interface IFileUploadResponse { - fileStorageId: string; - fileName: string; - downloadUrl: string; - fileType: string; - fileSize: number; - secloreFileId: string; - protected: boolean; -} +export interface IFileUploadResponse { + fileStorageId: string; + fileName: string; + downloadUrl: string; + fileType: string; + fileSize: number; + secloreFileId: string; + protected: boolean; +} diff --git a/nodes/SecloreProtect/Services/Interfaces/LoginInterfaces.ts b/nodes/SecloreProtect/Services/Interfaces/LoginInterfaces.ts index d971879..612ae24 100644 --- a/nodes/SecloreProtect/Services/Interfaces/LoginInterfaces.ts +++ b/nodes/SecloreProtect/Services/Interfaces/LoginInterfaces.ts @@ -1,13 +1,13 @@ -export interface ILoginRequest { - tenantId: string; - tenantSecret: string; -} - -export interface ILoginResponse { - accessToken: string; - refreshToken: string; -} - -export interface IRefreshTokenRequest { - refreshToken: string; -} +export interface ILoginRequest { + tenantId: string; + tenantSecret: string; +} + +export interface ILoginResponse { + accessToken: string; + refreshToken: string; +} + +export interface IRefreshTokenRequest { + refreshToken: string; +} diff --git a/nodes/SecloreProtect/Services/Interfaces/ProtectInterfaces.ts b/nodes/SecloreProtect/Services/Interfaces/ProtectInterfaces.ts index e9cb61b..8090922 100644 --- a/nodes/SecloreProtect/Services/Interfaces/ProtectInterfaces.ts +++ b/nodes/SecloreProtect/Services/Interfaces/ProtectInterfaces.ts @@ -1,37 +1,37 @@ -export interface IExtRefProtectionDetail { - externalReferenceId: string; - externalReferenceName?: string; - externalReferenceData?: string; - externalAppId?: string; -} - -export interface IProtectWithExternalRefIdRequest { - hotfolderExternalReference: IExtRefProtectionDetail; - fileExternalReference?: IExtRefProtectionDetail; - fileStorageId: string; -} - -export interface IProtectWithExternalRefIdResponse { - fileStorageId: string; - secloreFileId: string; -} - -export interface IProtectWithFileIdRequest { - existingProtectedFileId: string; - fileStorageId: string; -} - -export interface IProtectWithFileIdResponse { - fileStorageId: string; - secloreFileId: string; -} - -export interface IProtectWithHotFolderRequest { - hotfolderId: string; - fileStorageId: string; -} - -export interface IProtectWithHotFolderResponse { - fileStorageId: string; - secloreFileId: string; -} +export interface IExtRefProtectionDetail { + externalReferenceId: string; + externalReferenceName?: string; + externalReferenceData?: string; + externalAppId?: string; +} + +export interface IProtectWithExternalRefIdRequest { + hotfolderExternalReference: IExtRefProtectionDetail; + fileExternalReference?: IExtRefProtectionDetail; + fileStorageId: string; +} + +export interface IProtectWithExternalRefIdResponse { + fileStorageId: string; + secloreFileId: string; +} + +export interface IProtectWithFileIdRequest { + existingProtectedFileId: string; + fileStorageId: string; +} + +export interface IProtectWithFileIdResponse { + fileStorageId: string; + secloreFileId: string; +} + +export interface IProtectWithHotFolderRequest { + hotfolderId: string; + fileStorageId: string; +} + +export interface IProtectWithHotFolderResponse { + fileStorageId: string; + secloreFileId: string; +} diff --git a/nodes/SecloreProtect/Services/Interfaces/UnprotectInterfaces.ts b/nodes/SecloreProtect/Services/Interfaces/UnprotectInterfaces.ts index 51c2b0e..cd9bedb 100644 --- a/nodes/SecloreProtect/Services/Interfaces/UnprotectInterfaces.ts +++ b/nodes/SecloreProtect/Services/Interfaces/UnprotectInterfaces.ts @@ -1,7 +1,7 @@ -export interface IUnprotectRequest { - fileStorageId: string; -} - -export interface IUnprotectResponse { - fileStorageId: string; -} +export interface IUnprotectRequest { + fileStorageId: string; +} + +export interface IUnprotectResponse { + fileStorageId: string; +} -- 2.40.1 From 9f6db09edf80664e3271c9d22f472ee02b2a7bfa Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Wed, 22 Oct 2025 10:14:14 +0000 Subject: [PATCH 07/22] npm build successful --- .gitignore | 2 + nodes/SecloreProtect/SecloreProtect.node.ts | 414 ++++++++++---------- package.json | 7 +- tsconfig.json | 3 +- 4 files changed, 214 insertions(+), 212 deletions(-) diff --git a/.gitignore b/.gitignore index de4d1f0..2a61503 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ dist node_modules +package-lock.json +.n8n/.env \ No newline at end of file diff --git a/nodes/SecloreProtect/SecloreProtect.node.ts b/nodes/SecloreProtect/SecloreProtect.node.ts index accc028..5ea9301 100644 --- a/nodes/SecloreProtect/SecloreProtect.node.ts +++ b/nodes/SecloreProtect/SecloreProtect.node.ts @@ -1,229 +1,227 @@ import { - IExecuteFunctions, - INodeExecutionData, - INodeType, - INodeTypeDescription, - NodeOperationError, + IExecuteFunctions, + INodeExecutionData, + INodeType, + INodeTypeDescription, + NodeOperationError, } from 'n8n-workflow'; import { SecloreDRMFileService } from './Services/SecloreDRMFileService'; export class SecloreProtect implements INodeType { - description: INodeTypeDescription = { - displayName: 'Seclore Protect', - name: 'secloreProtect', - icon: 'file:SecloreProtect.svg', - group: ['transform'], - version: 1, - subtitle: '={{$parameter["operation"]}}', - description: 'Protect files using Seclore DRM with HotFolder configuration', - defaults: { - name: 'Seclore Protect', - }, - inputs: ['main'], - outputs: ['main'], - credentials: [ - { - name: 'secloreProtectApi', - required: true, - }, - ], - properties: [ - { - displayName: 'Operation', - name: 'operation', - type: 'options', - noDataExpression: true, - options: [ - { - name: 'Protect File with HotFolder', - value: 'protectWithHotFolder', - description: 'Protect a file using HotFolder ID configuration', - action: 'Protect file with HotFolder', - }, - ], - default: 'protectWithHotFolder', - }, - { - displayName: 'HotFolder ID', - name: 'hotfolderId', - type: 'string', - required: true, - default: '', - placeholder: 'e.g., hf-12345', - description: 'The ID of the HotFolder configuration to use for protection', - displayOptions: { - show: { - operation: ['protectWithHotFolder'], - }, - }, - }, - { - displayName: 'Input Binary Property', - name: 'binaryPropertyName', - type: 'string', - default: 'data', - required: true, - description: 'Name of the binary property that contains the file to protect', - displayOptions: { - show: { - operation: ['protectWithHotFolder'], - }, - }, - }, - { - displayName: 'Output Binary Property', - name: 'outputBinaryPropertyName', - type: 'string', - default: 'data', - required: true, - description: 'Name of the binary property where the protected file will be stored', - displayOptions: { - show: { - operation: ['protectWithHotFolder'], - }, - }, - }, - { - displayName: 'Correlation ID', - name: 'correlationId', - type: 'string', - default: '', - placeholder: 'e.g., req-12345', - description: 'Optional correlation ID for request tracking and logging', - displayOptions: { - show: { - operation: ['protectWithHotFolder'], - }, - }, - }, - { - displayName: 'Retry Count', - name: 'retryCount', - type: 'number', - default: 3, - description: 'Number of retry attempts for failed requests', - displayOptions: { - show: { - operation: ['protectWithHotFolder'], - }, - }, - }, - ], - }; + description: INodeTypeDescription = { + displayName: 'Seclore Protect', + name: 'secloreProtect', + icon: 'file:SecloreProtect.svg', + group: ['transform'], + version: 1, + subtitle: '={{$parameter["operation"]}}', + description: 'Protect files using Seclore DRM with HotFolder configuration', + defaults: { + name: 'Seclore Protect', + }, + inputs: ['main'], + outputs: ['main'], + credentials: [ + { + name: 'secloreProtectApi', + required: true, + }, + ], + properties: [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + noDataExpression: true, + options: [ + { + name: 'Protect File with HotFolder', + value: 'protectWithHotFolder', + description: 'Protect a file using HotFolder ID configuration', + action: 'Protect file with HotFolder', + }, + ], + default: 'protectWithHotFolder', + }, + { + displayName: 'HotFolder ID', + name: 'hotfolderId', + type: 'string', + required: true, + default: '', + placeholder: 'e.g., hf-12345', + description: 'The ID of the HotFolder configuration to use for protection', + displayOptions: { + show: { + operation: ['protectWithHotFolder'], + }, + }, + }, + { + displayName: 'Input Binary Property', + name: 'binaryPropertyName', + type: 'string', + default: 'data', + required: true, + description: 'Name of the binary property that contains the file to protect', + displayOptions: { + show: { + operation: ['protectWithHotFolder'], + }, + }, + }, + { + displayName: 'Output Binary Property', + name: 'outputBinaryPropertyName', + type: 'string', + default: 'data', + required: true, + description: 'Name of the binary property where the protected file will be stored', + displayOptions: { + show: { + operation: ['protectWithHotFolder'], + }, + }, + }, + { + displayName: 'Correlation ID', + name: 'correlationId', + type: 'string', + default: '', + placeholder: 'e.g., req-12345', + description: 'Optional correlation ID for request tracking and logging', + displayOptions: { + show: { + operation: ['protectWithHotFolder'], + }, + }, + }, + { + displayName: 'Retry Count', + name: 'retryCount', + type: 'number', + default: 3, + description: 'Number of retry attempts for failed requests', + displayOptions: { + show: { + operation: ['protectWithHotFolder'], + }, + }, + }, + ], + }; - async execute(this: IExecuteFunctions): Promise { - const items = this.getInputData(); - const returnData: INodeExecutionData[] = []; + async execute(this: IExecuteFunctions): Promise { + const items = this.getInputData(); + const returnData: INodeExecutionData[] = []; - // Get credentials - const credentials = await this.getCredentials('secloreProtectApi'); - const baseUrl = credentials.baseUrl as string; - const tenantId = credentials.tenantId as string; - const tenantSecret = credentials.tenantSecret as string; + // Get credentials + const credentials = await this.getCredentials('secloreProtectApi'); + const baseUrl = credentials.baseUrl as string; + const tenantId = credentials.tenantId as string; + const tenantSecret = credentials.tenantSecret as string; - // Initialize the file service - const fileService = new SecloreDRMFileService( - this, - baseUrl, - tenantId, - tenantSecret - ); + // Initialize the file service + const fileService = new SecloreDRMFileService(this, baseUrl, tenantId, tenantSecret); - // Get node parameters - const operation = this.getNodeParameter('operation', 0) as string; + // Get node parameters + const operation = this.getNodeParameter('operation', 0) as string; - for (let i = 0; i < items.length; i++) { - try { - if (operation === 'protectWithHotFolder') { - // Get parameters for this item - const hotfolderId = this.getNodeParameter('hotfolderId', i) as string; - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; - const outputBinaryPropertyName = this.getNodeParameter('outputBinaryPropertyName', i) as string; - const correlationId = this.getNodeParameter('correlationId', i) as string; - const retryCount = this.getNodeParameter('retryCount', i) as number; + for (let i = 0; i < items.length; i++) { + try { + if (operation === 'protectWithHotFolder') { + // Get parameters for this item + const hotfolderId = this.getNodeParameter('hotfolderId', i) as string; + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; + const outputBinaryPropertyName = this.getNodeParameter( + 'outputBinaryPropertyName', + i, + ) as string; + const correlationId = this.getNodeParameter('correlationId', i) as string; + const retryCount = this.getNodeParameter('retryCount', i) as number; - // Validate required parameters - if (!hotfolderId) { - throw new NodeOperationError(this.getNode(), 'HotFolder ID is required', { - itemIndex: i, - }); - } + // Validate required parameters + if (!hotfolderId) { + throw new NodeOperationError(this.getNode(), 'HotFolder ID is required', { + itemIndex: i, + }); + } - // Get input binary data - const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); - const fileBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); + // Get input binary data + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); + const fileBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); - // Upload the file first - const uploadResult = await fileService.uploadFile( - new Uint8Array(fileBuffer), - binaryData.fileName || 'file', - correlationId || undefined, - retryCount - ); + // Upload the file first + const uploadResult = await fileService.uploadFile( + new Uint8Array(fileBuffer), + binaryData.fileName || 'file', + correlationId || undefined, + retryCount, + ); - // Protect the uploaded file with HotFolder - const protectResult = await fileService.protectWithHotFolder( - { - hotfolderId, - fileStorageId: uploadResult.fileStorageId, - }, - correlationId || undefined, - retryCount - ); + // Protect the uploaded file with HotFolder + const protectResult = await fileService.protectWithHotFolder( + { + hotfolderId, + fileStorageId: uploadResult.fileStorageId, + }, + correlationId || undefined, + retryCount, + ); - // Download the protected file - const protectedFileData = await fileService.downloadFile( - protectResult.fileStorageId, - correlationId || undefined, - retryCount - ); + // Download the protected file + const protectedFileData = await fileService.downloadFile( + protectResult.fileStorageId, + correlationId || undefined, + retryCount, + ); - // Create output binary data - const outputBinaryData = await this.helpers.prepareBinaryData( - protectedFileData.buffer, - binaryData.fileName || 'protected_file', - binaryData.mimeType - ); + // Create output binary data + const outputBinaryData = await this.helpers.prepareBinaryData( + Buffer.from(protectedFileData), + binaryData.fileName || 'protected_file', + binaryData.mimeType, + ); - // Create return item with binary data and metadata - const returnItem: INodeExecutionData = { - json: { - success: true, - originalFileStorageId: uploadResult.fileStorageId, - protectedFileStorageId: protectResult.fileStorageId, - secloreFileId: protectResult.secloreFileId, - hotfolderId, - fileName: binaryData.fileName, - fileSize: protectedFileData.length, - correlationId: correlationId || null, - }, - binary: { - [outputBinaryPropertyName]: outputBinaryData, - }, - }; + // Create return item with binary data and metadata + const returnItem: INodeExecutionData = { + json: { + success: true, + originalFileStorageId: uploadResult.fileStorageId, + protectedFileStorageId: protectResult.fileStorageId, + secloreFileId: protectResult.secloreFileId, + hotfolderId, + fileName: binaryData.fileName, + fileSize: protectedFileData.length, + correlationId: correlationId || null, + }, + binary: { + [outputBinaryPropertyName]: outputBinaryData, + }, + }; - returnData.push(returnItem); - } - } catch (error) { - // Handle errors gracefully - if (this.continueOnFail()) { - const returnItem: INodeExecutionData = { - json: { - success: false, - error: error.message, - itemIndex: i, - }, - }; - returnData.push(returnItem); - } else { - throw new NodeOperationError(this.getNode(), error.message, { - itemIndex: i, - }); - } - } - } + returnData.push(returnItem); + } + } catch (error) { + // Handle errors gracefully + if (this.continueOnFail()) { + const returnItem: INodeExecutionData = { + json: { + success: false, + error: error.message, + itemIndex: i, + }, + }; + returnData.push(returnItem); + } else { + throw new NodeOperationError(this.getNode(), error.message, { + itemIndex: i, + }); + } + } + } - return [returnData]; - } + return [returnData]; + } } diff --git a/package.json b/package.json index 395533e..7f5d8eb 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,15 @@ { "name": "n8n-nodes-secloreprotect", "version": "0.1.0", - "description": "", + "description": "n8n community node for Seclore Protect - secure file protection using DRM technology", "license": "MIT", "homepage": "", "keywords": [ "n8n-community-node-package" ], "author": { - "name": "", - "email": "" + "name": "Seclore Technology", + "email": "support@seclore.com" }, "repository": { "type": "git", @@ -39,6 +39,7 @@ }, "devDependencies": { "@n8n/node-cli": "*", + "@types/node": "^24.9.1", "eslint": "9.32.0", "prettier": "3.6.2", "release-it": "^19.0.4", diff --git a/tsconfig.json b/tsconfig.json index b73660f..e084103 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,8 @@ "declaration": true, "sourceMap": true, "skipLibCheck": true, - "outDir": "./dist/" + "outDir": "./dist/", + "types": ["node"] }, "include": ["credentials/**/*", "nodes/**/*", "nodes/**/*.json", "package.json"] } -- 2.40.1 From 6e7e28a2e60dcd6c608a530fccc0257e3189205b Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Fri, 24 Oct 2025 06:10:55 +0000 Subject: [PATCH 08/22] POC successful for protect with hf --- .gitignore | 2 +- credentials/SecloreProtect.credentials.ts | 58 -- credentials/SecloreProtectApi.credentials.ts | 58 ++ .../SecloreProtect.dark.svg | 0 icons/SecloreProtect.light.svg | 11 + icons/github.dark.svg | 3 - icons/github.svg | 3 - nodes/SecloreProtect/SecloreProtect.node.ts | 19 +- .../Services/SecloreDRMApiService.ts | 668 +++++++++--------- .../Services/SecloreDRMFileService.ts | 549 +++++++------- 10 files changed, 708 insertions(+), 663 deletions(-) delete mode 100644 credentials/SecloreProtect.credentials.ts create mode 100644 credentials/SecloreProtectApi.credentials.ts rename nodes/SecloreProtect/SecloreProtect.svg => icons/SecloreProtect.dark.svg (100%) create mode 100644 icons/SecloreProtect.light.svg delete mode 100644 icons/github.dark.svg delete mode 100644 icons/github.svg diff --git a/.gitignore b/.gitignore index 2a61503..b64847f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ dist node_modules package-lock.json -.n8n/.env \ No newline at end of file +.n8n \ No newline at end of file diff --git a/credentials/SecloreProtect.credentials.ts b/credentials/SecloreProtect.credentials.ts deleted file mode 100644 index f2c60bc..0000000 --- a/credentials/SecloreProtect.credentials.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { - ICredentialTestRequest, - ICredentialType, - INodeProperties, -} from 'n8n-workflow'; - -export class SecloreProtectApi implements ICredentialType { - name = 'secloreProtectApi'; - displayName = 'Seclore Protect API'; - documentationUrl = 'https://docs.seclore.com/'; - properties: INodeProperties[] = [ - { - displayName: 'Base URL', - name: 'baseUrl', - type: 'string', - default: 'https://api.seclore.com', - placeholder: 'https://api.seclore.com', - description: 'The base URL of your Seclore API instance', - required: true, - }, - { - displayName: 'Tenant ID', - name: 'tenantId', - type: 'string', - default: '', - placeholder: 'your-tenant-id', - description: 'Your Seclore tenant ID', - required: true, - }, - { - displayName: 'Tenant Secret', - name: 'tenantSecret', - type: 'string', - typeOptions: { - password: true, - }, - default: '', - description: 'Your Seclore tenant secret', - required: true, - }, - ]; - - // Optional: Add credential test - test: ICredentialTestRequest = { - request: { - baseURL: '={{$credentials.baseUrl}}', - url: '/seclore/drm/1.0/auth/login', - method: 'POST', - body: { - tenantId: '={{$credentials.tenantId}}', - tenantSecret: '={{$credentials.tenantSecret}}', - }, - headers: { - 'Content-Type': 'application/json', - }, - }, - }; -} diff --git a/credentials/SecloreProtectApi.credentials.ts b/credentials/SecloreProtectApi.credentials.ts new file mode 100644 index 0000000..f034503 --- /dev/null +++ b/credentials/SecloreProtectApi.credentials.ts @@ -0,0 +1,58 @@ +import { ICredentialTestRequest, ICredentialType, INodeProperties, Icon } from 'n8n-workflow'; + +export class SecloreProtectApi implements ICredentialType { + name = 'secloreProtectApi'; + displayName = 'Seclore Protect API'; + documentationUrl = 'https://docs.seclore.com/'; + icon: Icon = { + light: 'file:../icons/SecloreProtect.light.svg', + dark: 'file:../icons/SecloreProtect.dark.svg', + }; + properties: INodeProperties[] = [ + { + displayName: 'Base URL', + name: 'baseUrl', + type: 'string', + default: 'https://api.seclore.com', + placeholder: 'https://api.seclore.com', + description: 'The base URL of your Seclore API instance', + required: true, + }, + { + displayName: 'Tenant ID', + name: 'tenantId', + type: 'string', + default: '', + placeholder: 'your-tenant-id', + description: 'Your Seclore tenant ID', + required: true, + }, + { + displayName: 'Tenant Secret', + name: 'tenantSecret', + type: 'string', + typeOptions: { + password: true, + }, + default: '', + description: 'Your Seclore tenant secret', + required: true, + }, + ]; + + // Optional: Add credential test + test: ICredentialTestRequest = { + request: { + baseURL: '={{$credentials.baseUrl}}', + url: '/seclore/drm/1.0/auth/login', + method: 'POST', + body: { + tenantId: '={{$credentials.tenantId}}', + tenantSecret: '={{$credentials.tenantSecret}}', + }, + headers: { + 'Content-Type': 'application/json', + }, + }, + }; +} diff --git a/nodes/SecloreProtect/SecloreProtect.svg b/icons/SecloreProtect.dark.svg similarity index 100% rename from nodes/SecloreProtect/SecloreProtect.svg rename to icons/SecloreProtect.dark.svg diff --git a/icons/SecloreProtect.light.svg b/icons/SecloreProtect.light.svg new file mode 100644 index 0000000..58541ba --- /dev/null +++ b/icons/SecloreProtect.light.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/icons/github.dark.svg b/icons/github.dark.svg deleted file mode 100644 index 0366b08..0000000 --- a/icons/github.dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/icons/github.svg b/icons/github.svg deleted file mode 100644 index fe1ac05..0000000 --- a/icons/github.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/nodes/SecloreProtect/SecloreProtect.node.ts b/nodes/SecloreProtect/SecloreProtect.node.ts index 5ea9301..e51750b 100644 --- a/nodes/SecloreProtect/SecloreProtect.node.ts +++ b/nodes/SecloreProtect/SecloreProtect.node.ts @@ -12,7 +12,8 @@ export class SecloreProtect implements INodeType { description: INodeTypeDescription = { displayName: 'Seclore Protect', name: 'secloreProtect', - icon: 'file:SecloreProtect.svg', + icon: 'file:../../icons/SecloreProtect.light.svg', + usableAsTool: true, // TODO: make it false/ don't allow it to be used as a tool group: ['transform'], version: 1, subtitle: '={{$parameter["operation"]}}', @@ -39,7 +40,7 @@ export class SecloreProtect implements INodeType { name: 'Protect File with HotFolder', value: 'protectWithHotFolder', description: 'Protect a file using HotFolder ID configuration', - action: 'Protect file with HotFolder', + action: 'Protect file with hotfolder', }, ], default: 'protectWithHotFolder', @@ -129,6 +130,8 @@ export class SecloreProtect implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { + console.log('Data'); + console.log(items[i]); try { if (operation === 'protectWithHotFolder') { // Get parameters for this item @@ -148,10 +151,16 @@ export class SecloreProtect implements INodeType { }); } + console.log('assertBinaryData'); // Get input binary data const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); + + console.log('getBinaryDataBuffer'); const fileBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); + console.log('fileBuffer', fileBuffer); + console.log('binaryData.fileName', binaryData.fileName); + // Upload the file first const uploadResult = await fileService.uploadFile( new Uint8Array(fileBuffer), @@ -160,6 +169,8 @@ export class SecloreProtect implements INodeType { retryCount, ); + console.log('File upload response', uploadResult); + // Protect the uploaded file with HotFolder const protectResult = await fileService.protectWithHotFolder( { @@ -170,6 +181,8 @@ export class SecloreProtect implements INodeType { retryCount, ); + console.log('File protect response', protectResult); + // Download the protected file const protectedFileData = await fileService.downloadFile( protectResult.fileStorageId, @@ -177,6 +190,8 @@ export class SecloreProtect implements INodeType { retryCount, ); + console.log('Protected file data', protectedFileData); + // Create output binary data const outputBinaryData = await this.helpers.prepareBinaryData( Buffer.from(protectedFileData), diff --git a/nodes/SecloreProtect/Services/SecloreDRMApiService.ts b/nodes/SecloreProtect/Services/SecloreDRMApiService.ts index 9cfa37d..f8713d7 100644 --- a/nodes/SecloreProtect/Services/SecloreDRMApiService.ts +++ b/nodes/SecloreProtect/Services/SecloreDRMApiService.ts @@ -1,367 +1,387 @@ -import { IExecuteFunctions, IHttpRequestOptions } from 'n8n-workflow'; -import { ILoginRequest, ILoginResponse, IRefreshTokenRequest } from './Interfaces/LoginInterfaces'; +import { IExecuteFunctions, IHttpRequestOptions, NodeApiError } from 'n8n-workflow'; import { IErrorResponse } from './Interfaces/ErrorInterfaces'; -import { IProtectWithExternalRefIdRequest, IProtectWithExternalRefIdResponse, IProtectWithFileIdRequest, IProtectWithFileIdResponse, IProtectWithHotFolderRequest, IProtectWithHotFolderResponse } from './Interfaces/ProtectInterfaces'; -import FormData from 'form-data'; -import { IUnprotectRequest, IUnprotectResponse } from './Interfaces/UnprotectInterfaces'; import { IFileUploadResponse } from './Interfaces/FileStorageInterfaces'; +import { ILoginRequest, ILoginResponse, IRefreshTokenRequest } from './Interfaces/LoginInterfaces'; +import { + IProtectWithExternalRefIdRequest, + IProtectWithExternalRefIdResponse, + IProtectWithFileIdRequest, + IProtectWithFileIdResponse, + IProtectWithHotFolderRequest, + IProtectWithHotFolderResponse, +} from './Interfaces/ProtectInterfaces'; +import { IUnprotectRequest, IUnprotectResponse } from './Interfaces/UnprotectInterfaces'; export class SecloreDRMApiService { - private baseUrl: string; + private baseUrl: string; - constructor(private context: IExecuteFunctions, baseUrl: string) { - this.baseUrl = baseUrl; - } + constructor( + private context: IExecuteFunctions, + baseUrl: string, + ) { + this.baseUrl = baseUrl; + } - /** - * Common error handler for HTTP responses - * @param error - The error object from httpRequest - * @param customMessages - Optional custom error messages for specific status codes - */ - private handleHttpError(error: any, customMessages?: { [statusCode: number]: string }): never { - const statusCode = error.statusCode; - const errorResponse = error.response?.body as IErrorResponse; - - if (customMessages && customMessages[statusCode]) { - throw new Error(`${customMessages[statusCode]}: ${errorResponse?.errorMessage || 'Unknown error'}`); - } - - // Default error handling - switch (statusCode) { - case 400: - throw new Error(`Bad Request: ${errorResponse?.errorMessage || 'Invalid request data'}`); - case 401: - throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid credentials'}`); - case 413: - throw new Error(`Payload Too Large: ${errorResponse?.errorMessage || 'File size exceeds limit'}`); - case 500: - throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); - default: - throw error; - } - } + /** + * Common error handler for HTTP responses + * @param error - The error object from httpRequest + * @param customMessages - Optional custom error messages for specific status codes + */ + private handleHttpError( + error: NodeApiError, + customMessages?: { [statusCode: number]: string }, + ): never { + const statusCode: number = parseInt(error.httpCode ?? '0'); + const errorResponse = error.errorResponse as unknown as IErrorResponse; - /** - * Login Endpoint to generate Access Token and Refresh Token for JWT Authorization. - * Upon successful login, all the existing previous tokens for that tenant will be invalidated. - * - * @param tenantId - The tenant ID - * @param tenantSecret - The tenant secret - * @param correlationId - Optional request ID for logging purpose - * @returns Promise - Access token and refresh token - * @throws Error on authentication failure or server error - */ - async login(tenantId: string, tenantSecret: string, correlationId?: string): Promise { - const requestBody: ILoginRequest = { - tenantId, - tenantSecret, - }; + if (customMessages && customMessages[statusCode]) { + throw new Error( + `${customMessages[statusCode]}: ${errorResponse?.errorMessage || 'Unknown error'}`, + ); + } - const headers: { [key: string]: string } = { - 'Content-Type': 'application/json', - }; + // Default error handling + switch (statusCode) { + case 400: + throw new Error(`Bad Request: ${errorResponse?.errorMessage || 'Invalid request data'}`); + case 401: + throw new Error(`Unauthorized: ${errorResponse?.errorMessage || 'Invalid credentials'}`); + case 413: + throw new Error( + `Payload Too Large: ${errorResponse?.errorMessage || 'File size exceeds limit'}`, + ); + case 500: + throw new Error(`Server Error: ${errorResponse?.errorMessage || 'Internal server error'}`); + default: + throw error; + } + } - // Add correlation ID if provided - if (correlationId) { - headers['X-SECLORE-CORRELATION-ID'] = correlationId; - } + /** + * Login Endpoint to generate Access Token and Refresh Token for JWT Authorization. + * Upon successful login, all the existing previous tokens for that tenant will be invalidated. + * + * @param tenantId - The tenant ID + * @param tenantSecret - The tenant secret + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - Access token and refresh token + * @throws Error on authentication failure or server error + */ + async login( + tenantId: string, + tenantSecret: string, + correlationId?: string, + ): Promise { + const requestBody: ILoginRequest = { + tenantId, + tenantSecret, + }; - const options: IHttpRequestOptions = { - method: 'POST', - url: `${this.baseUrl}/seclore/drm/1.0/auth/login`, - headers, - body: requestBody, - json: true, - }; + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + }; - try { - const response = await this.context.helpers.httpRequest(options); - return response as ILoginResponse; - } catch (error: any) { - this.handleHttpError(error); - } - } + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } - /** - * Endpoint for generating new Access Token and Refresh Token using an existing valid Refresh Token. - * Upon successful response, all the previous existing Access Tokens and Refresh Tokens of that tenant will be invalidated. - * - * @param refreshToken - The existing valid refresh token - * @param correlationId - Optional request ID for logging purpose - * @returns Promise - New access token and refresh token - * @throws Error on authentication failure or server error - */ - async refreshToken(refreshToken: string, correlationId?: string): Promise { - const requestBody: IRefreshTokenRequest = { - refreshToken, - }; + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/auth/login`, + headers, + body: requestBody, + json: true, + }; - const headers: { [key: string]: string } = { - 'Content-Type': 'application/json', - }; + try { + const response = await this.context.helpers.httpRequest(options); + return response as ILoginResponse; + } catch (error: unknown) { + this.handleHttpError(error as NodeApiError); + } + } - // Add correlation ID if provided - if (correlationId) { - headers['X-SECLORE-CORRELATION-ID'] = correlationId; - } + /** + * Endpoint for generating new Access Token and Refresh Token using an existing valid Refresh Token. + * Upon successful response, all the previous existing Access Tokens and Refresh Tokens of that tenant will be invalidated. + * + * @param refreshToken - The existing valid refresh token + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - New access token and refresh token + * @throws Error on authentication failure or server error + */ + async refreshToken(refreshToken: string, correlationId?: string): Promise { + const requestBody: IRefreshTokenRequest = { + refreshToken, + }; - const options: IHttpRequestOptions = { - method: 'POST', - url: `${this.baseUrl}/seclore/drm/1.0/auth/refresh`, - headers, - body: requestBody, - json: true, - }; + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + }; - try { - const response = await this.context.helpers.httpRequest(options); - return response as ILoginResponse; - } catch (error: any) { - this.handleHttpError(error, { 401: 'Unauthorized' }); - } - } + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } - /** - * Protect file using external identifier of protected File and HotFolder with PS configured against the logged in Tenant in application. - * - * @param protectRequest - The protection request details - * @param accessToken - JWT access token for authorization - * @param correlationId - Optional request ID for logging purpose - * @returns Promise - File storage ID and Seclore file ID - * @throws Error on bad request, authentication failure or server error - */ - async protectWithExternalRefId( - protectRequest: IProtectWithExternalRefIdRequest, - accessToken: string, - correlationId?: string - ): Promise { - const headers: { [key: string]: string } = { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${accessToken}`, - }; + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/auth/refresh`, + headers, + body: requestBody, + json: true, + }; - // Add correlation ID if provided - if (correlationId) { - headers['X-SECLORE-CORRELATION-ID'] = correlationId; - } + try { + const response = await this.context.helpers.httpRequest(options); + return response as ILoginResponse; + } catch (error: unknown) { + this.handleHttpError(error as NodeApiError, { 401: 'Unauthorized' }); + } + } - const options: IHttpRequestOptions = { - method: 'POST', - url: `${this.baseUrl}/seclore/drm/1.0/protect/externalref`, - headers, - body: protectRequest, - json: true, - }; + /** + * Protect file using external identifier of protected File and HotFolder with PS configured against the logged in Tenant in application. + * + * @param protectRequest - The protection request details + * @param accessToken - JWT access token for authorization + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - File storage ID and Seclore file ID + * @throws Error on bad request, authentication failure or server error + */ + async protectWithExternalRefId( + protectRequest: IProtectWithExternalRefIdRequest, + accessToken: string, + correlationId?: string, + ): Promise { + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + Authorization: `Bearer ${accessToken}`, + }; - try { - const response = await this.context.helpers.httpRequest(options); - return response as IProtectWithExternalRefIdResponse; - } catch (error: any) { - this.handleHttpError(error); - } - } + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } - /** - * Protects file using File ID of already protected file with PS configured against the logged in Tenant in application. - * - * @param protectRequest - The protection request details with existing protected file ID - * @param accessToken - JWT access token for authorization - * @param correlationId - Optional request ID for logging purpose - * @returns Promise - File storage ID and Seclore file ID - * @throws Error on bad request, authentication failure or server error - */ - async protectWithFileId( - protectRequest: IProtectWithFileIdRequest, - accessToken: string, - correlationId?: string - ): Promise { - const headers: { [key: string]: string } = { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${accessToken}`, - }; + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/protect/externalref`, + headers, + body: protectRequest, + json: true, + }; - // Add correlation ID if provided - if (correlationId) { - headers['X-SECLORE-CORRELATION-ID'] = correlationId; - } + try { + const response = await this.context.helpers.httpRequest(options); + return response as IProtectWithExternalRefIdResponse; + } catch (error: unknown) { + this.handleHttpError(error as NodeApiError); + } + } - const options: IHttpRequestOptions = { - method: 'POST', - url: `${this.baseUrl}/seclore/drm/1.0/protect/fileid`, - headers, - body: protectRequest, - json: true, - }; + /** + * Protects file using File ID of already protected file with PS configured against the logged in Tenant in application. + * + * @param protectRequest - The protection request details with existing protected file ID + * @param accessToken - JWT access token for authorization + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - File storage ID and Seclore file ID + * @throws Error on bad request, authentication failure or server error + */ + async protectWithFileId( + protectRequest: IProtectWithFileIdRequest, + accessToken: string, + correlationId?: string, + ): Promise { + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + Authorization: `Bearer ${accessToken}`, + }; - try { - const response = await this.context.helpers.httpRequest(options); - return response as IProtectWithFileIdResponse; - } catch (error: any) { - this.handleHttpError(error); - } - } + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } - /** - * Protects file using HotFolder ID with PS configured against the logged in Tenant in application. - * - * @param protectRequest - The protection request details with hotfolder ID - * @param accessToken - JWT access token for authorization - * @param correlationId - Optional request ID for logging purpose - * @returns Promise - File storage ID and Seclore file ID - * @throws Error on bad request, authentication failure or server error - */ - async protectWithHotFolder( - protectRequest: IProtectWithHotFolderRequest, - accessToken: string, - correlationId?: string - ): Promise { - const headers: { [key: string]: string } = { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${accessToken}`, - }; + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/protect/fileid`, + headers, + body: protectRequest, + json: true, + }; - // Add correlation ID if provided - if (correlationId) { - headers['X-SECLORE-CORRELATION-ID'] = correlationId; - } + try { + const response = await this.context.helpers.httpRequest(options); + return response as IProtectWithFileIdResponse; + } catch (error: unknown) { + this.handleHttpError(error as NodeApiError); + } + } - const options: IHttpRequestOptions = { - method: 'POST', - url: `${this.baseUrl}/seclore/drm/1.0/protect/hf`, - headers, - body: protectRequest, - json: true, - }; + /** + * Protects file using HotFolder ID with PS configured against the logged in Tenant in application. + * + * @param protectRequest - The protection request details with hotfolder ID + * @param accessToken - JWT access token for authorization + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - File storage ID and Seclore file ID + * @throws Error on bad request, authentication failure or server error + */ + async protectWithHotFolder( + protectRequest: IProtectWithHotFolderRequest, + accessToken: string, + correlationId?: string, + ): Promise { + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + Authorization: `Bearer ${accessToken}`, + }; - try { - const response = await this.context.helpers.httpRequest(options); - return response as IProtectWithHotFolderResponse; - } catch (error: any) { - this.handleHttpError(error); - } - } + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } - /** - * Unprotects file with PS configured against the logged in Tenant in application. - * - * @param unprotectRequest - The unprotect request details with file storage ID - * @param accessToken - JWT access token for authorization - * @param correlationId - Optional request ID for logging purpose - * @returns Promise - File storage ID of unprotected file - * @throws Error on bad request, authentication failure or server error - */ - async unprotect( - unprotectRequest: IUnprotectRequest, - accessToken: string, - correlationId?: string - ): Promise { - const headers: { [key: string]: string } = { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${accessToken}`, - }; + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/protect/hf`, + headers, + body: protectRequest, + json: true, + }; - // Add correlation ID if provided - if (correlationId) { - headers['X-SECLORE-CORRELATION-ID'] = correlationId; - } + try { + const response = await this.context.helpers.httpRequest(options); + return response as IProtectWithHotFolderResponse; + } catch (error: unknown) { + this.handleHttpError(error as NodeApiError); + } + } - const options: IHttpRequestOptions = { - method: 'POST', - url: `${this.baseUrl}/seclore/drm/1.0/unprotect`, - headers, - body: unprotectRequest, - json: true, - }; + /** + * Unprotects file with PS configured against the logged in Tenant in application. + * + * @param unprotectRequest - The unprotect request details with file storage ID + * @param accessToken - JWT access token for authorization + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - File storage ID of unprotected file + * @throws Error on bad request, authentication failure or server error + */ + async unprotect( + unprotectRequest: IUnprotectRequest, + accessToken: string, + correlationId?: string, + ): Promise { + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + Authorization: `Bearer ${accessToken}`, + }; - try { - const response = await this.context.helpers.httpRequest(options); - return response as IUnprotectResponse; - } catch (error: any) { - this.handleHttpError(error); - } - } + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } - /** - * Adds a new file to the file storage for currently logged in Tenant. - * - * @param fileBuffer - The file buffer data - * @param fileName - The name of the file - * @param accessToken - JWT access token for authorization - * @param correlationId - Optional request ID for logging purpose - * @returns Promise - File storage details including file ID and metadata - * @throws Error on authentication failure, payload too large, or server error - */ - async uploadFile( - fileBuffer: Uint8Array, - fileName: string, - accessToken: string, - correlationId?: string - ): Promise { - const headers: { [key: string]: string } = { - 'Authorization': `Bearer ${accessToken}`, - }; + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/unprotect`, + headers, + body: unprotectRequest, + json: true, + }; - // Add correlation ID if provided - if (correlationId) { - headers['X-SECLORE-CORRELATION-ID'] = correlationId; - } + try { + const response = await this.context.helpers.httpRequest(options); + return response as IUnprotectResponse; + } catch (error: unknown) { + this.handleHttpError(error as NodeApiError); + } + } - // Create FormData for multipart/form-data upload - const formData = new FormData(); - formData.append('file', fileBuffer, fileName); + /** + * Adds a new file to the file storage for currently logged in Tenant. + * + * @param fileBuffer - The file buffer data + * @param fileName - The name of the file + * @param accessToken - JWT access token for authorization + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - File storage details including file ID and metadata + * @throws Error on authentication failure, payload too large, or server error + */ + async uploadFile( + fileBuffer: Uint8Array, + fileName: string, + accessToken: string, + correlationId?: string, + ): Promise { + const headers: { [key: string]: string } = { + Authorization: `Bearer ${accessToken}`, + }; - const options: IHttpRequestOptions = { - method: 'POST', - url: `${this.baseUrl}/seclore/drm/filestorage/1.0/upload`, - headers, - body: formData, - }; + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } - try { - const response = await this.context.helpers.httpRequest(options); - return response as IFileUploadResponse; - } catch (error: any) { - this.handleHttpError(error); - } - } + // Create FormData for multipart/form-data upload + const formData = new FormData(); + const file = new Blob([fileBuffer], { type: 'application/octet-stream' }); + formData.append('file', file, fileName); - /** - * Downloads file with fileStorageId from file storage of currently logged in Tenant. - * NOTE: Files whose fileStorageId has 'DL_' prefix will be deleted from the file storage after download. - * - * @param fileStorageId - Storage ID of the file to be retrieved - * @param accessToken - JWT access token for authorization - * @param correlationId - Optional request ID for logging purpose - * @returns Promise - The downloaded file data - * @throws Error on authentication failure or server error - */ - async downloadFile( - fileStorageId: string, - accessToken: string, - correlationId?: string - ): Promise { - const headers: { [key: string]: string } = { - 'Authorization': `Bearer ${accessToken}`, - }; + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/filestorage/1.0/upload`, + headers, + body: formData, + }; - // Add correlation ID if provided - if (correlationId) { - headers['X-SECLORE-CORRELATION-ID'] = correlationId; - } + try { + const response = await this.context.helpers.httpRequest(options); + return response as IFileUploadResponse; + } catch (error: unknown) { + this.handleHttpError(error as NodeApiError); + } + } - const options: IHttpRequestOptions = { - method: 'GET', - url: `${this.baseUrl}/seclore/drm/filestorage/1.0/download/${fileStorageId}`, - headers, - encoding: 'arraybuffer', - }; + /** + * Downloads file with fileStorageId from file storage of currently logged in Tenant. + * NOTE: Files whose fileStorageId has 'DL_' prefix will be deleted from the file storage after download. + * + * @param fileStorageId - Storage ID of the file to be retrieved + * @param accessToken - JWT access token for authorization + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - The downloaded file data + * @throws Error on authentication failure or server error + */ + async downloadFile( + fileStorageId: string, + accessToken: string, + correlationId?: string, + ): Promise { + const headers: { [key: string]: string } = { + Authorization: `Bearer ${accessToken}`, + }; - try { - const response = await this.context.helpers.httpRequest(options); - return new Uint8Array(response as ArrayBuffer); - } catch (error: any) { - this.handleHttpError(error); - } - } + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + const options: IHttpRequestOptions = { + method: 'GET', + url: `${this.baseUrl}/seclore/drm/filestorage/1.0/download/${fileStorageId}`, + headers, + encoding: 'arraybuffer', + }; + + try { + const response = await this.context.helpers.httpRequest(options); + return new Uint8Array(response as ArrayBuffer); + } catch (error: unknown) { + this.handleHttpError(error as NodeApiError); + } + } } diff --git a/nodes/SecloreProtect/Services/SecloreDRMFileService.ts b/nodes/SecloreProtect/Services/SecloreDRMFileService.ts index ae078cc..7a8192d 100644 --- a/nodes/SecloreProtect/Services/SecloreDRMFileService.ts +++ b/nodes/SecloreProtect/Services/SecloreDRMFileService.ts @@ -1,298 +1,303 @@ import { IExecuteFunctions } from 'n8n-workflow'; -import { SecloreDRMApiService } from './SecloreDRMApiService'; -import { IProtectWithExternalRefIdRequest, IProtectWithExternalRefIdResponse, IProtectWithFileIdRequest, IProtectWithFileIdResponse, IProtectWithHotFolderRequest, IProtectWithHotFolderResponse } from './Interfaces/ProtectInterfaces'; -import { IUnprotectRequest, IUnprotectResponse } from './Interfaces/UnprotectInterfaces'; import { IFileUploadResponse } from './Interfaces/FileStorageInterfaces'; +import { + IProtectWithExternalRefIdRequest, + IProtectWithExternalRefIdResponse, + IProtectWithFileIdRequest, + IProtectWithFileIdResponse, + IProtectWithHotFolderRequest, + IProtectWithHotFolderResponse, +} from './Interfaces/ProtectInterfaces'; +import { IUnprotectRequest, IUnprotectResponse } from './Interfaces/UnprotectInterfaces'; +import { SecloreDRMApiService } from './SecloreDRMApiService'; export class SecloreDRMFileService { - private apiService: SecloreDRMApiService; - private tenantId: string; - private tenantSecret: string; - private accessToken?: string; - private refreshToken?: string; - private tokenExpiry?: Date; - private refreshPromise?: Promise; - private loginPromise?: Promise; + private apiService: SecloreDRMApiService; + private tenantId: string; + private tenantSecret: string; + private accessToken?: string; + private refreshToken?: string; + private tokenExpiry?: Date; + private refreshPromise?: Promise; + private loginPromise?: Promise; - constructor( - context: IExecuteFunctions, - baseUrl: string, - tenantId: string, - tenantSecret: string, - private defaultRetryCount: number = 3 - ) { - this.apiService = new SecloreDRMApiService(context, baseUrl); - this.tenantId = tenantId; - this.tenantSecret = tenantSecret; - } + constructor( + context: IExecuteFunctions, + baseUrl: string, + tenantId: string, + tenantSecret: string, + private defaultRetryCount: number = 3, + ) { + this.apiService = new SecloreDRMApiService(context, baseUrl); + this.tenantId = tenantId; + this.tenantSecret = tenantSecret; + } - /** - * Ensures we have a valid access token, logging in if necessary - * @param correlationId - Optional correlation ID for logging - */ - private async ensureAuthenticated(correlationId?: string): Promise { - // If we don't have a token or it's expired, login - if (!this.accessToken || (this.tokenExpiry && new Date() >= this.tokenExpiry)) { - // If there's already a login in progress, wait for it - if (this.loginPromise) { - await this.loginPromise; - return; - } - - // Start login and store the promise - this.loginPromise = this.login(correlationId); - try { - await this.loginPromise; - } finally { - this.loginPromise = undefined; - } - } - } + /** + * Ensures we have a valid access token, logging in if necessary + * @param correlationId - Optional correlation ID for logging + */ + private async ensureAuthenticated(correlationId?: string): Promise { + // If we don't have a token or it's expired, login + if (!this.accessToken || (this.tokenExpiry && new Date() >= this.tokenExpiry)) { + // If there's already a login in progress, wait for it + if (this.loginPromise) { + await this.loginPromise; + return; + } - /** - * Performs login and stores tokens - * @param correlationId - Optional correlation ID for logging - */ - private async login(correlationId?: string): Promise { - try { - const loginResponse = await this.apiService.login( - this.tenantId, - this.tenantSecret, - correlationId - ); - - this.accessToken = loginResponse.accessToken; - this.refreshToken = loginResponse.refreshToken; - - // Set token expiry to 50 minutes from now (assuming 1 hour token life) - this.tokenExpiry = new Date(Date.now() + 50 * 60 * 1000); - } catch (error) { - this.clearTokens(); - throw error; - } - } + // Start login and store the promise + this.loginPromise = this.login(correlationId); + try { + await this.loginPromise; + } finally { + this.loginPromise = undefined; + } + } + } - /** - * Attempts to refresh the access token with concurrency protection - * @param correlationId - Optional correlation ID for logging - */ - private async refreshAccessToken(correlationId?: string): Promise { - // If there's already a refresh in progress, wait for it - if (this.refreshPromise) { - await this.refreshPromise; - return; - } + /** + * Performs login and stores tokens + * @param correlationId - Optional correlation ID for logging + */ + private async login(correlationId?: string): Promise { + try { + const loginResponse = await this.apiService.login( + this.tenantId, + this.tenantSecret, + correlationId, + ); - if (!this.refreshToken) { - throw new Error('No refresh token available'); - } + this.accessToken = loginResponse.accessToken; + this.refreshToken = loginResponse.refreshToken; - // Start refresh and store the promise - this.refreshPromise = this.performTokenRefresh(correlationId); - try { - await this.refreshPromise; - } finally { - this.refreshPromise = undefined; - } - } + // Set token expiry to 50 minutes from now (assuming 1 hour token life) + this.tokenExpiry = new Date(Date.now() + 50 * 60 * 1000); + } catch (error) { + this.clearTokens(); + throw error; + } + } - /** - * Performs the actual token refresh - * @param correlationId - Optional correlation ID for logging - */ - private async performTokenRefresh(correlationId?: string): Promise { - try { - const refreshResponse = await this.apiService.refreshToken( - this.refreshToken!, - correlationId - ); - - this.accessToken = refreshResponse.accessToken; - this.refreshToken = refreshResponse.refreshToken; - - // Set token expiry to 50 minutes from now - this.tokenExpiry = new Date(Date.now() + 50 * 60 * 1000); - } catch (error) { - this.clearTokens(); - throw error; - } - } + /** + * Attempts to refresh the access token with concurrency protection + * @param correlationId - Optional correlation ID for logging + */ + private async refreshAccessToken(correlationId?: string): Promise { + // If there's already a refresh in progress, wait for it + if (this.refreshPromise) { + await this.refreshPromise; + return; + } - /** - * Clears stored tokens and pending promises - */ - private clearTokens(): void { - this.accessToken = undefined; - this.refreshToken = undefined; - this.tokenExpiry = undefined; - this.refreshPromise = undefined; - this.loginPromise = undefined; - } + if (!this.refreshToken) { + throw new Error('No refresh token available'); + } - /** - * Executes an API call with automatic authentication and retry logic - * @param apiCall - The API call function to execute - * @param retryCount - Number of retries (defaults to class default) - * @param correlationId - Optional correlation ID for logging - */ - private async executeWithRetry( - apiCall: (accessToken: string) => Promise, - retryCount: number = this.defaultRetryCount, - correlationId?: string - ): Promise { - let lastError: Error; + // Start refresh and store the promise + this.refreshPromise = this.performTokenRefresh(correlationId); + try { + await this.refreshPromise; + } finally { + this.refreshPromise = undefined; + } + } - for (let attempt = 0; attempt <= retryCount; attempt++) { - try { - // Ensure we have a valid token - await this.ensureAuthenticated(correlationId); - - if (!this.accessToken) { - throw new Error('Failed to obtain access token'); - } + /** + * Performs the actual token refresh + * @param correlationId - Optional correlation ID for logging + */ + private async performTokenRefresh(correlationId?: string): Promise { + try { + const refreshResponse = await this.apiService.refreshToken(this.refreshToken!, correlationId); - // Execute the API call - return await apiCall(this.accessToken); - - } catch (error: any) { - lastError = error; - - // If it's an authentication error and we have retries left, try to refresh token - if (error.message.includes('Unauthorized') && attempt < retryCount) { - try { - await this.refreshAccessToken(correlationId); - continue; // Retry with new token - } catch (refreshError) { - // If refresh fails, clear tokens and try full login on next attempt - this.clearTokens(); - } - } - - // If it's the last attempt or not an auth error, throw - if (attempt === retryCount) { - throw lastError; - } - - // Wait before retry (exponential backoff) - await new Promise(resolve => { - const delay = Math.pow(2, attempt) * 1000; - // Use a simple delay implementation - const start = Date.now(); - while (Date.now() - start < delay) { - // Busy wait for delay - } - resolve(undefined); - }); - } - } + this.accessToken = refreshResponse.accessToken; + this.refreshToken = refreshResponse.refreshToken; - throw lastError!; - } + // Set token expiry to 50 minutes from now + this.tokenExpiry = new Date(Date.now() + 50 * 60 * 1000); + } catch (error) { + this.clearTokens(); + throw error; + } + } - /** - * Protect file using external identifier with automatic authentication and retry - */ - async protectWithExternalRefId( - protectRequest: IProtectWithExternalRefIdRequest, - correlationId?: string, - retryCount?: number - ): Promise { - return this.executeWithRetry( - (accessToken) => this.apiService.protectWithExternalRefId(protectRequest, accessToken, correlationId), - retryCount, - correlationId - ); - } + /** + * Clears stored tokens and pending promises + */ + private clearTokens(): void { + this.accessToken = undefined; + this.refreshToken = undefined; + this.tokenExpiry = undefined; + this.refreshPromise = undefined; + this.loginPromise = undefined; + } - /** - * Protect file using existing protected file ID with automatic authentication and retry - */ - async protectWithFileId( - protectRequest: IProtectWithFileIdRequest, - correlationId?: string, - retryCount?: number - ): Promise { - return this.executeWithRetry( - (accessToken) => this.apiService.protectWithFileId(protectRequest, accessToken, correlationId), - retryCount, - correlationId - ); - } + /** + * Executes an API call with automatic authentication and retry logic + * @param apiCall - The API call function to execute + * @param retryCount - Number of retries (defaults to class default) + * @param correlationId - Optional correlation ID for logging + */ + private async executeWithRetry( + apiCall: (accessToken: string) => Promise, + retryCount: number = this.defaultRetryCount, + correlationId?: string, + ): Promise { + let lastError: Error; - /** - * Protect file using HotFolder ID with automatic authentication and retry - */ - async protectWithHotFolder( - protectRequest: IProtectWithHotFolderRequest, - correlationId?: string, - retryCount?: number - ): Promise { - return this.executeWithRetry( - (accessToken) => this.apiService.protectWithHotFolder(protectRequest, accessToken, correlationId), - retryCount, - correlationId - ); - } + for (let attempt = 0; attempt <= retryCount; attempt++) { + try { + // Ensure we have a valid token + await this.ensureAuthenticated(correlationId); - /** - * Unprotect file with automatic authentication and retry - */ - async unprotect( - unprotectRequest: IUnprotectRequest, - correlationId?: string, - retryCount?: number - ): Promise { - return this.executeWithRetry( - (accessToken) => this.apiService.unprotect(unprotectRequest, accessToken, correlationId), - retryCount, - correlationId - ); - } + if (!this.accessToken) { + throw new Error('Failed to obtain access token'); + } - /** - * Upload file with automatic authentication and retry - */ - async uploadFile( - fileBuffer: Uint8Array, - fileName: string, - correlationId?: string, - retryCount?: number - ): Promise { - return this.executeWithRetry( - (accessToken) => this.apiService.uploadFile(fileBuffer, fileName, accessToken, correlationId), - retryCount, - correlationId - ); - } + // Execute the API call + return await apiCall(this.accessToken); + } catch (error: unknown) { + lastError = error as Error; + // If it's an authentication error and we have retries left, try to refresh token + if ((error as Error).message.includes('Unauthorized') && attempt < retryCount) { + try { + await this.refreshAccessToken(correlationId); + continue; // Retry with new token + } catch (error: unknown) { + console.error(error); + // If refresh fails, clear tokens and try full login on next attempt + this.clearTokens(); + } + } - /** - * Download file with automatic authentication and retry - * NOTE: Files whose fileStorageId has 'DL_' prefix will be deleted from the file storage after download. - */ - async downloadFile( - fileStorageId: string, - correlationId?: string, - retryCount?: number - ): Promise { - return this.executeWithRetry( - (accessToken) => this.apiService.downloadFile(fileStorageId, accessToken, correlationId), - retryCount, - correlationId - ); - } + // If it's the last attempt or not an auth error, throw + if (attempt === retryCount) { + throw lastError; + } - /** - * Get current access token (for debugging/monitoring) - */ - getAccessToken(): string | undefined { - return this.accessToken; - } + // Wait before retry (exponential backoff) + await new Promise((resolve) => { + const delay = Math.pow(2, attempt) * 1000; + // Use a simple delay implementation + const start = Date.now(); + while (Date.now() - start < delay) { + // Busy wait for delay + } + resolve(undefined); + }); + } + } - /** - * Check if currently authenticated - */ - isAuthenticated(): boolean { - return !!this.accessToken && (!this.tokenExpiry || new Date() < this.tokenExpiry); - } + throw lastError!; + } + /** + * Protect file using external identifier with automatic authentication and retry + */ + async protectWithExternalRefId( + protectRequest: IProtectWithExternalRefIdRequest, + correlationId?: string, + retryCount?: number, + ): Promise { + return this.executeWithRetry( + (accessToken) => + this.apiService.protectWithExternalRefId(protectRequest, accessToken, correlationId), + retryCount, + correlationId, + ); + } + + /** + * Protect file using existing protected file ID with automatic authentication and retry + */ + async protectWithFileId( + protectRequest: IProtectWithFileIdRequest, + correlationId?: string, + retryCount?: number, + ): Promise { + return this.executeWithRetry( + (accessToken) => + this.apiService.protectWithFileId(protectRequest, accessToken, correlationId), + retryCount, + correlationId, + ); + } + + /** + * Protect file using HotFolder ID with automatic authentication and retry + */ + async protectWithHotFolder( + protectRequest: IProtectWithHotFolderRequest, + correlationId?: string, + retryCount?: number, + ): Promise { + return this.executeWithRetry( + (accessToken) => + this.apiService.protectWithHotFolder(protectRequest, accessToken, correlationId), + retryCount, + correlationId, + ); + } + + /** + * Unprotect file with automatic authentication and retry + */ + async unprotect( + unprotectRequest: IUnprotectRequest, + correlationId?: string, + retryCount?: number, + ): Promise { + return this.executeWithRetry( + (accessToken) => this.apiService.unprotect(unprotectRequest, accessToken, correlationId), + retryCount, + correlationId, + ); + } + + /** + * Upload file with automatic authentication and retry + */ + async uploadFile( + fileBuffer: Uint8Array, + fileName: string, + correlationId?: string, + retryCount?: number, + ): Promise { + return this.executeWithRetry( + (accessToken) => this.apiService.uploadFile(fileBuffer, fileName, accessToken, correlationId), + retryCount, + correlationId, + ); + } + + /** + * Download file with automatic authentication and retry + * NOTE: Files whose fileStorageId has 'DL_' prefix will be deleted from the file storage after download. + */ + async downloadFile( + fileStorageId: string, + correlationId?: string, + retryCount?: number, + ): Promise { + return this.executeWithRetry( + (accessToken) => this.apiService.downloadFile(fileStorageId, accessToken, correlationId), + retryCount, + correlationId, + ); + } + + /** + * Get current access token (for debugging/monitoring) + */ + getAccessToken(): string | undefined { + return this.accessToken; + } + + /** + * Check if currently authenticated + */ + isAuthenticated(): boolean { + return !!this.accessToken && (!this.tokenExpiry || new Date() < this.tokenExpiry); + } } -- 2.40.1 From 8f16019d6e0bc5f1af87baa060eed636561b8edc Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Mon, 27 Oct 2025 17:36:40 +0530 Subject: [PATCH 09/22] icon and logging changes --- .gitignore | 3 +- credentials/SecloreProtectApi.credentials.ts | 5 +- .../{SecloreProtect.dark.svg => seclore.svg} | 0 nodes/SecloreProtect/SecloreProtect.node.ts | 367 +++++++++++---- .../Services/SecloreDRMApiService.ts | 429 +++++++++++------- .../Services/SecloreDRMFileService.ts | 132 ++++-- .../SecloreProtect/seclore.svg | 0 7 files changed, 648 insertions(+), 288 deletions(-) rename icons/{SecloreProtect.dark.svg => seclore.svg} (100%) rename icons/SecloreProtect.light.svg => nodes/SecloreProtect/seclore.svg (100%) diff --git a/.gitignore b/.gitignore index b64847f..4d79ed6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ dist node_modules package-lock.json -.n8n \ No newline at end of file +.n8n +.devcontainer \ No newline at end of file diff --git a/credentials/SecloreProtectApi.credentials.ts b/credentials/SecloreProtectApi.credentials.ts index f034503..cbf91fd 100644 --- a/credentials/SecloreProtectApi.credentials.ts +++ b/credentials/SecloreProtectApi.credentials.ts @@ -4,10 +4,7 @@ export class SecloreProtectApi implements ICredentialType { name = 'secloreProtectApi'; displayName = 'Seclore Protect API'; documentationUrl = 'https://docs.seclore.com/'; - icon: Icon = { - light: 'file:../icons/SecloreProtect.light.svg', - dark: 'file:../icons/SecloreProtect.dark.svg', - }; + icon: Icon = 'file:../icons/seclore.svg'; properties: INodeProperties[] = [ { displayName: 'Base URL', diff --git a/icons/SecloreProtect.dark.svg b/icons/seclore.svg similarity index 100% rename from icons/SecloreProtect.dark.svg rename to icons/seclore.svg diff --git a/nodes/SecloreProtect/SecloreProtect.node.ts b/nodes/SecloreProtect/SecloreProtect.node.ts index e51750b..c703716 100644 --- a/nodes/SecloreProtect/SecloreProtect.node.ts +++ b/nodes/SecloreProtect/SecloreProtect.node.ts @@ -4,6 +4,7 @@ import { INodeType, INodeTypeDescription, NodeOperationError, + NodeOutput, } from 'n8n-workflow'; import { SecloreDRMFileService } from './Services/SecloreDRMFileService'; @@ -12,12 +13,12 @@ export class SecloreProtect implements INodeType { description: INodeTypeDescription = { displayName: 'Seclore Protect', name: 'secloreProtect', - icon: 'file:../../icons/SecloreProtect.light.svg', + icon: 'file:seclore.svg', usableAsTool: true, // TODO: make it false/ don't allow it to be used as a tool group: ['transform'], version: 1, - subtitle: '={{$parameter["operation"]}}', - description: 'Protect files using Seclore DRM with HotFolder configuration', + subtitle: '={{$parameter["resource"] + ": " + $parameter["operation"]}}', + description: 'Protect files using Seclore DRM', defaults: { name: 'Seclore Protect', }, @@ -31,17 +32,42 @@ export class SecloreProtect implements INodeType { ], properties: [ { - displayName: 'Operation', - name: 'operation', + displayName: 'Resource', + name: 'resource', type: 'options', noDataExpression: true, options: [ { - name: 'Protect File with HotFolder', + name: 'Protection', + value: 'protection', + description: 'File protection operations', + }, + ], + default: 'protection', + }, + { + displayName: 'Operation', + name: 'operation', + type: 'options', + noDataExpression: true, + displayOptions: { + show: { + resource: ['protection'], + }, + }, + options: [ + { + name: 'Protect with Hot Folder', value: 'protectWithHotFolder', description: 'Protect a file using HotFolder ID configuration', action: 'Protect file with hotfolder', }, + { + name: 'Unprotect', + value: 'unprotect', + description: 'Unprotect a file using file ID', + action: 'Unprotect file', + }, ], default: 'protectWithHotFolder', }, @@ -50,11 +76,12 @@ export class SecloreProtect implements INodeType { name: 'hotfolderId', type: 'string', required: true, - default: '', - placeholder: 'e.g., hf-12345', + default: '1000201', + placeholder: '1000201', description: 'The ID of the HotFolder configuration to use for protection', displayOptions: { show: { + resource: ['protection'], operation: ['protectWithHotFolder'], }, }, @@ -68,6 +95,7 @@ export class SecloreProtect implements INodeType { description: 'Name of the binary property that contains the file to protect', displayOptions: { show: { + resource: ['protection'], operation: ['protectWithHotFolder'], }, }, @@ -81,6 +109,7 @@ export class SecloreProtect implements INodeType { description: 'Name of the binary property where the protected file will be stored', displayOptions: { show: { + resource: ['protection'], operation: ['protectWithHotFolder'], }, }, @@ -94,6 +123,7 @@ export class SecloreProtect implements INodeType { description: 'Optional correlation ID for request tracking and logging', displayOptions: { show: { + resource: ['protection'], operation: ['protectWithHotFolder'], }, }, @@ -106,14 +136,79 @@ export class SecloreProtect implements INodeType { description: 'Number of retry attempts for failed requests', displayOptions: { show: { + resource: ['protection'], operation: ['protectWithHotFolder'], }, }, }, + // Unprotect operation parameters + { + displayName: 'File ID', + name: 'fileId', + type: 'string', + required: true, + default: '', + placeholder: 'e.g., file-12345', + description: 'The ID of the file to unprotect', + displayOptions: { + show: { + resource: ['protection'], + operation: ['unprotect'], + }, + }, + }, + { + displayName: 'Output Binary Property', + name: 'outputBinaryPropertyName', + type: 'string', + default: 'data', + required: true, + description: 'Name of the binary property where the unprotected file will be stored', + displayOptions: { + show: { + resource: ['protection'], + operation: ['unprotect'], + }, + }, + }, + { + displayName: 'Correlation ID', + name: 'correlationId', + type: 'string', + default: '', + placeholder: 'e.g., req-12345', + description: 'Optional correlation ID for request tracking and logging', + displayOptions: { + show: { + resource: ['protection'], + operation: ['unprotect'], + }, + }, + }, + { + displayName: 'Retry Count', + name: 'retryCount', + type: 'number', + default: 3, + description: 'Number of retry attempts for failed requests', + displayOptions: { + show: { + resource: ['protection'], + operation: ['unprotect'], + }, + }, + }, ], }; - async execute(this: IExecuteFunctions): Promise { + customOperations = { + protection: { + protectWithHotFolder: this.protectWithHotFolder, + unprotect: this.unprotect, + }, + }; + + async protectWithHotFolder(this: IExecuteFunctions): Promise { const items = this.getInputData(); const returnData: INodeExecutionData[] = []; @@ -126,98 +221,182 @@ export class SecloreProtect implements INodeType { // Initialize the file service const fileService = new SecloreDRMFileService(this, baseUrl, tenantId, tenantSecret); - // Get node parameters - const operation = this.getNodeParameter('operation', 0) as string; + for (let i = 0; i < items.length; i++) { + console.log('Data'); + console.log(items[i]); + try { + // Get parameters for this item + const hotfolderId = this.getNodeParameter('hotfolderId', i) as string; + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; + const outputBinaryPropertyName = this.getNodeParameter( + 'outputBinaryPropertyName', + i, + ) as string; + const correlationId = this.getNodeParameter('correlationId', i) as string; + const retryCount = this.getNodeParameter('retryCount', i) as number; + + // Validate required parameters + if (!hotfolderId) { + throw new NodeOperationError(this.getNode(), 'HotFolder ID is required', { + itemIndex: i, + }); + } + + console.log('assertBinaryData'); + // Get input binary data + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); + + console.log('getBinaryDataBuffer'); + const fileBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); + + console.log('fileBuffer', fileBuffer); + console.log('binaryData.fileName', binaryData.fileName); + + // Upload the file first + const uploadResult = await fileService.uploadFile( + new Uint8Array(fileBuffer), + binaryData.fileName || 'file', + correlationId || undefined, + retryCount, + ); + + console.log('File upload response', uploadResult); + + // Protect the uploaded file with HotFolder + const protectResult = await fileService.protectWithHotFolder( + { + hotfolderId, + fileStorageId: uploadResult.fileStorageId, + }, + correlationId || undefined, + retryCount, + ); + + console.log('File protect response', protectResult); + + // Download the protected file + const protectedFileData = await fileService.downloadFile( + protectResult.fileStorageId, + correlationId || undefined, + retryCount, + ); + + console.log('Protected file data', protectedFileData); + + // Create output binary data + const outputBinaryData = await this.helpers.prepareBinaryData( + Buffer.from(protectedFileData), + binaryData.fileName || 'protected_file', + binaryData.mimeType, + ); + + // Create return item with binary data and metadata + const returnItem: INodeExecutionData = { + json: { + success: true, + originalFileStorageId: uploadResult.fileStorageId, + protectedFileStorageId: protectResult.fileStorageId, + secloreFileId: protectResult.secloreFileId, + hotfolderId, + fileName: binaryData.fileName, + fileSize: protectedFileData.length, + correlationId: correlationId || null, + }, + binary: { + [outputBinaryPropertyName]: outputBinaryData, + }, + }; + + returnData.push(returnItem); + } catch (error) { + // Handle errors gracefully + if (this.continueOnFail()) { + const returnItem: INodeExecutionData = { + json: { + success: false, + error: error.message, + itemIndex: i, + }, + }; + returnData.push(returnItem); + } else { + throw new NodeOperationError(this.getNode(), error.message, { + itemIndex: i, + }); + } + } + } + + return [returnData]; + } + + async unprotect(this: IExecuteFunctions): Promise { + const items = this.getInputData(); + const returnData: INodeExecutionData[] = []; + + // Get credentials + const credentials = await this.getCredentials('secloreProtectApi'); + const baseUrl = credentials.baseUrl as string; + const tenantId = credentials.tenantId as string; + const tenantSecret = credentials.tenantSecret as string; + + // Initialize the file service + const fileService = new SecloreDRMFileService(this, baseUrl, tenantId, tenantSecret); for (let i = 0; i < items.length; i++) { console.log('Data'); console.log(items[i]); try { - if (operation === 'protectWithHotFolder') { - // Get parameters for this item - const hotfolderId = this.getNodeParameter('hotfolderId', i) as string; - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; - const outputBinaryPropertyName = this.getNodeParameter( - 'outputBinaryPropertyName', - i, - ) as string; - const correlationId = this.getNodeParameter('correlationId', i) as string; - const retryCount = this.getNodeParameter('retryCount', i) as number; + // Get parameters for this item + const fileId = this.getNodeParameter('fileId', i) as string; + const outputBinaryPropertyName = this.getNodeParameter( + 'outputBinaryPropertyName', + i, + ) as string; + const correlationId = this.getNodeParameter('correlationId', i) as string; + const retryCount = this.getNodeParameter('retryCount', i) as number; - // Validate required parameters - if (!hotfolderId) { - throw new NodeOperationError(this.getNode(), 'HotFolder ID is required', { - itemIndex: i, - }); - } - - console.log('assertBinaryData'); - // Get input binary data - const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); - - console.log('getBinaryDataBuffer'); - const fileBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); - - console.log('fileBuffer', fileBuffer); - console.log('binaryData.fileName', binaryData.fileName); - - // Upload the file first - const uploadResult = await fileService.uploadFile( - new Uint8Array(fileBuffer), - binaryData.fileName || 'file', - correlationId || undefined, - retryCount, - ); - - console.log('File upload response', uploadResult); - - // Protect the uploaded file with HotFolder - const protectResult = await fileService.protectWithHotFolder( - { - hotfolderId, - fileStorageId: uploadResult.fileStorageId, - }, - correlationId || undefined, - retryCount, - ); - - console.log('File protect response', protectResult); - - // Download the protected file - const protectedFileData = await fileService.downloadFile( - protectResult.fileStorageId, - correlationId || undefined, - retryCount, - ); - - console.log('Protected file data', protectedFileData); - - // Create output binary data - const outputBinaryData = await this.helpers.prepareBinaryData( - Buffer.from(protectedFileData), - binaryData.fileName || 'protected_file', - binaryData.mimeType, - ); - - // Create return item with binary data and metadata - const returnItem: INodeExecutionData = { - json: { - success: true, - originalFileStorageId: uploadResult.fileStorageId, - protectedFileStorageId: protectResult.fileStorageId, - secloreFileId: protectResult.secloreFileId, - hotfolderId, - fileName: binaryData.fileName, - fileSize: protectedFileData.length, - correlationId: correlationId || null, - }, - binary: { - [outputBinaryPropertyName]: outputBinaryData, - }, - }; - - returnData.push(returnItem); + // Validate required parameters + if (!fileId) { + throw new NodeOperationError(this.getNode(), 'File ID is required', { + itemIndex: i, + }); } + + console.log('Unprotecting file with ID:', fileId); + + // Unprotect the file using the file ID + // Note: You'll need to implement unprotectFile in your SecloreDRMFileService + // For now, using downloadFile as placeholder - replace with actual unprotect method + const unprotectedFileData = await fileService.downloadFile( + fileId, + correlationId || undefined, + retryCount, + ); + + console.log('Unprotected file data', unprotectedFileData); + + // Create output binary data + const outputBinaryData = await this.helpers.prepareBinaryData( + Buffer.from(unprotectedFileData), + 'unprotected_file', + 'application/octet-stream', + ); + + // Create return item with binary data and metadata + const returnItem: INodeExecutionData = { + json: { + success: true, + fileId, + fileSize: unprotectedFileData.length, + correlationId: correlationId || null, + }, + binary: { + [outputBinaryPropertyName]: outputBinaryData, + }, + }; + + returnData.push(returnItem); } catch (error) { // Handle errors gracefully if (this.continueOnFail()) { diff --git a/nodes/SecloreProtect/Services/SecloreDRMApiService.ts b/nodes/SecloreProtect/Services/SecloreDRMApiService.ts index f8713d7..2870132 100644 --- a/nodes/SecloreProtect/Services/SecloreDRMApiService.ts +++ b/nodes/SecloreProtect/Services/SecloreDRMApiService.ts @@ -1,4 +1,4 @@ -import { IExecuteFunctions, IHttpRequestOptions, NodeApiError } from 'n8n-workflow'; +import { IExecuteFunctions, IHttpRequestOptions, NodeApiError, LoggerProxy as Logger } from 'n8n-workflow'; import { IErrorResponse } from './Interfaces/ErrorInterfaces'; import { IFileUploadResponse } from './Interfaces/FileStorageInterfaces'; import { ILoginRequest, ILoginResponse, IRefreshTokenRequest } from './Interfaces/LoginInterfaces'; @@ -72,32 +72,38 @@ export class SecloreDRMApiService { tenantSecret: string, correlationId?: string, ): Promise { - const requestBody: ILoginRequest = { - tenantId, - tenantSecret, - }; - - const headers: { [key: string]: string } = { - 'Content-Type': 'application/json', - }; - - // Add correlation ID if provided - if (correlationId) { - headers['X-SECLORE-CORRELATION-ID'] = correlationId; - } - - const options: IHttpRequestOptions = { - method: 'POST', - url: `${this.baseUrl}/seclore/drm/1.0/auth/login`, - headers, - body: requestBody, - json: true, - }; - + const who = "SecloreDRMApiService::login:: "; try { + Logger.debug(who + 'Attempting login', { tenantId, correlationId }); + + const requestBody: ILoginRequest = { + tenantId, + tenantSecret, + }; + + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/auth/login`, + headers, + body: requestBody, + json: true, + }; + + Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, correlationId }); const response = await this.context.helpers.httpRequest(options); + Logger.debug(who + 'Login successful', { tenantId, correlationId }); return response as ILoginResponse; } catch (error: unknown) { + Logger.error(who + 'Login failed', { error, tenantId, correlationId }); this.handleHttpError(error as NodeApiError); } } @@ -112,31 +118,37 @@ export class SecloreDRMApiService { * @throws Error on authentication failure or server error */ async refreshToken(refreshToken: string, correlationId?: string): Promise { - const requestBody: IRefreshTokenRequest = { - refreshToken, - }; - - const headers: { [key: string]: string } = { - 'Content-Type': 'application/json', - }; - - // Add correlation ID if provided - if (correlationId) { - headers['X-SECLORE-CORRELATION-ID'] = correlationId; - } - - const options: IHttpRequestOptions = { - method: 'POST', - url: `${this.baseUrl}/seclore/drm/1.0/auth/refresh`, - headers, - body: requestBody, - json: true, - }; - + const who = "SecloreDRMApiService::refreshToken:: "; try { + Logger.debug(who + 'Attempting token refresh', { correlationId }); + + const requestBody: IRefreshTokenRequest = { + refreshToken, + }; + + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/auth/refresh`, + headers, + body: requestBody, + json: true, + }; + + Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, correlationId }); const response = await this.context.helpers.httpRequest(options); + Logger.debug(who + 'Token refresh successful', { correlationId }); return response as ILoginResponse; } catch (error: unknown) { + Logger.error(who + 'Token refresh failed', { error, correlationId }); this.handleHttpError(error as NodeApiError, { 401: 'Unauthorized' }); } } @@ -155,28 +167,46 @@ export class SecloreDRMApiService { accessToken: string, correlationId?: string, ): Promise { - const headers: { [key: string]: string } = { - 'Content-Type': 'application/json', - Authorization: `Bearer ${accessToken}`, - }; - - // Add correlation ID if provided - if (correlationId) { - headers['X-SECLORE-CORRELATION-ID'] = correlationId; - } - - const options: IHttpRequestOptions = { - method: 'POST', - url: `${this.baseUrl}/seclore/drm/1.0/protect/externalref`, - headers, - body: protectRequest, - json: true, - }; - + const who = "SecloreDRMApiService::protectWithExternalRefId:: "; try { + Logger.debug(who + 'Protecting file with external ref ID', { + fileStorageId: protectRequest.fileStorageId, + hotfolderExternalReferenceId: protectRequest.hotfolderExternalReference.externalReferenceId, + correlationId + }); + + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + Authorization: `Bearer ${accessToken}`, + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/protect/externalref`, + headers, + body: protectRequest, + json: true, + }; + + Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, correlationId }); const response = await this.context.helpers.httpRequest(options); + Logger.debug(who + 'Protection with external ref ID successful', { + fileStorageId: protectRequest.fileStorageId, + secloreFileId: (response as IProtectWithExternalRefIdResponse).secloreFileId, + correlationId + }); return response as IProtectWithExternalRefIdResponse; } catch (error: unknown) { + Logger.error(who + 'Protection with external ref ID failed', { + error, + fileStorageId: protectRequest.fileStorageId, + correlationId + }); this.handleHttpError(error as NodeApiError); } } @@ -195,28 +225,46 @@ export class SecloreDRMApiService { accessToken: string, correlationId?: string, ): Promise { - const headers: { [key: string]: string } = { - 'Content-Type': 'application/json', - Authorization: `Bearer ${accessToken}`, - }; - - // Add correlation ID if provided - if (correlationId) { - headers['X-SECLORE-CORRELATION-ID'] = correlationId; - } - - const options: IHttpRequestOptions = { - method: 'POST', - url: `${this.baseUrl}/seclore/drm/1.0/protect/fileid`, - headers, - body: protectRequest, - json: true, - }; - + const who = "SecloreDRMApiService::protectWithFileId:: "; try { + Logger.debug(who + 'Protecting file with file ID', { + existingProtectedFileId: protectRequest.existingProtectedFileId, + fileStorageId: protectRequest.fileStorageId, + correlationId + }); + + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + Authorization: `Bearer ${accessToken}`, + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/protect/fileid`, + headers, + body: protectRequest, + json: true, + }; + + Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, correlationId }); const response = await this.context.helpers.httpRequest(options); + Logger.debug(who + 'Protection with file ID successful', { + existingProtectedFileId: protectRequest.existingProtectedFileId, + secloreFileId: (response as IProtectWithFileIdResponse).secloreFileId, + correlationId + }); return response as IProtectWithFileIdResponse; } catch (error: unknown) { + Logger.error(who + 'Protection with file ID failed', { + error, + existingProtectedFileId: protectRequest.existingProtectedFileId, + correlationId + }); this.handleHttpError(error as NodeApiError); } } @@ -235,28 +283,47 @@ export class SecloreDRMApiService { accessToken: string, correlationId?: string, ): Promise { - const headers: { [key: string]: string } = { - 'Content-Type': 'application/json', - Authorization: `Bearer ${accessToken}`, - }; - - // Add correlation ID if provided - if (correlationId) { - headers['X-SECLORE-CORRELATION-ID'] = correlationId; - } - - const options: IHttpRequestOptions = { - method: 'POST', - url: `${this.baseUrl}/seclore/drm/1.0/protect/hf`, - headers, - body: protectRequest, - json: true, - }; - + const who = "SecloreDRMApiService::protectWithHotFolder:: "; try { + Logger.debug(who + 'Protecting file with hot folder', { + hotfolderId: protectRequest.hotfolderId, + fileStorageId: protectRequest.fileStorageId, + correlationId + }); + + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + Authorization: `Bearer ${accessToken}`, + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/protect/hf`, + headers, + body: protectRequest, + json: true, + }; + + Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, correlationId }); const response = await this.context.helpers.httpRequest(options); + Logger.debug(who + 'Protection with hot folder successful', { + hotfolderId: protectRequest.hotfolderId, + secloreFileId: (response as IProtectWithHotFolderResponse).secloreFileId, + correlationId + }); return response as IProtectWithHotFolderResponse; } catch (error: unknown) { + Logger.error(who + 'Protection with hot folder failed', { + error, + hotfolderId: protectRequest.hotfolderId, + fileStorageId: protectRequest.fileStorageId, + correlationId + }); this.handleHttpError(error as NodeApiError); } } @@ -275,28 +342,45 @@ export class SecloreDRMApiService { accessToken: string, correlationId?: string, ): Promise { - const headers: { [key: string]: string } = { - 'Content-Type': 'application/json', - Authorization: `Bearer ${accessToken}`, - }; - - // Add correlation ID if provided - if (correlationId) { - headers['X-SECLORE-CORRELATION-ID'] = correlationId; - } - - const options: IHttpRequestOptions = { - method: 'POST', - url: `${this.baseUrl}/seclore/drm/1.0/unprotect`, - headers, - body: unprotectRequest, - json: true, - }; - + const who = "SecloreDRMApiService::unprotect:: "; try { + Logger.debug(who + 'Unprotecting file', { + fileStorageId: unprotectRequest.fileStorageId, + correlationId + }); + + const headers: { [key: string]: string } = { + 'Content-Type': 'application/json', + Authorization: `Bearer ${accessToken}`, + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/1.0/unprotect`, + headers, + body: unprotectRequest, + json: true, + }; + + Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, correlationId }); const response = await this.context.helpers.httpRequest(options); + Logger.debug(who + 'Unprotection successful', { + originalFileStorageId: unprotectRequest.fileStorageId, + unprotectedFileStorageId: (response as IUnprotectResponse).fileStorageId, + correlationId + }); return response as IUnprotectResponse; } catch (error: unknown) { + Logger.error(who + 'Unprotection failed', { + error, + fileStorageId: unprotectRequest.fileStorageId, + correlationId + }); this.handleHttpError(error as NodeApiError); } } @@ -317,31 +401,50 @@ export class SecloreDRMApiService { accessToken: string, correlationId?: string, ): Promise { - const headers: { [key: string]: string } = { - Authorization: `Bearer ${accessToken}`, - }; - - // Add correlation ID if provided - if (correlationId) { - headers['X-SECLORE-CORRELATION-ID'] = correlationId; - } - - // Create FormData for multipart/form-data upload - const formData = new FormData(); - const file = new Blob([fileBuffer], { type: 'application/octet-stream' }); - formData.append('file', file, fileName); - - const options: IHttpRequestOptions = { - method: 'POST', - url: `${this.baseUrl}/seclore/drm/filestorage/1.0/upload`, - headers, - body: formData, - }; - + const who = "SecloreDRMApiService::uploadFile:: "; try { + Logger.debug(who + 'Uploading file', { + fileName, + fileSize: fileBuffer.length, + correlationId + }); + + const headers: { [key: string]: string } = { + Authorization: `Bearer ${accessToken}`, + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + // Create FormData for multipart/form-data upload + const formData = new FormData(); + const file = new Blob([fileBuffer], { type: 'application/octet-stream' }); + formData.append('file', file, fileName); + + const options: IHttpRequestOptions = { + method: 'POST', + url: `${this.baseUrl}/seclore/drm/filestorage/1.0/upload`, + headers, + body: formData, + }; + + Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, fileName, correlationId }); const response = await this.context.helpers.httpRequest(options); + Logger.debug(who + 'File upload successful', { + fileName, + fileStorageId: (response as IFileUploadResponse).fileStorageId, + correlationId + }); return response as IFileUploadResponse; } catch (error: unknown) { + Logger.error(who + 'File upload failed', { + error, + fileName, + fileSize: fileBuffer.length, + correlationId + }); this.handleHttpError(error as NodeApiError); } } @@ -361,26 +464,44 @@ export class SecloreDRMApiService { accessToken: string, correlationId?: string, ): Promise { - const headers: { [key: string]: string } = { - Authorization: `Bearer ${accessToken}`, - }; - - // Add correlation ID if provided - if (correlationId) { - headers['X-SECLORE-CORRELATION-ID'] = correlationId; - } - - const options: IHttpRequestOptions = { - method: 'GET', - url: `${this.baseUrl}/seclore/drm/filestorage/1.0/download/${fileStorageId}`, - headers, - encoding: 'arraybuffer', - }; - + const who = "SecloreDRMApiService::downloadFile:: "; try { + Logger.debug(who + 'Downloading file', { + fileStorageId, + correlationId + }); + + const headers: { [key: string]: string } = { + Authorization: `Bearer ${accessToken}`, + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + const options: IHttpRequestOptions = { + method: 'GET', + url: `${this.baseUrl}/seclore/drm/filestorage/1.0/download/${fileStorageId}`, + headers, + encoding: 'arraybuffer', + }; + + Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, fileStorageId, correlationId }); const response = await this.context.helpers.httpRequest(options); - return new Uint8Array(response as ArrayBuffer); + const fileData = new Uint8Array(response as ArrayBuffer); + Logger.debug(who + 'File download successful', { + fileStorageId, + fileSize: fileData.length, + correlationId + }); + return fileData; } catch (error: unknown) { + Logger.error(who + 'File download failed', { + error, + fileStorageId, + correlationId + }); this.handleHttpError(error as NodeApiError); } } diff --git a/nodes/SecloreProtect/Services/SecloreDRMFileService.ts b/nodes/SecloreProtect/Services/SecloreDRMFileService.ts index 7a8192d..42349da 100644 --- a/nodes/SecloreProtect/Services/SecloreDRMFileService.ts +++ b/nodes/SecloreProtect/Services/SecloreDRMFileService.ts @@ -1,4 +1,4 @@ -import { IExecuteFunctions } from 'n8n-workflow'; +import { IExecuteFunctions, LoggerProxy as Logger } from 'n8n-workflow'; import { IFileUploadResponse } from './Interfaces/FileStorageInterfaces'; import { IProtectWithExternalRefIdRequest, @@ -61,7 +61,9 @@ export class SecloreDRMFileService { * @param correlationId - Optional correlation ID for logging */ private async login(correlationId?: string): Promise { + const who = "SecloreDRMFileService::login:: "; try { + Logger.debug(who + 'Attempting login', { tenantId: this.tenantId, correlationId }); const loginResponse = await this.apiService.login( this.tenantId, this.tenantSecret, @@ -73,7 +75,9 @@ export class SecloreDRMFileService { // Set token expiry to 50 minutes from now (assuming 1 hour token life) this.tokenExpiry = new Date(Date.now() + 50 * 60 * 1000); + Logger.info(who + 'Login successful', { tenantId: this.tenantId, correlationId }); } catch (error) { + Logger.error(who + 'Login failed', { error, tenantId: this.tenantId, correlationId }); this.clearTokens(); throw error; } @@ -108,7 +112,9 @@ export class SecloreDRMFileService { * @param correlationId - Optional correlation ID for logging */ private async performTokenRefresh(correlationId?: string): Promise { + const who = "SecloreDRMFileService::performTokenRefresh:: "; try { + Logger.debug(who + 'Attempting token refresh', { correlationId }); const refreshResponse = await this.apiService.refreshToken(this.refreshToken!, correlationId); this.accessToken = refreshResponse.accessToken; @@ -116,7 +122,9 @@ export class SecloreDRMFileService { // Set token expiry to 50 minutes from now this.tokenExpiry = new Date(Date.now() + 50 * 60 * 1000); + Logger.info(who + 'Token refresh successful', { correlationId }); } catch (error) { + Logger.error(who + 'Token refresh failed', { error, correlationId }); this.clearTokens(); throw error; } @@ -164,8 +172,8 @@ export class SecloreDRMFileService { try { await this.refreshAccessToken(correlationId); continue; // Retry with new token - } catch (error: unknown) { - console.error(error); + } catch (refreshError: unknown) { + Logger.error('SecloreDRMFileService::executeWithRetry:: Token refresh failed', { refreshError, correlationId }); // If refresh fails, clear tokens and try full login on next attempt this.clearTokens(); } @@ -200,12 +208,21 @@ export class SecloreDRMFileService { correlationId?: string, retryCount?: number, ): Promise { - return this.executeWithRetry( - (accessToken) => - this.apiService.protectWithExternalRefId(protectRequest, accessToken, correlationId), - retryCount, - correlationId, - ); + const who = "SecloreDRMFileService::protectWithExternalRefId:: "; + try { + Logger.debug(who + 'Protecting file with external ref ID', { fileStorageId: protectRequest.fileStorageId, hotfolderExternalReferenceId: protectRequest.hotfolderExternalReference.externalReferenceId, correlationId }); + const result = await this.executeWithRetry( + (accessToken) => + this.apiService.protectWithExternalRefId(protectRequest, accessToken, correlationId), + retryCount, + correlationId, + ); + Logger.info(who + 'File protected with external ref ID successfully', { fileStorageId: protectRequest.fileStorageId, secloreFileId: result.secloreFileId, correlationId }); + return result; + } catch (error) { + Logger.error(who + 'Protect with external ref ID failed', { error, fileStorageId: protectRequest.fileStorageId, correlationId }); + throw error; + } } /** @@ -216,12 +233,21 @@ export class SecloreDRMFileService { correlationId?: string, retryCount?: number, ): Promise { - return this.executeWithRetry( - (accessToken) => - this.apiService.protectWithFileId(protectRequest, accessToken, correlationId), - retryCount, - correlationId, - ); + const who = "SecloreDRMFileService::protectWithFileId:: "; + try { + Logger.debug(who + 'Protecting file with file ID', { existingProtectedFileId: protectRequest.existingProtectedFileId, fileStorageId: protectRequest.fileStorageId, correlationId }); + const result = await this.executeWithRetry( + (accessToken) => + this.apiService.protectWithFileId(protectRequest, accessToken, correlationId), + retryCount, + correlationId, + ); + Logger.info(who + 'File protected with file ID successfully', { existingProtectedFileId: protectRequest.existingProtectedFileId, secloreFileId: result.secloreFileId, correlationId }); + return result; + } catch (error) { + Logger.error(who + 'Protect with file ID failed', { error, existingProtectedFileId: protectRequest.existingProtectedFileId, correlationId }); + throw error; + } } /** @@ -232,12 +258,21 @@ export class SecloreDRMFileService { correlationId?: string, retryCount?: number, ): Promise { - return this.executeWithRetry( - (accessToken) => - this.apiService.protectWithHotFolder(protectRequest, accessToken, correlationId), - retryCount, - correlationId, - ); + const who = "SecloreDRMFileService::protectWithHotFolder:: "; + try { + Logger.debug(who + 'Protecting file with hot folder', { hotfolderId: protectRequest.hotfolderId, fileStorageId: protectRequest.fileStorageId, correlationId }); + const result = await this.executeWithRetry( + (accessToken) => + this.apiService.protectWithHotFolder(protectRequest, accessToken, correlationId), + retryCount, + correlationId, + ); + Logger.info(who + 'File protected with hot folder successfully', { hotfolderId: protectRequest.hotfolderId, fileStorageId: protectRequest.fileStorageId, secloreFileId: result.secloreFileId, correlationId }); + return result; + } catch (error) { + Logger.error(who + 'Protect with hot folder failed', { error, hotfolderId: protectRequest.hotfolderId, fileStorageId: protectRequest.fileStorageId, correlationId }); + throw error; + } } /** @@ -248,11 +283,20 @@ export class SecloreDRMFileService { correlationId?: string, retryCount?: number, ): Promise { - return this.executeWithRetry( - (accessToken) => this.apiService.unprotect(unprotectRequest, accessToken, correlationId), - retryCount, - correlationId, - ); + const who = "SecloreDRMFileService::unprotect:: "; + try { + Logger.debug(who + 'Unprotecting file', { fileStorageId: unprotectRequest.fileStorageId, correlationId }); + const result = await this.executeWithRetry( + (accessToken) => this.apiService.unprotect(unprotectRequest, accessToken, correlationId), + retryCount, + correlationId, + ); + Logger.info(who + 'File unprotected successfully', { originalFileStorageId: unprotectRequest.fileStorageId, unprotectedFileStorageId: result.fileStorageId, correlationId }); + return result; + } catch (error) { + Logger.error(who + 'Unprotect file failed', { error, fileStorageId: unprotectRequest.fileStorageId, correlationId }); + throw error; + } } /** @@ -264,11 +308,20 @@ export class SecloreDRMFileService { correlationId?: string, retryCount?: number, ): Promise { - return this.executeWithRetry( + const who = "SecloreDRMFileService::uploadFile:: "; + try { + Logger.debug(who + 'Uploading file', { fileName, correlationId }); + const result = await this.executeWithRetry( (accessToken) => this.apiService.uploadFile(fileBuffer, fileName, accessToken, correlationId), - retryCount, - correlationId, - ); + retryCount, + correlationId, + ); + Logger.info(who + 'File uploaded successfully', { fileName, correlationId }); + return result; + } catch (error) { + Logger.error(who + 'Upload file failed', { error, fileName, correlationId }); + throw error; + } } /** @@ -280,11 +333,20 @@ export class SecloreDRMFileService { correlationId?: string, retryCount?: number, ): Promise { - return this.executeWithRetry( - (accessToken) => this.apiService.downloadFile(fileStorageId, accessToken, correlationId), - retryCount, - correlationId, - ); + const who = "SecloreDRMFileService::downloadFile:: "; + try { + Logger.debug(who + 'Downloading file', { fileStorageId, correlationId }); + const result = await this.executeWithRetry( + (accessToken) => this.apiService.downloadFile(fileStorageId, accessToken, correlationId), + retryCount, + correlationId, + ); + Logger.info(who + 'File downloaded successfully', { fileStorageId, fileSize: result.length, correlationId }); + return result; + } catch (error) { + Logger.error(who + 'Download file failed', { error, fileStorageId, correlationId }); + throw error; + } } /** diff --git a/icons/SecloreProtect.light.svg b/nodes/SecloreProtect/seclore.svg similarity index 100% rename from icons/SecloreProtect.light.svg rename to nodes/SecloreProtect/seclore.svg -- 2.40.1 From b784b8d8117ec7ded5293cf968a2f51ed0caf05c Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Mon, 27 Oct 2025 17:47:21 +0530 Subject: [PATCH 10/22] separated functions into files --- nodes/SecloreProtect/SecloreProtect.node.ts | 258 +----------------- .../operations/protectWithHotFolder.ts | 153 +++++++++++ nodes/SecloreProtect/operations/unprotect.ts | 197 +++++++++++++ nodes/SecloreProtect/seclore.svg | 11 - 4 files changed, 358 insertions(+), 261 deletions(-) create mode 100644 nodes/SecloreProtect/operations/protectWithHotFolder.ts create mode 100644 nodes/SecloreProtect/operations/unprotect.ts delete mode 100644 nodes/SecloreProtect/seclore.svg diff --git a/nodes/SecloreProtect/SecloreProtect.node.ts b/nodes/SecloreProtect/SecloreProtect.node.ts index c703716..2c19533 100644 --- a/nodes/SecloreProtect/SecloreProtect.node.ts +++ b/nodes/SecloreProtect/SecloreProtect.node.ts @@ -1,19 +1,16 @@ import { - IExecuteFunctions, - INodeExecutionData, INodeType, INodeTypeDescription, - NodeOperationError, - NodeOutput, } from 'n8n-workflow'; -import { SecloreDRMFileService } from './Services/SecloreDRMFileService'; +import { protectWithHotFolder } from './operations/protectWithHotFolder'; +import { unprotect } from './operations/unprotect'; export class SecloreProtect implements INodeType { description: INodeTypeDescription = { displayName: 'Seclore Protect', name: 'secloreProtect', - icon: 'file:seclore.svg', + icon: 'file:../../icons/seclore.svg', usableAsTool: true, // TODO: make it false/ don't allow it to be used as a tool group: ['transform'], version: 1, @@ -100,20 +97,6 @@ export class SecloreProtect implements INodeType { }, }, }, - { - displayName: 'Output Binary Property', - name: 'outputBinaryPropertyName', - type: 'string', - default: 'data', - required: true, - description: 'Name of the binary property where the protected file will be stored', - displayOptions: { - show: { - resource: ['protection'], - operation: ['protectWithHotFolder'], - }, - }, - }, { displayName: 'Correlation ID', name: 'correlationId', @@ -143,27 +126,12 @@ export class SecloreProtect implements INodeType { }, // Unprotect operation parameters { - displayName: 'File ID', - name: 'fileId', - type: 'string', - required: true, - default: '', - placeholder: 'e.g., file-12345', - description: 'The ID of the file to unprotect', - displayOptions: { - show: { - resource: ['protection'], - operation: ['unprotect'], - }, - }, - }, - { - displayName: 'Output Binary Property', - name: 'outputBinaryPropertyName', + displayName: 'Input Binary Property', + name: 'binaryPropertyName', type: 'string', default: 'data', required: true, - description: 'Name of the binary property where the unprotected file will be stored', + description: 'Name of the binary property that contains the protected file to unprotect', displayOptions: { show: { resource: ['protection'], @@ -203,219 +171,9 @@ export class SecloreProtect implements INodeType { customOperations = { protection: { - protectWithHotFolder: this.protectWithHotFolder, - unprotect: this.unprotect, + protectWithHotFolder, + unprotect, }, }; - async protectWithHotFolder(this: IExecuteFunctions): Promise { - const items = this.getInputData(); - const returnData: INodeExecutionData[] = []; - - // Get credentials - const credentials = await this.getCredentials('secloreProtectApi'); - const baseUrl = credentials.baseUrl as string; - const tenantId = credentials.tenantId as string; - const tenantSecret = credentials.tenantSecret as string; - - // Initialize the file service - const fileService = new SecloreDRMFileService(this, baseUrl, tenantId, tenantSecret); - - for (let i = 0; i < items.length; i++) { - console.log('Data'); - console.log(items[i]); - try { - // Get parameters for this item - const hotfolderId = this.getNodeParameter('hotfolderId', i) as string; - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; - const outputBinaryPropertyName = this.getNodeParameter( - 'outputBinaryPropertyName', - i, - ) as string; - const correlationId = this.getNodeParameter('correlationId', i) as string; - const retryCount = this.getNodeParameter('retryCount', i) as number; - - // Validate required parameters - if (!hotfolderId) { - throw new NodeOperationError(this.getNode(), 'HotFolder ID is required', { - itemIndex: i, - }); - } - - console.log('assertBinaryData'); - // Get input binary data - const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); - - console.log('getBinaryDataBuffer'); - const fileBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); - - console.log('fileBuffer', fileBuffer); - console.log('binaryData.fileName', binaryData.fileName); - - // Upload the file first - const uploadResult = await fileService.uploadFile( - new Uint8Array(fileBuffer), - binaryData.fileName || 'file', - correlationId || undefined, - retryCount, - ); - - console.log('File upload response', uploadResult); - - // Protect the uploaded file with HotFolder - const protectResult = await fileService.protectWithHotFolder( - { - hotfolderId, - fileStorageId: uploadResult.fileStorageId, - }, - correlationId || undefined, - retryCount, - ); - - console.log('File protect response', protectResult); - - // Download the protected file - const protectedFileData = await fileService.downloadFile( - protectResult.fileStorageId, - correlationId || undefined, - retryCount, - ); - - console.log('Protected file data', protectedFileData); - - // Create output binary data - const outputBinaryData = await this.helpers.prepareBinaryData( - Buffer.from(protectedFileData), - binaryData.fileName || 'protected_file', - binaryData.mimeType, - ); - - // Create return item with binary data and metadata - const returnItem: INodeExecutionData = { - json: { - success: true, - originalFileStorageId: uploadResult.fileStorageId, - protectedFileStorageId: protectResult.fileStorageId, - secloreFileId: protectResult.secloreFileId, - hotfolderId, - fileName: binaryData.fileName, - fileSize: protectedFileData.length, - correlationId: correlationId || null, - }, - binary: { - [outputBinaryPropertyName]: outputBinaryData, - }, - }; - - returnData.push(returnItem); - } catch (error) { - // Handle errors gracefully - if (this.continueOnFail()) { - const returnItem: INodeExecutionData = { - json: { - success: false, - error: error.message, - itemIndex: i, - }, - }; - returnData.push(returnItem); - } else { - throw new NodeOperationError(this.getNode(), error.message, { - itemIndex: i, - }); - } - } - } - - return [returnData]; - } - - async unprotect(this: IExecuteFunctions): Promise { - const items = this.getInputData(); - const returnData: INodeExecutionData[] = []; - - // Get credentials - const credentials = await this.getCredentials('secloreProtectApi'); - const baseUrl = credentials.baseUrl as string; - const tenantId = credentials.tenantId as string; - const tenantSecret = credentials.tenantSecret as string; - - // Initialize the file service - const fileService = new SecloreDRMFileService(this, baseUrl, tenantId, tenantSecret); - - for (let i = 0; i < items.length; i++) { - console.log('Data'); - console.log(items[i]); - try { - // Get parameters for this item - const fileId = this.getNodeParameter('fileId', i) as string; - const outputBinaryPropertyName = this.getNodeParameter( - 'outputBinaryPropertyName', - i, - ) as string; - const correlationId = this.getNodeParameter('correlationId', i) as string; - const retryCount = this.getNodeParameter('retryCount', i) as number; - - // Validate required parameters - if (!fileId) { - throw new NodeOperationError(this.getNode(), 'File ID is required', { - itemIndex: i, - }); - } - - console.log('Unprotecting file with ID:', fileId); - - // Unprotect the file using the file ID - // Note: You'll need to implement unprotectFile in your SecloreDRMFileService - // For now, using downloadFile as placeholder - replace with actual unprotect method - const unprotectedFileData = await fileService.downloadFile( - fileId, - correlationId || undefined, - retryCount, - ); - - console.log('Unprotected file data', unprotectedFileData); - - // Create output binary data - const outputBinaryData = await this.helpers.prepareBinaryData( - Buffer.from(unprotectedFileData), - 'unprotected_file', - 'application/octet-stream', - ); - - // Create return item with binary data and metadata - const returnItem: INodeExecutionData = { - json: { - success: true, - fileId, - fileSize: unprotectedFileData.length, - correlationId: correlationId || null, - }, - binary: { - [outputBinaryPropertyName]: outputBinaryData, - }, - }; - - returnData.push(returnItem); - } catch (error) { - // Handle errors gracefully - if (this.continueOnFail()) { - const returnItem: INodeExecutionData = { - json: { - success: false, - error: error.message, - itemIndex: i, - }, - }; - returnData.push(returnItem); - } else { - throw new NodeOperationError(this.getNode(), error.message, { - itemIndex: i, - }); - } - } - } - - return [returnData]; - } } diff --git a/nodes/SecloreProtect/operations/protectWithHotFolder.ts b/nodes/SecloreProtect/operations/protectWithHotFolder.ts new file mode 100644 index 0000000..ceff624 --- /dev/null +++ b/nodes/SecloreProtect/operations/protectWithHotFolder.ts @@ -0,0 +1,153 @@ +import { + IExecuteFunctions, + INodeExecutionData, + NodeOperationError, + NodeOutput, + LoggerProxy as Logger, +} from 'n8n-workflow'; + +import { SecloreDRMFileService } from '../Services/SecloreDRMFileService'; + +export async function protectWithHotFolder(this: IExecuteFunctions): Promise { + const items = this.getInputData(); + const returnData: INodeExecutionData[] = []; + + // Initialize logger with the current execution context + Logger.init(this.logger); + + Logger.info('Seclore Protect with HotFolder operation started', { itemCount: items.length }); + + // Get credentials + const credentials = await this.getCredentials('secloreProtectApi'); + const baseUrl = credentials.baseUrl as string; + const tenantId = credentials.tenantId as string; + const tenantSecret = credentials.tenantSecret as string; + + // Initialize the file service + const fileService = new SecloreDRMFileService(this, baseUrl, tenantId, tenantSecret); + + for (let i = 0; i < items.length; i++) { + Logger.debug('Processing item', { itemIndex: i, itemData: items[i] }); + try { + // Get parameters for this item + const hotfolderId = this.getNodeParameter('hotfolderId', i) as string; + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; + const correlationId = this.getNodeParameter('correlationId', i) as string; + const retryCount = this.getNodeParameter('retryCount', i) as number; + + // Validate required parameters + if (!hotfolderId) { + throw new NodeOperationError(this.getNode(), 'HotFolder ID is required', { + itemIndex: i, + }); + } + + Logger.debug('Asserting binary data', { binaryPropertyName, itemIndex: i }); + // Get input binary data + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); + + Logger.debug('Getting binary data buffer', { binaryPropertyName, itemIndex: i }); + const fileBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); + + Logger.debug('Binary data retrieved', { + fileName: binaryData.fileName, + fileSize: fileBuffer.length, + mimeType: binaryData.mimeType, + itemIndex: i + }); + + // Upload the file first + const uploadResult = await fileService.uploadFile( + new Uint8Array(fileBuffer), + binaryData.fileName || 'file', + correlationId || undefined, + retryCount, + ); + + Logger.info('File uploaded successfully', { fileStorageId: uploadResult.fileStorageId, fileName: binaryData.fileName }); + Logger.debug('File upload response', { uploadResult }); + + // Protect the uploaded file with HotFolder + const protectResult = await fileService.protectWithHotFolder( + { + hotfolderId, + fileStorageId: uploadResult.fileStorageId, + }, + correlationId || undefined, + retryCount, + ); + + Logger.info('File protected successfully', { + originalFileStorageId: uploadResult.fileStorageId, + protectedFileStorageId: protectResult.fileStorageId, + secloreFileId: protectResult.secloreFileId, + hotfolderId, + fileName: binaryData.fileName + }); + Logger.debug('File protect response', { protectResult }); + + // Download the protected file + const protectedFileData = await fileService.downloadFile( + protectResult.fileStorageId, + correlationId || undefined, + retryCount, + ); + + Logger.info('Protected file downloaded successfully', { + fileStorageId: protectResult.fileStorageId, + fileSize: protectedFileData.length, + fileName: binaryData.fileName + }); + + // Create output binary data + const outputBinaryData = await this.helpers.prepareBinaryData( + Buffer.from(protectedFileData), + binaryData.fileName || 'protected_file', + binaryData.mimeType, + ); + + // Create return item with binary data and metadata + const returnItem: INodeExecutionData = { + json: { + success: true, + originalFileStorageId: uploadResult.fileStorageId, + protectedFileStorageId: protectResult.fileStorageId, + secloreFileId: protectResult.secloreFileId, + hotfolderId, + fileName: binaryData.fileName, + fileSize: protectedFileData.length, + correlationId: correlationId || null, + }, + binary: { + data: outputBinaryData, + }, + }; + + returnData.push(returnItem); + } catch (error) { + // Handle errors gracefully + Logger.error('Protect with HotFolder operation failed', { error, itemIndex: i }); + if (this.continueOnFail()) { + const returnItem: INodeExecutionData = { + json: { + success: false, + error: error.message, + itemIndex: i, + }, + }; + returnData.push(returnItem); + } else { + throw new NodeOperationError(this.getNode(), error.message, { + itemIndex: i, + }); + } + } + } + + Logger.info('Seclore Protect with HotFolder operation completed', { + processedItems: returnData.length, + successfulItems: returnData.filter(item => item.json.success).length + }); + + return [returnData]; +} diff --git a/nodes/SecloreProtect/operations/unprotect.ts b/nodes/SecloreProtect/operations/unprotect.ts new file mode 100644 index 0000000..a0d4031 --- /dev/null +++ b/nodes/SecloreProtect/operations/unprotect.ts @@ -0,0 +1,197 @@ +import { + IExecuteFunctions, + INodeExecutionData, + NodeOperationError, + NodeOutput, + LoggerProxy as Logger, +} from 'n8n-workflow'; + +import { SecloreDRMFileService } from '../Services/SecloreDRMFileService'; + +/** + * Uploads a file, unprotects it, and downloads the unprotected version + * @param fileService - The SecloreDRMFileService instance + * @param fileBuffer - The file buffer to upload + * @param fileName - The name of the file + * @param correlationId - Optional correlation ID for tracking + * @param retryCount - Number of retries for operations + * @returns Promise containing the unprotected file data and metadata + */ +async function unprotectFile( + context: IExecuteFunctions, + fileService: SecloreDRMFileService, + fileBuffer: Buffer, + fileName: string, + correlationId?: string, + retryCount: number = 3, +): Promise<{ + unprotectedFileData: Uint8Array; + originalFileStorageId: string; + unprotectedFileStorageId: string; + fileName: string; + fileSize: number; +}> { + // Upload the protected file + const uploadResult = await fileService.uploadFile( + new Uint8Array(fileBuffer), + fileName, + correlationId, + retryCount, + ); + + Logger.info('File uploaded successfully', { fileStorageId: uploadResult.fileStorageId, fileName }); + Logger.debug('File upload response', {uploadResult}); + + // Unprotect the uploaded file + Logger.debug('Unprotecting file', { fileStorageId: uploadResult.fileStorageId, fileName }); + const unprotectResult = await fileService.unprotect( + { + fileStorageId: uploadResult.fileStorageId, + }, + correlationId, + retryCount, + ); + + Logger.info('File unprotected successfully', { originalFileStorageId: uploadResult.fileStorageId, unprotectedFileStorageId: unprotectResult.fileStorageId, fileName }); + + Logger.info('Downloading unprotected file', { fileStorageId: unprotectResult.fileStorageId, fileName }); + // Download the unprotected file + const unprotectedFileData = await fileService.downloadFile( + unprotectResult.fileStorageId, + correlationId, + retryCount, + ); + + Logger.info('Unprotected file downloaded successfully', { fileStorageId: unprotectResult.fileStorageId, fileSize: unprotectedFileData.length, fileName }); + + return { + unprotectedFileData, + originalFileStorageId: uploadResult.fileStorageId, + unprotectedFileStorageId: unprotectResult.fileStorageId, + fileName, + fileSize: unprotectedFileData.length, + }; +} + +export async function unprotect(this: IExecuteFunctions): Promise { + const items = this.getInputData(); + const returnData: INodeExecutionData[] = []; + + // Initialize logger with the current execution context + Logger.init(this.logger); + + Logger.info('Seclore Unprotect operation started', { itemCount: items.length }); + + // Get credentials + const credentials = await this.getCredentials('secloreProtectApi'); + const baseUrl = credentials.baseUrl as string; + const tenantId = credentials.tenantId as string; + const tenantSecret = credentials.tenantSecret as string; + + // Initialize the file service + const fileService = new SecloreDRMFileService(this, baseUrl, tenantId, tenantSecret); + + for (let i = 0; i < items.length; i++) { + Logger.debug('Processing item', { itemIndex: i, itemData: items[i] }); + try { + // Get parameters for this item + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; + const correlationId = this.getNodeParameter('correlationId', i) as string; + const retryCount = this.getNodeParameter('retryCount', i) as number; + + Logger.debug('Asserting binary data', { binaryPropertyName, itemIndex: i }); + // Get input binary data + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); + + Logger.debug('Getting binary data buffer', { binaryPropertyName, itemIndex: i }); + const fileBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); + + Logger.debug('Binary data retrieved', { + fileName: binaryData.fileName, + fileSize: fileBuffer.length, + mimeType: binaryData.mimeType, + itemIndex: i + }); + + // Use the combined upload, unprotect, and download function + try { + Logger.debug('Starting unprotect file operation', { + fileName: binaryData.fileName, + correlationId, + retryCount, + itemIndex: i + }); + + const result = await unprotectFile( + this, + fileService, + fileBuffer, + binaryData.fileName || 'protected_file', + correlationId || undefined, + retryCount, + ); + + Logger.info('Unprotect file operation completed successfully', { + fileName: result.fileName, + originalFileStorageId: result.originalFileStorageId, + unprotectedFileStorageId: result.unprotectedFileStorageId, + fileSize: result.fileSize, + itemIndex: i + }); + + // Create output binary data + const outputBinaryData = await this.helpers.prepareBinaryData( + Buffer.from(result.unprotectedFileData), + binaryData.fileName || 'unprotected_file', + binaryData.mimeType, + ); + + // Create return item with binary data and metadata + const returnItem: INodeExecutionData = { + json: { + success: true, + originalFileStorageId: result.originalFileStorageId, + unprotectedFileStorageId: result.unprotectedFileStorageId, + fileName: result.fileName, + fileSize: result.fileSize, + correlationId: correlationId || null, + }, + binary: { + data: outputBinaryData, + }, + }; + + returnData.push(returnItem); + } catch (unprotectError) { + Logger.error('Unprotect file operation failed with error', { unprotectError }); + + // Re-throw the error to be handled by the outer catch block + throw unprotectError; + } + } catch (error) { + // Handle errors gracefully + Logger.error('Unprotect file operation failed with error', { error }); + if (this.continueOnFail()) { + const returnItem: INodeExecutionData = { + json: { + success: false, + error: error.message, + itemIndex: i, + }, + }; + returnData.push(returnItem); + } else { + throw new NodeOperationError(this.getNode(), error.message, { + itemIndex: i, + }); + } + } + } + + Logger.info('Seclore Unprotect operation completed', { + processedItems: returnData.length, + successfulItems: returnData.filter(item => item.json.success).length + }); + + return [returnData]; +} diff --git a/nodes/SecloreProtect/seclore.svg b/nodes/SecloreProtect/seclore.svg deleted file mode 100644 index 58541ba..0000000 --- a/nodes/SecloreProtect/seclore.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - \ No newline at end of file -- 2.40.1 From 14e7cbf9fcfe6df20d213160d800e247e62ece5d Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Mon, 27 Oct 2025 18:03:58 +0530 Subject: [PATCH 11/22] delete original file once unprotected --- .../Services/SecloreDRMApiService.ts | 52 +++++ .../Services/SecloreDRMFileService.ts | 23 +++ nodes/SecloreProtect/operations/unprotect.ts | 190 +++++++++++++----- 3 files changed, 219 insertions(+), 46 deletions(-) diff --git a/nodes/SecloreProtect/Services/SecloreDRMApiService.ts b/nodes/SecloreProtect/Services/SecloreDRMApiService.ts index 2870132..94285b8 100644 --- a/nodes/SecloreProtect/Services/SecloreDRMApiService.ts +++ b/nodes/SecloreProtect/Services/SecloreDRMApiService.ts @@ -505,4 +505,56 @@ export class SecloreDRMApiService { this.handleHttpError(error as NodeApiError); } } + + /** + * Deletes a file with fileStorageId from file storage of currently logged in Tenant. + * + * @param fileStorageId - Storage ID of the file to be deleted + * @param accessToken - JWT access token for authorization + * @param correlationId - Optional request ID for logging purpose + * @returns Promise - No response body on successful deletion + * @throws Error on authentication failure or server error + */ + async deleteFile( + fileStorageId: string, + accessToken: string, + correlationId?: string, + ): Promise { + const who = "SecloreDRMApiService::deleteFile:: "; + try { + Logger.debug(who + 'Deleting file', { + fileStorageId, + correlationId + }); + + const headers: { [key: string]: string } = { + Authorization: `Bearer ${accessToken}`, + }; + + // Add correlation ID if provided + if (correlationId) { + headers['X-SECLORE-CORRELATION-ID'] = correlationId; + } + + const options: IHttpRequestOptions = { + method: 'DELETE', + url: `${this.baseUrl}/seclore/drm/filestorage/1.0/${fileStorageId}`, + headers, + }; + + Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, fileStorageId, correlationId }); + await this.context.helpers.httpRequest(options); + Logger.debug(who + 'File deletion successful', { + fileStorageId, + correlationId + }); + } catch (error: unknown) { + Logger.error(who + 'File deletion failed', { + error, + fileStorageId, + correlationId + }); + this.handleHttpError(error as NodeApiError); + } + } } diff --git a/nodes/SecloreProtect/Services/SecloreDRMFileService.ts b/nodes/SecloreProtect/Services/SecloreDRMFileService.ts index 42349da..92f0d5d 100644 --- a/nodes/SecloreProtect/Services/SecloreDRMFileService.ts +++ b/nodes/SecloreProtect/Services/SecloreDRMFileService.ts @@ -349,6 +349,29 @@ export class SecloreDRMFileService { } } + /** + * Delete file with automatic authentication and retry + */ + async deleteFile( + fileStorageId: string, + correlationId?: string, + retryCount?: number, + ): Promise { + const who = "SecloreDRMFileService::deleteFile:: "; + try { + Logger.debug(who + 'Deleting file', { fileStorageId, correlationId }); + await this.executeWithRetry( + (accessToken) => this.apiService.deleteFile(fileStorageId, accessToken, correlationId), + retryCount, + correlationId, + ); + Logger.info(who + 'File deleted successfully', { fileStorageId, correlationId }); + } catch (error) { + Logger.error(who + 'Delete file failed', { error, fileStorageId, correlationId }); + throw error; + } + } + /** * Get current access token (for debugging/monitoring) */ diff --git a/nodes/SecloreProtect/operations/unprotect.ts b/nodes/SecloreProtect/operations/unprotect.ts index a0d4031..9c9d5b5 100644 --- a/nodes/SecloreProtect/operations/unprotect.ts +++ b/nodes/SecloreProtect/operations/unprotect.ts @@ -8,6 +8,41 @@ import { import { SecloreDRMFileService } from '../Services/SecloreDRMFileService'; +/** + * Deletes a file from storage with error handling (does not throw errors) + * @param fileService - The SecloreDRMFileService instance + * @param fileStorageId - The file storage ID to delete + * @param correlationId - Optional correlation ID for tracking + * @param retryCount - Number of retries for operations + */ +async function deleteFile( + fileService: SecloreDRMFileService, + fileStorageId: string, + correlationId?: string, + retryCount: number = 3, +): Promise { + const who = "unprotect::deleteFileWithErrorHandling:: "; + try { + Logger.debug(who + 'Attempting to delete file', { fileStorageId, correlationId, retryCount }); + + await fileService.deleteFile( + fileStorageId, + correlationId, + retryCount, + ); + + Logger.debug(who + 'File deleted successfully', { fileStorageId, correlationId }); + } catch (error) { + // Log error but don't throw - this is for cleanup operations + Logger.error(who + 'File deletion failed, continuing operation', { + error, + fileStorageId, + correlationId, + message: 'This is a cleanup operation, continuing despite deletion failure' + }); + } +} + /** * Uploads a file, unprotects it, and downloads the unprotected version * @param fileService - The SecloreDRMFileService instance @@ -31,91 +66,144 @@ async function unprotectFile( fileName: string; fileSize: number; }> { - // Upload the protected file - const uploadResult = await fileService.uploadFile( - new Uint8Array(fileBuffer), - fileName, - correlationId, - retryCount, - ); + const who = "unprotect::unprotectFile:: "; + var originalFileStorageId: string = ''; + try { + Logger.debug(who + 'Starting unprotect file operation', { fileName, fileSize: fileBuffer.length, correlationId, retryCount }); + + // Upload the protected file + Logger.debug(who + 'Uploading protected file', { fileName, fileSize: fileBuffer.length, correlationId }); + const uploadResult = await fileService.uploadFile( + new Uint8Array(fileBuffer), + fileName, + correlationId, + retryCount, + ); - Logger.info('File uploaded successfully', { fileStorageId: uploadResult.fileStorageId, fileName }); - Logger.debug('File upload response', {uploadResult}); + Logger.debug(who + 'File uploaded successfully', { fileStorageId: uploadResult.fileStorageId, fileName, correlationId }); - // Unprotect the uploaded file - Logger.debug('Unprotecting file', { fileStorageId: uploadResult.fileStorageId, fileName }); - const unprotectResult = await fileService.unprotect( - { - fileStorageId: uploadResult.fileStorageId, - }, - correlationId, - retryCount, - ); + originalFileStorageId = uploadResult.fileStorageId; - Logger.info('File unprotected successfully', { originalFileStorageId: uploadResult.fileStorageId, unprotectedFileStorageId: unprotectResult.fileStorageId, fileName }); + // check if the file is already unprotected + if (!uploadResult.protected) { + Logger.debug(who + 'File is already unprotected', { fileStorageId: uploadResult.fileStorageId, fileName, correlationId }); + return { + unprotectedFileData: fileBuffer, + originalFileStorageId: uploadResult.fileStorageId, + unprotectedFileStorageId: uploadResult.fileStorageId, + fileName, + fileSize: fileBuffer.length, + }; + } - Logger.info('Downloading unprotected file', { fileStorageId: unprotectResult.fileStorageId, fileName }); - // Download the unprotected file - const unprotectedFileData = await fileService.downloadFile( - unprotectResult.fileStorageId, - correlationId, - retryCount, - ); + // Unprotect the uploaded file + Logger.debug(who + 'Unprotecting file', { fileStorageId: uploadResult.fileStorageId, fileName, correlationId }); + const unprotectResult = await fileService.unprotect( + { + fileStorageId: uploadResult.fileStorageId, + }, + correlationId, + retryCount, + ); - Logger.info('Unprotected file downloaded successfully', { fileStorageId: unprotectResult.fileStorageId, fileSize: unprotectedFileData.length, fileName }); + Logger.debug(who + 'File unprotected successfully', { + originalFileStorageId: uploadResult.fileStorageId, + unprotectedFileStorageId: unprotectResult.fileStorageId, + fileName, + correlationId + }); - return { - unprotectedFileData, - originalFileStorageId: uploadResult.fileStorageId, - unprotectedFileStorageId: unprotectResult.fileStorageId, - fileName, - fileSize: unprotectedFileData.length, - }; + // Download the unprotected file + Logger.debug(who + 'Downloading unprotected file', { fileStorageId: unprotectResult.fileStorageId, fileName, correlationId }); + const unprotectedFileData = await fileService.downloadFile( + unprotectResult.fileStorageId, + correlationId, + retryCount, + ); + + Logger.debug(who + 'Unprotected file downloaded successfully', { + fileStorageId: unprotectResult.fileStorageId, + fileSize: unprotectedFileData.length, + fileName, + correlationId + }); + + const result = { + unprotectedFileData, + originalFileStorageId: uploadResult.fileStorageId, + unprotectedFileStorageId: unprotectResult.fileStorageId, + fileName, + fileSize: unprotectedFileData.length, + }; + + Logger.debug(who + 'Unprotect file operation completed successfully', { + fileName: result.fileName, + originalFileStorageId: result.originalFileStorageId, + unprotectedFileStorageId: result.unprotectedFileStorageId, + fileSize: result.fileSize, + correlationId + }); + + return result; + } catch (error) { + Logger.error(who + 'Unprotect file operation failed', { error, fileName, correlationId }); + throw error; + } finally { + if (originalFileStorageId !== '') { + await deleteFile(fileService, originalFileStorageId, correlationId, retryCount); + } + } } export async function unprotect(this: IExecuteFunctions): Promise { + const who = "unprotect::unprotect:: "; const items = this.getInputData(); const returnData: INodeExecutionData[] = []; // Initialize logger with the current execution context Logger.init(this.logger); - Logger.info('Seclore Unprotect operation started', { itemCount: items.length }); + Logger.debug(who + 'Seclore Unprotect operation started', { itemCount: items.length }); // Get credentials + Logger.debug(who + 'Getting credentials', {}); const credentials = await this.getCredentials('secloreProtectApi'); const baseUrl = credentials.baseUrl as string; const tenantId = credentials.tenantId as string; const tenantSecret = credentials.tenantSecret as string; // Initialize the file service + Logger.debug(who + 'Initializing file service', { baseUrl, tenantId }); const fileService = new SecloreDRMFileService(this, baseUrl, tenantId, tenantSecret); for (let i = 0; i < items.length; i++) { - Logger.debug('Processing item', { itemIndex: i, itemData: items[i] }); + Logger.debug(who + 'Processing item', { itemIndex: i }); try { // Get parameters for this item + Logger.debug(who + 'Getting node parameters', { itemIndex: i }); const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; const correlationId = this.getNodeParameter('correlationId', i) as string; const retryCount = this.getNodeParameter('retryCount', i) as number; - Logger.debug('Asserting binary data', { binaryPropertyName, itemIndex: i }); + Logger.debug(who + 'Asserting binary data', { binaryPropertyName, itemIndex: i }); // Get input binary data const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); - Logger.debug('Getting binary data buffer', { binaryPropertyName, itemIndex: i }); + Logger.debug(who + 'Getting binary data buffer', { binaryPropertyName, itemIndex: i }); const fileBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); - Logger.debug('Binary data retrieved', { + Logger.debug(who + 'Binary data retrieved', { fileName: binaryData.fileName, fileSize: fileBuffer.length, mimeType: binaryData.mimeType, - itemIndex: i + itemIndex: i, + correlationId, + retryCount }); // Use the combined upload, unprotect, and download function try { - Logger.debug('Starting unprotect file operation', { + Logger.debug(who + 'Starting unprotect file operation', { fileName: binaryData.fileName, correlationId, retryCount, @@ -131,15 +219,22 @@ export async function unprotect(this: IExecuteFunctions): Promise { retryCount, ); - Logger.info('Unprotect file operation completed successfully', { + Logger.debug(who + 'Unprotect file operation completed successfully', { fileName: result.fileName, originalFileStorageId: result.originalFileStorageId, unprotectedFileStorageId: result.unprotectedFileStorageId, fileSize: result.fileSize, - itemIndex: i + itemIndex: i, + correlationId }); // Create output binary data + Logger.debug(who + 'Preparing binary data for output', { + fileName: binaryData.fileName, + mimeType: binaryData.mimeType, + fileSize: result.fileSize, + itemIndex: i + }); const outputBinaryData = await this.helpers.prepareBinaryData( Buffer.from(result.unprotectedFileData), binaryData.fileName || 'unprotected_file', @@ -161,17 +256,19 @@ export async function unprotect(this: IExecuteFunctions): Promise { }, }; + Logger.debug(who + 'Adding result to return data', { itemIndex: i, success: true }); returnData.push(returnItem); } catch (unprotectError) { - Logger.error('Unprotect file operation failed with error', { unprotectError }); + Logger.error(who + 'Unprotect file operation failed', { unprotectError, itemIndex: i }); // Re-throw the error to be handled by the outer catch block throw unprotectError; } } catch (error) { // Handle errors gracefully - Logger.error('Unprotect file operation failed with error', { error }); + Logger.error(who + 'Item processing failed', { error, itemIndex: i }); if (this.continueOnFail()) { + Logger.debug(who + 'Continuing on fail, adding error item', { itemIndex: i, errorMessage: error.message }); const returnItem: INodeExecutionData = { json: { success: false, @@ -181,6 +278,7 @@ export async function unprotect(this: IExecuteFunctions): Promise { }; returnData.push(returnItem); } else { + Logger.error(who + 'Throwing NodeOperationError', { error: error.message, itemIndex: i }); throw new NodeOperationError(this.getNode(), error.message, { itemIndex: i, }); @@ -188,7 +286,7 @@ export async function unprotect(this: IExecuteFunctions): Promise { } } - Logger.info('Seclore Unprotect operation completed', { + Logger.debug(who + 'Seclore Unprotect operation completed', { processedItems: returnData.length, successfulItems: returnData.filter(item => item.json.success).length }); -- 2.40.1 From 60b90f2f4d12092974389aa570d9a93fda9d5069 Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Mon, 27 Oct 2025 20:46:44 +0530 Subject: [PATCH 12/22] some cleanup --- nodes/SecloreProtect/SecloreProtect.node.ts | 28 -- .../Services/SecloreDRMApiService.ts | 8 +- .../operations/protectWithHotFolder.ts | 300 +++++++++++++----- nodes/SecloreProtect/operations/unprotect.ts | 10 +- 4 files changed, 232 insertions(+), 114 deletions(-) diff --git a/nodes/SecloreProtect/SecloreProtect.node.ts b/nodes/SecloreProtect/SecloreProtect.node.ts index 2c19533..57f9116 100644 --- a/nodes/SecloreProtect/SecloreProtect.node.ts +++ b/nodes/SecloreProtect/SecloreProtect.node.ts @@ -97,20 +97,6 @@ export class SecloreProtect implements INodeType { }, }, }, - { - displayName: 'Correlation ID', - name: 'correlationId', - type: 'string', - default: '', - placeholder: 'e.g., req-12345', - description: 'Optional correlation ID for request tracking and logging', - displayOptions: { - show: { - resource: ['protection'], - operation: ['protectWithHotFolder'], - }, - }, - }, { displayName: 'Retry Count', name: 'retryCount', @@ -139,20 +125,6 @@ export class SecloreProtect implements INodeType { }, }, }, - { - displayName: 'Correlation ID', - name: 'correlationId', - type: 'string', - default: '', - placeholder: 'e.g., req-12345', - description: 'Optional correlation ID for request tracking and logging', - displayOptions: { - show: { - resource: ['protection'], - operation: ['unprotect'], - }, - }, - }, { displayName: 'Retry Count', name: 'retryCount', diff --git a/nodes/SecloreProtect/Services/SecloreDRMApiService.ts b/nodes/SecloreProtect/Services/SecloreDRMApiService.ts index 94285b8..75e0b92 100644 --- a/nodes/SecloreProtect/Services/SecloreDRMApiService.ts +++ b/nodes/SecloreProtect/Services/SecloreDRMApiService.ts @@ -13,14 +13,10 @@ import { import { IUnprotectRequest, IUnprotectResponse } from './Interfaces/UnprotectInterfaces'; export class SecloreDRMApiService { - private baseUrl: string; - constructor( private context: IExecuteFunctions, - baseUrl: string, - ) { - this.baseUrl = baseUrl; - } + private baseUrl: string, + ) { } /** * Common error handler for HTTP responses diff --git a/nodes/SecloreProtect/operations/protectWithHotFolder.ts b/nodes/SecloreProtect/operations/protectWithHotFolder.ts index ceff624..9644cf4 100644 --- a/nodes/SecloreProtect/operations/protectWithHotFolder.ts +++ b/nodes/SecloreProtect/operations/protectWithHotFolder.ts @@ -5,34 +5,182 @@ import { NodeOutput, LoggerProxy as Logger, } from 'n8n-workflow'; - +import crypto from 'node:crypto'; import { SecloreDRMFileService } from '../Services/SecloreDRMFileService'; +/** + * Deletes a file from storage with error handling (does not throw errors) + * @param fileService - The SecloreDRMFileService instance + * @param fileStorageId - The file storage ID to delete + * @param correlationId - Optional correlation ID for tracking + * @param retryCount - Number of retries for operations + */ +async function deleteFile( + fileService: SecloreDRMFileService, + fileStorageId: string, + correlationId?: string, + retryCount: number = 3, +): Promise { + const who = "protectWithHotFolder::deleteFile:: "; + try { + Logger.debug(who + 'Attempting to delete file', { fileStorageId, correlationId, retryCount }); + + await fileService.deleteFile( + fileStorageId, + correlationId, + retryCount, + ); + + Logger.debug(who + 'File deleted successfully', { fileStorageId, correlationId }); + } catch (error) { + // Log error but don't throw - this is for cleanup operations + Logger.error(who + 'File deletion failed, continuing operation', { + error, + fileStorageId, + correlationId, + message: 'This is a cleanup operation, continuing despite deletion failure' + }); + } +} + +/** + * Uploads a file, protects it with hot folder, and downloads the protected version + * @param fileService - The SecloreDRMFileService instance + * @param fileBuffer - The file buffer to upload + * @param fileName - The name of the file + * @param hotfolderId - The hot folder ID to use for protection + * @param correlationId - Optional correlation ID for tracking + * @param retryCount - Number of retries for operations + * @returns Promise containing the protected file data and metadata + */ +async function protectFileWithHotFolder( + fileService: SecloreDRMFileService, + fileBuffer: Buffer, + fileName: string, + hotfolderId: string, + correlationId?: string, + retryCount: number = 3, +): Promise<{ + protectedFileData: Uint8Array; + originalFileStorageId: string; + protectedFileStorageId: string; + secloreFileId: string; + fileName: string; + fileSize: number; +}> { + const who = "protectWithHotFolder::protectFileWithHotFolder:: "; + var originalFileStorageId: string = ''; + const protectedFileName = `${fileName}.html`; + try { + Logger.debug(who + 'Starting protect file with hot folder operation', { fileName, fileSize: fileBuffer.length, hotfolderId, correlationId, retryCount }); + + // Upload the file first + Logger.debug(who + 'Uploading file', { fileName, fileSize: fileBuffer.length, correlationId }); + const uploadResult = await fileService.uploadFile( + new Uint8Array(fileBuffer), + fileName, + correlationId, + retryCount, + ); + + Logger.debug(who + 'File uploaded successfully', { fileStorageId: uploadResult.fileStorageId, fileName, correlationId }); + + originalFileStorageId = uploadResult.fileStorageId; + + // Protect the uploaded file with HotFolder + Logger.debug(who + 'Protecting file with hot folder', { fileStorageId: uploadResult.fileStorageId, hotfolderId, fileName, correlationId }); + const protectResult = await fileService.protectWithHotFolder( + { + hotfolderId, + fileStorageId: uploadResult.fileStorageId, + }, + correlationId, + retryCount, + ); + + Logger.debug(who + 'File protected successfully', { + originalFileStorageId: uploadResult.fileStorageId, + protectedFileStorageId: protectResult.fileStorageId, + secloreFileId: protectResult.secloreFileId, + hotfolderId, + fileName, + correlationId + }); + + // Download the protected file + Logger.debug(who + 'Downloading protected file', { fileStorageId: protectResult.fileStorageId, fileName, correlationId }); + const protectedFileData = await fileService.downloadFile( + protectResult.fileStorageId, + correlationId, + retryCount, + ); + + Logger.debug(who + 'Protected file downloaded successfully', { + fileStorageId: protectResult.fileStorageId, + fileSize: protectedFileData.length, + fileName: protectedFileName, + correlationId + }); + + const result = { + protectedFileData, + originalFileStorageId: uploadResult.fileStorageId, + protectedFileStorageId: protectResult.fileStorageId, + secloreFileId: protectResult.secloreFileId, + fileName: protectedFileName, + fileSize: protectedFileData.length, + }; + + Logger.debug(who + 'Protect file with hot folder operation completed successfully', { + fileName: protectedFileName, + originalFileStorageId: result.originalFileStorageId, + protectedFileStorageId: result.protectedFileStorageId, + secloreFileId: result.secloreFileId, + fileSize: result.fileSize, + hotfolderId, + correlationId + }); + + return result; + } catch (error) { + Logger.error(who + 'Protect file with hot folder operation failed', { error, fileName, hotfolderId, correlationId }); + throw error; + } finally { + if (originalFileStorageId !== '') { + await deleteFile(fileService, originalFileStorageId, correlationId, retryCount); + } + } +} + export async function protectWithHotFolder(this: IExecuteFunctions): Promise { + const who = "protectWithHotFolder::protectWithHotFolder:: "; const items = this.getInputData(); const returnData: INodeExecutionData[] = []; // Initialize logger with the current execution context Logger.init(this.logger); - Logger.info('Seclore Protect with HotFolder operation started', { itemCount: items.length }); + Logger.debug(who + 'Seclore Protect with HotFolder operation started', { itemCount: items.length }); // Get credentials + Logger.debug(who + 'Getting credentials', {}); const credentials = await this.getCredentials('secloreProtectApi'); const baseUrl = credentials.baseUrl as string; const tenantId = credentials.tenantId as string; const tenantSecret = credentials.tenantSecret as string; // Initialize the file service + Logger.debug(who + 'Initializing file service', { baseUrl, tenantId }); const fileService = new SecloreDRMFileService(this, baseUrl, tenantId, tenantSecret); for (let i = 0; i < items.length; i++) { - Logger.debug('Processing item', { itemIndex: i, itemData: items[i] }); + Logger.debug(who + 'Processing item', { itemIndex: i }); try { // Get parameters for this item + Logger.debug(who + 'Getting node parameters', { itemIndex: i }); const hotfolderId = this.getNodeParameter('hotfolderId', i) as string; const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; - const correlationId = this.getNodeParameter('correlationId', i) as string; + const correlationId = crypto.randomUUID().toString(); const retryCount = this.getNodeParameter('retryCount', i) as number; // Validate required parameters @@ -42,92 +190,95 @@ export async function protectWithHotFolder(this: IExecuteFunctions): Promise item.json.success).length }); diff --git a/nodes/SecloreProtect/operations/unprotect.ts b/nodes/SecloreProtect/operations/unprotect.ts index 9c9d5b5..a304028 100644 --- a/nodes/SecloreProtect/operations/unprotect.ts +++ b/nodes/SecloreProtect/operations/unprotect.ts @@ -5,7 +5,7 @@ import { NodeOutput, LoggerProxy as Logger, } from 'n8n-workflow'; - +import crypto from 'node:crypto'; import { SecloreDRMFileService } from '../Services/SecloreDRMFileService'; /** @@ -53,7 +53,6 @@ async function deleteFile( * @returns Promise containing the unprotected file data and metadata */ async function unprotectFile( - context: IExecuteFunctions, fileService: SecloreDRMFileService, fileBuffer: Buffer, fileName: string, @@ -182,7 +181,7 @@ export async function unprotect(this: IExecuteFunctions): Promise { // Get parameters for this item Logger.debug(who + 'Getting node parameters', { itemIndex: i }); const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; - const correlationId = this.getNodeParameter('correlationId', i) as string; + const correlationId = crypto.randomUUID().toString(); const retryCount = this.getNodeParameter('retryCount', i) as number; Logger.debug(who + 'Asserting binary data', { binaryPropertyName, itemIndex: i }); @@ -211,11 +210,10 @@ export async function unprotect(this: IExecuteFunctions): Promise { }); const result = await unprotectFile( - this, fileService, fileBuffer, binaryData.fileName || 'protected_file', - correlationId || undefined, + correlationId, retryCount, ); @@ -249,7 +247,7 @@ export async function unprotect(this: IExecuteFunctions): Promise { unprotectedFileStorageId: result.unprotectedFileStorageId, fileName: result.fileName, fileSize: result.fileSize, - correlationId: correlationId || null, + correlationId: correlationId, }, binary: { data: outputBinaryData, -- 2.40.1 From c8ce3b1f94d020d7283f6c3bba2a43c2190cd439 Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Mon, 27 Oct 2025 20:51:39 +0530 Subject: [PATCH 13/22] file already protected handled --- nodes/SecloreProtect/operations/protectWithHotFolder.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nodes/SecloreProtect/operations/protectWithHotFolder.ts b/nodes/SecloreProtect/operations/protectWithHotFolder.ts index 9644cf4..18aa04f 100644 --- a/nodes/SecloreProtect/operations/protectWithHotFolder.ts +++ b/nodes/SecloreProtect/operations/protectWithHotFolder.ts @@ -85,6 +85,11 @@ async function protectFileWithHotFolder( Logger.debug(who + 'File uploaded successfully', { fileStorageId: uploadResult.fileStorageId, fileName, correlationId }); + // check if the file is already protected + if (uploadResult.protected) { + throw new Error('File is already protected'); + } + originalFileStorageId = uploadResult.fileStorageId; // Protect the uploaded file with HotFolder -- 2.40.1 From bbee58f204164a530863614fbd3488f7669022a0 Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Tue, 28 Oct 2025 12:40:08 +0530 Subject: [PATCH 14/22] node and operations name simplified --- nodes/SecloreProtect/SecloreProtect.node.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nodes/SecloreProtect/SecloreProtect.node.ts b/nodes/SecloreProtect/SecloreProtect.node.ts index 57f9116..d676d74 100644 --- a/nodes/SecloreProtect/SecloreProtect.node.ts +++ b/nodes/SecloreProtect/SecloreProtect.node.ts @@ -8,7 +8,7 @@ import { unprotect } from './operations/unprotect'; export class SecloreProtect implements INodeType { description: INodeTypeDescription = { - displayName: 'Seclore Protect', + displayName: 'Seclore', name: 'secloreProtect', icon: 'file:../../icons/seclore.svg', usableAsTool: true, // TODO: make it false/ don't allow it to be used as a tool @@ -17,7 +17,7 @@ export class SecloreProtect implements INodeType { subtitle: '={{$parameter["resource"] + ": " + $parameter["operation"]}}', description: 'Protect files using Seclore DRM', defaults: { - name: 'Seclore Protect', + name: 'Seclore', }, inputs: ['main'], outputs: ['main'], @@ -57,13 +57,13 @@ export class SecloreProtect implements INodeType { name: 'Protect with Hot Folder', value: 'protectWithHotFolder', description: 'Protect a file using HotFolder ID configuration', - action: 'Protect file with hotfolder', + action: 'Protect with hotfolder', }, { name: 'Unprotect', value: 'unprotect', description: 'Unprotect a file using file ID', - action: 'Unprotect file', + action: 'Unprotect', }, ], default: 'protectWithHotFolder', -- 2.40.1 From 9f46e5e8ffd17e50cfe103b2c3b388b43b7c8349 Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Wed, 29 Oct 2025 10:35:14 +0530 Subject: [PATCH 15/22] new filename to be read from headers --- .../Interfaces/FileStorageInterfaces.ts | 10 ++ .../Services/Interfaces/LoginInterfaces.ts | 1 + .../Services/Interfaces/ProtectInterfaces.ts | 3 + .../Interfaces/UnprotectInterfaces.ts | 1 + .../Services/SecloreDRMApiService.ts | 110 +++++++++++++----- .../Services/SecloreDRMFileService.ts | 6 +- nodes/SecloreProtect/Services/Utils.ts | 60 ++++++++++ .../operations/protectWithHotFolder.ts | 18 +-- nodes/SecloreProtect/operations/unprotect.ts | 17 ++- 9 files changed, 182 insertions(+), 44 deletions(-) create mode 100644 nodes/SecloreProtect/Services/Utils.ts diff --git a/nodes/SecloreProtect/Services/Interfaces/FileStorageInterfaces.ts b/nodes/SecloreProtect/Services/Interfaces/FileStorageInterfaces.ts index de8e3a3..e82dee9 100644 --- a/nodes/SecloreProtect/Services/Interfaces/FileStorageInterfaces.ts +++ b/nodes/SecloreProtect/Services/Interfaces/FileStorageInterfaces.ts @@ -6,4 +6,14 @@ export interface IFileUploadResponse { fileSize: number; secloreFileId: string; protected: boolean; + headers?: { [key: string]: string }; +} + +export interface IFileDownloadResponse { + data: Uint8Array; + headers?: { [key: string]: string }; +} + +export interface IFileDeleteResponse { + headers?: { [key: string]: string }; } diff --git a/nodes/SecloreProtect/Services/Interfaces/LoginInterfaces.ts b/nodes/SecloreProtect/Services/Interfaces/LoginInterfaces.ts index 612ae24..ad54ca9 100644 --- a/nodes/SecloreProtect/Services/Interfaces/LoginInterfaces.ts +++ b/nodes/SecloreProtect/Services/Interfaces/LoginInterfaces.ts @@ -6,6 +6,7 @@ export interface ILoginRequest { export interface ILoginResponse { accessToken: string; refreshToken: string; + headers?: { [key: string]: string }; } export interface IRefreshTokenRequest { diff --git a/nodes/SecloreProtect/Services/Interfaces/ProtectInterfaces.ts b/nodes/SecloreProtect/Services/Interfaces/ProtectInterfaces.ts index 8090922..e9da0b3 100644 --- a/nodes/SecloreProtect/Services/Interfaces/ProtectInterfaces.ts +++ b/nodes/SecloreProtect/Services/Interfaces/ProtectInterfaces.ts @@ -14,6 +14,7 @@ export interface IProtectWithExternalRefIdRequest { export interface IProtectWithExternalRefIdResponse { fileStorageId: string; secloreFileId: string; + headers?: { [key: string]: string }; } export interface IProtectWithFileIdRequest { @@ -24,6 +25,7 @@ export interface IProtectWithFileIdRequest { export interface IProtectWithFileIdResponse { fileStorageId: string; secloreFileId: string; + headers?: { [key: string]: string }; } export interface IProtectWithHotFolderRequest { @@ -34,4 +36,5 @@ export interface IProtectWithHotFolderRequest { export interface IProtectWithHotFolderResponse { fileStorageId: string; secloreFileId: string; + headers?: { [key: string]: string }; } diff --git a/nodes/SecloreProtect/Services/Interfaces/UnprotectInterfaces.ts b/nodes/SecloreProtect/Services/Interfaces/UnprotectInterfaces.ts index cd9bedb..11a4b01 100644 --- a/nodes/SecloreProtect/Services/Interfaces/UnprotectInterfaces.ts +++ b/nodes/SecloreProtect/Services/Interfaces/UnprotectInterfaces.ts @@ -4,4 +4,5 @@ export interface IUnprotectRequest { export interface IUnprotectResponse { fileStorageId: string; + headers?: { [key: string]: string }; } diff --git a/nodes/SecloreProtect/Services/SecloreDRMApiService.ts b/nodes/SecloreProtect/Services/SecloreDRMApiService.ts index 75e0b92..e0cf464 100644 --- a/nodes/SecloreProtect/Services/SecloreDRMApiService.ts +++ b/nodes/SecloreProtect/Services/SecloreDRMApiService.ts @@ -1,6 +1,6 @@ import { IExecuteFunctions, IHttpRequestOptions, NodeApiError, LoggerProxy as Logger } from 'n8n-workflow'; import { IErrorResponse } from './Interfaces/ErrorInterfaces'; -import { IFileUploadResponse } from './Interfaces/FileStorageInterfaces'; +import { IFileUploadResponse, IFileDownloadResponse, IFileDeleteResponse } from './Interfaces/FileStorageInterfaces'; import { ILoginRequest, ILoginResponse, IRefreshTokenRequest } from './Interfaces/LoginInterfaces'; import { IProtectWithExternalRefIdRequest, @@ -95,9 +95,15 @@ export class SecloreDRMApiService { }; Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, correlationId }); - const response = await this.context.helpers.httpRequest(options); + const response = await this.context.helpers.httpRequest({ ...options, returnFullResponse: true }); Logger.debug(who + 'Login successful', { tenantId, correlationId }); - return response as ILoginResponse; + + const loginResponse: ILoginResponse = { + ...(response.body as ILoginResponse), + headers: response.headers as { [key: string]: string } + }; + + return loginResponse; } catch (error: unknown) { Logger.error(who + 'Login failed', { error, tenantId, correlationId }); this.handleHttpError(error as NodeApiError); @@ -140,9 +146,15 @@ export class SecloreDRMApiService { }; Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, correlationId }); - const response = await this.context.helpers.httpRequest(options); + const response = await this.context.helpers.httpRequest({ ...options, returnFullResponse: true }); Logger.debug(who + 'Token refresh successful', { correlationId }); - return response as ILoginResponse; + + const refreshResponse: ILoginResponse = { + ...(response.body as ILoginResponse), + headers: response.headers as { [key: string]: string } + }; + + return refreshResponse; } catch (error: unknown) { Logger.error(who + 'Token refresh failed', { error, correlationId }); this.handleHttpError(error as NodeApiError, { 401: 'Unauthorized' }); @@ -190,13 +202,19 @@ export class SecloreDRMApiService { }; Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, correlationId }); - const response = await this.context.helpers.httpRequest(options); + const response = await this.context.helpers.httpRequest({ ...options, returnFullResponse: true }); Logger.debug(who + 'Protection with external ref ID successful', { fileStorageId: protectRequest.fileStorageId, - secloreFileId: (response as IProtectWithExternalRefIdResponse).secloreFileId, + secloreFileId: (response.body as IProtectWithExternalRefIdResponse).secloreFileId, correlationId }); - return response as IProtectWithExternalRefIdResponse; + + const protectResponse: IProtectWithExternalRefIdResponse = { + ...(response.body as IProtectWithExternalRefIdResponse), + headers: response.headers as { [key: string]: string } + }; + + return protectResponse; } catch (error: unknown) { Logger.error(who + 'Protection with external ref ID failed', { error, @@ -248,13 +266,19 @@ export class SecloreDRMApiService { }; Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, correlationId }); - const response = await this.context.helpers.httpRequest(options); + const response = await this.context.helpers.httpRequest({ ...options, returnFullResponse: true }); Logger.debug(who + 'Protection with file ID successful', { existingProtectedFileId: protectRequest.existingProtectedFileId, - secloreFileId: (response as IProtectWithFileIdResponse).secloreFileId, + secloreFileId: (response.body as IProtectWithFileIdResponse).secloreFileId, correlationId }); - return response as IProtectWithFileIdResponse; + + const protectResponse: IProtectWithFileIdResponse = { + ...(response.body as IProtectWithFileIdResponse), + headers: response.headers as { [key: string]: string } + }; + + return protectResponse; } catch (error: unknown) { Logger.error(who + 'Protection with file ID failed', { error, @@ -306,13 +330,19 @@ export class SecloreDRMApiService { }; Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, correlationId }); - const response = await this.context.helpers.httpRequest(options); + const response = await this.context.helpers.httpRequest({ ...options, returnFullResponse: true }); Logger.debug(who + 'Protection with hot folder successful', { hotfolderId: protectRequest.hotfolderId, - secloreFileId: (response as IProtectWithHotFolderResponse).secloreFileId, + secloreFileId: (response.body as IProtectWithHotFolderResponse).secloreFileId, correlationId }); - return response as IProtectWithHotFolderResponse; + + const protectResponse: IProtectWithHotFolderResponse = { + ...(response.body as IProtectWithHotFolderResponse), + headers: response.headers as { [key: string]: string } + }; + + return protectResponse; } catch (error: unknown) { Logger.error(who + 'Protection with hot folder failed', { error, @@ -364,13 +394,19 @@ export class SecloreDRMApiService { }; Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, correlationId }); - const response = await this.context.helpers.httpRequest(options); + const response = await this.context.helpers.httpRequest({ ...options, returnFullResponse: true }); Logger.debug(who + 'Unprotection successful', { originalFileStorageId: unprotectRequest.fileStorageId, - unprotectedFileStorageId: (response as IUnprotectResponse).fileStorageId, + unprotectedFileStorageId: (response.body as IUnprotectResponse).fileStorageId, correlationId }); - return response as IUnprotectResponse; + + const unprotectResponse: IUnprotectResponse = { + ...(response.body as IUnprotectResponse), + headers: response.headers as { [key: string]: string } + }; + + return unprotectResponse; } catch (error: unknown) { Logger.error(who + 'Unprotection failed', { error, @@ -427,13 +463,19 @@ export class SecloreDRMApiService { }; Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, fileName, correlationId }); - const response = await this.context.helpers.httpRequest(options); + const response = await this.context.helpers.httpRequest({ ...options, returnFullResponse: true }); Logger.debug(who + 'File upload successful', { fileName, - fileStorageId: (response as IFileUploadResponse).fileStorageId, + fileStorageId: (response.body as IFileUploadResponse).fileStorageId, correlationId }); - return response as IFileUploadResponse; + + const uploadResponse: IFileUploadResponse = { + ...(response.body as IFileUploadResponse), + headers: response.headers as { [key: string]: string } + }; + + return uploadResponse; } catch (error: unknown) { Logger.error(who + 'File upload failed', { error, @@ -452,14 +494,14 @@ export class SecloreDRMApiService { * @param fileStorageId - Storage ID of the file to be retrieved * @param accessToken - JWT access token for authorization * @param correlationId - Optional request ID for logging purpose - * @returns Promise - The downloaded file data + * @returns Promise - The downloaded file data with headers * @throws Error on authentication failure or server error */ async downloadFile( fileStorageId: string, accessToken: string, correlationId?: string, - ): Promise { + ): Promise { const who = "SecloreDRMApiService::downloadFile:: "; try { Logger.debug(who + 'Downloading file', { @@ -484,14 +526,20 @@ export class SecloreDRMApiService { }; Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, fileStorageId, correlationId }); - const response = await this.context.helpers.httpRequest(options); - const fileData = new Uint8Array(response as ArrayBuffer); + const response = await this.context.helpers.httpRequest({ ...options, returnFullResponse: true }); + const fileData = new Uint8Array(response.body as ArrayBuffer); Logger.debug(who + 'File download successful', { fileStorageId, fileSize: fileData.length, correlationId }); - return fileData; + + const downloadResponse: IFileDownloadResponse = { + data: fileData, + headers: response.headers as { [key: string]: string } + }; + + return downloadResponse; } catch (error: unknown) { Logger.error(who + 'File download failed', { error, @@ -508,14 +556,14 @@ export class SecloreDRMApiService { * @param fileStorageId - Storage ID of the file to be deleted * @param accessToken - JWT access token for authorization * @param correlationId - Optional request ID for logging purpose - * @returns Promise - No response body on successful deletion + * @returns Promise - Response headers on successful deletion * @throws Error on authentication failure or server error */ async deleteFile( fileStorageId: string, accessToken: string, correlationId?: string, - ): Promise { + ): Promise { const who = "SecloreDRMApiService::deleteFile:: "; try { Logger.debug(who + 'Deleting file', { @@ -539,11 +587,17 @@ export class SecloreDRMApiService { }; Logger.debug(who + 'Making HTTP request', { url: options.url, method: options.method, fileStorageId, correlationId }); - await this.context.helpers.httpRequest(options); + const response = await this.context.helpers.httpRequest({ ...options, returnFullResponse: true }); Logger.debug(who + 'File deletion successful', { fileStorageId, correlationId }); + + const deleteResponse: IFileDeleteResponse = { + headers: response.headers as { [key: string]: string } + }; + + return deleteResponse; } catch (error: unknown) { Logger.error(who + 'File deletion failed', { error, diff --git a/nodes/SecloreProtect/Services/SecloreDRMFileService.ts b/nodes/SecloreProtect/Services/SecloreDRMFileService.ts index 92f0d5d..f5b62dc 100644 --- a/nodes/SecloreProtect/Services/SecloreDRMFileService.ts +++ b/nodes/SecloreProtect/Services/SecloreDRMFileService.ts @@ -1,5 +1,5 @@ import { IExecuteFunctions, LoggerProxy as Logger } from 'n8n-workflow'; -import { IFileUploadResponse } from './Interfaces/FileStorageInterfaces'; +import { IFileDownloadResponse, IFileUploadResponse } from './Interfaces/FileStorageInterfaces'; import { IProtectWithExternalRefIdRequest, IProtectWithExternalRefIdResponse, @@ -332,7 +332,7 @@ export class SecloreDRMFileService { fileStorageId: string, correlationId?: string, retryCount?: number, - ): Promise { + ): Promise { const who = "SecloreDRMFileService::downloadFile:: "; try { Logger.debug(who + 'Downloading file', { fileStorageId, correlationId }); @@ -341,7 +341,7 @@ export class SecloreDRMFileService { retryCount, correlationId, ); - Logger.info(who + 'File downloaded successfully', { fileStorageId, fileSize: result.length, correlationId }); + Logger.info(who + 'File downloaded successfully', { fileStorageId, fileSize: result.data.length, correlationId }); return result; } catch (error) { Logger.error(who + 'Download file failed', { error, fileStorageId, correlationId }); diff --git a/nodes/SecloreProtect/Services/Utils.ts b/nodes/SecloreProtect/Services/Utils.ts new file mode 100644 index 0000000..c11dd4a --- /dev/null +++ b/nodes/SecloreProtect/Services/Utils.ts @@ -0,0 +1,60 @@ +import { LoggerProxy as Logger } from 'n8n-workflow'; + +/** + * Extracts filename from Content-Disposition header + * @param headers - Response headers object + * @returns The extracted filename or null if not found + */ +export function getFileNameFromHeaders(headers?: { [key: string]: string }): string | null { + const who = "Utils::getFileNameFromHeaders:: "; + + if (!headers) { + Logger.debug(who + 'No headers provided'); + return null; + } + + // Look for content-disposition header (case-insensitive) + const contentDisposition = Object.keys(headers).find(key => + key.toLowerCase() === 'content-disposition' + ); + + if (!contentDisposition || !headers[contentDisposition]) { + Logger.debug(who + 'Content-Disposition header not found'); + return null; + } + + const headerValue = headers[contentDisposition]; + Logger.debug(who + 'Found Content-Disposition header', { headerValue }); + + // Handle different filename formats in Content-Disposition header + // Format 1: filename*=UTF-8''encoded-filename + const utf8Match = headerValue.match(/filename\*=UTF-8''([^;]+)/i); + if (utf8Match) { + try { + const decodedFilename = decodeURIComponent(utf8Match[1]); + Logger.debug(who + 'Extracted filename from UTF-8 format', { filename: decodedFilename }); + return decodedFilename; + } catch (error) { + Logger.error(who + 'Failed to decode UTF-8 filename', { error, encodedFilename: utf8Match[1] }); + } + } + + // Format 2: filename="quoted-filename" + const quotedMatch = headerValue.match(/filename="([^"]+)"/i); + if (quotedMatch) { + Logger.debug(who + 'Extracted filename from quoted format', { filename: quotedMatch[1] }); + return quotedMatch[1]; + } + + // Format 3: filename=unquoted-filename + const unquotedMatch = headerValue.match(/filename=([^;]+)/i); + if (unquotedMatch) { + const filename = unquotedMatch[1].trim(); + Logger.debug(who + 'Extracted filename from unquoted format', { filename }); + return filename; + } + + Logger.debug(who + 'Could not extract filename from Content-Disposition header', { headerValue }); + return null; +} + diff --git a/nodes/SecloreProtect/operations/protectWithHotFolder.ts b/nodes/SecloreProtect/operations/protectWithHotFolder.ts index 18aa04f..ceb7b92 100644 --- a/nodes/SecloreProtect/operations/protectWithHotFolder.ts +++ b/nodes/SecloreProtect/operations/protectWithHotFolder.ts @@ -7,6 +7,7 @@ import { } from 'n8n-workflow'; import crypto from 'node:crypto'; import { SecloreDRMFileService } from '../Services/SecloreDRMFileService'; +import { getFileNameFromHeaders } from '../Services/Utils'; /** * Deletes a file from storage with error handling (does not throw errors) @@ -70,7 +71,6 @@ async function protectFileWithHotFolder( }> { const who = "protectWithHotFolder::protectFileWithHotFolder:: "; var originalFileStorageId: string = ''; - const protectedFileName = `${fileName}.html`; try { Logger.debug(who + 'Starting protect file with hot folder operation', { fileName, fileSize: fileBuffer.length, hotfolderId, correlationId, retryCount }); @@ -120,24 +120,28 @@ async function protectFileWithHotFolder( retryCount, ); + // Try to get the actual filename from response headers, fallback to constructed name + const actualFileName = getFileNameFromHeaders(protectedFileData.headers) || fileName; + Logger.debug(who + 'Protected file downloaded successfully', { fileStorageId: protectResult.fileStorageId, - fileSize: protectedFileData.length, - fileName: protectedFileName, + fileSize: protectedFileData.data.length, + originalFileName: fileName, + actualFileName, correlationId }); const result = { - protectedFileData, + protectedFileData: protectedFileData.data, originalFileStorageId: uploadResult.fileStorageId, protectedFileStorageId: protectResult.fileStorageId, secloreFileId: protectResult.secloreFileId, - fileName: protectedFileName, - fileSize: protectedFileData.length, + fileName: actualFileName, + fileSize: protectedFileData.data.length, }; Logger.debug(who + 'Protect file with hot folder operation completed successfully', { - fileName: protectedFileName, + fileName: result.fileName, originalFileStorageId: result.originalFileStorageId, protectedFileStorageId: result.protectedFileStorageId, secloreFileId: result.secloreFileId, diff --git a/nodes/SecloreProtect/operations/unprotect.ts b/nodes/SecloreProtect/operations/unprotect.ts index a304028..8e5ecdc 100644 --- a/nodes/SecloreProtect/operations/unprotect.ts +++ b/nodes/SecloreProtect/operations/unprotect.ts @@ -7,6 +7,7 @@ import { } from 'n8n-workflow'; import crypto from 'node:crypto'; import { SecloreDRMFileService } from '../Services/SecloreDRMFileService'; +import { getFileNameFromHeaders } from '../Services/Utils'; /** * Deletes a file from storage with error handling (does not throw errors) @@ -120,19 +121,23 @@ async function unprotectFile( retryCount, ); + // Try to get the actual filename from response headers, fallback to original filename + const actualFileName = getFileNameFromHeaders(unprotectedFileData.headers) || fileName; + Logger.debug(who + 'Unprotected file downloaded successfully', { fileStorageId: unprotectResult.fileStorageId, - fileSize: unprotectedFileData.length, - fileName, + fileSize: unprotectedFileData.data.length, + originalFileName: fileName, + actualFileName: actualFileName, correlationId }); const result = { - unprotectedFileData, + unprotectedFileData: unprotectedFileData.data, originalFileStorageId: uploadResult.fileStorageId, unprotectedFileStorageId: unprotectResult.fileStorageId, - fileName, - fileSize: unprotectedFileData.length, + fileName: actualFileName, + fileSize: unprotectedFileData.data.length, }; Logger.debug(who + 'Unprotect file operation completed successfully', { @@ -235,7 +240,7 @@ export async function unprotect(this: IExecuteFunctions): Promise { }); const outputBinaryData = await this.helpers.prepareBinaryData( Buffer.from(result.unprotectedFileData), - binaryData.fileName || 'unprotected_file', + result.fileName, binaryData.mimeType, ); -- 2.40.1 From 645ea3889f158a5b90f2acb832bc50fd66253445 Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Tue, 4 Nov 2025 11:12:48 +0530 Subject: [PATCH 16/22] readme updated --- credentials/SecloreProtectApi.credentials.ts | 2 +- nodes/SecloreProtect/operations/protectWithHotFolder.ts | 2 +- nodes/SecloreProtect/operations/unprotect.ts | 2 +- package.json | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/credentials/SecloreProtectApi.credentials.ts b/credentials/SecloreProtectApi.credentials.ts index cbf91fd..d096c36 100644 --- a/credentials/SecloreProtectApi.credentials.ts +++ b/credentials/SecloreProtectApi.credentials.ts @@ -2,7 +2,7 @@ import { ICredentialTestRequest, ICredentialType, INodeProperties, Icon } from ' export class SecloreProtectApi implements ICredentialType { name = 'secloreProtectApi'; - displayName = 'Seclore Protect API'; + displayName = 'Seclore API'; documentationUrl = 'https://docs.seclore.com/'; icon: Icon = 'file:../icons/seclore.svg'; properties: INodeProperties[] = [ diff --git a/nodes/SecloreProtect/operations/protectWithHotFolder.ts b/nodes/SecloreProtect/operations/protectWithHotFolder.ts index ceb7b92..c4dc3f5 100644 --- a/nodes/SecloreProtect/operations/protectWithHotFolder.ts +++ b/nodes/SecloreProtect/operations/protectWithHotFolder.ts @@ -70,7 +70,7 @@ async function protectFileWithHotFolder( fileSize: number; }> { const who = "protectWithHotFolder::protectFileWithHotFolder:: "; - var originalFileStorageId: string = ''; + let originalFileStorageId: string = ''; try { Logger.debug(who + 'Starting protect file with hot folder operation', { fileName, fileSize: fileBuffer.length, hotfolderId, correlationId, retryCount }); diff --git a/nodes/SecloreProtect/operations/unprotect.ts b/nodes/SecloreProtect/operations/unprotect.ts index 8e5ecdc..e07182f 100644 --- a/nodes/SecloreProtect/operations/unprotect.ts +++ b/nodes/SecloreProtect/operations/unprotect.ts @@ -67,7 +67,7 @@ async function unprotectFile( fileSize: number; }> { const who = "unprotect::unprotectFile:: "; - var originalFileStorageId: string = ''; + let originalFileStorageId: string = ''; try { Logger.debug(who + 'Starting unprotect file operation', { fileName, fileSize: fileBuffer.length, correlationId, retryCount }); diff --git a/package.json b/package.json index 7f5d8eb..56ee87c 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "n8n-nodes-secloreprotect", + "name": "n8n-nodes-seclore", "version": "0.1.0", "description": "n8n community node for Seclore Protect - secure file protection using DRM technology", "license": "MIT", @@ -13,7 +13,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/seclore/n8n-nodes-secloreprotect.git" + "url": "https://repo.seclore.com/public/n8n-nodes-seclore.git" }, "scripts": { "build": "n8n-node build", -- 2.40.1 From 2bdafdf7ce9e2f45fe29ba84229fc87f0453aa00 Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Wed, 5 Nov 2025 11:09:26 +0530 Subject: [PATCH 17/22] Updated SecloreProtect API credentials and node operations to reflect DRM terminology. --- credentials/SecloreProtectApi.credentials.ts | 4 +- nodes/SecloreProtect/SecloreProtect.node.ts | 63 +++++++++++++------- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/credentials/SecloreProtectApi.credentials.ts b/credentials/SecloreProtectApi.credentials.ts index d096c36..fcce8cb 100644 --- a/credentials/SecloreProtectApi.credentials.ts +++ b/credentials/SecloreProtectApi.credentials.ts @@ -10,9 +10,9 @@ export class SecloreProtectApi implements ICredentialType { displayName: 'Base URL', name: 'baseUrl', type: 'string', - default: 'https://api.seclore.com', + default: '', placeholder: 'https://api.seclore.com', - description: 'The base URL of your Seclore API instance', + description: 'The base URL of your Seclore DRM Server', required: true, }, { diff --git a/nodes/SecloreProtect/SecloreProtect.node.ts b/nodes/SecloreProtect/SecloreProtect.node.ts index d676d74..79d3f0c 100644 --- a/nodes/SecloreProtect/SecloreProtect.node.ts +++ b/nodes/SecloreProtect/SecloreProtect.node.ts @@ -35,12 +35,17 @@ export class SecloreProtect implements INodeType { noDataExpression: true, options: [ { - name: 'Protection', - value: 'protection', - description: 'File protection operations', + name: 'DRM Protection', + value: 'drmProtection', + description: 'DRM file protection operations', + }, + { + name: 'DRM Unprotection', + value: 'drmUnprotection', + description: 'DRM file unprotection operations', }, ], - default: 'protection', + default: 'drmProtection', }, { displayName: 'Operation', @@ -49,36 +54,50 @@ export class SecloreProtect implements INodeType { noDataExpression: true, displayOptions: { show: { - resource: ['protection'], + resource: ['drmProtection'], }, }, options: [ { - name: 'Protect with Hot Folder', + name: 'Protect using Policy', value: 'protectWithHotFolder', description: 'Protect a file using HotFolder ID configuration', - action: 'Protect with hotfolder', - }, - { - name: 'Unprotect', - value: 'unprotect', - description: 'Unprotect a file using file ID', - action: 'Unprotect', + action: 'Protect file using policy', }, ], default: 'protectWithHotFolder', }, + { + displayName: 'Operation', + name: 'operation', + type: 'options', + noDataExpression: true, + displayOptions: { + show: { + resource: ['drmUnprotection'], + }, + }, + options: [ + { + name: 'Unprotect', + value: 'unprotect', + description: 'Unprotect a protected file', + action: 'Unprotect file', + }, + ], + default: 'unprotect', + }, { displayName: 'HotFolder ID', name: 'hotfolderId', type: 'string', required: true, - default: '1000201', - placeholder: '1000201', + default: '', + placeholder: '', description: 'The ID of the HotFolder configuration to use for protection', displayOptions: { show: { - resource: ['protection'], + resource: ['drmProtection'], operation: ['protectWithHotFolder'], }, }, @@ -92,7 +111,7 @@ export class SecloreProtect implements INodeType { description: 'Name of the binary property that contains the file to protect', displayOptions: { show: { - resource: ['protection'], + resource: ['drmProtection'], operation: ['protectWithHotFolder'], }, }, @@ -105,7 +124,7 @@ export class SecloreProtect implements INodeType { description: 'Number of retry attempts for failed requests', displayOptions: { show: { - resource: ['protection'], + resource: ['drmProtection'], operation: ['protectWithHotFolder'], }, }, @@ -120,7 +139,7 @@ export class SecloreProtect implements INodeType { description: 'Name of the binary property that contains the protected file to unprotect', displayOptions: { show: { - resource: ['protection'], + resource: ['drmUnprotection'], operation: ['unprotect'], }, }, @@ -133,7 +152,7 @@ export class SecloreProtect implements INodeType { description: 'Number of retry attempts for failed requests', displayOptions: { show: { - resource: ['protection'], + resource: ['drmUnprotection'], operation: ['unprotect'], }, }, @@ -142,8 +161,10 @@ export class SecloreProtect implements INodeType { }; customOperations = { - protection: { + drmProtection: { protectWithHotFolder, + }, + drmUnprotection: { unprotect, }, }; -- 2.40.1 From 7ecf38f9321fc69e4012c079fb51e14bc3b475ae Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Wed, 5 Nov 2025 11:19:27 +0530 Subject: [PATCH 18/22] removed unnecessary files --- .devcontainer/Dockerfile | 43 - .devcontainer/README.md | 158 - .devcontainer/devcontainer.json | 91 - .devcontainer/docker-compose.yml | 37 - .devcontainer/post-create.sh | 161 - .github/workflows/ci.yml | 28 - .vscode/extensions.json | 7 - .vscode/launch.json | 12 - README_TEMPLATE.md | 48 - package-lock.json | 7226 ------------------------------ 10 files changed, 7811 deletions(-) delete mode 100644 .devcontainer/Dockerfile delete mode 100644 .devcontainer/README.md delete mode 100644 .devcontainer/devcontainer.json delete mode 100644 .devcontainer/docker-compose.yml delete mode 100644 .devcontainer/post-create.sh delete mode 100644 .github/workflows/ci.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 README_TEMPLATE.md delete mode 100644 package-lock.json diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index 25f7898..0000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,43 +0,0 @@ -# Use the official Node.js development container as base -FROM mcr.microsoft.com/devcontainers/javascript-node:1-20-bullseye - -# Set the working directory -WORKDIR /workspaces - -# Install additional system dependencies that might be needed for n8n -RUN apt-get update && apt-get install -y \ - python3 \ - python3-pip \ - build-essential \ - curl \ - git \ - && rm -rf /var/lib/apt/lists/* - -# Switch to node user for security -USER node - -# Set up npm configuration for the node user -RUN npm config set prefix '/home/node/.npm-global' -ENV PATH=/home/node/.npm-global/bin:$PATH - -# Create necessary directories -RUN mkdir -p /home/node/.n8n \ - && mkdir -p /home/node/.npm-global - -# Pre-install some global packages to speed up container startup -RUN npm install -g npm@latest typescript ts-node nodemon - -# Set the default shell to bash for better development experience -SHELL ["/bin/bash", "-c"] - -# Expose the default n8n port -EXPOSE 5678 - -# Set environment variables for n8n -ENV N8N_HOST=0.0.0.0 -ENV N8N_PORT=5678 -ENV N8N_PROTOCOL=http -ENV NODE_ENV=development - -# Set the default command -CMD ["bash"] diff --git a/.devcontainer/README.md b/.devcontainer/README.md deleted file mode 100644 index 9761db6..0000000 --- a/.devcontainer/README.md +++ /dev/null @@ -1,158 +0,0 @@ -# Seclore n8n Development Container - -This devcontainer provides a complete development environment for the Seclore n8n custom node project. - -## 🚀 Quick Start - -1. **Open in Container**: - - Open this project in VS Code - - Click "Reopen in Container" when prompted - - Or use Command Palette: `Dev Containers: Reopen in Container` - -2. **Wait for Setup**: - - The container will automatically install dependencies - - This may take a few minutes on first run - -3. **Start Development**: - ```bash - start_dev # Build and start n8n with custom nodes - ``` - -4. **Access n8n**: - - Open http://localhost:5678 in your browser - - Your custom Seclore Protect node will be available - -## 📦 What's Included - -### Software -- **Node.js 20.x** - Latest LTS version -- **npm** - Latest version -- **n8n** - Latest version (globally installed) -- **TypeScript** - For development -- **ts-node** - TypeScript execution -- **nodemon** - Auto-restart on changes - -### VS Code Extensions -- **TypeScript & JavaScript**: Enhanced language support -- **ESLint & Prettier**: Code formatting and linting -- **Node.js IntelliSense**: Smart completions for Node.js -- **npm IntelliSense**: Package import suggestions -- **Git Tools**: GitLens and Git Graph -- **REST Client**: API testing tools -- **Docker**: Container management - -### Development Tools -- **build_and_test**: Build project and run linter -- **start_dev**: Build and start n8n with custom nodes -- **watch_build**: Auto-rebuild on file changes -- **~/start-n8n.sh**: Direct n8n startup script - -## 🔧 Development Workflow - -### 1. Make Changes -Edit your TypeScript files in: -- `nodes/SecloreProtect/` - Main node logic -- `Services/` - API service classes -- `credentials/` - Credential definitions - -### 2. Build & Test -```bash -build_and_test # Compile TypeScript and run linter -``` - -### 3. Start n8n -```bash -start_dev # Build and start n8n -# OR -~/start-n8n.sh # Start n8n directly (after manual build) -``` - -### 4. Auto-rebuild (Optional) -```bash -watch_build # Watch for changes and auto-rebuild -``` - -## 🌐 Port Forwarding - -The container automatically forwards these ports: -- **5678**: n8n web interface -- **3000**: Development server -- **8080**: Alternative port - -## 📁 Volume Mounts - -- **Project Files**: `/workspaces/Seclore n8n` (your source code) -- **n8n Data**: `~/.n8n` (n8n configuration and data) -- **Node Modules**: Cached for faster rebuilds - -## 🔐 Environment Variables - -The container sets up these environment variables: -```bash -N8N_HOST=0.0.0.0 -N8N_PORT=5678 -N8N_PROTOCOL=http -NODE_ENV=development -N8N_LOG_LEVEL=debug -N8N_CUSTOM_EXTENSIONS=/workspaces/Seclore n8n -``` - -## 🛠️ Customization - -### Adding Extensions -Edit `.devcontainer/devcontainer.json` and add extension IDs to the `extensions` array. - -### Changing Ports -Modify the `forwardPorts` array in `devcontainer.json`. - -### Additional Software -Add installation commands to `.devcontainer/post-create.sh`. - -## 🐛 Troubleshooting - -### Container Won't Start -- Check Docker is running -- Ensure you have enough disk space -- Try rebuilding: `Dev Containers: Rebuild Container` - -### n8n Won't Start -- Check if port 5678 is available -- Verify the build completed successfully -- Check logs for error messages - -### Build Errors -- Run `npm install` to ensure dependencies are installed -- Check TypeScript compilation errors -- Verify all import paths are correct - -### Custom Node Not Visible -- Ensure the build completed successfully -- Check that `N8N_CUSTOM_EXTENSIONS` points to the correct path -- Restart n8n after making changes - -## 📚 Useful Commands - -```bash -# Development -npm run build # Build the project -npm run lint # Run ESLint -npm run lint:fix # Fix ESLint issues - -# n8n -n8n start # Start n8n manually -n8n --help # n8n help - -# Container -cat ~/welcome.txt # Show welcome message -source ~/dev-scripts.sh # Reload development functions -``` - -## 🎯 Tips - -1. **Use the integrated terminal** in VS Code for the best experience -2. **Enable auto-save** in VS Code for faster development cycles -3. **Use the REST Client extension** to test your APIs -4. **Check the n8n logs** in the terminal for debugging -5. **Use `watch_build`** during active development for auto-rebuilds - -Happy coding! 🚀 diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index afebf6e..0000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "name": "Seclore n8n Development", - "image": "mcr.microsoft.com/devcontainers/javascript-node:1-20-bullseye", - - "features": { - "ghcr.io/devcontainers/features/git:1": {}, - "ghcr.io/devcontainers/features/github-cli:1": {} - }, - - "customizations": { - "vscode": { - "extensions": [ - // TypeScript and JavaScript - "ms-vscode.vscode-typescript-next", - "bradlc.vscode-tailwindcss", - "esbenp.prettier-vscode", - "dbaeumer.vscode-eslint", - - // Node.js specific - "ms-vscode.vscode-node-azure-pack", - "christian-kohler.npm-intellisense", - "eg2.vscode-npm-script", - "leizongmin.node-module-intellisense", - - // General development - "ms-vscode.vscode-json", - "redhat.vscode-yaml", - "ms-vscode.hexdump", - "ms-vscode.vscode-markdown", - - // Git and version control - "mhutchie.git-graph", - "eamodio.gitlens", - - // API and REST - "humao.rest-client", - "rangav.vscode-thunder-client", - - // Utilities - "formulahendry.auto-rename-tag", - "streetsidesoftware.code-spell-checker", - "ms-vscode.vscode-todo-highlight", - "gruntfuggly.todo-tree", - - // Docker (for n8n) - "ms-azuretools.vscode-docker" - ], - - "settings": { - "typescript.preferences.includePackageJsonAutoImports": "on", - "typescript.suggest.autoImports": true, - "typescript.updateImportsOnFileMove.enabled": "always", - "editor.formatOnSave": true, - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit", - "source.organizeImports": "explicit" - }, - "files.associations": { - "*.json": "jsonc" - }, - "npm.enableScriptExplorer": true, - "npm.scriptExplorerAction": "run" - } - } - }, - - "forwardPorts": [5678, 3000, 8080], - "portsAttributes": { - "5678": { - "label": "n8n", - "onAutoForward": "notify" - }, - "3000": { - "label": "Development Server", - "onAutoForward": "notify" - }, - "8080": { - "label": "Alternative Port", - "onAutoForward": "ignore" - } - }, - - "postCreateCommand": ".devcontainer/post-create.sh", - - "remoteUser": "node", - - "mounts": [ - "source=${localWorkspaceFolder}/.n8n,target=/home/node/.n8n,type=bind,consistency=cached" - ] -} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml deleted file mode 100644 index 7bf8325..0000000 --- a/.devcontainer/docker-compose.yml +++ /dev/null @@ -1,37 +0,0 @@ -version: '3.8' - -services: - app: - build: - context: . - dockerfile: Dockerfile - - volumes: - - ../..:/workspaces:cached - - node_modules:/workspaces/Seclore\ n8n/node_modules - - n8n_data:/home/node/.n8n - - ports: - - "5678:5678" # n8n - - "3000:3000" # Development server - - "8080:8080" # Alternative port - - environment: - - N8N_HOST=0.0.0.0 - - N8N_PORT=5678 - - N8N_PROTOCOL=http - - NODE_ENV=development - - N8N_LOG_LEVEL=debug - - # Keep container running - command: sleep infinity - - # Use node user for security - user: node - - # Set working directory - working_dir: /workspaces/Seclore n8n - -volumes: - node_modules: - n8n_data: diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh deleted file mode 100644 index c5f1de9..0000000 --- a/.devcontainer/post-create.sh +++ /dev/null @@ -1,161 +0,0 @@ -#!/bin/bash - -# Make script executable and set proper permissions -chmod +x /workspaces/*/devcontainer/post-create.sh - -echo "🚀 Setting up Seclore n8n Development Environment..." - -# Update npm to latest version -echo "📦 Updating npm..." -npm install -g npm@latest - -# Install n8n globally -echo "🔧 Installing n8n..." -npm install -g n8n - -# Install common development tools -echo "🛠️ Installing development tools..." -npm install -g typescript ts-node nodemon - -# Install project dependencies -echo "📋 Installing project dependencies..." -npm install - -# Create .n8n directory if it doesn't exist -mkdir -p ~/.n8n - -# Set up n8n environment variables -echo "⚙️ Setting up n8n configuration..." -cat > ~/.n8n/.env << EOF -# n8n Configuration -N8N_BASIC_AUTH_ACTIVE=false -N8N_HOST=0.0.0.0 -N8N_PORT=5678 -N8N_PROTOCOL=http - -# Development settings -NODE_ENV=development -N8N_LOG_LEVEL=debug - -# Custom nodes path -N8N_CUSTOM_EXTENSIONS=/workspaces/Seclore\ n8n -EOF - -# Create a startup script for n8n -echo "📝 Creating n8n startup script..." -cat > ~/start-n8n.sh << 'EOF' -#!/bin/bash -echo "🎯 Starting n8n with custom Seclore nodes..." -echo "📍 Custom nodes path: /workspaces/Seclore n8n" -echo "🌐 n8n will be available at: http://localhost:5678" -echo "" - -# Build the custom nodes first -cd "/workspaces/Seclore n8n" -npm run build - -# Start n8n with custom nodes -N8N_CUSTOM_EXTENSIONS="/workspaces/Seclore n8n" n8n start -EOF - -chmod +x ~/start-n8n.sh - -# Create development scripts -echo "📋 Creating development scripts..." -cat > ~/dev-scripts.sh << 'EOF' -#!/bin/bash - -# Function to build and test the custom node -build_and_test() { - echo "🔨 Building Seclore n8n nodes..." - cd "/workspaces/Seclore n8n" - npm run build - - if [ $? -eq 0 ]; then - echo "✅ Build successful!" - echo "🧪 Running linter..." - npm run lint - else - echo "❌ Build failed!" - return 1 - fi -} - -# Function to start n8n in development mode -start_dev() { - echo "🚀 Starting n8n in development mode..." - build_and_test && ~/start-n8n.sh -} - -# Function to watch for changes and rebuild -watch_build() { - echo "👀 Watching for changes..." - cd "/workspaces/Seclore n8n" - npm run build:watch -} - -# Export functions -export -f build_and_test -export -f start_dev -export -f watch_build - -echo "📚 Available commands:" -echo " build_and_test - Build and lint the project" -echo " start_dev - Build and start n8n with custom nodes" -echo " watch_build - Watch for changes and rebuild automatically" -echo " ~/start-n8n.sh - Start n8n directly (after manual build)" -EOF - -chmod +x ~/dev-scripts.sh - -# Add to bashrc for easy access -echo "source ~/dev-scripts.sh" >> ~/.bashrc - -# Create a welcome message -echo "📄 Creating welcome message..." -cat > ~/welcome.txt << 'EOF' -🎉 Seclore n8n Development Environment Ready! - -📁 Project Structure: - /workspaces/Seclore n8n/ - ├── nodes/SecloreProtect/ # Custom n8n node - ├── credentials/ # Credential types - └── Services/ # API services - -🚀 Quick Start: - 1. Run: start_dev # Build and start n8n - 2. Open: http://localhost:5678 # Access n8n interface - 3. Use: build_and_test # Build and test changes - -🔧 Development Commands: - - start_dev : Build project and start n8n - - build_and_test : Build project and run linter - - watch_build : Auto-rebuild on file changes - - ~/start-n8n.sh : Start n8n (manual build required) - -📦 Installed Tools: - - Node.js 20.x - - npm (latest) - - n8n (latest) - - TypeScript - - ts-node - - nodemon - -🔌 VS Code Extensions: - - TypeScript & JavaScript support - - ESLint & Prettier - - Node.js IntelliSense - - Git tools - - REST client for API testing - -Happy coding! 🎯 -EOF - -# Display welcome message -echo "" -echo "✅ Setup complete!" -echo "" -cat ~/welcome.txt -echo "" -echo "💡 Tip: Run 'cat ~/welcome.txt' anytime to see this guide again." -echo "" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 7cab9aa..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: CI - -on: - pull_request: - push: - branches: - - main - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: '22' - - - name: Install dependencies - run: 'npm ci' - - - name: Run lint - run: 'npm run lint' - - - name: Run build - run: 'npm run build' diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index 306a6af..0000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "recommendations": [ - "dbaeumer.vscode-eslint", - "EditorConfig.EditorConfig", - "esbenp.prettier-vscode", - ] -} diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index ed1a625..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Attach to running n8n", - "processId": "${command:PickProcess}", - "request": "attach", - "skipFiles": ["/**"], - "type": "node" - } - ] -} diff --git a/README_TEMPLATE.md b/README_TEMPLATE.md deleted file mode 100644 index a8d7860..0000000 --- a/README_TEMPLATE.md +++ /dev/null @@ -1,48 +0,0 @@ -# n8n-nodes-_node-name_ - -This is an n8n community node. It lets you use _app/service name_ in your n8n workflows. - -_App/service name_ is _one or two sentences describing the service this node integrates with_. - -[n8n](https://n8n.io/) is a [fair-code licensed](https://docs.n8n.io/reference/license/) workflow automation platform. - -[Installation](#installation) -[Operations](#operations) -[Credentials](#credentials) -[Compatibility](#compatibility) -[Usage](#usage) -[Resources](#resources) -[Version history](#version-history) - -## Installation - -Follow the [installation guide](https://docs.n8n.io/integrations/community-nodes/installation/) in the n8n community nodes documentation. - -## Operations - -_List the operations supported by your node._ - -## Credentials - -_If users need to authenticate with the app/service, provide details here. You should include prerequisites (such as signing up with the service), available authentication methods, and how to set them up._ - -## Compatibility - -_State the minimum n8n version, as well as which versions you test against. You can also include any known version incompatibility issues._ - -## Usage - -_This is an optional section. Use it to help users with any difficult or confusing aspects of the node._ - -_By the time users are looking for community nodes, they probably already know n8n basics. But if you expect new users, you can link to the [Try it out](https://docs.n8n.io/try-it-out/) documentation to help them get started._ - -## Resources - -* [n8n community nodes documentation](https://docs.n8n.io/integrations/#community-nodes) -* _Link to app/service documentation._ - -## Version history - -_This is another optional section. If your node has multiple versions, include a short description of available versions and what changed, as well as any compatibility impact._ - - diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index aeff92d..0000000 --- a/package-lock.json +++ /dev/null @@ -1,7226 +0,0 @@ -{ - "name": "n8n-nodes-secloreprotect", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "n8n-nodes-secloreprotect", - "version": "0.1.0", - "license": "MIT", - "devDependencies": { - "@n8n/node-cli": "*", - "eslint": "9.32.0", - "prettier": "3.6.2", - "release-it": "^19.0.4", - "typescript": "5.9.2" - }, - "peerDependencies": { - "n8n-workflow": "*" - } - }, - "node_modules/@clack/core": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.5.0.tgz", - "integrity": "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==", - "dev": true, - "license": "MIT", - "dependencies": { - "picocolors": "^1.0.0", - "sisteransi": "^1.0.5" - } - }, - "node_modules/@clack/prompts": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.11.0.tgz", - "integrity": "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@clack/core": "0.5.0", - "picocolors": "^1.0.0", - "sisteransi": "^1.0.5" - } - }, - "node_modules/@emnapi/core": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.5.0.tgz", - "integrity": "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.1.0", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.5.0.tgz", - "integrity": "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", - "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", - "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.6", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", - "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", - "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/js": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz", - "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", - "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.15.2", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.4.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true, - "license": "BSD-3-Clause", - "peer": true - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@inquirer/ansi": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.1.tgz", - "integrity": "sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@inquirer/checkbox": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.0.tgz", - "integrity": "sha512-5+Q3PKH35YsnoPTh75LucALdAxom6xh5D1oeY561x4cqBuH24ZFVyFREPe14xgnrtmGu3EEt1dIi60wRVSnGCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/ansi": "^1.0.1", - "@inquirer/core": "^10.3.0", - "@inquirer/figures": "^1.0.14", - "@inquirer/type": "^3.0.9", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/confirm": { - "version": "5.1.19", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.19.tgz", - "integrity": "sha512-wQNz9cfcxrtEnUyG5PndC8g3gZ7lGDBzmWiXZkX8ot3vfZ+/BLjR8EvyGX4YzQLeVqtAlY/YScZpW7CW8qMoDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/core": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.0.tgz", - "integrity": "sha512-Uv2aPPPSK5jeCplQmQ9xadnFx2Zhj9b5Dj7bU6ZeCdDNNY11nhYy4btcSdtDguHqCT2h5oNeQTcUNSGGLA7NTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/ansi": "^1.0.1", - "@inquirer/figures": "^1.0.14", - "@inquirer/type": "^3.0.9", - "cli-width": "^4.1.0", - "mute-stream": "^2.0.0", - "signal-exit": "^4.1.0", - "wrap-ansi": "^6.2.0", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/core/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@inquirer/core/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@inquirer/core/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@inquirer/editor": { - "version": "4.2.21", - "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.21.tgz", - "integrity": "sha512-MjtjOGjr0Kh4BciaFShYpZ1s9400idOdvQ5D7u7lE6VztPFoyLcVNE5dXBmEEIQq5zi4B9h2kU+q7AVBxJMAkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.0", - "@inquirer/external-editor": "^1.0.2", - "@inquirer/type": "^3.0.9" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/expand": { - "version": "4.0.21", - "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.21.tgz", - "integrity": "sha512-+mScLhIcbPFmuvU3tAGBed78XvYHSvCl6dBiYMlzCLhpr0bzGzd8tfivMMeqND6XZiaZ1tgusbUHJEfc6YzOdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/external-editor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.2.tgz", - "integrity": "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "chardet": "^2.1.0", - "iconv-lite": "^0.7.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/figures": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.14.tgz", - "integrity": "sha512-DbFgdt+9/OZYFM+19dbpXOSeAstPy884FPy1KjDu4anWwymZeOYhMY1mdFri172htv6mvc/uvIAAi7b7tvjJBQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@inquirer/input": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.2.5.tgz", - "integrity": "sha512-7GoWev7P6s7t0oJbenH0eQ0ThNdDJbEAEtVt9vsrYZ9FulIokvd823yLyhQlWHJPGce1wzP53ttfdCZmonMHyA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/number": { - "version": "3.0.21", - "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.21.tgz", - "integrity": "sha512-5QWs0KGaNMlhbdhOSCFfKsW+/dcAVC2g4wT/z2MCiZM47uLgatC5N20kpkDQf7dHx+XFct/MJvvNGy6aYJn4Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/password": { - "version": "4.0.21", - "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.21.tgz", - "integrity": "sha512-xxeW1V5SbNFNig2pLfetsDb0svWlKuhmr7MPJZMYuDnCTkpVBI+X/doudg4pznc1/U+yYmWFFOi4hNvGgUo7EA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/ansi": "^1.0.1", - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/prompts": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.9.0.tgz", - "integrity": "sha512-X7/+dG9SLpSzRkwgG5/xiIzW0oMrV3C0HOa7YHG1WnrLK+vCQHfte4k/T80059YBdei29RBC3s+pSMvPJDU9/A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/checkbox": "^4.3.0", - "@inquirer/confirm": "^5.1.19", - "@inquirer/editor": "^4.2.21", - "@inquirer/expand": "^4.0.21", - "@inquirer/input": "^4.2.5", - "@inquirer/number": "^3.0.21", - "@inquirer/password": "^4.0.21", - "@inquirer/rawlist": "^4.1.9", - "@inquirer/search": "^3.2.0", - "@inquirer/select": "^4.4.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/rawlist": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.9.tgz", - "integrity": "sha512-AWpxB7MuJrRiSfTKGJ7Y68imYt8P9N3Gaa7ySdkFj1iWjr6WfbGAhdZvw/UnhFXTHITJzxGUI9k8IX7akAEBCg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/search": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.0.tgz", - "integrity": "sha512-a5SzB/qrXafDX1Z4AZW3CsVoiNxcIYCzYP7r9RzrfMpaLpB+yWi5U8BWagZyLmwR0pKbbL5umnGRd0RzGVI8bQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.0", - "@inquirer/figures": "^1.0.14", - "@inquirer/type": "^3.0.9", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/select": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.0.tgz", - "integrity": "sha512-kaC3FHsJZvVyIjYBs5Ih8y8Bj4P/QItQWrZW22WJax7zTN+ZPXVGuOM55vzbdCP9zKUiBd9iEJVdesujfF+cAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/ansi": "^1.0.1", - "@inquirer/core": "^10.3.0", - "@inquirer/figures": "^1.0.14", - "@inquirer/type": "^3.0.9", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/type": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.9.tgz", - "integrity": "sha512-QPaNt/nmE2bLGQa9b7wwyRJoLZ7pN6rcyXvzU0YCmivmJyq1BVo94G98tStRWkoD1RgDX5C+dPlhhHzNdu/W/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/@n8n_io/riot-tmpl": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@n8n_io/riot-tmpl/-/riot-tmpl-4.0.1.tgz", - "integrity": "sha512-/zdRbEfTFjsm1NqnpPQHgZTkTdbp5v3VUxGeMA9098sps8jRCTraQkc3AQstJgHUm7ylBXJcIVhnVeLUMWAfwQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "eslint-config-riot": "^1.0.0" - } - }, - "node_modules/@n8n/errors": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@n8n/errors/-/errors-0.5.0.tgz", - "integrity": "sha512-0Vk1Eb3Uor+zeF/WVnuhFgJc51wEBTZNBlVQy3mvyr3sGmW86bP1jA7wmRsd0DZbswPwN0vNOl/TmkDTEopOtQ==", - "license": "SEE LICENSE IN LICENSE.md", - "peer": true, - "dependencies": { - "callsites": "3.1.0" - } - }, - "node_modules/@n8n/eslint-plugin-community-nodes": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@n8n/eslint-plugin-community-nodes/-/eslint-plugin-community-nodes-0.6.0.tgz", - "integrity": "sha512-VafBm+pHvOiO/DPZfdyYBHWS6ZEeu3jMwK3E1lxE7rXUbLlRoqW3YL4jnJ5R8JIChMVcZeoybGALt1lnuixyjA==", - "dev": true, - "license": "SEE LICENSE IN LICENSE.md", - "dependencies": { - "@typescript-eslint/utils": "^8.35.0", - "fastest-levenshtein": "1.0.16" - }, - "peerDependencies": { - "eslint": ">= 9" - } - }, - "node_modules/@n8n/node-cli": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@n8n/node-cli/-/node-cli-0.13.0.tgz", - "integrity": "sha512-4YRA1r3D2k+qA2psKNQHd+g077slvJpRunyRt3etgI5Kmbo445wQJSMF03+f4Els1EP3AO7eN7F6HSTz0AHtzA==", - "dev": true, - "license": "SEE LICENSE IN LICENSE.md", - "dependencies": { - "@clack/prompts": "^0.11.0", - "@n8n/eslint-plugin-community-nodes": "0.6.0", - "@oclif/core": "^4.5.2", - "change-case": "^5.4.4", - "eslint-import-resolver-typescript": "^4.4.3", - "eslint-plugin-import-x": "^4.15.2", - "eslint-plugin-n8n-nodes-base": "1.16.3", - "fast-glob": "3.2.12", - "handlebars": "4.7.8", - "picocolors": "1.0.1", - "prettier": "3.6.2", - "prompts": "^2.4.2", - "rimraf": "6.0.1", - "ts-morph": "^26.0.0", - "typescript-eslint": "^8.35.0" - }, - "bin": { - "n8n-node": "bin/n8n-node.mjs" - }, - "peerDependencies": { - "eslint": ">= 9" - } - }, - "node_modules/@n8n/tournament": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@n8n/tournament/-/tournament-1.0.6.tgz", - "integrity": "sha512-UGSxYXXVuOX0yL6HTLBStKYwLIa0+JmRKiSZSCMcM2s2Wax984KWT6XIA1TR/27i7yYpDk1MY14KsTPnuEp27A==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@n8n_io/riot-tmpl": "^4.0.1", - "ast-types": "^0.16.1", - "esprima-next": "^5.8.4", - "recast": "^0.22.0" - }, - "engines": { - "node": ">=20.15", - "pnpm": ">=9.5" - } - }, - "node_modules/@n8n/tournament/node_modules/ast-types": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", - "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", - "license": "MIT", - "peer": true, - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", - "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodeutils/defaults-deep": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@nodeutils/defaults-deep/-/defaults-deep-1.1.0.tgz", - "integrity": "sha512-gG44cwQovaOFdSR02jR9IhVRpnDP64VN6JdjYJTfNz4J4fWn7TQnmrf22nSjRqlwlxPcW8PL/L3KbJg3tdwvpg==", - "dev": true, - "license": "ISC", - "dependencies": { - "lodash": "^4.15.0" - } - }, - "node_modules/@oclif/core": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/@oclif/core/-/core-4.5.5.tgz", - "integrity": "sha512-iQzlaJQgPeUXrtrX71OzDwxPikQ7c2FhNd8U8rBB7BCtj2XYfmzBT/Hmbc+g9OKDIG/JkbJT0fXaWMMBrhi+1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.3.2", - "ansis": "^3.17.0", - "clean-stack": "^3.0.1", - "cli-spinners": "^2.9.2", - "debug": "^4.4.3", - "ejs": "^3.1.10", - "get-package-type": "^0.1.0", - "indent-string": "^4.0.0", - "is-wsl": "^2.2.0", - "lilconfig": "^3.1.3", - "minimatch": "^9.0.5", - "semver": "^7.7.3", - "string-width": "^4.2.3", - "supports-color": "^8", - "tinyglobby": "^0.2.14", - "widest-line": "^3.1.0", - "wordwrap": "^1.0.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@octokit/auth-token": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", - "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/core": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.5.tgz", - "integrity": "sha512-t54CUOsFMappY1Jbzb7fetWeO0n6K0k/4+/ZpkS+3Joz8I4VcvY9OiEBFRYISqaI2fq5sCiPtAjRDOzVYG8m+Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/auth-token": "^6.0.0", - "@octokit/graphql": "^9.0.2", - "@octokit/request": "^10.0.4", - "@octokit/request-error": "^7.0.1", - "@octokit/types": "^15.0.0", - "before-after-hook": "^4.0.0", - "universal-user-agent": "^7.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/endpoint": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.1.tgz", - "integrity": "sha512-7P1dRAZxuWAOPI7kXfio88trNi/MegQ0IJD3vfgC3b+LZo1Qe6gRJc2v0mz2USWWJOKrB2h5spXCzGbw+fAdqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/types": "^15.0.0", - "universal-user-agent": "^7.0.2" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/graphql": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.2.tgz", - "integrity": "sha512-iz6KzZ7u95Fzy9Nt2L8cG88lGRMr/qy1Q36ih/XVzMIlPDMYwaNLE/ENhqmIzgPrlNWiYJkwmveEetvxAgFBJw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/request": "^10.0.4", - "@octokit/types": "^15.0.0", - "universal-user-agent": "^7.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/openapi-types": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-26.0.0.tgz", - "integrity": "sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-13.2.0.tgz", - "integrity": "sha512-YuAlyjR8o5QoRSOvMHxSJzPtogkNMgeMv2mpccrvdUGeC3MKyfi/hS+KiFwyH/iRKIKyx+eIMsDjbt3p9r2GYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/types": "^15.0.0" - }, - "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=6" - } - }, - "node_modules/@octokit/plugin-request-log": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-6.0.0.tgz", - "integrity": "sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=6" - } - }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-16.1.0.tgz", - "integrity": "sha512-nCsyiKoGRnhH5LkH8hJEZb9swpqOcsW+VXv1QoyUNQXJeVODG4+xM6UICEqyqe9XFr6LkL8BIiFCPev8zMDXPw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/types": "^15.0.0" - }, - "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=6" - } - }, - "node_modules/@octokit/request": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.5.tgz", - "integrity": "sha512-TXnouHIYLtgDhKo+N6mXATnDBkV05VwbR0TtMWpgTHIoQdRQfCSzmy/LGqR1AbRMbijq/EckC/E3/ZNcU92NaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/endpoint": "^11.0.1", - "@octokit/request-error": "^7.0.1", - "@octokit/types": "^15.0.0", - "fast-content-type-parse": "^3.0.0", - "universal-user-agent": "^7.0.2" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/request-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.0.1.tgz", - "integrity": "sha512-CZpFwV4+1uBrxu7Cw8E5NCXDWFNf18MSY23TdxCBgjw1tXXHvTrZVsXlW8hgFTOLw8RQR1BBrMvYRtuyaijHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/types": "^15.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/rest": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-22.0.0.tgz", - "integrity": "sha512-z6tmTu9BTnw51jYGulxrlernpsQYXpui1RK21vmXn8yF5bp6iX16yfTtJYGK5Mh1qDkvDOmp2n8sRMcQmR8jiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/core": "^7.0.2", - "@octokit/plugin-paginate-rest": "^13.0.1", - "@octokit/plugin-request-log": "^6.0.0", - "@octokit/plugin-rest-endpoint-methods": "^16.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/types": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-15.0.0.tgz", - "integrity": "sha512-8o6yDfmoGJUIeR9OfYU0/TUJTnMPG2r68+1yEdUeG2Fdqpj8Qetg0ziKIgcBm0RW/j29H41WP37CYCEhp6GoHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/openapi-types": "^26.0.0" - } - }, - "node_modules/@phun-ky/typeof": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@phun-ky/typeof/-/typeof-2.0.3.tgz", - "integrity": "sha512-oeQJs1aa8Ghke8JIK9yuq/+KjMiaYeDZ38jx7MhkXncXlUKjqQ3wEm2X3qCKyjo+ZZofZj+WsEEiqkTtRuE2xQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^20.9.0 || >=22.0.0", - "npm": ">=10.8.2" - }, - "funding": { - "url": "https://github.com/phun-ky/typeof?sponsor=1" - } - }, - "node_modules/@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@ts-morph/common": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.27.0.tgz", - "integrity": "sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-glob": "^3.3.3", - "minimatch": "^10.0.1", - "path-browserify": "^1.0.1" - } - }, - "node_modules/@ts-morph/common/node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/@ts-morph/common/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@ts-morph/common/node_modules/minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", - "dev": true, - "license": "ISC", - "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", - "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/parse-path": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@types/parse-path/-/parse-path-7.0.3.tgz", - "integrity": "sha512-LriObC2+KYZD3FzCrgWGv/qufdUy4eXrxcLgQMfYXgPbLIecKIsVBaQgUPmxSSLcjmYbDTQbMgr6qr6l/eb7Bg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.1.tgz", - "integrity": "sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.46.1", - "@typescript-eslint/type-utils": "8.46.1", - "@typescript-eslint/utils": "8.46.1", - "@typescript-eslint/visitor-keys": "8.46.1", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.46.1", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.1.tgz", - "integrity": "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.46.1", - "@typescript-eslint/types": "8.46.1", - "@typescript-eslint/typescript-estree": "8.46.1", - "@typescript-eslint/visitor-keys": "8.46.1", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.1.tgz", - "integrity": "sha512-FOIaFVMHzRskXr5J4Jp8lFVV0gz5ngv3RHmn+E4HYxSJ3DgDzU7fVI1/M7Ijh1zf6S7HIoaIOtln1H5y8V+9Zg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.46.1", - "@typescript-eslint/types": "^8.46.1", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.1.tgz", - "integrity": "sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.46.1", - "@typescript-eslint/visitor-keys": "8.46.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.1.tgz", - "integrity": "sha512-X88+J/CwFvlJB+mK09VFqx5FE4H5cXD+H/Bdza2aEWkSb8hnWIQorNcscRl4IEo1Cz9VI/+/r/jnGWkbWPx54g==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.1.tgz", - "integrity": "sha512-+BlmiHIiqufBxkVnOtFwjah/vrkF4MtKKvpXrKSPLCkCtAp8H01/VV43sfqA98Od7nJpDcFnkwgyfQbOG0AMvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.46.1", - "@typescript-eslint/typescript-estree": "8.46.1", - "@typescript-eslint/utils": "8.46.1", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.1.tgz", - "integrity": "sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.1.tgz", - "integrity": "sha512-uIifjT4s8cQKFQ8ZBXXyoUODtRoAd7F7+G8MKmtzj17+1UbdzFl52AzRyZRyKqPHhgzvXunnSckVu36flGy8cg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.46.1", - "@typescript-eslint/tsconfig-utils": "8.46.1", - "@typescript-eslint/types": "8.46.1", - "@typescript-eslint/visitor-keys": "8.46.1", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "8.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.1.tgz", - "integrity": "sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.46.1", - "@typescript-eslint/types": "8.46.1", - "@typescript-eslint/typescript-estree": "8.46.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.1.tgz", - "integrity": "sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.46.1", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", - "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", - "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", - "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", - "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", - "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", - "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", - "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", - "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", - "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", - "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", - "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", - "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", - "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", - "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", - "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", - "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.11" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", - "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", - "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", - "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "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" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ansis": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/ansis/-/ansis-3.17.0.tgz", - "integrity": "sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/assert": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", - "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "is-nan": "^1.3.2", - "object-is": "^1.1.5", - "object.assign": "^4.1.4", - "util": "^0.12.5" - } - }, - "node_modules/ast-types": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.15.2.tgz", - "integrity": "sha512-c27loCv9QkZinsa5ProX751khO9DJl/AcB5c2KNtA6NRvHKS0PgLfcftz72KVq504vB0Gku5s2kUZzDBvQWvHg==", - "license": "MIT", - "peer": true, - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, - "license": "MIT" - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "retry": "0.13.1" - } - }, - "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", - "peer": true - }, - "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", - "peer": true, - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/basic-ftp": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", - "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/before-after-hook": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", - "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/bundle-name": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", - "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "run-applescript": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/c12": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/c12/-/c12-3.3.0.tgz", - "integrity": "sha512-K9ZkuyeJQeqLEyqldbYLG3wjqwpw4BVaAqvmxq3GYKK0b1A/yYQdIcJxkzAOWcNVWhJpRXAPfZFueekiY/L8Dw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chokidar": "^4.0.3", - "confbox": "^0.2.2", - "defu": "^6.1.4", - "dotenv": "^17.2.2", - "exsolve": "^1.0.7", - "giget": "^2.0.0", - "jiti": "^2.5.1", - "ohash": "^2.0.11", - "pathe": "^2.0.3", - "perfect-debounce": "^2.0.0", - "pkg-types": "^2.3.0", - "rc9": "^2.1.2" - }, - "peerDependencies": { - "magicast": "^0.3.5" - }, - "peerDependenciesMeta": { - "magicast": { - "optional": true - } - } - }, - "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", - "peer": true, - "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-bind-apply-helpers": { - "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==", - "license": "MIT", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/change-case": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", - "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/chardet": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.0.tgz", - "integrity": "sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==", - "dev": true, - "license": "MIT" - }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "license": "BSD-3-Clause", - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/citty": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", - "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "consola": "^3.2.3" - } - }, - "node_modules/clean-stack": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", - "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 12" - } - }, - "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", - "peer": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "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", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "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", - "peer": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/code-block-writer": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz", - "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", - "dev": true, - "license": "MIT" - }, - "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" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "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", - "peer": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/comment-parser": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", - "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/confbox": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", - "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/consola": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", - "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.18.0 || >=16.10.0" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "license": "BSD-3-Clause", - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/data-uri-to-buffer": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", - "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/default-browser": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", - "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", - "dev": true, - "license": "MIT", - "dependencies": { - "bundle-name": "^4.1.0", - "default-browser-id": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser-id": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", - "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "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", - "peer": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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", - "peer": true, - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/defu": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", - "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", - "dev": true, - "license": "MIT" - }, - "node_modules/degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/degenerator/node_modules/ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "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", - "peer": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/destr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", - "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", - "dev": true, - "license": "MIT" - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dotenv": { - "version": "17.2.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", - "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "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", - "peer": true, - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/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", - "peer": true, - "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", - "peer": true, - "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", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/eslint": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.32.0.tgz", - "integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.0", - "@eslint/config-helpers": "^0.3.0", - "@eslint/core": "^0.15.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.32.0", - "@eslint/plugin-kit": "^0.3.4", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-config-riot": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-riot/-/eslint-config-riot-1.0.0.tgz", - "integrity": "sha512-NB/L/1Y30qyJcG5xZxCJKW/+bqyj+llbcCwo9DEz8bESIP0SLTOQ8T1DWCCFc+wJ61AMEstj4511PSScqMMfCw==", - "license": "MIT", - "peer": true - }, - "node_modules/eslint-import-context": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", - "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-tsconfig": "^4.10.1", - "stable-hash-x": "^0.2.0" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-import-context" - }, - "peerDependencies": { - "unrs-resolver": "^1.0.0" - }, - "peerDependenciesMeta": { - "unrs-resolver": { - "optional": true - } - } - }, - "node_modules/eslint-import-resolver-typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-4.4.4.tgz", - "integrity": "sha512-1iM2zeBvrYmUNTj2vSC/90JTHDth+dfOfiNKkxApWRsTJYNrc8rOdxxIf5vazX+BiAXTeOT0UvWpGI/7qIWQOw==", - "dev": true, - "license": "ISC", - "dependencies": { - "debug": "^4.4.1", - "eslint-import-context": "^0.1.8", - "get-tsconfig": "^4.10.1", - "is-bun-module": "^2.0.0", - "stable-hash-x": "^0.2.0", - "tinyglobby": "^0.2.14", - "unrs-resolver": "^1.7.11" - }, - "engines": { - "node": "^16.17.0 || >=18.6.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-import-resolver-typescript" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*", - "eslint-plugin-import-x": "*" - }, - "peerDependenciesMeta": { - "eslint-plugin-import": { - "optional": true - }, - "eslint-plugin-import-x": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-import-x": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.16.1.tgz", - "integrity": "sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "^8.35.0", - "comment-parser": "^1.4.1", - "debug": "^4.4.1", - "eslint-import-context": "^0.1.9", - "is-glob": "^4.0.3", - "minimatch": "^9.0.3 || ^10.0.1", - "semver": "^7.7.2", - "stable-hash-x": "^0.2.0", - "unrs-resolver": "^1.9.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-import-x" - }, - "peerDependencies": { - "@typescript-eslint/utils": "^8.0.0", - "eslint": "^8.57.0 || ^9.0.0", - "eslint-import-resolver-node": "*" - }, - "peerDependenciesMeta": { - "@typescript-eslint/utils": { - "optional": true - }, - "eslint-import-resolver-node": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-local": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-local/-/eslint-plugin-local-1.0.0.tgz", - "integrity": "sha512-bcwcQnKL/Iw5Vi/F2lG1he5oKD2OGjhsLmrcctkWrWq5TujgiaYb0cj3pZgr3XI54inNVnneOFdAx1daLoYLJQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint-plugin-n8n-nodes-base": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-n8n-nodes-base/-/eslint-plugin-n8n-nodes-base-1.16.3.tgz", - "integrity": "sha512-edLX42Vg4B+y0kzkitTVDmHZQrG5/wUZO874N5Z9leBuxt5TG1pqMY4zdr35RlpM4p4REr/T9x+6DpsQSL63WA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/utils": "^6.21.0", - "camel-case": "^4.1.2", - "eslint-plugin-local": "^1.0.0", - "indefinite": "^2.5.1", - "pascal-case": "^3.1.2", - "pluralize": "^8.0.0", - "sentence-case": "^3.0.4", - "title-case": "^3.0.3" - }, - "engines": { - "node": ">=20.15", - "pnpm": ">=9.6" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/ts-api-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", - "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/eslint-plugin-n8n-nodes-base/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima-next": { - "version": "5.8.4", - "resolved": "https://registry.npmjs.org/esprima-next/-/esprima-next-5.8.4.tgz", - "integrity": "sha512-8nYVZ4ioIH4Msjb/XmhnBdz5WRRBaYqevKa1cv9nGJdCehMbzZCPNEEnqfLCZVetUVrUPEcb5IYyu1GG4hFqgg==", - "license": "BSD-2-Clause", - "peer": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eta": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/eta/-/eta-4.0.1.tgz", - "integrity": "sha512-0h0oBEsF6qAJU7eu9ztvJoTo8D2PAq/4FvXVIQA1fek3WOTe6KPsVJycekG1+g1N6mfpblkheoGwaUhMtnlH4A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/bgub/eta?sponsor=1" - } - }, - "node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/execa/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/exsolve": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", - "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-content-type-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", - "integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true, - "license": "ISC" - }, - "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", - "peer": true, - "dependencies": { - "is-callable": "^1.2.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "license": "MIT", - "peer": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/generator-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", - "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "license": "ISC", - "peer": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-east-asian-width": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", - "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "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", - "peer": true, - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-tsconfig": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.12.0.tgz", - "integrity": "sha512-LScr2aNr2FbjAjZh2C6X6BxRx1/x+aTDExct/xyq2XKbYOiG5c0aK7pMsSuyc0brz3ibr/lbQiHD9jzt4lccJw==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/get-uri": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", - "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/giget": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/giget/-/giget-2.0.0.tgz", - "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "citty": "^0.1.6", - "consola": "^3.4.0", - "defu": "^6.1.4", - "node-fetch-native": "^1.6.6", - "nypm": "^0.6.0", - "pathe": "^2.0.3" - }, - "bin": { - "giget": "dist/cli.mjs" - } - }, - "node_modules/git-up": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/git-up/-/git-up-8.1.1.tgz", - "integrity": "sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-ssh": "^1.4.0", - "parse-url": "^9.2.0" - } - }, - "node_modules/git-url-parse": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-16.1.0.tgz", - "integrity": "sha512-cPLz4HuK86wClEW7iDdeAKcCVlWXmrLpb2L+G9goW0Z1dtpNS6BXXSOckUTlJT/LDQViE1QZKstNORzHsLnobw==", - "dev": true, - "license": "MIT", - "dependencies": { - "git-up": "^8.1.0" - } - }, - "node_modules/glob": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", - "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.3.1", - "jackspeak": "^4.1.1", - "minimatch": "^10.0.3", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", - "dev": true, - "license": "ISC", - "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, - "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-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "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", - "peer": true, - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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", - "peer": true, - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indefinite": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/indefinite/-/indefinite-2.5.2.tgz", - "integrity": "sha512-J3ELLIk835hmgDMUfNltTCrHz9+CteTnSuXJqvxZT18wo1U2M9/QeeJMw99QdZwPEEr1DE2aBYda101Ojjdw5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC", - "peer": true - }, - "node_modules/inquirer": { - "version": "12.9.6", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-12.9.6.tgz", - "integrity": "sha512-603xXOgyfxhuis4nfnWaZrMaotNT0Km9XwwBNWUKbIDqeCY89jGr2F9YPEMiNhU6XjIP4VoWISMBFfcc5NgrTw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/ansi": "^1.0.0", - "@inquirer/core": "^10.2.2", - "@inquirer/prompts": "^7.8.6", - "@inquirer/type": "^3.0.8", - "mute-stream": "^2.0.0", - "run-async": "^4.0.5", - "rxjs": "^7.8.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/ip-address": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", - "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/is-arguments": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", - "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "license": "MIT", - "peer": true - }, - "node_modules/is-bun-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", - "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.7.1" - } - }, - "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", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "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/is-generator-function": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", - "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.4", - "generator-function": "^2.0.0", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-inside-container/node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "dev": true, - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "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", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-ssh": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.1.tgz", - "integrity": "sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==", - "dev": true, - "license": "MIT", - "dependencies": { - "protocols": "^2.0.1" - } - }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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", - "peer": true, - "dependencies": { - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-unicode-supported": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", - "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/issue-parser": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-7.0.1.tgz", - "integrity": "sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash.capitalize": "^4.2.1", - "lodash.escaperegexp": "^4.1.2", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.uniqby": "^4.7.0" - }, - "engines": { - "node": "^18.17 || >=20.6.1" - } - }, - "node_modules/jackspeak": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", - "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jake": { - "version": "10.9.4", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", - "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "async": "^3.2.6", - "filelist": "^1.0.4", - "picocolors": "^1.1.1" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jake/node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/jiti": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", - "dev": true, - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/jmespath": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", - "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/js-base64": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz", - "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==", - "license": "BSD-3-Clause", - "peer": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/jssha": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.3.1.tgz", - "integrity": "sha512-VCMZj12FCFMQYcFLPRm/0lOBbLi8uM2BhXPTqw3U4YAfs4AZfiApOoBLoN8cQE60Z50m1MYMTQVCfgF/KaCVhQ==", - "license": "BSD-3-Clause", - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lilconfig": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT" - }, - "node_modules/lodash.capitalize": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", - "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.escaperegexp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", - "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.uniqby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", - "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", - "dev": true, - "license": "MIT" - }, - "node_modules/log-symbols": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", - "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-unicode-supported": "^2.0.0", - "yoctocolors": "^2.1.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/luxon": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz", - "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/macos-release": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-3.4.0.tgz", - "integrity": "sha512-wpGPwyg/xrSp4H4Db4xYSeAr6+cFQGHfspHzDUdYxswDnUW0L5Ov63UuJiSr8NMSpyaChO4u1n0MXUvVPtrN6A==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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", - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/md5": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true, - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 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" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "peer": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mimic-function": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", - "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "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==", - "dev": true, - "license": "MIT" - }, - "node_modules/mute-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", - "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/n8n-workflow": { - "version": "1.113.0", - "resolved": "https://registry.npmjs.org/n8n-workflow/-/n8n-workflow-1.113.0.tgz", - "integrity": "sha512-WiNbm2Us/lSOTioKQZeNdLMGlbOuDMUFVuC0aMVIrQl4YarUmIAyxH7xHkpOoWrahXwbg7PrW27aPkjjAHiEgg==", - "license": "SEE LICENSE IN LICENSE.md", - "peer": true, - "dependencies": { - "@n8n/errors": "^0.5.0", - "@n8n/tournament": "1.0.6", - "ast-types": "0.15.2", - "callsites": "3.1.0", - "esprima-next": "5.8.4", - "form-data": "4.0.0", - "jmespath": "0.16.0", - "js-base64": "3.7.2", - "jssha": "3.3.1", - "lodash": "4.17.21", - "luxon": "3.4.4", - "md5": "2.3.0", - "recast": "0.22.0", - "title-case": "3.0.3", - "transliteration": "2.3.5", - "xml2js": "0.6.2", - "zod": "3.25.67" - } - }, - "node_modules/napi-postinstall": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", - "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", - "dev": true, - "license": "MIT", - "bin": { - "napi-postinstall": "lib/cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/napi-postinstall" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "license": "MIT" - }, - "node_modules/netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/new-github-release-url": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/new-github-release-url/-/new-github-release-url-2.0.0.tgz", - "integrity": "sha512-NHDDGYudnvRutt/VhKFlX26IotXe1w0cmkDm6JGquh5bz/bDTw0LufSmH/GxTjEdpHEO+bVKFTwdrcGa/9XlKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^2.5.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/new-github-release-url/node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, - "license": "MIT", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/node-fetch-native": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", - "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nypm": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.2.tgz", - "integrity": "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==", - "dev": true, - "license": "MIT", - "dependencies": { - "citty": "^0.1.6", - "consola": "^3.4.2", - "pathe": "^2.0.3", - "pkg-types": "^2.3.0", - "tinyexec": "^1.0.1" - }, - "bin": { - "nypm": "dist/cli.mjs" - }, - "engines": { - "node": "^14.16.0 || >=16.10.0" - } - }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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", - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, - "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", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0", - "has-symbols": "^1.1.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ohash": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", - "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", - "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "default-browser": "^5.2.1", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "wsl-utils": "^0.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/ora": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-9.0.0.tgz", - "integrity": "sha512-m0pg2zscbYgWbqRR6ABga5c3sZdEon7bSgjnlXC64kxtxLOyjRcbbUkLj7HFyy/FTD+P2xdBWu8snGhYI0jc4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^5.6.2", - "cli-cursor": "^5.0.0", - "cli-spinners": "^3.2.0", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^2.1.0", - "log-symbols": "^7.0.1", - "stdin-discarder": "^0.2.2", - "string-width": "^8.1.0", - "strip-ansi": "^7.1.2" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/ora/node_modules/cli-spinners": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.3.0.tgz", - "integrity": "sha512-/+40ljC3ONVnYIttjMWrlL51nItDAbBrq2upN8BPyvGU/2n5Oxw3tbNwORCaNuNqLJnxGqOfjUuhsv7l5Q4IsQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/node_modules/string-width": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", - "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-east-asian-width": "^1.3.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/os-name": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-6.1.0.tgz", - "integrity": "sha512-zBd1G8HkewNd2A8oQ8c6BN/f/c9EId7rSUueOLGu28govmUctXmM+3765GwsByv9nYUdrLqHphXlYIc86saYsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "macos-release": "^3.3.0", - "windows-release": "^6.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pac-proxy-agent": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", - "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "get-uri": "^6.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.6", - "pac-resolver": "^7.0.1", - "socks-proxy-agent": "^8.0.5" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-resolver": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", - "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", - "dev": true, - "license": "MIT", - "dependencies": { - "degenerator": "^5.0.0", - "netmask": "^2.0.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-path": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.1.0.tgz", - "integrity": "sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "protocols": "^2.0.0" - } - }, - "node_modules/parse-url": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-9.2.0.tgz", - "integrity": "sha512-bCgsFI+GeGWPAvAiUv63ZorMeif3/U0zaXABGJbOWt5OH2KCaPHF6S+0ok4aqM9RuIPGyZdx9tR9l13PsW4AYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/parse-path": "^7.0.0", - "parse-path": "^7.0.0" - }, - "engines": { - "node": ">=14.13.0" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-scurry": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", - "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz", - "integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, - "license": "MIT" - }, - "node_modules/perfect-debounce": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.0.0.tgz", - "integrity": "sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==", - "dev": true, - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-types": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", - "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", - "dev": true, - "license": "MIT", - "dependencies": { - "confbox": "^0.2.2", - "exsolve": "^1.0.7", - "pathe": "^2.0.3" - } - }, - "node_modules/pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "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", - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", - "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/protocols": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.2.tgz", - "integrity": "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/proxy-agent": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", - "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.6", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.1.0", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.5" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true, - "license": "MIT" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/rc9": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", - "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", - "dev": true, - "license": "MIT", - "dependencies": { - "defu": "^6.1.4", - "destr": "^2.0.3" - } - }, - "node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/recast": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.22.0.tgz", - "integrity": "sha512-5AAx+mujtXijsEavc5lWXBPQqrM4+Dl5qNH96N2aNeuJFUzpiiToKPsxQD/zAIJHspz7zz0maX0PCtCTFVlixQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "assert": "^2.0.0", - "ast-types": "0.15.2", - "esprima": "~4.0.0", - "source-map": "~0.6.1", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/release-it": { - "version": "19.0.5", - "resolved": "https://registry.npmjs.org/release-it/-/release-it-19.0.5.tgz", - "integrity": "sha512-bYlUKC0TQroBKi8jQUeoxLHql4d9Fx/2EQLHPKUobXTNSiTS2WY8vlgdHZRhRjVEMyAWwyadJVKfFZnRJuRn4Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/webpro" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/webpro" - } - ], - "license": "MIT", - "dependencies": { - "@nodeutils/defaults-deep": "1.1.0", - "@octokit/rest": "22.0.0", - "@phun-ky/typeof": "2.0.3", - "async-retry": "1.3.3", - "c12": "3.3.0", - "ci-info": "^4.3.0", - "eta": "4.0.1", - "git-url-parse": "16.1.0", - "inquirer": "12.9.6", - "issue-parser": "7.0.1", - "lodash.merge": "4.6.2", - "mime-types": "3.0.1", - "new-github-release-url": "2.0.0", - "open": "10.2.0", - "ora": "9.0.0", - "os-name": "6.1.0", - "proxy-agent": "6.5.0", - "semver": "7.7.2", - "tinyglobby": "0.2.15", - "undici": "6.21.3", - "url-join": "5.0.0", - "wildcard-match": "5.1.4", - "yargs-parser": "21.1.1" - }, - "bin": { - "release-it": "bin/release-it.js" - }, - "engines": { - "node": "^20.12.0 || >=22.0.0" - } - }, - "node_modules/release-it/node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/release-it/node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/release-it/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", - "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^11.0.0", - "package-json-from-dist": "^1.0.0" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-applescript": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", - "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/run-async": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-4.0.6.tgz", - "integrity": "sha512-IoDlSLTs3Yq593mb3ZoKWKXMNu3UpObxhgA/Xuid5p4bbfi2jdY1Hj0m1K+0/tEuQTxIGMhQDqGjKb7RuxGpAQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rxjs": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "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", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-regex": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", - "license": "ISC", - "peer": true - }, - "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/sentence-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", - "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3", - "upper-case-first": "^2.0.2" - } - }, - "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", - "peer": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.8.7", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", - "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ip-address": "^10.0.1", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", - "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "socks": "^2.8.3" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stable-hash-x": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", - "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/stdin-discarder": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", - "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs": { - "name": "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/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/string-width/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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/tinyexec": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", - "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", - "dev": true, - "license": "MIT" - }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/title-case": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", - "integrity": "sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "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" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/transliteration": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/transliteration/-/transliteration-2.3.5.tgz", - "integrity": "sha512-HAGI4Lq4Q9dZ3Utu2phaWgtm3vB6PkLUFqWAScg/UW+1eZ/Tg6Exo4oC0/3VUol/w4BlefLhUUSVBr/9/ZGQOw==", - "license": "MIT", - "peer": true, - "dependencies": { - "yargs": "^17.5.1" - }, - "bin": { - "slugify": "dist/bin/slugify", - "transliterate": "dist/bin/transliterate" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" - } - }, - "node_modules/ts-morph": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-26.0.0.tgz", - "integrity": "sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ts-morph/common": "~0.27.0", - "code-block-writer": "^13.0.3" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", - "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-eslint": { - "version": "8.46.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.46.1.tgz", - "integrity": "sha512-VHgijW803JafdSsDO8I761r3SHrgk4T00IdyQ+/UsthtgPRsBWQLqoSxOolxTpxRKi1kGXK0bSz4CoAc9ObqJA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/eslint-plugin": "8.46.1", - "@typescript-eslint/parser": "8.46.1", - "@typescript-eslint/typescript-estree": "8.46.1", - "@typescript-eslint/utils": "8.46.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/uglify-js": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "dev": true, - "license": "BSD-2-Clause", - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/undici": { - "version": "6.21.3", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz", - "integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.17" - } - }, - "node_modules/universal-user-agent": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", - "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==", - "dev": true, - "license": "ISC" - }, - "node_modules/unrs-resolver": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", - "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "napi-postinstall": "^0.3.0" - }, - "funding": { - "url": "https://opencollective.com/unrs-resolver" - }, - "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.11.1", - "@unrs/resolver-binding-android-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-x64": "1.11.1", - "@unrs/resolver-binding-freebsd-x64": "1.11.1", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", - "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-musl": "1.11.1", - "@unrs/resolver-binding-wasm32-wasi": "1.11.1", - "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", - "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", - "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" - } - }, - "node_modules/upper-case-first": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", - "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-join": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", - "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "license": "MIT", - "peer": true, - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.19", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", - "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", - "license": "MIT", - "peer": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "for-each": "^0.3.5", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wildcard-match": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/wildcard-match/-/wildcard-match-5.1.4.tgz", - "integrity": "sha512-wldeCaczs8XXq7hj+5d/F38JE2r7EXgb6WQDM84RVwxy81T/sxB5e9+uZLK9Q9oNz1mlvjut+QtvgaOQFPVq/g==", - "dev": true, - "license": "ISC" - }, - "node_modules/windows-release": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-6.1.0.tgz", - "integrity": "sha512-1lOb3qdzw6OFmOzoY0nauhLG72TpWtb5qgYPiSh/62rjc1XidBSDio2qw0pwHh17VINF217ebIkZJdFLZFn9SA==", - "dev": true, - "license": "MIT", - "dependencies": { - "execa": "^8.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true, - "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", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "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/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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/wsl-utils": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", - "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-wsl": "^3.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wsl-utils/node_modules/is-wsl": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-inside-container": "^1.0.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/xml2js": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", - "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", - "license": "MIT", - "peer": true, - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "license": "ISC", - "peer": true, - "engines": { - "node": ">=10" - } - }, - "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", - "peer": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "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" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yoctocolors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", - "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yoctocolors-cjs": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", - "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zod": { - "version": "3.25.67", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.67.tgz", - "integrity": "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==", - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - } - } -} -- 2.40.1 From e63b217e4faf4d9fd668d40217ab0de864064cd1 Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Wed, 5 Nov 2025 11:42:18 +0530 Subject: [PATCH 19/22] package.json updated --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 56ee87c..8fe543a 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "n8n-nodes-seclore", + "name": "@seclore/n8n-nodes-seclore", "version": "0.1.0", "description": "n8n community node for Seclore Protect - secure file protection using DRM technology", "license": "MIT", -- 2.40.1 From 043c06e7acb31d029a70bb7603c1b0765d152d67 Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Tue, 11 Nov 2025 16:32:05 +0530 Subject: [PATCH 20/22] review comments resolved --- nodes/SecloreProtect/SecloreProtect.node.ts | 4 ++-- nodes/SecloreProtect/operations/protectWithHotFolder.ts | 2 +- nodes/SecloreProtect/operations/unprotect.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nodes/SecloreProtect/SecloreProtect.node.ts b/nodes/SecloreProtect/SecloreProtect.node.ts index 79d3f0c..d8e3672 100644 --- a/nodes/SecloreProtect/SecloreProtect.node.ts +++ b/nodes/SecloreProtect/SecloreProtect.node.ts @@ -11,7 +11,7 @@ export class SecloreProtect implements INodeType { displayName: 'Seclore', name: 'secloreProtect', icon: 'file:../../icons/seclore.svg', - usableAsTool: true, // TODO: make it false/ don't allow it to be used as a tool + usableAsTool: true, group: ['transform'], version: 1, subtitle: '={{$parameter["resource"] + ": " + $parameter["operation"]}}', @@ -59,7 +59,7 @@ export class SecloreProtect implements INodeType { }, options: [ { - name: 'Protect using Policy', + name: 'Protect Using Policy', value: 'protectWithHotFolder', description: 'Protect a file using HotFolder ID configuration', action: 'Protect file using policy', diff --git a/nodes/SecloreProtect/operations/protectWithHotFolder.ts b/nodes/SecloreProtect/operations/protectWithHotFolder.ts index c4dc3f5..202b3ee 100644 --- a/nodes/SecloreProtect/operations/protectWithHotFolder.ts +++ b/nodes/SecloreProtect/operations/protectWithHotFolder.ts @@ -189,7 +189,7 @@ export async function protectWithHotFolder(this: IExecuteFunctions): Promise { // Get parameters for this item Logger.debug(who + 'Getting node parameters', { itemIndex: i }); const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; - const correlationId = crypto.randomUUID().toString(); + const correlationId = crypto.randomUUID(); const retryCount = this.getNodeParameter('retryCount', i) as number; Logger.debug(who + 'Asserting binary data', { binaryPropertyName, itemIndex: i }); -- 2.40.1 From 264d2c7136d906ffe55ee31051e08caa7cc6a6fe Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Tue, 11 Nov 2025 16:32:19 +0530 Subject: [PATCH 21/22] missing readme added --- README.md | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/README.md b/README.md index 7e6e78e..d12132f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,137 @@ # n8n-nodes-seclore +This is an n8n community node. It lets you use Seclore DRM Server in your n8n workflows. + +[Seclore](https://www.seclore.com) is a leading data-centric security platform that provides enterprise-grade Digital Rights Management (DRM) capabilities to protect sensitive files and documents throughout their lifecycle. + +[n8n](https://n8n.io/) is a [fair-code licensed](https://docs.n8n.io/reference/license/) workflow automation platform. + +[Installation](#installation) +[Operations](#operations) +[Credentials](#credentials) +[Compatibility](#compatibility) +[Usage](#usage) +[Resources](#resources) + +## Installation + +Follow the [installation guide](https://docs.n8n.io/integrations/community-nodes/installation/) in the n8n community nodes documentation. + +Use `n8n-nodes-seclore` as the package name. + +## Operations + +This node supports the following operations with Seclore DRM Server: + +### DRM Protection +#### Protect using Policy +- **Description**: Protects files using Seclore's HotFolder ID configuration and policy-based protection +- **Required Parameters**: + - **HotFolder ID**: The ID of the HotFolder configuration to use for protection + - **Input Binary Property**: Name of the binary property containing the file to protect (default: 'data') + - **Retry Count**: Number of retry attempts for failed requests (default: 3) +- **Output**: Protected file with DRM protection applied according to the specified policy + + +### DRM Unprotection +#### Unprotect +- **Description**: Removes DRM protection from Seclore-protected files +- **Required Parameters**: + - **Input Binary Property**: Name of the binary property containing the protected file (default: 'data') + - **Retry Count**: Number of retry attempts for failed requests (default: 3) +- **Output**: Unprotected original file content + + +## Credentials + +To use this node, you need to authenticate with your Seclore DRM Server. The following credentials are required: + +### Prerequisites +- Access to a Seclore DRM Server instance +- Valid tenant credentials (Tenant ID and Tenant Secret) +- Appropriate permissions for file protection/unprotection operations + +### Authentication Setup +1. **Base URL**: The base URL of your Seclore DRM Server (e.g., `https://api.seclore.com`) +2. **Tenant ID**: Your unique Seclore tenant identifier +3. **Tenant Secret**: Your tenant's secret key for API authentication + +### Configuration Steps +1. In n8n, go to **Credentials** → **Create New** +2. Search for "Seclore API" and select it +3. Fill in your Seclore DRM Server details: + - **Base URL**: Enter your Seclore DRM Server base URL + - **Tenant ID**: Provide your unique tenant identifier + - **Tenant Secret**: Enter your tenant's secret key (will be masked for security) +4. Test the connection to ensure credentials are valid (tests against `/seclore/drm/1.0/auth/login` endpoint) +5. Save the credentials for use in your workflows + +## Compatibility + +- **Minimum n8n version**: 1.0.0 +- **Tested with n8n versions**: 1.0.0+ +- **Node.js version**: 18.x or higher +- **Seclore API version**: Compatible with Seclore DRM API v1.0 + +## Usage + +### Basic Workflow Examples + +#### Protecting Files with Policy +1. Use a trigger node to receive files (HTTP Request, File Trigger, etc.) +2. Add the **Seclore** node to your workflow +3. Configure the node: + - **Resource**: Select "DRM Protection" + - **Operation**: Select "Protect using Policy" + - **HotFolder ID**: Enter your HotFolder configuration ID + - **Input Binary Property**: Specify the binary property name (default: 'data') + - **Retry Count**: Set retry attempts (default: 3) +4. Configure your Seclore API credentials +5. The node will return the protected file with DRM encryption applied according to your policy + +#### Unprotecting Files +1. Receive protected Seclore files in your workflow +2. Add the **Seclore** node to your workflow +3. Configure the node: + - **Resource**: Select "DRM Unprotection" + - **Operation**: Select "Unprotect" + - **Input Binary Property**: Specify the binary property containing the protected file (default: 'data') + - **Retry Count**: Set retry attempts (default: 3) +4. Configure your Seclore API credentials +5. The node will return the original unprotected file content + +### Important Notes +- Ensure your Seclore DRM Server is accessible from your n8n instance +- File operations may take time depending on file size and server performance +- Always handle errors appropriately in your workflows +- Protected files can only be unprotected by authorized users with proper credentials +- HotFolder ID must be configured in your Seclore Policy Server before using protection operations +- The node supports binary data processing for both input and output files +- Retry mechanism is built-in for handling temporary network or server issues + +### Error Handling +The node includes comprehensive error handling and logging: +- Connection failures to Seclore server +- Authentication errors +- File processing errors +- Automatic cleanup of temporary files + +## Resources + +* [n8n community nodes documentation](https://docs.n8n.io/integrations/#community-nodes) +* [Seclore Official Documentation](https://docs.seclore.com/) +* [Seclore Support](https://support.seclore.com/) + +## License + +This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details. + +## Support + +For issues related to this n8n node: +- Create an issue in this repository +- Contact: support@seclore.com + +For Seclore platform support: +- Visit [Seclore Support Portal](https://support.seclore.com/) +- Check [Seclore Documentation](https://docs.seclore.com/) -- 2.40.1 From a934931037892b6a80159ded4eac00eda3d8ad5e Mon Sep 17 00:00:00 2001 From: "atharva.dev" Date: Wed, 12 Nov 2025 16:55:32 +0530 Subject: [PATCH 22/22] Add CONTRIBUTING.md to outline contribution workflow and guidelines --- CONTRIBUTING.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..d3e8d39 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,58 @@ +# Contributing + +## Workflow + +A **feature branch workflow** is followed for this repository. All development work is done on ticket branches that are merged directly into the `main` branch. + +## Pre-requisite + +- Verify that you have local git setup as mentioned in **[this guide](https://repo.seclore.com/common/user_guides/src/branch/main/docs/coding_processes.md#setting-up-base-machine)** +- A JIRA ticket should be created for the work you plan to contribute + +## Contribution Process + +### Branch Structure + +- **`main`**: Production-ready code. This branch should always be stable and deployable. All ticket branches are created from and merged into this branch. + +### Branch Naming Convention + +Create branches using the following naming structure: + +- **Format**: `ticket/` + +Examples: +- `ticket/PS-378` +- `ticket/PS-379` + +### Step-by-Step Contribution Process + +1. **Create a branch from `main`** + ```bash + git checkout main + git pull origin main + git checkout -b ticket/ + ``` + +2. **Follow standard development process**: + - Effort Estimates + - Design Documentation (if required) + - Test Cases + - Code Implementation (following project coding standards) + +3. **Raise a Pull Request** + - Create a PR **from your ticket branch into the `main` branch** + - PR title format: `() ` + - Add relevant documentation links in the PR description + - Update the PR link in the JIRA ticket comments + +4. **Code Review** + - Address review comments + - Ensure all CI checks pass + - Get required approvals + +5. **Merge to Main** + - Upon PR approval, **squash and merge** the ticket branch into `main` + - Delete the ticket branch after successful merge + +--- \ No newline at end of file -- 2.40.1