diff --git a/.arcconfig b/.arcconfig deleted file mode 100644 index 0df938ee..00000000 --- a/.arcconfig +++ /dev/null @@ -1,3 +0,0 @@ -{ - "conduit_uri" : "https://phab.nylas.com/" -} diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 002b4aa0..00000000 --- a/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["env"] -} diff --git a/.cursor/rules/nylas-nodejs-sdk-rules.mdc b/.cursor/rules/nylas-nodejs-sdk-rules.mdc new file mode 100644 index 00000000..cd42faed --- /dev/null +++ b/.cursor/rules/nylas-nodejs-sdk-rules.mdc @@ -0,0 +1,536 @@ +--- +description: +globs: +alwaysApply: true +--- +# Nylas Node.js SDK Development Rules + +## Rule 1: Adding a New API Resource + +### Description +User wants to add support for a completely new Nylas API resource (e.g., /v3/widgets). + +### Conditions +- Matches files: Any file +- Code selection matches: Case-insensitive phrases like "add new resource", "new endpoint group", etc. + +### Instructions + +To add support for a new Nylas API resource (let's call it `{{RESOURCE_NAME}}`), follow these steps: + +#### 1. Define Models +- Create a new file `src/models/{{RESOURCE_NAME_LC}}.ts` +- Define TypeScript interfaces/types for: + - The main resource object (e.g., `{{RESOURCE_NAME}}`) with all properties documented + - Request bodies (e.g., `Create{{RESOURCE_NAME}}Request`, `Update{{RESOURCE_NAME}}Request`) + - Query parameters (e.g., `List{{RESOURCE_NAME}}QueryParams`, `Find{{RESOURCE_NAME}}QueryParams`) + - Use standard response types from `src/models/response.ts` (`NylasResponse`, `NylasListResponse`) + - Use consistent property naming (camelCase) and proper TSDoc annotations +- Export all types from the new model file +- Add the export statement to `src/models/index.ts` + +Example model structure: +```typescript +import { ListQueryParams } from './listQueryParams.js'; + +/** + * Interface representing a Nylas {{RESOURCE_NAME}} object. + */ +export interface {{RESOURCE_NAME}} { + id: string; + grantId: string; + object: '{{RESOURCE_NAME_LC}}'; + // Add all resource properties with appropriate types and optionality +} + +/** + * Interface representing the query parameters for listing {{RESOURCE_NAME_LC}}s. + */ +export interface List{{RESOURCE_NAME}}QueryParams extends ListQueryParams { + // Add specific query parameters +} + +/** + * Interface representing the query parameters for retrieving a single {{RESOURCE_NAME_LC}}. + */ +export interface Find{{RESOURCE_NAME}}QueryParams { + // Add specific query parameters +} + +/** + * Interface for creating a {{RESOURCE_NAME_LC}}. + */ +export type Create{{RESOURCE_NAME}}Request = { + // Add all properties needed for creation +}; + +/** + * Interface for updating a {{RESOURCE_NAME_LC}}. + */ +export type Update{{RESOURCE_NAME}}Request = { + // Add all properties needed for updating +}; +``` + +#### 2. Define Resource Class +- Create a new file `src/resources/{{RESOURCE_NAME_LC}}.ts` +- Create a class `{{RESOURCE_NAME}}` that extends `Resource` from `src/resources/resource.ts` +- Import all models defined in the previous step +- Define interface parameters for each endpoint method +- Implement public methods for each endpoint (e.g., `list`, `find`, `create`, `update`, `destroy`) +- Use typed parameters and return values for all methods +- Call appropriate protected methods from the base `Resource` class + +Example resource implementation: +```typescript +import { Overrides } from '../config.js'; +import { + Create{{RESOURCE_NAME}}Request, + {{RESOURCE_NAME}}, + List{{RESOURCE_NAME}}QueryParams, + Find{{RESOURCE_NAME}}QueryParams, + Update{{RESOURCE_NAME}}Request, +} from '../models/{{RESOURCE_NAME_LC}}.js'; +import { + NylasResponse, + NylasListResponse, + NylasBaseResponse, +} from '../models/response.js'; +import { AsyncListResponse, Resource } from './resource.js'; + +/** + * @property {{RESOURCE_NAME_LC}}Id The id of the {{RESOURCE_NAME}} to retrieve. + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ +interface Find{{RESOURCE_NAME}}Params { + identifier: string; + {{RESOURCE_NAME_LC}}Id: string; + queryParams: Find{{RESOURCE_NAME}}QueryParams; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ +interface List{{RESOURCE_NAME}}Params { + identifier: string; + queryParams: List{{RESOURCE_NAME}}QueryParams; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property requestBody The values to create the {{RESOURCE_NAME}} with + */ +interface Create{{RESOURCE_NAME}}Params { + identifier: string; + requestBody: Create{{RESOURCE_NAME}}Request; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property {{RESOURCE_NAME_LC}}Id The id of the {{RESOURCE_NAME}} to retrieve. + * @property requestBody The values to update the {{RESOURCE_NAME}} with + */ +interface Update{{RESOURCE_NAME}}Params { + identifier: string; + {{RESOURCE_NAME_LC}}Id: string; + requestBody: Update{{RESOURCE_NAME}}Request; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property {{RESOURCE_NAME_LC}}Id The id of the {{RESOURCE_NAME}} to retrieve. + */ +interface Destroy{{RESOURCE_NAME}}Params { + identifier: string; + {{RESOURCE_NAME_LC}}Id: string; +} + +/** + * Nylas {{RESOURCE_NAME}}s API + * + * [Add a brief description of the resource] + */ +export class {{RESOURCE_NAME}}s extends Resource { + /** + * Return all {{RESOURCE_NAME}}s + * @return The list of {{RESOURCE_NAME}}s + */ + public list({ + identifier, + queryParams, + overrides, + }: List{{RESOURCE_NAME}}Params & Overrides): AsyncListResponse< + NylasListResponse<{{RESOURCE_NAME}}> + > { + return super._list({ + queryParams, + path: `/v3/grants/${identifier}/{{RESOURCE_NAME_LC}}s`, + overrides, + }); + } + + /** + * Return a {{RESOURCE_NAME}} + * @return The {{RESOURCE_NAME}} + */ + public find({ + identifier, + {{RESOURCE_NAME_LC}}Id, + queryParams, + overrides, + }: Find{{RESOURCE_NAME}}Params & Overrides): Promise> { + return super._find({ + path: `/v3/grants/${identifier}/{{RESOURCE_NAME_LC}}s/${{{RESOURCE_NAME_LC}}Id}`, + queryParams, + overrides, + }); + } + + /** + * Create a {{RESOURCE_NAME}} + * @return The created {{RESOURCE_NAME}} + */ + public create({ + identifier, + requestBody, + overrides, + }: Create{{RESOURCE_NAME}}Params & Overrides): Promise> { + return super._create({ + path: `/v3/grants/${identifier}/{{RESOURCE_NAME_LC}}s`, + requestBody, + overrides, + }); + } + + /** + * Update a {{RESOURCE_NAME}} + * @return The updated {{RESOURCE_NAME}} + */ + public update({ + identifier, + {{RESOURCE_NAME_LC}}Id, + requestBody, + overrides, + }: Update{{RESOURCE_NAME}}Params & Overrides): Promise> { + return super._update({ + path: `/v3/grants/${identifier}/{{RESOURCE_NAME_LC}}s/${{{RESOURCE_NAME_LC}}Id}`, + requestBody, + overrides, + }); + } + + /** + * Delete a {{RESOURCE_NAME}} + * @return The deletion response + */ + public destroy({ + identifier, + {{RESOURCE_NAME_LC}}Id, + overrides, + }: Destroy{{RESOURCE_NAME}}Params & Overrides): Promise { + return super._destroy({ + path: `/v3/grants/${identifier}/{{RESOURCE_NAME_LC}}s/${{{RESOURCE_NAME_LC}}Id}`, + overrides, + }); + } +} +``` + +#### 3. Register Resource +- Open `src/nylas.ts` +- Import the new `{{RESOURCE_NAME}}s` class +- Add a property for the resource to the `Nylas` class +- Instantiate in the `Nylas` constructor + +Example: +```typescript +import { {{RESOURCE_NAME}}s } from './resources/{{RESOURCE_NAME_LC}}s.js'; + +export class Nylas { + // ... existing properties + public {{RESOURCE_NAME_LC}}s: {{RESOURCE_NAME}}s; + + constructor(config: NylasConfig) { + // ... existing code + this.{{RESOURCE_NAME_LC}}s = new {{RESOURCE_NAME}}s(this.apiClient); + } +} +``` + +#### 4. Add Tests +- Create a new test file `tests/resources/{{RESOURCE_NAME_LC}}.test.ts` +- Write tests for each method in the new resource class +- Use mocking to simulate `apiClient` behavior +- Test all API endpoints and parameter combinations + +## Rule 2: Adding a New Endpoint to an Existing Resource + +### Description +User wants to add a new endpoint to an existing API resource (e.g., adding 'send RSVP' to Events). + +### Conditions +- Matches files: `src/resources/` or `src/models/` TypeScript files +- Code selection matches: Case-insensitive phrases like "add endpoint", "new method" + +### Instructions + +#### 1. Define/Update Models +- Open `src/models/{{RESOURCE_NAME_LC}}.ts` +- Add or update TypeScript interfaces/types for: + - Request bodies with proper types and documentation + - Query parameters with proper types and documentation + - Response objects (if unique) +- Examples: + ```typescript + /** + * Interface for the {{NEW_ENDPOINT_NAME}} request + */ + export interface {{RESOURCE_NAME}}{{NEW_ENDPOINT_NAME}}Request { + // Add properties needed for this endpoint + } + + /** + * Interface for the {{NEW_ENDPOINT_NAME}} query parameters + */ + export interface {{RESOURCE_NAME}}{{NEW_ENDPOINT_NAME}}QueryParams { + // Add query parameters needed for this endpoint + } + ``` + +#### 2. Add Method to Resource Class +- Open `src/resources/{{RESOURCE_NAME_LC}}.ts` +- Define an interface for the method parameters: + ```typescript + /** + * @property identifier The identifier of the grant to act upon + * @property {{RESOURCE_NAME_LC}}Id The id of the {{RESOURCE_NAME}} to act upon + * @property requestBody The request body for the {{NEW_ENDPOINT_NAME}} action + * @property queryParams The query parameters for the request + */ + interface {{RESOURCE_NAME}}{{NEW_ENDPOINT_NAME}}Params { + identifier: string; + {{RESOURCE_NAME_LC}}Id: string; + requestBody: {{RESOURCE_NAME}}{{NEW_ENDPOINT_NAME}}Request; + queryParams?: {{RESOURCE_NAME}}{{NEW_ENDPOINT_NAME}}QueryParams; + } + ``` +- Add a new public method to the `{{RESOURCE_NAME}}` class: + ```typescript + /** + * [Description of what the method does] + * @return [Description of what the method returns] + */ + public {{NEW_ENDPOINT_NAME}}({ + identifier, + {{RESOURCE_NAME_LC}}Id, + requestBody, + queryParams, + overrides, + }: {{RESOURCE_NAME}}{{NEW_ENDPOINT_NAME}}Params & Overrides): Promise> { + return super._create({ // or _update, _find, etc. depending on the method + path: `/v3/grants/${identifier}/{{RESOURCE_NAME_LC}}s/${{{RESOURCE_NAME_LC}}Id}/{{NEW_ENDPOINT_PATH}}`, + requestBody, + queryParams, + overrides, + }); + } + ``` + +#### 3. Add Tests +- Open `tests/resources/{{RESOURCE_NAME_LC}}.test.ts` +- Add new tests for the method: + ```typescript + describe('{{NEW_ENDPOINT_NAME}}', () => { + it('should call the API client with the correct parameters', async () => { + // Setup test data + const mockResponse = { /* mock response data */ }; + const requestBody = { /* request body */ }; + const queryParams = { /* query params */ }; + + // Mock client request + (apiClient.request as jest.Mock).mockResolvedValue(mockResponse); + + // Call the method + const result = await {{RESOURCE_NAME_LC}}.{{NEW_ENDPOINT_NAME}}({ + identifier: 'grant-id', + {{RESOURCE_NAME_LC}}Id: '{{RESOURCE_NAME_LC}}-id', + requestBody, + queryParams, + }); + + // Assertions + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', // or appropriate method + path: '/v3/grants/grant-id/{{RESOURCE_NAME_LC}}s/{{RESOURCE_NAME_LC}}-id/{{NEW_ENDPOINT_PATH}}', + body: requestBody, + queryParams, + }); + expect(result).toEqual(mockResponse); + }); + + // Add more test cases for error scenarios, edge cases, etc. + }); + ``` + +## Rule 3: Updating an Existing Endpoint + +### Description +User wants to modify an existing API endpoint (e.g., change parameters, update response). + +### Conditions +- Matches files: `src/resources/` or `src/models/` TypeScript files +- Code selection matches: Case-insensitive phrases like "update", "modify", "change" + +### Instructions + +#### 1. Update Models +- Open `src/models/{{RESOURCE_NAME_LC}}.ts` +- Identify the interfaces/types that need to be updated: + ```typescript + // Example: Add new properties or modify existing ones + export interface {{RESOURCE_NAME}} { + // ... existing properties + newProperty?: string; // Add new optional property + updatedProperty: NewType; // Change type of an existing property + } + + // Example: Add new request parameters or modify existing ones + export interface Create{{RESOURCE_NAME}}Request { + // ... existing properties + newParameter?: string; // Add new parameter + } + ``` + +#### 2. Update Resource Method +- Open `src/resources/{{RESOURCE_NAME_LC}}.ts` +- Locate the method that needs to be updated +- Update parameter interface if needed: + ```typescript + interface Update{{RESOURCE_NAME}}Params { + // ... existing properties + newParameter?: string; // Add new parameter if needed + } + ``` +- Update method implementation if needed: + ```typescript + public update({ + identifier, + {{RESOURCE_NAME_LC}}Id, + requestBody, + newParameter, // Add new parameter if needed + overrides, + }: Update{{RESOURCE_NAME}}Params & Overrides): Promise> { + // Update implementation if needed + return super._update({ + path: `/v3/grants/${identifier}/{{RESOURCE_NAME_LC}}s/${{{RESOURCE_NAME_LC}}Id}`, + requestBody, + queryParams: { newQueryParam: newParameter }, // Add if needed + overrides, + }); + } + ``` + +#### 3. Update Tests +- Open `tests/resources/{{RESOURCE_NAME_LC}}.test.ts` +- Update existing tests to account for changes +- Add new tests for new functionality: + ```typescript + it('should handle new parameters correctly', async () => { + // Test specific new parameter handling + const mockResponse = { /* mock response data */ }; + const requestBody = { + /* request body with new properties */ + newProperty: 'value', + }; + + (apiClient.request as jest.Mock).mockResolvedValue(mockResponse); + + const result = await {{RESOURCE_NAME_LC}}.update({ + identifier: 'grant-id', + {{RESOURCE_NAME_LC}}Id: '{{RESOURCE_NAME_LC}}-id', + requestBody, + newParameter: 'value', // New parameter + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/v3/grants/grant-id/{{RESOURCE_NAME_LC}}s/{{RESOURCE_NAME_LC}}-id', + body: requestBody, + queryParams: { + newQueryParam: 'value', // New query parameter + }, + }); + expect(result).toEqual(mockResponse); + }); + ``` + +## Rule 4: SDK Model Structure Reference + +### Model Organization + +- `src/models/`: Contains all TypeScript interfaces and types for the API + - Each resource has its own file (e.g., `contacts.ts`, `events.ts`) + - Common response types in `response.ts` + - Error types in `error.ts` + - Common query parameter types in `listQueryParams.ts` + +### Standard Model Patterns + +#### Resource Models +- Main resource model named after the resource (`Contact`, `Event`, etc.) +- Always includes `id`, `grantId`, and `object` properties +- All models should use proper JSDoc comments + +```typescript +/** + * Interface representing a Nylas {{RESOURCE_NAME}} object. + */ +export interface {{RESOURCE_NAME}} { + id: string; + grantId: string; + object: '{{RESOURCE_NAME_LC}}'; + // Resource-specific properties +} +``` + +#### Request/Response Models +- Request models should be suffixed with `Request` (e.g., `CreateContactRequest`) +- Query parameter models should be suffixed with `QueryParams` (e.g., `ListContactQueryParams`) +- Response models should use the standard `NylasResponse` or `NylasListResponse` types + +```typescript +/** + * Interface for creating a {{RESOURCE_NAME_LC}}. + */ +export type Create{{RESOURCE_NAME}}Request = { + // Properties needed for creation +}; + +/** + * Interface representing the query parameters for listing {{RESOURCE_NAME_LC}}s. + */ +export interface List{{RESOURCE_NAME}}QueryParams extends ListQueryParams { + // Resource-specific query parameters +} +``` + +#### Response Handling +- For single-item responses: `NylasResponse<{{RESOURCE_NAME}}>` +- For list responses: `NylasListResponse<{{RESOURCE_NAME}}>` +- For paginated list responses in resource classes: `AsyncListResponse>` +- For simple acknowledgement responses: `NylasBaseResponse` + +### Best Practices for Models + +- Keep models focused and cohesive +- Use optional properties (`?`) for fields that may not always be present +- Use proper TypeScript typing (avoid `any` when possible) +- Document all properties with JSDoc comments +- For complex structures, compose from smaller interfaces +- Reuse common patterns and types across resources +- Export all models from their respective files and from `index.ts` +- Maintain consistency with existing model patterns +- Use camelCase for all model properties +- Group related properties together in interfaces \ No newline at end of file diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..c7d08e78 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +node_modules +lib +examples +docs diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index f83543cd..00000000 --- a/.eslintrc +++ /dev/null @@ -1,22 +0,0 @@ -{ - "env": { - "es6": true, - "jest": true - }, - "extends": [ - "prettier", - ], - "plugins": [ - "prettier" - ], - "rules": { - "prettier/prettier": ["error", { - "singleQuote": true, - "trailingComma": "es5" - }], - "prefer-const": "warn", - }, - "parserOptions": { - "sourceType": "module" - } -} diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..8f630b6d --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,46 @@ +module.exports = { + env: { + es6: true, + node: true, + jest: true, + }, + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 2021, + sourceType: 'module', + }, + plugins: ['@typescript-eslint', 'eslint-plugin-import'], + extends: [ + 'eslint:recommended', + 'prettier', + 'plugin:@typescript-eslint/eslint-recommended', + 'plugin:@typescript-eslint/recommended', + ], + rules: { + 'no-console': ['error', { allow: ['warn', 'error', 'time'] }], + '@typescript-eslint/no-var-requires': 0, + '@typescript-eslint/no-unused-vars': [ + 'error', + { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }, + ], + '@typescript-eslint/no-empty-function': 0, + '@typescript-eslint/no-explicit-any': 0, + '@typescript-eslint/camelcase': [ + 'error', + { properties: 'never', ignoreDestructuring: true }, + ], + 'no-undef': 'error', + 'import/extensions': ['error', 'ignorePackages'], + }, + settings: { + 'import/extensions': ['.js'], + }, + overrides: [ + { + files: ['*.spec.ts', '*.test.ts', 'tests/**/*.ts'], + rules: { + 'import/extensions': 'off', + }, + }, + ], +}; diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..6918ccc7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,26 @@ +--- +name: Bug report +about: Report a bug or issue to help us improve +title: '' +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Some steps involved to reproduce the bug and any code samples you can share. +``` +// Helps us with reproducing the error :) +``` + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**SDK Version:** +Providing the SDK version can help with the reproduction of the issue and to know if a change could have broken something. + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..11fc491e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/clubhouse.yml b/.github/workflows/clubhouse.yml new file mode 100644 index 00000000..519da60c --- /dev/null +++ b/.github/workflows/clubhouse.yml @@ -0,0 +1,61 @@ +name: Linked Clubhouse Story +on: + pull_request: + types: [opened, closed, labeled] + +jobs: + clubhouse: + runs-on: ubuntu-latest + if: ${{ github.event.pull_request.draft == false }} + steps: + - uses: singingwolfboy/create-linked-clubhouse-story@v1.7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + clubhouse-token: ${{ secrets.CLUBHOUSE_TOKEN }} + project-name: Node SDK + opened-state-name: Reviewing + merged-state-name: Done + closed-state-name: Won't Pursue + ignored-users: dependabot + label-iteration-group-map: | + { + "Team Citadel": { + "groupId": "5fb68610-2b02-4e26-a5e1-f2ec20d6e176", + "excludeName": "Backlog" + } + } + user-map: | + { + "AaronDDM": "5f622398-b918-4e0a-8f87-495cbfb63682", + "BahramKouhestani: "5fa31422-7ab3-46c6-89ef-fbde9120a640", + "bengotow": "5d659cde-7f97-4da0-88c5-50c5c0c0053e", + "BenLloydPearson": "5d260325-a60e-4a03-99ee-3b614b1cedfd", + "benjaminwhtan": "5d89014d-8fda-49a1-8f8c-ce8c72cd1b96", + "billwjo": "5d2372c8-2f19-4409-a86c-97462c626d10", + "chorrell": "5f0dd62e-bd28-4eac-aec6-526c7a96b19c", + "danielliu": "607ddce2-652a-48a5-ae5f-0d42811ede81", + "davidting": "5e0e4200-3c79-4755-aab9-a4a16f8ddcf1", + "dominicj-nylas": "5e947e4e-d40e-477e-85d0-21f2b323c069", + "dtom90": "604fa1a5-f5ce-4c4e-908a-3a87c15db98d", + "aiirwiick": "60ab71f2-b85d-4317-9018-df3e48e89dab", + "sammywen": "607da402-9bee-4ca4-80d5-b8f833840732", + "jesmarcannao": "5e441a1c-a7b5-40c8-8634-ef9f0bcce5c1", + "jhatch28": "5d0a9c4e-48a5-419b-a9b4-68fa672b96c9", + "jieunsharonkim": "5d03a446-3f70-4747-8bfd-af099463b4a4", + "jonafato": "5e9f1493-a9b5-436f-9c8b-c933631bbf8a", + "jseller": "604625a6-1d18-428e-a825-09233513387a", + "khamidou": "5d0ab326-3910-4ae8-b2f2-37bf2465d296", + "kdoby": "5d769b41-2f29-42a0-ac47-73ad93682db4", + "lkaileh": "5d23983d-49b8-4481-a947-87ff2bc56066", + "Gerdie": "5e1d52c6-7e82-4015-ab26-a59c357cfd4a", + "maxwell-schwartz": "5d48497f-0016-46f1-9a3c-149806c3599a", + "mypile": "60465c2b-1a8b-42dc-a467-d6d084d8f4f8", + "pfista": "5d0d0771-c540-4206-94b1-47e9fbef88b0", + "pengfeiye": "5d1533b0-fa0e-4557-a6fc-80e97923d817", + "peterdemarzio": "5e138a88-26cf-4814-b9fe-0c1f0ddcb8c0", + "philrenaud": "5e9f7a55-876b-453f-b137-b8677727fb81", + "spang": "5d13f026-00a6-4a9c-ba80-0048f43427f4", + "yusra-ahmed": "5d237850-e39b-4e75-8c52-89003602a59a", + "nylas-marcus": "5fc55708-44b9-41e8-aec0-004c3af90e69", + "mrashed-dev": "609964df-eb6c-4d74-8799-e33b7d503a09" + } diff --git a/.github/workflows/pull-reqeust.yml b/.github/workflows/pull-reqeust.yml new file mode 100644 index 00000000..4ef4fdbb --- /dev/null +++ b/.github/workflows/pull-reqeust.yml @@ -0,0 +1,41 @@ +name: Pull Request +on: + # Trigger the workflow on push or pull request, + # but only for the main branch + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + checks: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [ 18.x, 20.x, 24.x, 25.x ] + name: Nodejs ${{ matrix.node-version }} + steps: + - uses: actions/checkout@v2 + - name: Setup Nodejs ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + + - name: Install dependencies and build + run: npm install + + - name: Run lint checks + run: npm run lint:ci + + - name: Run prettier checks + run: npm run lint:prettier:check + + - name: Run tests + run: npm run test:coverage + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/sdk-reference.yaml b/.github/workflows/sdk-reference.yaml new file mode 100644 index 00000000..0a70a568 --- /dev/null +++ b/.github/workflows/sdk-reference.yaml @@ -0,0 +1,43 @@ +name: sdk-reference + +on: + push: + branches: + - main + pull_request: + +jobs: + docs: + runs-on: ubuntu-latest + environment: + name: sdk-reference + url: ${{ steps.deploy.outputs.url }} + steps: + - uses: actions/checkout@v2 + - name: Setup Nodejs + uses: actions/setup-node@v1 + with: + node-version: 18.x + - name: Install dependencies and build + run: npm install + - name: Build docs + run: npm run build:docs + - name: Set env BRANCH + run: echo "BRANCH=$(echo $GITHUB_REF | cut -d'/' -f 3)" >> $GITHUB_ENV + - name: Set env CLOUDFLARE_BRANCH + run: | + if [[ $BRANCH == 'main' && $GITHUB_EVENT_NAME == 'push' ]]; then + echo "CLOUDFLARE_BRANCH=main" >> "$GITHUB_ENV" + else + echo "CLOUDFLARE_BRANCH=$BRANCH" >> "$GITHUB_ENV" + fi + - name: Publish to Cloudflare Pages + uses: cloudflare/pages-action@v1 + id: deploy + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + projectName: nylas-nodejs-sdk-reference + directory: docs + wranglerVersion: "3" + branch: ${{ env.CLOUDFLARE_BRANCH }} diff --git a/.gitignore b/.gitignore index 0ce4bf9a..79aca361 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,8 @@ _SpecRunner.html tags CTAGS .idea +coverage +docs +cjs +esm +.env \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..7b52c4b2 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +node_modules +lib +docs \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..c7b3df0b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "semi": true, + "trailingComma": "es5", + "singleQuote": true, + "printWidth": 80 +} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 35dbd514..00000000 --- a/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: node_js -node_js: - - "8" - -script: - - yarn lint - - yarn build - - yarn test diff --git a/CHANGELOG.md b/CHANGELOG.md index 4521cdf8..f26d9480 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,57 +1,810 @@ # Changelog -### 4.2.1 / 2018-03-08 - -* Add status code to error to allow it to bubble up from API request errors -* Improvements to example/sample-app -* Move version mismatch warning to only print if both API and SDK versions are present. This will decrease unhelpful spamming. -* Add linkedAt to the account model -* Parse response into JSON if it is a string. - -### 4.2.0 / 2018-02-07 - -* Bump supported Nylas API version to 2.0 -* Add support for new contact fields and functionality - - -### 4.1.0 / 2017-12-27 - -* Added variable for supported version of Nylas API - set to `1.0` and will be updated when the SDK supports later versions of the API -* Added warnings when the version of the API that the SDK supports differs from the version of the API that the application is using - -### 4.0.0 / 2017-11-06 - -* Converted Coffeescript to ES6 -* Added ESLint and Prettier for linting -* Updated test framework from Jasmine 1.0 to Jest -* Changed Travis to run Node 8 and lint, build, and test code in CI -* Updated docs and example code -* Added `search()` for messages and threads -* Added `upgrade()` and `downgrade()` for account management -* Added `getRaw()` for retrieving raw messages -* **BREAKING CHANGE**: Changed API for sending raw messages to use `draft.send()` instead of `Message.sendRaw()` -* Changed `list()` to override default `offset` with user’s -* **BREAKING CHANGE**: Changed models for `Contact`, `Draft`, `Event`, `File`, `Folder`, `Message`, and `Thread` to accurately reflect the attribute that the API returns -* Return headers correctly for `expanded` view for `Message` objects -* **BREAKING CHANGE**: Return `Message` object instead of `Draft` object after send -* Return sending failures for partial sends -* Return server errors for SMTP exceptions on send -* **BREAKING CHANGE**: Privatized `_range()`, `_getModel()`, and `_getModelCollection()` (not documented) -* **BREAKING CHANGE**: Removed `draft` attribute on `Message` and `Draft` objects, since the object type is already distinguished -* **BREAKING CHANGE**: Removed support for `Tag` objects, which has been deprecated, and instance methods on `Thread` for `Tag` changes -* **BREAKING CHANGE**: Removed support for `generateCursor()`, which has been deprecated -* **BREAKING CHANGE**: Removed support for the `trial` option for auth, which has been deprecated - -### 3.1.1 / 2017-10-06 - -* No longer throw an error after successful calls to `Message.sendRaw()` -* Add status to event model -* Don't require secret for `urlForAuthentication()`, allowing client-side usage without leaking or faking the app secret -* Catch rejected promises in some missing cases -* Emit `DeltaStream` retry status as an event -* Don't `console.log()`, ever (callers should instrument desired logging) -* Fix missing fields and typos in message and thread models - -### 3.0.0 / 2016-08-14 - -* Add support for `view=expanded` option. Now all methods on that hit the API can take querystring params as objects. Additionally, you can pass in `{expanded: true}` for convenience. -* **BREAKING CHANGE**: `DeltaStream` now also supports `view=expanded`, `exclude_types`, and `include_types`, as well as any arbitrary query string param. `Delta::startStream` now takes an object as a second argument for query string params, instead of an `exclude_types` array. + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [8.0.1] - 2026-01-23 + +### Added +- Add missing `originalStartTime` field to `Event` model for recurring event instances + +## [8.0.0] - 2025-12-12 + +### Added +- Migrated the SDK from `node-fetch` to the native Fetch API available in Node.js 18+. +- Removed the custom fetch wrapper abstraction. +- Updated Node.js engine requirements. +- Updated Folders.find method to support optional queryParams (includeHiddenFolders, select). +- Support for query parameters (`includeHiddenFolders`, `select`) in `folders.find` method ([#685](https://github.com/nylas/nylas-nodejs/issues/685)). + +### Breaking change +- Requires Node.js 18+. Support for Node 16 has been dropped. + +## [7.13.3] - 2025-10-10 + +### Fixed +- Make `conferencing` property optional in `Event` model to handle events without conferencing details ([#678](https://github.com/nylas/nylas-nodejs/issues/678)) + +## [7.13.2] - 2025-10-01 + +### Fixed +- Make `Participant.email` optional in `Event` model to match API behavior ([#670](https://github.com/nylas/nylas-nodejs/issues/670)) +- Updated `ListGrantsQueryParams.sortBy` values to match API expectations (`'created_at' | 'updated_at'` instead of `'createdAt' | 'updatedAt'`) + +## [7.13.1] - 2025-09-18 + +### Fixed +- Broken CJS build outputs resulted in a "TypeError: Nylas is not a constructor" error + +## [7.13.0] - 2025-09-01 + +### Added +- Support `isPlaintext` boolean for messages send and drafts create requests +- Expose raw response headers on all responses via non-enumerable `rawHeaders` while keeping existing `headers` camelCased + +## [7.12.0] - 2025-08-01 + +### Changed +- Upgraded node-fetch from v2 to v3 for better ESM support and compatibility with edge environments + +### Fixed +- Fixed test expectations for file attachment sizes and content types to match actual implementation behavior +- Updated Jest configuration to properly handle ESM modules from node-fetch v3 +- Removed incompatible AbortSignal import from node-fetch externals (now uses native Node.js AbortSignal) + + +## [7.11.0] - 2025-06-23 + +### Added +- Support for new message `fields` query parameter values: `include_tracking_options` and `raw_mime` +- Support for `trackingOptions` property in Message responses when using `fields=include_tracking_options` +- Support for `rawMime` property in Message responses when using `fields=raw_mime` +- `MessageTrackingOptions` interface for tracking message opens, thread replies, link clicks, and custom labels +- Support for `includeHiddenFolders` query parameter in folders list endpoint for Microsoft accounts +- Support for `singleLevel` query parameter in `ListFolderQueryParams` for Microsoft accounts to control folder hierarchy traversal + +### Fixed +- Fixed 3MB payload size limit to consider total request size (message body + attachments) instead of just attachment size when determining whether to use multipart/form-data encoding + +## [7.10.0] - 2025-05-27 + +### Added +- Support for 'zoom' as a provider type in Auth module +- Support for `tentativeAsBusy` parameter in FreeBusy requests to control how tentative events are treated + +### Fixed +- Event status type to use 'maybe' instead of 'tentative' in Event interface to match API documentation +- Missing `/cancel` suffix in Notetaker API endpoint +- URL encoding for API path components to properly handle special characters + +## [7.9.0] - 2025-04-30 + +### Added +- Support for Notetaker API endpoints +- Notetaker settings to calendar and event models +- Support for `tentativeAsBusy` parameter in availability and event listing + +### Deprecated +- Providing timeout in milliseconds via request overrides - please use seconds instead + +## [7.8.0] - 2025-03-03 + +### Added +- Support for `listImportEvents` method to import events from a specified calendar within a given time frame +- Support for returning all response headers in node sdk for error responses + +### Fixed +- Grants support for queryParams in list method first parameter + +## [7.7.4] - 2025-01-23 + +### Fixed +- `any_email` was not transformed to a comma delimited list for messages.list + +## [7.7.3] - 2025-01-23 + +### Changed +- `latestMessageReceivedDate` & `latestMessageSentDate` to be optional on threads model + +### Removed +- `createdAt` field from message model + +### Fixed +- Issue where timeout was not being respected when overriding the timeout in the request options +- Issue where query params with array values were not being transformed into comma-delimited strings +- Transform anyEmail array into comma-delimited any_email parameter in threads list + +## [7.7.2] - 2024-12-02 + +### Fixed +- `credentials` resource to use correct endpoint + +## [7.7.1] - 2024-11-25 + +### Fixed +- Query parameters for array values + +## [7.7.0] - 2024-11-14 + +### Added +- Support for Scheduling API + +### Fixed +- Issue where inline attachments > 3Mb were not sent correctly + +## [7.6.2] - 2024-10-31 + +### Added +- Missing `select` field on query params +- Missing `name` field on grant model +- Missing `masterEventId` on Event model + +### Fixed +- Webhook rotate secret calling the wrong endpoint + +## [7.6.1] - 2024-10-30 + +### Added +- Support for filtering events by masterEventID +- Support for gzip compression + +## [7.6.0] - 2024-10-18 + +### Added +- Support for filtering events by attendee email +- Buffer support for file attachments +- New webhook trigger types +- EWS as a provider + +### Changed +- Rotate secret endpoint from being a PUT to a POST call + +### Fixed +- Issue where crypto import was causing downstream Jest incompatibilities +- FormData import compatibility issues with ESM + +### Removed +- eslint-plugin-import from production dependencies + +## [7.5.2] - 2024-07-12 + +### Fixed +- Issue where metadata was being incorrectly modified before being sent to the API + +## [7.5.1] - 2024-07-09 + +### Added +- Collective availability method + +### Fixed +- Crash when timeout encountered + +### Security +- Bump `braces` sub-dependency from 3.0.2 to 3.0.3 + +## [7.5.0] - 2024-05-17 + +### Added +- Support for filtering by event type when listing events +- Support for filtering a list of folders + +### Fixed +- Query parameters not being formatted properly + +## [7.4.0] - 2024-05-01 + +### Added +- Support for `provider` field in code exchange response +- Clean messages support + +### Fixed +- Issue where attachments < 3mb were not being encoded correctly + +## [7.3.0] - 2024-04-15 + +### Added +- Response type to `sendRsvp` +- Support for adding custom headers to outgoing requests +- Support for custom headers field for drafts and messages +- Support for setting `include_grant_scopes` for auth url generation + +### Changed +- Incorrect `type` field in `When` models to `object` + +### Fixed +- Inaccuracy in `ReminderOverride` model + +## [7.2.1] - 2024-03-05 + +### Added +- Default timeout to match API (90 seconds) + +### Changed +- Improved message sending and draft create/update performance + +### Fixed +- Serialization/deserialization of keys with numbers in them + +## [7.2.0] - 2024-02-27 + +### Added +- Support for `roundTo` field in availability response model +- Support for `attributes` field in folder model +- Support for icloud as an auth provider + +### Fixed +- Query params not showing up in method parameters for finding a message +- Missing fields in message models + +### Removed +- Unnecessary `clientId` from detectProvider params + +## [7.1.0] - 2024-02-12 + +### Added +- Support for `/v3/connect/tokeninfo` endpoint +- Models can now directly be imported from the top-level `nylas` package + +### Fixed +- Inaccuracies in event and webhook models + +## [7.0.0] - 2024-02-05 + +### Added +- Support for both ES6 and CommonJS module systems +- Models for all API resources and endpoints, for all HTTP methods to reduce confusion on which fields are available for each endpoint +- Error classes for the different API errors as well as SDK-specific errors + +### Changed +- **BREAKING**: Node SDK v7 supports the Nylas API v3 exclusively, dropping support for any endpoints that are not available in v3 +- **BREAKING**: Convert `Nylas` class from a static to a non-static class +- **BREAKING**: Officially support minimum Node 16 +- **BREAKING**: Dropped the use of 'Collections' in favor of 'Resources' +- **BREAKING**: Removed all REST calls from models and moved them directly into resources +- Rewritten the majority of SDK to be more modular and efficient +- Removed the use of custom strings for serialization and deserialization, now automatically converting to camelCase and from the API's snake_case + +### Removed +- **BREAKING**: Local Webhook development support is removed due to incompatibility + +## [6.8.0] - 2023-02-03 + +### Added +- Local webhook testing support +- `hideParticipants` field to `Event` + +## [6.7.0] - 2023-01-18 + +### Added +- Support for rate limit errors +- responseType to AuthenticateUrlConfig +- New attributes for Event webhook notifications + +### Changed +- Event `visibility` field to be writeable + +### Security +- Bump `decode-uri-component` sub-dependency from 0.2.0 to 0.2.2 +- Bump `qs` sub-dependency from 6.5.2 to 6.5.3 +- Bump `json5` sub-dependency from 2.1.0 to 2.2.3 +- Bump `minimatch` sub-dependency from 3.0.4 to 3.1.2 + +## [6.6.1] - 2022-10-21 + +### Fixed +- Calendar color implementation + +## [6.6.0] - 2022-10-14 + +### Added +- Additional fields for job status webhook notifications +- Support for calendar colors (for Microsoft calendars) +- Support for event reminders + +### Fixed +- Typo in `SchedulerBooking.calendarInviteToGuests` attribute + +### Security +- Bump `minimist` sub-dependency from 1.2.5 to 1.2.6 + +## [6.5.1] - 2022-09-16 + +### Added +- Additional `Event` fields + +### Fixed +- Issue with `EventParticipant` not sending status on new event creation + +## [6.5.0] - 2022-07-29 + +### Added +- `metadata` field to `JobStatus` +- `interval_minutes` field in Scheduler booking config + +### Fixed +- `Event.originalStartTime` type to be `Date` +- `SchedulerBookingOpeningHours.accountId` deserialization +- Json value for `confirmationEmailToHost` in `SchedulerBooking` + +## [6.4.2] - 2022-06-14 + +### Added +- `Message.save()` functionality for updating existing messages +- Missing `reminderMinutes` field in `Event` + +## [6.4.1] - 2022-06-06 + +### Fixed +- Issue where API response data was being lost +- Incorrect tunnel index number in webhook example + +## [6.4.0] - 2022-05-10 + +### Added +- Support for collective and group events + +### Fixed +- `fileIdsToAttach` field not being set when initializing a `Draft` + +## [6.3.2] - 2022-05-04 + +### Added +- Missing `fileIdsToAttach` field in `DraftProperties` + +### Fixed +- JSON parse error when using `CalendarRestfulModelCollection.freeBusy` +- Base URL not being set for `SchedulerRestfulModelCollection` functions + +## [6.3.1] - 2022-04-22 + +### Added +- Missing order and emails field in calendar availability + +### Fixed +- Issue where passing in an array of one for `MessageRestfulModelCollection.findMultiple` throws an error + +## [6.3.0] - 2022-04-14 + +### Added +- Support for revoking a single access token +- Improved Outbox job status support +- Support Setting Redirect On Error in Authenticate URL Config + +### Fixed +- Issue where an empty response body could trigger a JSON deserialization error + +### Removed +- Usage of unreliable `node-fetch response.size` + +## [6.2.2] - 2022-04-01 + +### Added +- Allow getting raw message by message ID directly instead of needing to fetch the message first +- New `authenticationType` field in `ManagementAccount` + +### Fixed +- JSON error thrown when Nylas API returns non-JSON error payload + +## [6.2.1] - 2022-03-25 + +### Added +- Enable Nylas API v2.5 support + +### Fixed +- Circular dependency issue in `Attribute` +- `SchedulerBookingOpeningHoursProperties.days` and add missing fields to Scheduler models + +### Security +- Bump `node-fetch` dependency from 2.6.1 to 2.6.7 +- Bump `ajv` sub-dependency from 6.10.2 to 6.12.6 + +## [6.2.0] - 2022-02-04 + +### Added +- Support for returning multiple messages by a list of message IDs +- New field in `Draft` for adding files by file IDs +- Webhook Notification models +- Improved `Delta` support: added `Delta` model and two new methods; `since` and `longpoll` + +### Fixed +- Virtual Calendar logic and serialization + +## [6.1.0] - 2022-01-28 + +### Added +- Support for `Event` to ICS +- `comment` and `phoneNumber` fields to `EventParticipant` +- Support for `calendar` field in free-busy, availability, and consecutive availability queries + +### Fixed +- Issue where properties of `Model` type were sending read-only attributes to the API + +## [6.0.0] - 2022-01-12 + +### Added +- Introduction of interfaces that accompany models to improve experience when instantiating API models and provides better insight on "required" fields +- Several `Contact` fields that took an object as a value now take a corresponding `Contact` subclass type +- New `FreeBusy` type for `CalendarRestfulModelCollection.freeBusy()` return value +- New `CalendarAvailability` type for `CalendarRestfulModelCollection.availability()` return value +- New `CalendarConsecutiveAvailability` type for `CalendarRestfulModelCollection.consecutiveAvailability()` return value +- New `AuthorizationCode` type for `Connect.authorize()` return value +- New `AccessToken` type for `Nylas.exchangeCodeForToken()` return value +- New `ApplicationDetail` type for `Nylas.application()` return and parameter types +- Lots of new models are introduced, almost all API objects are represented as a model in the SDK now +- Introduction of `Enum` types + +### Changed +- **BREAKING**: Refactored `RestfulModel` and `RestfulModelCollection`, introduced `Model` and `ModelCollection` superclass for models that do not directly interact with the Nylas API +- **BREAKING**: Applied missing variable and return types, and applied stricter typing to improve deserialization and to adhere Typescript best practice +- **BREAKING**: `Event.when` is now of `When` type +- **BREAKING**: All `Event` fields for participants are now of `EventParticipant` type +- **BREAKING**: `NeuralMessageOptions` is now a `Model` class instead of an interface type +- **BREAKING**: `CalendarRestfulModelCollection.freeBusy()` now returns a (new) `FreeBusy` type instead of a JSON +- **BREAKING**: `CalendarRestfulModelCollection.availability()` now returns a (new) `CalendarAvailability` type instead of a JSON +- **BREAKING**: `CalendarRestfulModelCollection.consecutiveAvailability()` now returns a (new) `CalendarConsecutiveAvailability` type instead of a JSON +- **BREAKING**: `Connect.authorize()` now takes in a parameter of `VirtualCalendarProperties | NativeAuthenticationProperties` type (new) instead of an object and returns `AuthorizationCode` type (new) instead of a JSON +- **BREAKING**: `Connect.token()` now returns an `Account` type instead of a JSON +- **BREAKING**: `Contact`, `EventConferencing`, and `Folder` are now default exports +- **BREAKING**: `Nylas` has stricter parameters and introduction of defined return types +- **BREAKING**: `Nylas.exchangeCodeForToken()` now returns an `AccessToken` type that's a representation of the full API response as opposed to just the access token string +- **BREAKING**: `Nylas.application()` takes `ApplicationDetailProperties` type and returns an `ApplicationDetail` type + +### Removed +- **BREAKING**: `RestfulModelCollection.build()` as it does not allow for proper property and type hinting in favor of instantiating via `new Model()` +- **BREAKING**: `Connect.newAccount()` as it had no functionality +- **BREAKING**: `File.metadata()` as it doesn't appear any different than making a `NylasConnection.files().find()` call + +## [5.10.3] - 2022-01-04 + +### Fixed +- Prevent `Event` objects from sending an empty list of notifications when not set, causing errors for recurring events + +## [5.10.3] - 2021-12-16 + +### Added +- Missing `provider` option for `urlForAuthentication` +- Job status improvements + +## [5.10.2] - 2021-12-03 + +### Fixed +- Scheduler and Component types +- Component sending unmodifiable fields during update +- Bug where updating an event resulted in an API error + +## [5.10.1] - 2021-11-22 + +### Fixed +- Bug where booking a valid timeslot resulted in an API error + +## [5.10.0] - 2021-11-18 + +### Added +- Support for Event notifications +- Support for remaining Scheduler endpoints +- Metadata support for `Calendar`, `Message` and `ManagementAccount` + +## [5.9.0] - 2021-09-24 + +### Added +- Component CRUD Support +- Scheduler support + +## [5.8.0] - 2021-09-16 + +### Added +- Support for consecutive availability + +### Fixed +- Issue where JSON.stringify would omit read-only values +- Webhook example throwing error if body is not a raw body +- Readonly calendar attributes being sent for POST and PUT calls + +## [5.7.0] - 2021-08-18 + +### Added +- Missing fields for recurring events +- Support for conferencing + +### Fixed +- Minor issues with Neural API implementation +- Not rejecting uncaught errors during requests + +## [5.6.0] - 2021-07-14 + +### Added +- Support for `/calendars/availability` endpoint +- Support for the Neural API +- Linting, enabled and set up eslint and prettier + +### Fixed +- Jest test cases not respecting async methods +- Issue with parsing raw MIME emails + +## [5.5.1] - 2021-06-24 + +### Fixed +- Tracking object not being added to a pre-existing `draft` object +- `undefined` response when downloading file + +### Removed +- `request` dependency and related import statements + +## [5.5.0] - 2021-06-09 + +### Added +- Custom error class `NylasApiError` to add more error details returned from the API +- Support for read only fields +- Enable Nylas API v2.2 support + +### Changed +- Replaced deprecated `request` library with `node-fetch` + +### Fixed +- Bug where saving a `draft` object with an undefined `filesIds` would throw an error +- Typings for classes that extend `RestfulModelCollection` or `RestfulModelInstance` + +## [5.4.0] - 2021-05-21 + +### Added +- `metadata` field in the Event model to support new Event metadata feature +- Support for filtering `metadata` using `metadata_key`, `metadata_value`, and `metadata_pair` + +### Security +- Updated dependencies `lodash`, `y18n`, and `pug` to the latest stable version + +## [5.3.3] - 2021-03-26 + +### Changed +- Pass error message from the API to the SDK user +- Migrate `delta` streaming to `node-fetch` +- Migrate `exchangeCodeForToken` to `node-fetch` + +## [5.3.2] - 2021-01-11 + +### Fixed +- Typing fixes to `nylas.drafts` and other `RestfulModelCollections` + +## [5.3.1] - 2020-11-20 + +### Added +- Update readme with syntax highlighting + +### Changed +- Drop async dependency for smaller package fingerprint. Async is replaced with promises + +### Removed +- Circular dependency in `nylas-connection.ts` + +## [5.3.0] - 2020-09-23 + +### Added +- `JobStatus` model and collection + +### Changed +- Refactor parameter ordering in `find()` and `draft.send()` methods [backwards compatible] + +### Fixed +- Bug where setting `event.start` and `event.end` did not set `event.when` if `event.when` didn't exist + +## [5.2.0] - 2020-07-27 + +### Added +- Implement support for GET /contacts/groups +- Support GET /resources +- Support POST, PUT and DELETE for calendars, and add location, timezone and isPrimary attributes +- `object` attribute to `event.when` object + +### Changed +- Update lodash import + +## [5.1.0] - 2020-06-04 + +### Added +- Support recurring events +- Implement list & update application details endpoints +- Support free-busy endpoint on Calendars collection + +### Fixed +- Bug which was overwriting properties on message objects + +## [5.0.0] - 2020-05-07 + +### Changed +- **BREAKING**: Officially support minimum Node 16 + +### Removed +- **BREAKING**: `appId` and `appSecret`. Please use `clientId` and `clientSecret` +- **BREAKING**: `Thread.folder`. Please use `Thread.folders` + +### Added +- Migrate to Typescript + +## [4.10.1] - 2020-05-06 + +### Fixed +- Update `exchangeCodeForToken` to reject when no `access_token` is returned +- Unhandled error when response is undefined +- Get contact picture request to correctly use callback, if provided + +## [4.10.0] - 2020-02-24 + +### Added +- iCalUID attribute to Event model +- Allow file streaming uploads + +### Changed +- Update SUPPORTED_API_VERSION to 2.1 +- Update Thread.folder to use Folder model, and rename to Thread.folders + +## [4.9.0] - 2020-01-24 + +### Added +- Update Thread participants to use EmailParticipant + +### Changed +- Remove error handling in /connect models + +### Security +- Bump handlebars version + +## [4.8.0] - 2019-10-09 + +### Added +- Support for `/connect/token` endpoint + +### Fixed +- Events so that they support all time subojects + +## [4.7.1] - 2019-09-18 + +### Added +- Support for `/connect/authorize` endpoint +- Improvements to example/webhooks + +### Changed +- Update formatting for DeprecationWarnings +- Update package-lock.json + +### Fixed +- Draft deletion bug + +## [4.7.0] - 2019-08-20 + +### Added +- Support for `/token-info` endpoint +- Webhooks CRUD functionality + +### Changed +- Update app id and app secret to client id and client secret + +## [4.6.2] - 2019-07-26 + +### Added +- contentDisposition to File +- emailAddress to ManagementAccount +- provider to ManagementAccount +- `groups` and `source` to contact attributes + +### Changed +- Update dependancies + +### Fixed +- Contact birthday type from date to string +- `emailAddresses` attribute in Contact model + +## [4.6.1] - 2019-07-10 + +### Added +- billingState to Account model +- Update webhooks example code + +### Fixed +- Error to string reassignment bug + +## [4.6.0] - 2019-06-20 + +### Added +- Enable link tracking + +## [4.5.0] - 2019-04-02 + +### Added +- Support for `/ip_addresses` endpoint + +## [4.4.0] - 2019-03-25 + +### Added +- Support for `revoke-all` endpoint + +## [4.3.0] - 2019-03-18 + +### Added +- X-Nylas-Client-Id header for HTTP requests + +## [4.2.3] - 2019-02-21 + +### Changed +- Replace Underscore with lodash +- Replace Bluebird promises with native promises +- Upgrade all other dependencies and devDependencies to latest versions +- Reduce package size by only including `lib` directory + +### Removed +- Drop unnecessary dependencies: express-session, clone + +## [4.2.2] - 2018-03-08 + +### Added +- Status code to error to allow it to bubble up from API request errors +- Improvements to example/sample-app +- linkedAt to the account model + +### Changed +- Move version mismatch warning to only print if both API and SDK versions are present. This will decrease unhelpful spamming +- Parse response into JSON if it is a string + +## [4.2.0] - 2018-02-07 + +### Added +- Support for new contact fields and functionality + +### Changed +- Bump supported Nylas API version to 2.0 + +## [4.1.0] - 2017-12-27 + +### Added +- Variable for supported version of Nylas API - set to `1.0` and will be updated when the SDK supports later versions of the API +- Warnings when the version of the API that the SDK supports differs from the version of the API that the application is using + +## [4.0.0] - 2017-11-06 + +### Added +- ESLint and Prettier for linting +- `search()` for messages and threads +- `upgrade()` and `downgrade()` for account management +- `getRaw()` for retrieving raw messages + +### Changed +- **BREAKING**: Converted Coffeescript to ES6 +- **BREAKING**: Updated test framework from Jasmine 1.0 to Jest +- **BREAKING**: Changed Travis to run Node 8 and lint, build, and test code in CI +- **BREAKING**: Updated docs and example code +- **BREAKING**: Changed API for sending raw messages to use `draft.send()` instead of `Message.sendRaw()` +- **BREAKING**: Changed models for `Contact`, `Draft`, `Event`, `File`, `Folder`, `Message`, and `Thread` to accurately reflect the attribute that the API returns +- **BREAKING**: Return `Message` object instead of `Draft` object after send +- **BREAKING**: Privatized `_range()`, `_getModel()`, and `_getModelCollection()` (not documented) +- Changed `list()` to override default `offset` with user's +- Return headers correctly for `expanded` view for `Message` objects +- Return sending failures for partial sends +- Return server errors for SMTP exceptions on send + +### Removed +- **BREAKING**: `draft` attribute on `Message` and `Draft` objects, since the object type is already distinguished +- **BREAKING**: Support for `Tag` objects, which has been deprecated, and instance methods on `Thread` for `Tag` changes +- **BREAKING**: Support for `generateCursor()`, which has been deprecated +- **BREAKING**: Support for the `trial` option for auth, which has been deprecated + +## [3.1.1] - 2017-10-06 + +### Added +- Status to event model +- Emit `DeltaStream` retry status as an event + +### Fixed +- No longer throw an error after successful calls to `Message.sendRaw()` +- Don't require secret for `urlForAuthentication()`, allowing client-side usage without leaking or faking the app secret +- Catch rejected promises in some missing cases +- Don't `console.log()`, ever (callers should instrument desired logging) +- Missing fields and typos in message and thread models + +## [3.0.0] - 2016-08-14 + +### Added +- Support for `view=expanded` option. Now all methods on that hit the API can take querystring params as objects. Additionally, you can pass in `{expanded: true}` for convenience + +### Changed +- **BREAKING**: `DeltaStream` now also supports `view=expanded`, `exclude_types`, and `include_types`, as well as any arbitrary query string param. `Delta::startStream` now takes an object as a second argument for query string params, instead of an `exclude_types` array diff --git a/Contributing.md b/Contributing.md new file mode 100644 index 00000000..97d469d2 --- /dev/null +++ b/Contributing.md @@ -0,0 +1,39 @@ +# Contribute to Nylas +πŸ‘πŸŽ‰ First off, thanks for taking the time to contribute! πŸŽ‰πŸ‘ + +The following is a set of guidelines for contributing to the Nylas Node SDK; these are guidelines, not rules, so please use your best judgement and feel free to propose changes to this document via pull request. + +# How to Ask a Question + +If you have a question about how to use the Node SDK, please [create an issue](https://github.com/nylas/nylas-nodejs/issues) and label it as a question. If you have more general questions about the Nylas Communications Platform, or the Nylas Email, Calendar, and Contacts API, please reach out to support@nylas.com to get help. + +# How To Contribute +## Report a Bug or Request a Feature + +If you encounter any bugs while using this software, or want to request a new feature or enhancement, please [create an issue](https://github.com/nylas/nylas-nodejs/issues) to report it, and make sure you add a label to indicate what type of issue it is. + +## Contribute Code + +Pull requests are welcome for bug fixes. If you want to implement something new, [please request a feature](https://github.com/nylas/nylas-nodejs/issues) first so we can discuss it. + +While writing your code contribution, make sure you test your changes by running + +`npm test` + +Our linter can be run with: + +`npm run lint` + +To use the package during local development, symlink the directory: + +`npm link` in the `nylas-nodejs` directory +`npm link nylas` in the directory with your code that uses the package + +Please ensure that your contributions don’t cause a decrease to test coverage. + +## Creating a Pull Request + +Please follow [best practices](https://github.com/trein/dev-best-practices/wiki/Git-Commit-Best-Practices) for creating git commits. When your code is ready to be submitted, you can [submit a pull request](https://help.github.com/articles/creating-a-pull-request/) to begin the code review process. + +All PRs from contributors that aren't employed by Nylas must contain the following text in the PR description: "I confirm that this contribution is made under the terms of the MIT license and that I have the authority necessary to make this contribution on behalf of its copyright owner." + diff --git a/README.md b/README.md index 0bb114db..549d9c89 100644 --- a/README.md +++ b/README.md @@ -1,533 +1,109 @@ -Nylas Node.js SDK [![Travis build status](https://travis-ci.org/nylas/nylas-nodejs.svg?branch=master)](https://travis-ci.org/nylas/nylas-nodejs) -====================== +
+ + Nylas + + +

Nylas Node.js SDK

+ +

+ The official Node.js SDK for the Nylas Communications Platform +

+ +

+ npm version + code coverage + downloads + license +

+ +

+ πŸ“– Documentation β€’ + πŸš€ Get Started β€’ + πŸ’‘ Examples β€’ + πŸ“š API Reference +

+
-Installation ------------- -Install the Nylas SDK: +
-`npm install nylas` or `yarn add nylas` +This is the GitHub repository for the Nylas Node SDK. This repo is primarily for anyone who wants to make contributions to the SDK, or install it from source. If you are looking to use Node to access the Nylas Email, Calendar, or Contacts API you should refer to our official [Node SDK Quickstart Guide](https://developer.nylas.com/docs/developer-tools/sdk/node-sdk/). +The Nylas Communications Platform provides REST APIs for [Email](https://developer.nylas.com/docs/connectivity/email/), [Calendar](https://developer.nylas.com/docs/connectivity/calendar/), and [Contacts](https://developer.nylas.com/docs/connectivity/contacts/), and the Node SDK is the quickest way to build your integration using JavaScript. -API Overview ------------- +Here are some resources to help you get started: -Every resource (i.e., messages, events, contacts) is accessed via an instance of `Nylas`. Before making any requests, be sure to call `config` and initialize the `Nylas` instance with your `appId` and `appSecret`. Then, call `with` and pass it your `accessToken`. The `accessToken` allows `Nylas` to make requests for a given account's resources. +- [Sign up for your free Nylas account](https://dashboard.nylas.com/register) +- [Sign up for the Nylas v3 Beta program to access the v3 Dashboard](https://info.nylas.com/apiv3betasignup.html?utm_source=github&utm_medium=devrel-surfaces&utm_campaign=&utm_content=node-sdk-upgrade) +- [Nylas API v3 Quickstart Guide](https://developer.nylas.com/docs/v3-beta/v3-quickstart/) +- [Nylas SDK Reference](https://nylas-nodejs-sdk-reference.pages.dev/) +- [Nylas API Reference](https://developer.nylas.com/docs/api/) +- [Nylas Samples repo for code samples and example applications](https://github.com/orgs/nylas-samples/repositories?q=&type=all&language=javascript) -```javascript -import Nylas from 'nylas'; +## βš™οΈ Install -Nylas.config({ - appId: APP_ID, - appSecret: APP_SECRET, -}); - -const nylas = Nylas.with(ACCESS_TOKEN); -``` - -Every resource method accepts an optional callback as the last argument: - -```javascript -nylas.threads.list({}, (err, threads) => { - console.log(threads.length); -}); -``` - -Additionally, every resource method returns a promise, so you don't have to use callbacks if your code is promise-friendly. Here's an example using promises: - -```javascript -nylas.threads.list({}).then(threads => { - console.log(threads.length); -}); -``` - -And here's an example using async/await: - -```javascript -const getThreadCount = async nylas => { - const threads = await nylas.threads.list({}); - return threads.length; -}; -``` - - -Authentication ------ -The Nylas REST API uses server-side (three-legged) OAuth, and the Node.js bindings provide convenience methods that simplify the OAuth process. For more information about authenticating users with Nylas, visit the [API docs](https://nylas.com/docs/#authentication). - -`urlForAuthentication()` takes in an `options` object, which must have a `redirectURI` property defined. Other supported, but optional, properties are: - -* `loginHint` - The user's email address, if known. -* `state` - An arbitrary string that will be returned back as a query param in your `redirectURI`. -* `scopes` - An array of which scopes you'd like to auth with. Possible items are `'email'`, `'calendar'`, and `'contacts'`. If omitted, defaults to all scopes. - -### Step 1: Redirect the user to Nylas - -```javascript -import Nylas from 'nylas'; - -Nylas.config({ - appId: APP_ID, - appSecret: APP_SECRET, -}); - -router.get('/connect', (req, res, next) => { - options = { - redirectURI: 'http://localhost:3000/oauth/callback', - }; - res.redirect(Nylas.urlForAuthentication(options)); -}); -``` - -### Step 2: Handle the Authentication Response - -```javascript -router.get('/oauth/callback', (req, res, next) => { - if (req.query.code) { - Nylas.exchangeCodeForToken(req.query.code).then(token => { - // save the token to the current session, save it to the user model, etc. - }); - } else if (req.query.error) { - res.render('error', { - message: req.query.reason, - error: { - status: - 'Please try authenticating again or use a different email account.', - stack: '', - }, - }); - } -}); -``` - -Fetching Messages, Events, Contacts, etc. ------ - -The Node.js SDK exposes API resources (threads, messages, folders, labels, files, events, contacts, etc.) as attributes of the `nylas` object. You can query these resources in several ways. Available filters can be found in the [API docs](https://www.nylas.com/docs/platform?node#filters). - - -```javascript -const nylas = Nylas.with(ACCESS_TOKEN); - -// Find the first thread matching the filter criteria - -nylas.threads.first({ from: EMAIL_ADDRESS }).then(thread => { - console.log(thread.subject); - console.log(thread.snippet); -}); - -// Count threads in inbox - -nylas.threads.count({ in: 'inbox' }).then(count => { - console.log(`There are ${count} threads in your inbox.`); -}); - -// Fetch a single thread - -nylas.threads - .find(THREAD_ID) - .then(thread => { - console.log(thread.subject); - }) - .catch(err => { - console.log(`Thread not found! Error: ${err.toString()}`); - }); - -// Fetch a single thread (using optional callback instead of promise) - -nylas.threads.find(THREAD_ID, (err, thread) => { - if (err) { - console.log(`Thread not found! Error: ${err.toString()}`); - return; - } - console.log(thread.subject); -}); - -// Iterate over every matching thread. Automatically paginates the underlying API -// as necessary and calls the provided block as threads are received. Calls the final -// block upon an error, or when processing is finished. - -nylas.threads.forEach( - { unread: false, from: 'chaiskye@gmail.com' }, - thread => console.log(thread.subject), - err => console.log('Finished iterating through threads.') -); - -// Returns an array of all matching threads, paginating the underlying API as necessary. -// May take a long time and return many, many objects if used with a broad filter. - -nylas.threads.list({ in: 'inbox' }).then(threads => { - console.log(threads); -}); - -``` - -Folders and Labels ------ - -The folders and labels API allows you to apply Gmail labels to whole threads or individual messages and, for providers other than Gmail, to move threads and messages between folders. - -Note that folders and labels are identical from the standpoint of the SDK. The only difference is that a message can have many labels but only a single folder. - -```javascript -const nylas = Nylas.with(ACCESS_TOKEN); - -// List the labels for this account (Gmail) -nylas.labels.list({}).then(labels => { - for (const label of labels) { - console.log(label.displayName); - console.log(label.id); - } -}); - -// List the labels this account (Exchange or IMAP) -nylas.folders.list({}).then(folders => { - for (const folder of folders) { - console.log(folder.displayName); - console.log(folder.id); - } -}); - -// Create a folder (Exchange or IMAP) -const fld = nylas.folders.build({ displayName: 'Reminders' }); -fld.save(); - -// Add the 'Spam' label to a thread (Gmail) -let spamLabel = undefined; -nylas.labels.list({}).then(labels => { - for (const label of labels) { - if (label.displayName == 'Spam') { - spamLabel = label; - break; - } - } - - nylas.threads.list({}, (err, threads) => { - const thread = threads[0]; - thread.labels.push(spamLabel); - thread.save(); - console.log(thread); - }); -}); -``` - -File Metadata ------ - -```javascript -const nylas = Nylas.with(ACCESS_TOKEN); - -// Get the metadata of a particular file -const f = nylas.files.build({ - id: fileId, -}); - -f.metadata((err, data) => { - console.log(data); -}); - -``` +**Note:** The Nylas Node SDK requires Node.js v16 or later. -On success, the file metadata should look like: -``` -{ - "content_type": "application/msword", - "filename": "Reinstatement of Corporation.doc", - "id": "9tm2n206vdj29wrhcxfvmvo4o", - "message_ids": [ - "93mtrpk4uo3wsvwcpb5yh57kp" - ], - "account_id": "6aakaxzi4j5gn6f7kbb9e0fxs", - "object": "file", - "size": 100864 -} -``` +### Set up using npm -Uploading Files ------ -Because of a bug in the library we use to issue HTTP requests, we can't pass a stream to the file upload function, which is why we read the file directly. +To run the Nylas Node SDK, first install [Node](https://nodejs.org/en/download/) and [npm](https://www.npmjs.com/get-npm) on your machine. -```javascript -import fs from 'fs'; +Then, head to the nearest command line and run the following: +`npm install nylas` -const nylas = Nylas.with(ACCESS_TOKEN); +Alternatively, you can use [Yarn](https://yarnpkg.com/en/) to install the Nylas Node SDK by running the `yarn add nylas` command. -fs.readFile(filePath, 'utf8', (err, data) => { - f = nylas.files.build({ - filename: filePath, - data: data, - contentType: 'text/plain', - }); +### Build from source - f.upload((err, file) => { - // Create a draft and attach the file to it. - const draft = nylas.drafts.build({ - subject: 'Ice Cream', - to: [{ email: 'helena@nylas.com' }], - body: 'Hey, find the file attached.', - }); - - draft.files = [file]; - - draft.send().then(message => { - console.log(`${message.id} was sent`); - }); - }); -}); +To install this package from source, clone this repo and run `npm install` from inside the project directory. +```bash +git clone https://github.com/nylas/nylas-nodejs.git +cd nylas-nodejs +npm install ``` -Downloading Files ------ +## ⚑️ Usage -```javascript -import fs from 'fs'; +To use this SDK, you must first [get a free Nylas account](https://dashboard.nylas.com/register). -const nylas = Nylas.with(ACCESS_TOKEN); +Then, follow the Quickstart guide to [set up your first app and get your API keys](https://developer.nylas.com/docs/v3-beta/v3-quickstart/). -const f = nylas.files.build({ - id: fileId, -}); +For code examples that demonstrate how to use this SDK, take a look at our [Node repos in the Nylas Samples collection](https://github.com/orgs/nylas-samples/repositories?q=&type=all&language=javascript&sort=). -f.download((err, file) => { - // File contains headers like 'Content-Disposition', - // and then the data is stored in 'body' - fs.writeFile('/tmp/' + file.filename, file.body); -}); +### πŸš€ Making Your First Request -``` - -Creating and Sending Drafts ------- -You can create, save, and send drafts. To send, first create a draft object with the correct fields (To/CC/BCC, subject, body, etc.), and then call `send`. When the draft is sent, the Nylas API will return a `Message` object. - -If you want to send a reply, set `replyMessageId` to the ID of the message to which you're replying. When that field is set, the Nylas API will set email headers to mark your message as a reply. - -```javascript -const nylas = Nylas.with(ACCESS_TOKEN); - -const draft = nylas.drafts.build({ - subject: 'My New Draft', - to: [{ email: 'ben@nylas.com' }], - replyToMessageId: MESSAGE_ID, -}); - -// Sending the draft - -draft.send().then(message => { - console.log(`${message.id} was sent`); -}); +You access Nylas resources (messages, calendars, events, contacts) through an instance of `Nylas`. The `Nylas` object must be initialized with your Nylas API key, and you can provide other additional configurations such as the Nylas API url and the timeout. -// Saving a draft +```typescript +import Nylas from "nylas"; -draft.save().then(draft => { - console.log(`${draft.id} was saved`); -}); - -// Retrieving and sending a saved draft - -const savedId = '1234'; - -nylas.drafts - .find(savedId) - .then(draft => draft.send()) - .then(message => { - console.log(`Sent ${message.subject}!`); - }); - -``` - -Searching Threads and Messages ------ -You can run a full-text search on threads and messages using `search` and passing a string to query. By default, the Nylas API returns 40 results, but you can pass a `limit` and `offset` to perform pagination. - -```javascript -const nylas = Nylas.with(ACCESS_TOKEN); - -nylas.messages.search('Hey!').then(messages => console.log(messages)); - -``` - -Using the Delta Streaming API ------- - -```javascript -const DELTA_EXCLUDE_TYPES = ['contact', 'calendar', 'event', 'file', 'tag']; -const nylas = Nylas.with(ACCESS_TOKEN); - -nylas.deltas.latestCursor((error, cursor) => { - // Save inital cursor. - persistCursor(cursor); - - // Start the stream and add event handlers. - const stream = nylas.deltas.startStream(cursor, DELTA_EXCLUDE_TYPES); - - stream - .on('delta', delta => { - // Handle the new delta. - console.log('Received delta:', delta); - // Save new cursor so this delta doesn't need to be re-fetched for future streams. - persistCursor(delta.cursor); - }) - .on('error', err => { - // Handle errors here, such as by restarting the stream at the last cursor. - console.error('Delta streaming error:', err); - }); - - // Closing the stream explicitly, if needed - stopButton.addEventListener('click', () => { - stream.close(); - }); +const nylas = new Nylas({ + apiKey: "NYLAS_API_KEY", }); ``` -Interacting with Events ----- -You can send calendar invites to events using the Nylas API. To send invites and updates to the event's participants, set `notify_participants` to `true`. +Once initialized you can use the object to make requests for a given account's resources, for example to list all the calendars for a given account: -```javascript -const nylas = Nylas.with(ACCESS_TOKEN); - -const event = nylas.events.build({ - title: 'Out of time', - calendarId: CALENDAR_ID, - when: { start_time: 1437500000, end_time: 1437501600 }, - participants: [{ email: 'helena@nylas.com', name: 'Helena Handbasket' }], -}); - -event.save({ notify_participants: true }).then(event => { - console.log(event); - console.log('Sent an invite to the participants'); +```typescript +nylas.calendars.list({ identifier: "GRANT_ID" }).then(calendars => { + console.log(calendars); }); - -// RSVP to an invite. Note that you can only RSVP to invites found in the -// "Emailed events" calendar. -nylas.events - .find(EVENT_ID) - .then(event => event.rsvp('maybe', 'I may attend this event')) - .then(event => console.log('RSVP sent!')); ``` -Sending and Retrieving Raw MIME ------ -To send raw MIME, you can build a draft and, instead of providing the normal fields, pass the MIME in an object as `rawMime`. - -To retrieve the raw MIME for an account's message, call `getRaw` on the message object, and the MIME will be returned in a promise. - -```javascript -const nylas = Nylas.with(ACCESS_TOKEN); - -// Send a message with raw MIME -const draft = nylas.drafts.build({ rawMime }); // rawMIME should be a MIME-format string with headers and multipart message -draft.send().then(message => console.log(message)); - -// Retrieve raw MIME for a message -nylas.messages - .first() - .then(message => message.getRaw()) - .then(rawMessage => console.log(rawMessage)); - -``` - -Accounts ----- - -It's possible to get details about the account you're accessing by using the `account` method: - -```javascript -const nylas = Nylas.with(ACCESS_TOKEN); - -nylas.account.get().then(account => console.log(account)); - -``` - -You can access the billing status and cancel/reactivate an account for the accounts in your app by using the `accounts` method: - -```javascript -// Show all billing statuses for accounts -Nylas.accounts.list().then(accounts => { - console.log(accounts.length); - for (const account of accounts) { - console.log( - account.id, - account.billingState, - account.syncState - ); - } -}); - -// Cancel the first account -Nylas.accounts - .first() - .then(account => account.downgrade()) - .then(response => console.log(response)); - -// Reactivate an account -Nylas.accounts - .first() - .then(account => account.upgrade()) - .then(response => console.log(response)); -``` - -Open-Source API ----- - -The [Nylas Sync Engine](http://github.com/nylas/sync-engine) is open-source, and you can also use the Node.js SDK with the open-source API. Since the open-source API provides no authentication or security, connecting to it is simple. - -It requires us to "auth" to it by passing the account id as an auth token. Here's an example of fetching the messages of the first account after getting the account ID: - -```javascript -import Nylas from 'nylas'; - -Nylas.config({ - appId: 'appId', // Doesn't matter when running locally - appSecret: 'appSecret', // Doesn't matter when running locally - apiServer: 'http://localhost:5555', -}); - -/* The open source version of the engine requires us to "auth" to it by - passing the account id as an auth token. Get the account id of the - first account. -*/ -Nylas.accounts.first().then(account => { - const nylas = Nylas.with(account.id).messages.list( - { limit: 20 }, - (err, messages) => { - for (const message of messages) { - console.log(message.subject); - } - } - ); -}); -``` - -Example Apps ----- - -We have a few example Express apps in the `example` directory that show examples for authentication and webhooks. You can run them to see how they're implemented: - -`npm install` or `yarn` - -`npm start` or `yarn start` - -Note that you'll need to replace the Nylas app ID and app secret in `app.js` or create a `config.js` file with your application's credentials. - - -Contributing ----- +## πŸ“š Documentation -We'd love your help making the Nylas Node.js SDK better. Come chat in the [Nylas community Slack channel](http://slack-invite.nylas.com/) or email support@nylas.com. +Nylas maintains a [reference guide for the Node SDK](https://nylas-nodejs-sdk-reference.pages.dev/) to help you get familiar with the available methods and classes. -Please sign the [Contributor License Agreement](https://goo.gl/forms/lKbET6S6iWsGoBbz2) before submitting pull requests. (It's similar to other projects, like NodeJS or Meteor.) +## ✨ Upgrading from 6.x -Tests can be run with: +See [UPGRADE.md](UPGRADE.md) for instructions on upgrading from 6.x to 7.x. -`npm test` or `yarn test` +**Note**: The Node SDK v7.x is not compatible with the Nylas API earlier than v3-beta. -Our linter can be run with: +## πŸ’™ Contributing -`npm run lint` or `yarn lint` +Please refer to [Contributing](Contributing.md) for information about how to make contributions to this project. We welcome questions, bug reports, and pull requests. -To use the package during local development, symlink the directory: +## πŸ“ License -`npm link` or `yarn link` in the `nylas-nodejs` directory -`npm link nylas` or `yarn link nylas` in the directory with your code that uses the package +This project is licensed under the terms of the MIT license. Please refer to [LICENSE](LICENSE.txt) for the full terms. diff --git a/UPGRADE.md b/UPGRADE.md new file mode 100644 index 00000000..648a23ac --- /dev/null +++ b/UPGRADE.md @@ -0,0 +1,200 @@ +# Upgrading to Nylas Node SDK v7.0 + +The Nylas Node SDK has been refactored and large parts of it have been rewritten for the upcoming release of the [Nylas API v3](https://developer.nylas.com/docs/v3-beta/). The goal was to have a product that is intuitive and easier to use. This guide helps you upgrade your code to use the new SDK. The new SDK also includes [documentation for the SDK's methods and models](https://nylas-nodejs-sdk-reference.pages.dev/) so you can easily find the implementation details you need. + +Head's up! Nylas API v3 [contains a lot of changes](https://developer.nylas.com/docs/v3-beta/features-and-changes/), and you should familiarize yourself with them before you start upgrading. + +⚠️ **Note:** The Nylas Node SDK v7.0 is not compatible with Nylas APIs earlier than 3.0 beta. If you are still using an earlier version of the API (such as Nylas v2.7), keep using the Nylas Node SDK v6.x until you can upgrade. + +## Initial Set up + +To upgrade to the new SDK, update your dependencies to use the new version. Do this by installing the new version of the SDK using npm or yarn. + +**Note:** The a minimum Node version is now the lowest supported LTS, Node v16. + +```bash +npm install nylas@beta +``` + +The first step to using the new SDK is to initialize a new instance of the Nylas SDK. Do this by passing in your API key to the constructor. You will notice a few changes here. + +First, the Nylas SDK is now a hybrid Node project, meaning we are using both CommonJS and ES6 modules. This means that you can import the Nylas SDK using either `require` or `import`. + +The second change is that the Nylas SDK entrypoint is no longer static. Instead of importing the Nylas SDK directly, you import the `Nylas` class from the SDK. This allows you to create multiple instances of the Nylas SDK, each with their own configuration. + +```typescript +import Nylas from "nylas"; + +const nylas = new Nylas({ + apiKey: "NYLAS_API_KEY", // Required to make API calls +}) +``` + +From here, you can use the `Nylas` instance to make API requests by accessing the different resources configured with your API Key. + +## New Models + +The new Nylas Node SDK now includes a specific model for each outgoing call to the Nylas API. Let's take a Nylas calendar object for example. In the previous SDK version there was only one `Calendar` object, and it simultaneously represented a Calendar that: + +- Is to be created +- Is to be updated +- Or is to be retrieved + +This meant that the models like the `Calendar` model had to be configured with _all_ the possible fields that could ever be used in any of the above scenarios. This made object very large and hard to anticipate as a developer. The new Node SDK has split the `Calendar` model into three models, one for each of the scenarios above. + +- `Calendar` (for retrieving a calendar) +- `CreateCalenderRequest` (for creating a calendar) +- `UpdateCalendarRequest` (for updating a calendar) + +```typescript +// Import only required if you need the typing +import { CreateCalendarRequest, UpdateCalendarRequest } from "nylas/lib/types/models/calendars"; + +const createCalendarRequest: CreateCalendarRequest = { + name: "My Calendar", // Calendar name is required + description: "This is my calendar", // Calendar description is optional + location: "My calendar location", // Calendar location is optional + timezone: "America/New_York", // Calendar timezone is optional +} + +const updateCalendarRequest: UpdateCalenderRequest = { + name: "My Updated Calendar", // All fields are optional since we are updating + hexColor: "#000000", // Other fields not present during creation are now available +} +``` + +Furthermore, these models are no longer classes but TypeScript interfaces. We also removed all functions that make API calls from the models. This means that the models are now just data structures, which makes them easier to understand and use. This includes the `save()` function. Instead now you can use the `create()`, `update()`, and `destroy()` functions on the resource class to make those requests to the API. + +## Making Requests to the Nylas API + +You use the `Nylas` instance you configured earlier to make requests to the Nylas API. The SDK is organized into different resources corresponding to each of the Email, Calendar, and Contacts APIs, and each resource includes all the available methods to make requests to that API. + +For example, to get a list of calendars, you can do so like: + +```typescript +import Nylas from "nylas"; +import { NylasListResponse } from "nylas/lib/types/models/responses"; +import { Calendar } from "nylas/lib/types/models/calendars"; + +const nylas = new Nylas({ + apiKey: "NYLAS_API_KEY", +}); + +const response: NylasListResponse = await + nylas.calendars.list({ + identifier: "GRANT_ID", // Required, the grant ID of the account to make the request for + }); +``` + +You might notice in the code above that there are some new concepts in the new SDK when making requests. These concepts are explained in more detail below. + +### Resource Parameters + +Each resource takes different parameters. All resources take an "identifier", which is the ID of the account ("grant") you want to make the request for. This is usually the Grant ID or the email address of the account. Some resources also take "query parameters" which are mainly used to filter data or pass in additional information. There are models available for all the query parameters that can be passed in. For example, listing a calendar you have `ListCalendersQueryParams`: + +```typescript +import Nylas from "nylas"; +import { NylasListResponse } from "nylas/lib/types/models/responses"; +import { Calendar, ListCalendersQueryParams } from "nylas/lib/types/models/calendars"; + +const nylas = new Nylas({ + apiKey: "NYLAS_API_KEY", +}); + +const queryParams: ListCalendersQueryParams = { + limit: 10 +} + +const response: NylasListResponse = await + nylas.calendars.list({ + identifier: "GRANT_ID", + queryParams, // Now you will get a maximum of 10 calendars back + }); +``` + +### Response Objects + +The new Nylas API v3 now has standard response objects for all requests (excluding OAuth endpoints). There are generally two main types of response objects: `NylasResponse` and `NylasListResponse`. + +The `NylasResponse` object is used for requests that return a single object, such as retrieving a single calendar. This returns a parameterized object of the type you are requesting (for example `Calendar`), and a string that represents the request ID. + +The `NylasListResponse` object is used for requests that return a list of objects, such as retrieving a _list_ of calendars. This returns a list of parameterized objects of the type you are requesting (for example, `Calendar`), a string representing the request ID, and another string representing the token of the next page for paginating a request. + +### Pagination + +The pagination mechanics have changes in Nylas API v3. Now, Nylas sends a `nextCursor` with a token value for the next page, if the "list" response returns more than one page of results. This means the v7.0 Node SDK now handles pagination differently. There are two ways to paginate a request: you can use the `next()` function to access the next page, or you can use a `for await...of` loop to auto-paginate until the end of the list. + +```typescript +// Get a list of Calendars +const calendars = nylas.calendars.list({ + identifier: 'Grant_ID', +}); + +// Option 1 - Use the next() function to get the next page +const nextPage = await calendars.next(); + +// Option 2 - Use a for await...of loop to auto-paginate until the end +for await (const item of calendars) { + // do something with each item +} +``` + +### Error Objects + +Like the response objects, Nylas v3 now has standard error objects for all requests (excluding OAuth endpoints). There are two superclass error classes, `AbstractNylasApiError`, used for errors returned by the API, and `AbstractNylasSdkError`, used for errors returned by the SDK. + +The `AbstractNylasApiError` includes two subclasses: `NylasOAuthError`, used for API errors that are returned from the OAuth endpoints, and `NylasApiError`, used for any other Nylas API errors. + +The SDK extracts the error details from the response and stores them in the error object, along with the request ID and the HTTP status code. + +`AbstractNylasSdkError` is used for errors returned by the SDK. Right now there's only one type of error we return, and that's a `NylasSdkTimeoutError` which is thrown when a request times out. + +## Authentication + +The SDK's authentication methods reflect [the methods available in the new Nylas API v3](https://developer.nylas.com/docs/developer-guide/v3-authentication/). While you can only create and manage your application's connectors (formerly called integrations) in the dashboard, you can manage almost everything else directly from the SDK. This includes managing grants, redirect URIs, OAuth tokens, and authenticating your users. + +There are two main methods to focus on when authenticating users to your application. The first is the `Auth#urlForOAuth2` method, which returns the URL that you should redirect your users to in order to authenticate them using Nylas' OAuth 2.0 implementation. + +The second is the `Auth#exchangeCodeForToken` method. Use this method to exchange the code Nylas returned from the authentication redirect for an access token from the OAuth provider. Nylas's response to this request includes both the access token, and information about the grant that was created. You don't _need_ to use the `grant_id` to make requests. Instead, you can use the authenticated email address directly as the identifier for the account. If you prefer to use the `grant_id`, you can extract it from the `CodeExchangeResponse` object and use that instead. + +The following code shows how to authenticate a user into a Nylas application: + +```typescript +import Nylas from "nylas"; + +const nylas = new Nylas({ + api_key: "NYLAS_API_KEY", +}); + +// Build the URL for authentication +const authURL = nylas.auth.urlForOAuth2({ + clientId: "CLIENT_ID", + redirectUri: "REDIRECT_URI", + loginHint: "example@email.com" +}); + +// Write code here to redirect the user to the url and parse the code +... + +// Exchange the code for an access token + +const codeExchangeResponse = nylas.auth.exchangeCodeForToken({ + redirectUri: "REDIRECT_URI", + clientId: "CLIENT_ID", + clientSecret: "CLIENT_SECRET", + code: "CODE" +}); + +// Now you can either use the email address that was authenticated or the grant ID in the response as the identifier + +const responseWithEmail: NylasListResponse = await + nylas.calendars.list({ + identifier: "example@email.com", + }); + +const responseWithGrant: NylasListResponse = await + nylas.calendars.list({ + identifier: codeExchangeResponse.grantId, + queryParams, // Now you will get a maximum of 10 calendars back + }); +``` diff --git a/__tests__/account-spec.js b/__tests__/account-spec.js deleted file mode 100644 index 39cb2924..00000000 --- a/__tests__/account-spec.js +++ /dev/null @@ -1,43 +0,0 @@ -import Promise from 'bluebird'; - -import Nylas from '../src/nylas'; -import NylasConnection from '../src/nylas-connection'; -import Account from '../src/models/account'; - -describe('account', () => { - let testContext; - const linkedAtNum = 1520546095; - - beforeEach(() => { - testContext = {}; - testContext.connection = new NylasConnection('123'); - testContext.connection.request = jest.fn(() => - Promise.resolve({ - account_id: 'hecea680y4sborshkiraj17c', - email_address: 'jeremy@emmerge.com', - id: 'hecea680y4sborshkiraj17c', - name: '', - object: 'account', - organization_unit: 'folder', - provider: 'eas', - sync_state: 'running', - linked_at: linkedAtNum, - }) - ); - }); - - test('should fetch an account model', () => { - testContext.connection.account.get(); - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'GET', - path: '/account', - qs: {}, - }); - }); - - test('linkedAt exsits on account', () => { - testContext.connection.account.get().then(function(account) { - expect(account.linkedAt); - }); - }); -}); diff --git a/__tests__/contact-spec.js b/__tests__/contact-spec.js deleted file mode 100644 index c3048ac8..00000000 --- a/__tests__/contact-spec.js +++ /dev/null @@ -1,161 +0,0 @@ -import Promise from 'bluebird'; - -import Nylas from '../src/nylas'; -import NylasConnection from '../src/nylas-connection'; -import Contact from '../src/models/contact'; - -describe('Contact', () => { - let testContext; - - beforeEach(() => { - testContext = {}; - testContext.connection = new NylasConnection('123'); - testContext.connection.request = jest.fn(() => { - return Promise.resolve(); - }); - testContext.contact = new Contact(testContext.connection); - return Promise.onPossiblyUnhandledRejection((e, promise) => {}); - }); - - describe('save', () => { - test('should do a POST request if the contact has no id', done => { - testContext.contact.id = undefined; - testContext.contact.save().then(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'POST', - body: { - id: undefined, - object: 'contact', - account_id: undefined, - given_name: undefined, - middle_name: undefined, - surname: undefined, - suffix: undefined, - nickname: undefined, - birthday: undefined, - job_title: undefined, - manager_name: undefined, - company_name: undefined, - office_location: undefined, - notes: undefined, - picture_url: undefined, - email_addresses: [], - im_addresses: [], - physical_addresses: [], - phone_numbers: [], - web_pages: [], - }, - qs: {}, - path: '/contacts', - }); - done(); - }); - }); - test('should do a POST request if the contact has no id', done => { - testContext.contact.id = '1257'; - testContext.contact.save().then(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'PUT', - body: { - id: '1257', - object: 'contact', - account_id: undefined, - given_name: undefined, - middle_name: undefined, - surname: undefined, - suffix: undefined, - nickname: undefined, - birthday: undefined, - job_title: undefined, - manager_name: undefined, - company_name: undefined, - office_location: undefined, - notes: undefined, - picture_url: undefined, - email_addresses: [], - im_addresses: [], - physical_addresses: [], - phone_numbers: [], - web_pages: [], - }, - qs: {}, - path: '/contacts/1257', - }); - done(); - }); - }); - }); - - describe('picture url', () => { - test('should make GET request for the picture', () => { - testContext.contact.id = 'a_pic_url'; - testContext.contact.getPicture(); - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'GET', - path: '/contacts/a_pic_url/picture', - qs: {}, - }); - }); - }); - - describe('when the request succeeds', () => { - beforeEach(() => { - testContext.connection.request = jest.fn(() => { - const contactJSON = { - id: '1257', - given_name: 'John', - middle_name: 'Jacob', - surname: 'Jingleheimer Schmidt', - }; - return Promise.resolve(contactJSON); - }); - }); - - test('should resolve with the contact object', done => { - testContext.contact.save().then(contact => { - expect(contact.id).toBe('1257'); - expect(contact.givenName).toBe('John'); - expect(contact.middleName).toBe('Jacob'); - expect(contact.surname).toBe('Jingleheimer Schmidt'); - done(); - }); - }); - - test('should call the callback with the contact object', done => { - testContext.contact.save((err, contact) => { - expect(err).toBe(null); - expect(contact.id).toBe('1257'); - expect(contact.givenName).toBe('John'); - expect(contact.middleName).toBe('Jacob'); - expect(contact.surname).toBe('Jingleheimer Schmidt'); - done(); - }); - }); - }); - - describe('when the request fails', () => { - beforeEach(() => { - testContext.error = new Error('Network error'); - testContext.connection.request = jest.fn(() => - Promise.reject(testContext.error) - ); - }); - - test('should reject with the error', done => { - testContext.contact.save().catch(err => { - expect(err).toBe(testContext.error); - done(); - }); - }); - - test('should call the callback with the error', done => { - testContext.contact - .save((err, contact) => { - expect(err).toBe(testContext.error); - expect(contact).toBe(undefined); - done(); - }) - .catch(() => {}); - }); - }); -}); diff --git a/__tests__/delta-spec.js b/__tests__/delta-spec.js deleted file mode 100644 index 7f8b7f3e..00000000 --- a/__tests__/delta-spec.js +++ /dev/null @@ -1,216 +0,0 @@ -import Promise from 'bluebird'; -import { EventEmitter } from 'events'; -import { PassThrough } from 'stream'; - -import Delta from '../src/models/delta'; -import NylasConnection from '../src/nylas-connection'; - -describe('Delta', () => { - let testContext; - - beforeEach(() => { - testContext = {}; - testContext.connection = new NylasConnection('123'); - testContext.delta = new Delta(testContext.connection); - jest.useFakeTimers(); - }); - - describe('startStream (delta streaming)', () => { - const createRequest = requestOpts => { - const request = new EventEmitter(); - request.origOpts = requestOpts; - request.abort = jest.fn(); - return request; - }; - - const createResponse = statusCode => { - const response = new PassThrough(); - response.statusCode = statusCode; - return response; - }; - - // Listens to the 'delta' event on the stream and pushes them to the returned array. - const observeDeltas = stream => { - const deltas = []; - stream.on('delta', delta => deltas.push(delta)); - return deltas; - }; - - test('start and close stream', () => { - const stream = testContext.delta._startStream( - createRequest, - 'deltacursor0' - ); - const { request } = stream; - - expect(request.origOpts.method).toBe('GET'); - expect(request.origOpts.path).toBe('/delta/streaming'); - expect(request.origOpts.qs).toEqual({ cursor: 'deltacursor0' }); - - const response = createResponse(200); - request.emit('response', response); - - expect(request.abort.mock.calls.length).toEqual(0); - stream.close(); - expect(request.abort.mock.calls.length).toEqual(1); - expect(stream.request).toEqual(undefined); - - // Make sure the stream doesn't auto-restart if explicitly closed. - jest.runTimersToTime(Delta.streamingTimeoutMs + 500); - expect(stream.request).toEqual(undefined); - }); - - test('passes the correct params to the request', () => { - const stream = testContext.delta._startStream( - createRequest, - 'deltacursor0', - { - expanded: true, - includeTypes: ['thread', 'message'], - excludeTypes: ['event'], - } - ); - const { request } = stream; - - expect(request.origOpts.method).toBe('GET'); - expect(request.origOpts.path).toBe('/delta/streaming'); - expect(request.origOpts.qs).toEqual({ - cursor: 'deltacursor0', - view: 'expanded', - include_types: 'thread,message', - exclude_types: 'event', - }); - }); - - test('stream response parsing', () => { - const stream = testContext.delta._startStream( - createRequest, - 'deltacursor0' - ); - const { request } = stream; - const deltas = observeDeltas(stream); - - const response = createResponse(200); - request.emit('response', response); - expect(deltas).toEqual([]); - expect(stream.cursor).toEqual('deltacursor0'); - - const delta1 = { - cursor: 'deltacursor1', - attributes: {}, - object: 'thread', - event: 'create', - id: 'deltaid1', - }; - - response.write(JSON.stringify(delta1)); - expect(deltas).toEqual([delta1]); - expect(stream.cursor).toEqual('deltacursor1'); - - stream.close(); - }); - - test('stream response parsing, delta split across data packets', () => { - const stream = testContext.delta._startStream( - createRequest, - 'deltacursor0' - ); - const { request } = stream; - const deltas = observeDeltas(stream); - - const response = createResponse(200); - request.emit('response', response); - expect(deltas).toEqual([]); - expect(stream.cursor).toEqual('deltacursor0'); - - const delta1 = { - cursor: 'deltacursor1', - attributes: {}, - object: 'thread', - event: 'create', - id: 'deltaid1', - }; - const deltaStr = JSON.stringify(delta1); - - // Partial data packet will not result in a delta yet... - response.write(deltaStr.substring(0, 20)); - expect(deltas).toEqual([]); - expect(stream.cursor).toEqual('deltacursor0'); - - // ...now the rest of the delta comes in, and there should be a delta object. - response.write(deltaStr.substring(20)); - expect(deltas).toEqual([delta1]); - expect(stream.cursor).toEqual('deltacursor1'); - - stream.close(); - }); - - test('stream timeout and auto-restart', () => { - const stream = testContext.delta._startStream( - createRequest, - 'deltacursor0' - ); - const { request } = stream; - - const response = createResponse(200); - request.emit('response', response); - expect(stream.cursor).toEqual('deltacursor0'); - - const expectRequestNotAborted = request => - expect(request.abort.calls.length).toEqual(0); - - // Server sends a heartbeat every 5 seconds. - response.write('\n'); - jest.runTimersToTime(5000); - expect(request.abort.mock.calls.length).toEqual(0); - response.write('\n'); - expect(request.abort.mock.calls.length).toEqual(0); - - // Actual response packets also reset the timeout. - jest.runTimersToTime(5000); - const delta1 = { cursor: 'deltacursor1' }; - response.write(JSON.stringify(delta1)); - expect(stream.cursor).toEqual('deltacursor1'); - jest.runTimersToTime(5500); - expect(request.abort.mock.calls.length).toEqual(0); - - // If the timeout has elapsed since the last data received, the stream is restarted. - jest.runTimersToTime(Delta.streamingTimeoutMs); - // The old request should have been aborted, and a new request created. - expect(request.abort.mock.calls.length).toEqual(1); - expect(stream.request).not.toBe(request); - // The new request should be using the last delta cursor received prior to timeout. - expect(stream.request.origOpts.path).toBe('/delta/streaming'); - expect(stream.request.origOpts.qs).toEqual({ cursor: 'deltacursor1' }); - - stream.close(); - }); - }); - - describe('latestCursor', () => { - test('returns a cursor', () => { - testContext.connection.request = jest.fn(() => - Promise.resolve({ cursor: 'abcdefg' }) - ); - - testContext.delta.latestCursor((err, cursor) => - expect(cursor).toEqual('abcdefg') - ); - - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'POST', - path: '/delta/latest_cursor', - }); - }); - - test('returns a null cursor in case of an error', () => { - testContext.connection.request = jest.fn(() => Promise.reject('Error.')); - testContext.delta - .latestCursor((err, cursor) => { - expect(err).toEqual('Error.'); - expect(cursor).toEqual(null); - }) - .catch(err => {}); - }); - }); -}); diff --git a/__tests__/draft-spec.js b/__tests__/draft-spec.js deleted file mode 100644 index c5a46ed4..00000000 --- a/__tests__/draft-spec.js +++ /dev/null @@ -1,292 +0,0 @@ -import Promise from 'bluebird'; -import request from 'request'; -import _ from 'underscore'; - -import Nylas from '../src/nylas'; -import NylasConnection from '../src/nylas-connection'; -import Draft from '../src/models/draft'; -import Message from '../src/models/message'; - -describe('Draft', () => { - let testContext; - - beforeEach(() => { - testContext = {}; - testContext.connection = new NylasConnection('123'); - testContext.connection.request = jest.fn(() => Promise.resolve({})); - testContext.draft = new Draft(testContext.connection); - return Promise.onPossiblyUnhandledRejection((e, promise) => {}); - }); - - describe('save', () => { - test('should do a POST request if the draft has no id', done => { - testContext.draft.id = undefined; - testContext.draft.save().then(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'POST', - body: { - id: undefined, - object: 'draft', - account_id: undefined, - to: [], - cc: [], - bcc: [], - from: [], - date: null, - body: '', - files: [], - events: [], - unread: undefined, - snippet: undefined, - thread_id: undefined, - subject: '', - version: undefined, - folder: undefined, - labels: [], - file_ids: [], - headers: undefined, - reply_to: [], - reply_to_message_id: undefined, - }, - qs: {}, - path: '/drafts', - }); - done(); - }); - }); - - test('should do a PUT request if the draft has an id', done => { - testContext.draft.id = 'id-1234'; - testContext.draft.save().then(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'PUT', - body: { - id: 'id-1234', - object: 'draft', - account_id: undefined, - to: [], - cc: [], - bcc: [], - from: [], - date: null, - body: '', - files: [], - events: [], - unread: undefined, - snippet: undefined, - thread_id: undefined, - subject: '', - version: undefined, - folder: undefined, - labels: [], - file_ids: [], - headers: undefined, - reply_to: [], - reply_to_message_id: undefined, - }, - qs: {}, - path: '/drafts/id-1234', - }); - done(); - }); - }); - - describe('when the request succeeds', () => { - beforeEach(() => { - testContext.connection.request = jest.fn(() => { - const draftJSON = { - id: 'id-1234', - version: 1, - }; - return Promise.resolve(draftJSON); - }); - }); - - test('should resolve with the draft object', done => { - testContext.draft.save().then(draft => { - expect(draft.id).toBe('id-1234'); - expect(draft.version).toBe(1); - done(); - }); - }); - - test('should call the callback with the draft object', done => { - testContext.draft.save((err, draft) => { - expect(err).toBe(null); - expect(draft.id).toBe('id-1234'); - expect(draft.version).toBe(1); - done(); - }); - }); - }); - - describe('when the request fails', () => { - beforeEach(() => { - testContext.error = new Error('Network error'); - testContext.connection.request = jest.fn(() => - Promise.reject(testContext.error) - ); - }); - - test('should reject with the error', done => { - testContext.draft.save().catch(err => { - expect(err).toBe(testContext.error); - done(); - }); - }); - - test('should call the callback with the error', done => { - testContext.draft - .save((err, draft) => { - expect(err).toBe(testContext.error); - expect(draft).toBe(undefined); - done(); - }) - .catch(() => {}); - }); - }); - }); - - describe('send', () => { - test('should send the draft_id and version if the draft has an id', done => { - testContext.draft.id = 'id-1234'; - testContext.draft.version = 2; - testContext.draft.send().then(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'POST', - body: { - draft_id: 'id-1234', - version: 2, - }, - path: '/send', - headers: {}, - json: true, - }); - done(); - }); - }); - - test('should send the draft JSON if the draft has no id', done => { - testContext.draft.id = undefined; - testContext.draft.subject = 'Test Subject'; - testContext.draft.send().then(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'POST', - body: { - id: undefined, - object: 'draft', - account_id: undefined, - to: [], - cc: [], - bcc: [], - from: [], - date: null, - body: '', - files: [], - events: [], - unread: undefined, - snippet: undefined, - thread_id: undefined, - subject: 'Test Subject', - version: undefined, - folder: undefined, - labels: [], - file_ids: [], - headers: undefined, - reply_to: [], - reply_to_message_id: undefined, - }, - path: '/send', - headers: {}, - json: true, - }); - done(); - }); - }); - - test('should send the draft as raw MIME if rawMime exists', done => { - const msg = `MIME-Version: 1.0 \ -Content-Type: text/plain; charset=UTF-8 \ -In-Reply-To: <84umizq7c4jtrew491brpa6iu-0@mailer.nylas.com> \ -References: <84umizq7c4jtrew491brpa6iu-0@mailer.nylas.com> \ -Subject: Meeting on Thursday \ -From: Bill \ -To: Ben Bitdiddle \ -\ -Hey Ben, \ -\ -Would you like to grab coffee @ 2pm this Thursday?`; - - const draft = testContext.connection.drafts.build({ rawMime: msg }); - draft.send().then(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - headers: { - 'Content-Type': 'message/rfc822', - }, - method: 'POST', - path: '/send', - body: msg, - json: false, - }); - done(); - }); - }); - - describe('when the request succeeds', () => { - beforeEach(() => { - testContext.connection.request = jest.fn(() => { - const draftJSON = { - id: 'id-1234', - thread_id: 'new-thread-id', - }; - return Promise.resolve(draftJSON); - }); - }); - - test('should resolve with the message object', done => { - testContext.draft.send().then(message => { - expect(message.id).toBe('id-1234'); - expect(message.threadId).toBe('new-thread-id'); - expect(message).toBeInstanceOf(Message); - done(); - }); - }); - - test('should call the callback with the message object', done => { - testContext.draft.send((err, message) => { - expect(err).toBe(null); - expect(message.id).toBe('id-1234'); - expect(message.threadId).toBe('new-thread-id'); - expect(message).toBeInstanceOf(Message); - done(); - }); - }); - }); - - describe('when the request fails', () => { - beforeEach(() => { - testContext.error = new Error('Network error'); - testContext.connection.request = jest.fn(() => - Promise.reject(testContext.error) - ); - }); - - test('should reject with the error', done => { - testContext.draft.send().catch(err => { - expect(err).toBe(testContext.error); - done(); - }); - }); - - test('should call the callback with the error', done => { - testContext.draft - .send((err, message) => { - expect(err).toBe(testContext.error); - expect(message).toBe(undefined); - done(); - }) - .catch(() => {}); - }); - }); - }); -}); diff --git a/__tests__/event-spec.js b/__tests__/event-spec.js deleted file mode 100644 index 3b65b53b..00000000 --- a/__tests__/event-spec.js +++ /dev/null @@ -1,170 +0,0 @@ -import Promise from 'bluebird'; -import request from 'request'; -import _ from 'underscore'; - -import Nylas from '../src/nylas'; -import NylasConnection from '../src/nylas-connection'; -import Event from '../src/models/event'; - -describe('Event', () => { - let testContext; - - beforeEach(() => { - testContext = {}; - testContext.connection = new NylasConnection('123'); - testContext.connection.request = jest.fn(() => Promise.resolve()); - testContext.event = new Event(testContext.connection); - return Promise.onPossiblyUnhandledRejection((e, promise) => {}); - }); - - describe('save', () => { - test('should do a POST request if the event has no id', done => { - testContext.event.id = undefined; - testContext.event.save().then(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'POST', - body: { - id: undefined, - object: 'event', - account_id: undefined, - calendar_id: undefined, - busy: undefined, - title: undefined, - description: undefined, - location: undefined, - when: undefined, - _start: undefined, - _end: undefined, - participants: [], - }, - qs: {}, - path: '/events', - }); - done(); - }); - }); - - test('should do a PUT request if the event has an id', done => { - testContext.event.id = 'id-1234'; - testContext.event.save().then(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'PUT', - body: { - id: 'id-1234', - object: 'event', - account_id: undefined, - calendar_id: undefined, - busy: undefined, - title: undefined, - description: undefined, - location: undefined, - when: undefined, - _start: undefined, - _end: undefined, - participants: [], - }, - qs: {}, - path: '/events/id-1234', - }); - done(); - }); - }); - - test('should include params in the request if they were passed in', done => { - testContext.event.save({ notify_participants: true }).then(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'POST', - body: { - object: 'event', - account_id: undefined, - calendar_id: undefined, - busy: undefined, - title: undefined, - description: undefined, - location: undefined, - when: undefined, - _start: undefined, - _end: undefined, - participants: [], - }, - qs: { - notify_participants: true, - }, - path: '/events', - }); - done(); - }); - }); - - describe('when the request succeeds', () => { - beforeEach(() => { - testContext.connection.request = jest.fn(() => { - const eventJSON = { - id: 'id-1234', - title: 'test event', - when: {}, - }; - return Promise.resolve(eventJSON); - }); - }); - - test('should resolve with the event object', done => { - testContext.event.save().then(event => { - expect(event.id).toBe('id-1234'); - expect(event.title).toBe('test event'); - done(); - }); - }); - - test('should call the callback with the event object', done => { - testContext.event.save((err, event) => { - expect(err).toBe(null); - expect(event.id).toBe('id-1234'); - expect(event.title).toBe('test event'); - done(); - }); - }); - }); - - describe('when the request fails', () => { - beforeEach(() => { - testContext.error = new Error('Network error'); - testContext.connection.request = jest.fn(() => - Promise.reject(testContext.error) - ); - }); - - test('should reject with the error', done => { - testContext.event.save().catch(err => { - expect(err).toBe(testContext.error); - done(); - }); - }); - - test('should call the callback with the error', done => { - testContext.event - .save((err, event) => { - expect(err).toBe(testContext.error); - expect(event).toBe(undefined); - done(); - }) - .catch(() => {}); - }); - }); - }); - - describe('rsvp', () => - test('should do a POST request to the RSVP endpoint', () => { - testContext.event.id = 'public_id'; - testContext.event.rsvp('yes', 'I will come.'); - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'POST', - body: { - event_id: 'public_id', - status: 'yes', - comment: 'I will come.', - }, - path: '/send-rsvp', - }); - })); -}); diff --git a/__tests__/file-spec.js b/__tests__/file-spec.js deleted file mode 100644 index 4bc31755..00000000 --- a/__tests__/file-spec.js +++ /dev/null @@ -1,265 +0,0 @@ -import Promise from 'bluebird'; -import request from 'request'; -import _ from 'underscore'; - -import Nylas from '../src/nylas'; -import NylasConnection from '../src/nylas-connection'; -import File from '../src/models/file'; - -describe('File', () => { - let testContext; - - beforeEach(() => { - testContext = {}; - testContext.connection = new NylasConnection('123'); - testContext.connection.request = jest.fn(() => Promise.resolve()); - testContext.file = new File(testContext.connection); - testContext.file.data = 'Sample data'; - testContext.file.contentType = 'text/plain'; - testContext.file.filename = 'sample.txt'; - testContext.file.id = 'fileId'; - return Promise.onPossiblyUnhandledRejection((e, promise) => {}); - }); - - describe('upload', () => { - test('should do a POST request', done => { - testContext.file.upload().catch(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'POST', - json: false, - path: '/files', - formData: { - file: { - value: 'Sample data', - options: { - filename: 'sample.txt', - contentType: 'text/plain', - }, - }, - }, - }); - done(); - }); - }); - - describe('when the request succeeds', () => { - beforeEach(() => { - testContext.connection.request = jest.fn(() => { - const fileJSON = [ - { - id: 'id-1234', - filename: 'sample.txt', - }, - ]; - return Promise.resolve(fileJSON); - }); - }); - - test('should resolve with the file object', done => { - testContext.file.upload().then(file => { - expect(file.id).toBe('id-1234'); - expect(file.filename).toBe('sample.txt'); - done(); - }); - }); - - test('should call the callback with the file object', done => { - testContext.file.upload((err, file) => { - expect(err).toBe(null); - expect(file.id).toBe('id-1234'); - expect(file.filename).toBe('sample.txt'); - done(); - }); - }); - }); - - describe('when the request fails', () => { - beforeEach(() => { - testContext.error = new Error('Network error'); - testContext.connection.request = jest.fn(() => { - return Promise.reject(testContext.error); - }); - }); - - test('should reject with the error', done => { - testContext.file.upload().catch(err => { - expect(err).toBe(testContext.error); - done(); - }); - }); - - test('should call the callback with the error', done => { - testContext.file - .upload((err, file) => { - expect(err).toBe(testContext.error); - expect(file).toBe(undefined); - done(); - }) - .catch(() => {}); - }); - }); - }); - - describe('download', () => { - test('should do a GET request', done => { - testContext.file.download().catch(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - path: '/files/fileId/download', - encoding: null, - downloadRequest: true, - }); - done(); - }); - }); - - describe('when the request succeeds', () => { - beforeEach(() => { - testContext.connection.request = jest.fn(() => { - const response = { - headers: { - header1: '1', - header2: '2', - }, - body: 'body', - otherField: 'other', - }; - return Promise.resolve(response); - }); - }); - - test('should resolve with the file information', done => { - testContext.file.download().then(file => { - const fileInfo = { - body: 'body', - header1: '1', - header2: '2', - }; - expect(file).toEqual(fileInfo); - done(); - }); - }); - - test('should call the callback with the file object', done => { - testContext.file.download((err, file) => { - const fileInfo = { - body: 'body', - header1: '1', - header2: '2', - }; - expect(err).toBe(null); - expect(file).toEqual(fileInfo); - done(); - }); - }); - }); - - describe('when the request fails', () => { - beforeEach(() => { - testContext.error = new Error('Network error'); - testContext.connection.request = jest.fn(() => { - return Promise.reject(testContext.error); - }); - }); - - test('should reject with the error', done => { - testContext.file.download().catch(err => { - expect(err).toBe(testContext.error); - done(); - }); - }); - - test('should call the callback with the error', done => { - testContext.file - .download((err, file) => { - expect(err).toBe(testContext.error); - expect(file).toBe(undefined); - done(); - }) - .catch(() => {}); - }); - }); - }); - - describe('metadata', () => { - test('should do a GET request', () => { - testContext.file.metadata(); - expect(testContext.connection.request).toHaveBeenCalledWith({ - path: '/files/fileId', - }); - }); - - describe('when the request succeeds', () => { - beforeEach(() => { - testContext.connection.request = jest.fn(() => { - const response = { - content_type: 'image/jpeg', - filename: 'sailing_photo.jpg', - id: 'dyla86usnzouam5wt7wt2bsvu', - message_ids: ['cud32592sewzy834bzhsbu0kt'], - account_id: '6aakaxzi4j5gn6f7kbb9e0fxs', - object: 'file', - size: 8380, - }; - return Promise.resolve(response); - }); - }); - - test('should resolve with the file information', done => { - testContext.file.metadata().then(response => { - const fileInfo = { - content_type: 'image/jpeg', - filename: 'sailing_photo.jpg', - id: 'dyla86usnzouam5wt7wt2bsvu', - message_ids: ['cud32592sewzy834bzhsbu0kt'], - account_id: '6aakaxzi4j5gn6f7kbb9e0fxs', - object: 'file', - size: 8380, - }; - expect(response).toEqual(fileInfo); - done(); - }); - }); - - test('should call the callback with the file object', done => { - testContext.file.metadata((err, response) => { - const fileInfo = { - content_type: 'image/jpeg', - filename: 'sailing_photo.jpg', - id: 'dyla86usnzouam5wt7wt2bsvu', - message_ids: ['cud32592sewzy834bzhsbu0kt'], - account_id: '6aakaxzi4j5gn6f7kbb9e0fxs', - object: 'file', - size: 8380, - }; - expect(err).toBe(null); - expect(response).toEqual(fileInfo); - done(); - }); - }); - }); - - describe('when the request fails', () => { - beforeEach(() => { - testContext.error = new Error('Network error'); - testContext.connection.request = jest.fn(() => { - return Promise.reject(testContext.error); - }); - }); - - test('should reject with the error', done => { - testContext.file.metadata().catch(err => { - expect(err).toBe(testContext.error); - done(); - }); - }); - - test('should call the callback with the error', done => { - testContext.file.metadata((err, file) => { - expect(err).toBe(testContext.error); - expect(file).toBe(undefined); - done(); - }); - }); - }); - }); -}); diff --git a/__tests__/label-spec.js b/__tests__/label-spec.js deleted file mode 100644 index be6dc121..00000000 --- a/__tests__/label-spec.js +++ /dev/null @@ -1,57 +0,0 @@ -import Promise from 'bluebird'; -import request from 'request'; -import _ from 'underscore'; - -import Nylas from '../src/nylas'; -import NylasConnection from '../src/nylas-connection'; -import Message from '../src/models/message'; -import { Label } from '../src/models/folder'; - -const testUntil = fn => { - let finished = false; - runs(() => fn(callback => (finished = true))); - waitsFor(() => finished); -}; - -describe('Label', () => { - let testContext; - - beforeEach(() => { - testContext = {}; - testContext.connection = new NylasConnection('123'); - testContext.connection.request = jest.fn(() => Promise.resolve()); - testContext.label = new Label(testContext.connection); - testContext.label.displayName = 'Label name'; - testContext.label.name = 'Longer label name'; - return Promise.onPossiblyUnhandledRejection((e, promise) => {}); - }); - - describe('save', () => { - test('should do a POST request if id is undefined', () => { - testContext.label.save(); - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'POST', - body: { - display_name: 'Label name', - name: 'Longer label name', - }, - qs: {}, - path: '/labels', - }); - }); - - test('should do a PUT if id is defined', () => { - testContext.label.id = 'label_id'; - testContext.label.save(); - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'PUT', - body: { - display_name: 'Label name', - name: 'Longer label name', - }, - qs: {}, - path: '/labels/label_id', - }); - }); - }); -}); diff --git a/__tests__/management-account-spec.js b/__tests__/management-account-spec.js deleted file mode 100644 index 0b18c368..00000000 --- a/__tests__/management-account-spec.js +++ /dev/null @@ -1,87 +0,0 @@ -import Promise from 'bluebird'; -import request from 'request'; -import _ from 'underscore'; - -import Nylas from '../src/nylas'; -import NylasConnection from '../src/nylas-connection'; - -describe('ManagementAccount', () => { - const APP_ID = 'abc'; - beforeEach(() => { - Nylas.config({ - appId: APP_ID, - appSecret: 'xyz', - }); - Promise.onPossiblyUnhandledRejection((e, promise) => {}); - }); - - describe('list', () => - test('should do a GET request to get the account list', () => { - Nylas.accounts.connection.request = jest.fn(() => - Promise.resolve([ - { - account_id: '8rilmlwuo4zmpjedz8bcplclk', - billing_state: 'free', - id: '8rilmlwuo4zmpjedz8bcplclk', - namespace_id: '2lrhtr5xxrqv3hrcre54tugru', - sync_state: 'running', - trial: false, - }, - ]) - ); - Nylas.accounts - .list({}, (err, account) => { - expect(accounts.length).toEqual(1); - expect(accounts[0].id).toEqual('8rilmlwuo4zmpjedz8bcplclk'); - }) - .then(() => - expect(Nylas.accounts.connection.request).toHaveBeenCalledWith({ - method: 'GET', - qs: { limit: 100, offset: 0 }, - path: `/a/${APP_ID}/accounts`, - }) - ); - })); - - describe('upgrade', () => - test('should POST to upgrade an account', () => { - Nylas.accounts.connection.request = jest.fn(() => - Promise.resolve([ - { - success: 'true', - }, - ]) - ); - Nylas.accounts - .first() - .then(account => account.upgrade()) - .then(resp => { - expect(Nylas.accounts.connection.request).toHaveBeenCalledWith({ - method: 'POST', - path: `/a/${APP_ID}/accounts/upgrade`, - }); - expect(resp.success).toBe('true'); - }); - })); - - describe('downgrade', () => - test('should POST to upgrade an account', () => { - Nylas.accounts.connection.request = jest.fn(() => - Promise.resolve([ - { - success: 'true', - }, - ]) - ); - Nylas.accounts - .first() - .then(account => account.downgrade()) - .then(resp => { - expect(Nylas.accounts.connection.request).toHaveBeenCalledWith({ - method: 'POST', - path: `/a/${APP_ID}/accounts/downgrade`, - }); - expect(resp.success).toBe('true'); - }); - })); -}); diff --git a/__tests__/message-spec.js b/__tests__/message-spec.js deleted file mode 100644 index 222fbf98..00000000 --- a/__tests__/message-spec.js +++ /dev/null @@ -1,77 +0,0 @@ -import Promise from 'bluebird'; -import request from 'request'; -import _ from 'underscore'; - -import Nylas from '../src/nylas'; -import NylasConnection from '../src/nylas-connection'; -import Message from '../src/models/message'; -import { Label } from '../src/models/folder'; - -describe('Message', () => { - let testContext; - - beforeEach(() => { - testContext = {}; - testContext.connection = new NylasConnection('123'); - testContext.connection.request = jest.fn(() => Promise.resolve()); - testContext.message = new Message(testContext.connection); - testContext.message.id = '4333'; - testContext.message.starred = true; - testContext.message.unread = false; - return Promise.onPossiblyUnhandledRejection((e, promise) => {}); - }); - - describe('save', () => { - test('should do a PUT request with labels if labels is defined. Additional arguments should be ignored.', () => { - const label = new Label(testContext.connection); - label.id = 'label_id'; - testContext.message.labels = [label]; - testContext.message.randomArgument = true; - testContext.message.save().then(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'PUT', - body: { - label_ids: ['label_id'], - starred: true, - unread: false, - }, - qs: {}, - path: '/messages/4333', - }); - }); - }); - - test('should do a PUT with folder if folder is defined', () => { - const label = new Label(testContext.connection); - label.id = 'label_id'; - testContext.message.folder = label; - testContext.message.save().then(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'PUT', - body: { - folder_id: 'label_id', - starred: true, - unread: false, - }, - qs: {}, - path: '/messages/4333', - }); - }); - }); - }); - - describe('getRaw', () => - test('should support getting raw messages', () => { - testContext.connection.request = jest.fn(() => Promise.resolve('MIME')); - testContext.message.getRaw().then(rawMessage => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - headers: { - Accept: 'message/rfc822', - }, - method: 'GET', - path: '/messages/4333', - }); - expect(rawMessage).toBe('MIME'); - }); - })); -}); diff --git a/__tests__/nylas-api-spec.js b/__tests__/nylas-api-spec.js deleted file mode 100644 index 5653fb59..00000000 --- a/__tests__/nylas-api-spec.js +++ /dev/null @@ -1,207 +0,0 @@ -import Promise from 'bluebird'; -import request from 'request'; - -import Nylas from '../src/nylas'; -import NylasConnection from '../src/nylas-connection'; - -describe('Nylas', () => { - beforeEach(() => { - Nylas.appId = undefined; - Nylas.appSecret = undefined; - Nylas.apiServer = 'https://api.nylas.com'; - return Promise.onPossiblyUnhandledRejection((e, promise) => {}); - }); - - describe('config', () => { - test('should allow you to populate the appId, appSecret, apiServer and authServer options', () => { - const newConfig = { - appId: 'newId', - appSecret: 'newSecret', - apiServer: 'https://api-staging.nylas.com/', - }; - - Nylas.config(newConfig); - expect(Nylas.appId).toBe(newConfig.appId); - expect(Nylas.appSecret).toBe(newConfig.appSecret); - expect(Nylas.apiServer).toBe(newConfig.apiServer); - }); - - test('should not override existing values unless new values are provided', () => { - const newConfig = { - appId: 'newId', - appSecret: 'newSecret', - }; - - Nylas.config(newConfig); - expect(Nylas.appId).toBe(newConfig.appId); - expect(Nylas.appSecret).toBe(newConfig.appSecret); - expect(Nylas.apiServer).toBe('https://api.nylas.com'); - }); - - test('should throw an exception if the server options do not contain ://', () => { - const newConfig = { - appId: 'newId', - appSecret: 'newSecret', - apiServer: 'dontknowwhatImdoing.nylas.com', - }; - - expect(() => Nylas.config(newConfig)).toThrow(); - }); - }); - - describe('with', () => { - test('should throw an exception if an access token is not provided', () => - expect(() => Nylas.with()).toThrow()); - - test('should return an NylasConnection for making requests with the access token', () => { - Nylas.config({ - appId: 'newId', - appSecret: 'newSecret', - }); - - const conn = Nylas.with('test-access-token'); - expect(conn instanceof NylasConnection).toEqual(true); - }); - }); - - describe('exchangeCodeForToken', () => { - beforeEach(() => - Nylas.config({ - appId: 'newId', - appSecret: 'newSecret', - }) - ); - - test('should throw an exception if no code is provided', () => - expect(() => Nylas.exchangeCodeForToken()).toThrow()); - - test('should throw an exception if the app id and secret have not been configured', () => { - Nylas.appId = undefined; - Nylas.appSecret = undefined; - expect(() => Nylas.exchangeCodeForToken('code-from-server')).toThrow(); - }); - - test('should return a promise', () => { - const p = Nylas.exchangeCodeForToken('code-from-server'); - expect(p instanceof Promise).toBe(true); - }); - - test('should make a request to /oauth/token with the correct grant_type and client params', () => { - request.Request = jest.fn(options => { - expect(options.url).toEqual('https://api.nylas.com/oauth/token'); - expect(options.qs).toEqual({ - client_id: 'newId', - client_secret: 'newSecret', - grant_type: 'authorization_code', - code: 'code-from-server', - }); - }); - Nylas.exchangeCodeForToken('code-from-server'); - }); - - test('should resolve with the returned access_token', done => { - request.Request = jest.fn(options => - options.callback(null, null, { access_token: '12345' }) - ); - - Nylas.exchangeCodeForToken('code-from-server').then(accessToken => { - expect(accessToken).toEqual('12345'); - done(); - }); - }); - - test('should reject with the request error', done => { - const error = new Error('network error'); - request.Request = jest.fn(options => options.callback(error, null, null)); - - Nylas.exchangeCodeForToken('code-from-server').catch(returnedError => { - expect(returnedError).toBe(error); - done(); - }); - }); - - describe('when provided an optional callback', () => { - test('should call it with the returned access_token', done => { - request.Request = jest.fn(options => - options.callback(null, null, { access_token: '12345' }) - ); - Nylas.exchangeCodeForToken( - 'code-from-server', - (returnedError, accessToken) => { - expect(accessToken).toBe('12345'); - done(); - } - ); - }); - - test('should call it with the request error', done => { - const error = new Error('network error'); - request.Request = jest.fn(options => - options.callback(error, null, null) - ); - - Nylas.exchangeCodeForToken( - 'code-from-server', - (returnedError, accessToken) => { - expect(returnedError).toBe(error); - done(); - } - ); - }); - }); - }); - - describe('urlForAuthentication', () => { - beforeEach(() => - Nylas.config({ - appId: 'newId', - appSecret: 'newSecret', - }) - ); - - test('should require a redirectURI', () => - expect(() => Nylas.urlForAuthentication()).toThrow()); - - test('should throw an exception if the app id has not been configured', () => { - Nylas.appId = undefined; - const options = { redirectURI: 'https://localhost/callback' }; - expect(() => Nylas.urlForAuthentication(options)).toThrow(); - }); - - test('should not throw an exception if the app secret has not been configured', () => { - Nylas.appSecret = undefined; - const options = { redirectURI: 'https://localhost/callback' }; - expect(Nylas.urlForAuthentication(options)).toEqual( - 'https://api.nylas.com/oauth/authorize?client_id=newId&response_type=code&login_hint=&redirect_uri=https://localhost/callback' - ); - }); - - test('should generate the correct authentication URL', () => { - const options = { redirectURI: 'https://localhost/callback' }; - expect(Nylas.urlForAuthentication(options)).toEqual( - 'https://api.nylas.com/oauth/authorize?client_id=newId&response_type=code&login_hint=&redirect_uri=https://localhost/callback' - ); - }); - - test('should use a login hint when provided in the options', () => { - const options = { - loginHint: 'ben@nylas.com', - redirectURI: 'https://localhost/callback', - }; - expect(Nylas.urlForAuthentication(options)).toEqual( - 'https://api.nylas.com/oauth/authorize?client_id=newId&response_type=code&login_hint=ben@nylas.com&redirect_uri=https://localhost/callback' - ); - }); - - test('should add scopes when provided in the options', () => { - const options = { - loginHint: 'test@nylas.com', - redirectURI: 'https://localhost/callback', - scopes: ['calendar', 'contacts'], - }; - expect(Nylas.urlForAuthentication(options)).toEqual( - 'https://api.nylas.com/oauth/authorize?client_id=newId&response_type=code&login_hint=test@nylas.com&redirect_uri=https://localhost/callback&scopes=calendar,contacts' - ); - }); - }); -}); diff --git a/__tests__/nylas-connection-spec.js b/__tests__/nylas-connection-spec.js deleted file mode 100644 index 5245e10d..00000000 --- a/__tests__/nylas-connection-spec.js +++ /dev/null @@ -1,55 +0,0 @@ -import _ from 'underscore'; - -import NylasConnection from '../src/nylas-connection'; - -import PACKAGE_JSON from '../package.json'; -const SDK_VERSION = PACKAGE_JSON.version; - -describe('NylasConnection', () => { - let testContext; - - beforeEach(() => { - testContext = {}; - testContext.connection = new NylasConnection('test-access-token'); - }); - - describe('requestOptions', () => - test("should pass view='expanded' when expanded param is provided", () => { - const options = { - method: 'GET', - path: '/threads/123', - qs: { expanded: true }, - }; - const result = testContext.connection.requestOptions(options); - expect(result.qs.expanded).toBeUndefined(); - expect(result.qs.view).toEqual('expanded'); - expect(result.headers['User-Agent']).toEqual( - `Nylas Node SDK v${SDK_VERSION}` - ); - })); - describe('mismatched api version warnings', () => { - test('should not warn if Nylas API version matches SDK supported API version', () => { - const noWarning = testContext.connection._getWarningForVersion( - '2.0', - '2.0' - ); - expect(noWarning).toEqual(''); - - const warnSdk = testContext.connection._getWarningForVersion( - '1.0', - '2.0' - ); - expect(warnSdk).toEqual( - `WARNING: SDK version may not support your Nylas API version. SDK supports version 1.0 of the API and your application is currently running on version 2.0 of the API. Please update the sdk to ensure it works properly.` - ); - - const warnApi = testContext.connection._getWarningForVersion( - '2.0', - '1.0' - ); - expect(warnApi).toEqual( - `WARNING: SDK version may not support your Nylas API version. SDK supports version 2.0 of the API and your application is currently running on version 1.0 of the API. Please update the version of the API that your application is using through the developer dashboard.` - ); - }); - }); -}); diff --git a/__tests__/restful-model-collection-spec.js b/__tests__/restful-model-collection-spec.js deleted file mode 100644 index c585e1e5..00000000 --- a/__tests__/restful-model-collection-spec.js +++ /dev/null @@ -1,684 +0,0 @@ -import Promise from 'bluebird'; -import request from 'request'; - -import Nylas from '../src/nylas'; -import NylasConnection from '../src/nylas-connection'; -import RestfulModelCollection from '../src/models/restful-model-collection'; -import Thread from '../src/models/thread'; -import Event from '../src/models/event'; - -describe('RestfulModelCollection', () => { - let testContext; - - beforeEach(() => { - Nylas.config({ - appId: '123', - appSecret: '123', - }); - testContext = {}; - testContext.connection = new NylasConnection('test-access-token'); - testContext.connection.request = jest.fn(() => Promise.resolve()); - testContext.collection = new RestfulModelCollection( - Thread, - testContext.connection - ); - }); - - describe('constructor', () => { - test('should require an inbox connection object', () => - expect(() => new RestfulModelCollection(Thread)).toThrow()); - - test('should require a model class', () => - expect(() => { - return new RestfulModelCollection(null, this.connection); - }).toThrow()); - }); - - describe('forEach', () => { - beforeEach(() => { - const threadsResponses = []; - for (let x = 0; x <= 3; x++) { - const response = []; - const count = x < 3 ? 99 : 12; - for ( - let i = 0, end = count, asc = 0 <= end; - asc ? i <= end : i >= end; - asc ? i++ : i-- - ) { - response.push({ - id: '123', - account_id: undefined, - subject: 'A', - }); - } - threadsResponses.push(response); - } - - testContext.collection._getModelCollection = jest.fn( - (params, offset, limit) => - Promise.resolve(threadsResponses[offset / 100]) - ); - }); - - test('should fetch models with the given params', () => { - const params = { from: 'ben@nylas.com' }; - const threads = [ - { - id: '123', - account_id: undefined, - subject: 'A', - }, - ]; - testContext.collection.forEach(params, () => {}, () => {}); - expect(testContext.collection._getModelCollection).toHaveBeenCalledWith( - params, - 0, - 100, - '/threads' - ); - }); - - test('should fetch repeatedly until fewer than requested models are returned', done => { - const params = { from: 'ben@nylas.com' }; - testContext.collection.forEach( - params, - () => {}, - () => { - expect( - testContext.collection._getModelCollection.mock.calls[0] - ).toEqual([{ from: 'ben@nylas.com' }, 0, 100, '/threads']); - expect( - testContext.collection._getModelCollection.mock.calls[1] - ).toEqual([{ from: 'ben@nylas.com' }, 100, 100, '/threads']); - expect( - testContext.collection._getModelCollection.mock.calls[2] - ).toEqual([{ from: 'ben@nylas.com' }, 200, 100, '/threads']); - expect( - testContext.collection._getModelCollection.mock.calls[3] - ).toEqual([{ from: 'ben@nylas.com' }, 300, 100, '/threads']); - done(); - } - ); - }); - - test('should call eachCallback with each model fetched', done => { - const params = { from: 'ben@nylas.com' }; - let eachCallCount = 0; - testContext.collection.forEach( - params, - () => (eachCallCount += 1), - () => { - expect(eachCallCount).toBe(313); - done(); - } - ); - }); - - test('should call completeCallback when finished', done => { - const params = { from: 'ben@nylas.com' }; - let doneCallCount = 0; - testContext.collection.forEach( - params, - () => {}, - () => { - doneCallCount += 1; - expect(doneCallCount).toBe(1); - done(); - } - ); - }); - }); - - describe('count', () => { - test('should make a request with the provided params and view=count', done => { - testContext.collection.count({ from: 'ben@nylas.com' }).catch(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'GET', - path: '/threads', - qs: { view: 'count', from: 'ben@nylas.com' }, - }); - done(); - }); - }); - - describe('when the request is successful', () => { - beforeEach(() => { - testContext.connection.request = jest.fn(() => - Promise.resolve({ count: 1023 }) - ); - }); - - test('should resolve with the count', done => { - testContext.collection.count({ from: 'ben@nylas.com' }).then(count => { - expect(count).toBe(1023); - done(); - }); - }); - - test('should call the optional callback with the count', done => { - testContext.collection.count( - { from: 'ben@nylas.com' }, - (callbackError, count) => { - expect(count).toBe(1023); - done(); - } - ); - }); - }); - - describe('when the request fails', () => { - beforeEach(() => { - testContext.error = new Error('Network error'); - testContext.connection.request = jest.fn(() => { - return Promise.reject(testContext.error); - }); - }); - - test('should reject with any error', done => { - testContext.collection - .count({ from: 'ben@nylas.com' }) - .catch(rejectError => { - expect(rejectError).toBe(testContext.error); - done(); - }); - }); - - test('should call the optional callback with any error', done => { - testContext.collection - .count({ from: 'ben@nylas.com' }, (callbackError, count) => { - expect(callbackError).toBe(testContext.error); - done(); - }) - .catch(() => {}); - }); - }); - }); - - describe('first', () => { - describe('when the request is successful', () => { - beforeEach(() => { - testContext.item = { - id: '123', - headers: { - 'In-Reply-To': null, - 'Message-Id': '<123@mailer.nylas.com>', - References: [], - }, - }; - testContext.items = [testContext.item]; - testContext.collection._getModelCollection = jest.fn(() => { - return Promise.resolve(testContext.items); - }); - }); - - test('should fetch one item with the provided params', done => { - testContext.collection - .first({ - from: 'ben@nylas.com', - view: 'expanded', - }) - .then(msg => { - expect( - testContext.collection._getModelCollection - ).toHaveBeenCalledWith( - { from: 'ben@nylas.com', view: 'expanded' }, - 0, - 1, - '/threads' - ); - expect(msg).toBe(testContext.item); - done(); - }); - }); - - test('should resolve with the first item', done => { - testContext.collection.first({ from: 'ben@nylas.com' }).then(item => { - expect(item).toBe(testContext.item); - done(); - }); - }); - - test('should call the optional callback with the first item', done => { - testContext.collection.first({ from: 'ben@nylas.com' }, (err, item) => { - expect(item).toBe(testContext.item); - done(); - }); - }); - - test('should not throw an exception when no items are returned', done => { - testContext.items = []; - testContext.collection.first({ from: 'ben@nylas.com' }).then(item => { - expect(item).toBe(undefined); - done(); - }); - }); - }); - - describe('when the request fails', () => { - beforeEach(() => { - testContext.error = new Error('Network error'); - testContext.collection._getModelCollection = jest.fn(() => { - return Promise.reject(testContext.error); - }); - }); - - test('should reject with any underlying error', done => { - testContext.collection.first({ from: 'ben@nylas.com' }).catch(err => { - expect(err).toBe(testContext.error); - done(); - }); - }); - - test('should call the optional callback with the underlying error', done => { - testContext.collection - .first({ from: 'ben@nylas.com' }, (err, item) => { - expect(err).toBe(testContext.error); - done(); - }) - .catch(() => {}); - }); - }); - }); - - describe('list', () => - test('should call range() with an infinite range', () => { - testContext.collection._range = jest.fn(); - - const params = { from: 'ben@nylas.com' }; - const callback = () => {}; - testContext.collection.list(params, callback); - expect(testContext.collection._range).toHaveBeenCalledWith({ - params, - limit: Infinity, - callback, - }); - })); - - describe('find', () => { - test('should reject with an error if an id is not provided', () => { - testContext.collection.find().catch(() => {}); - }); - - test('should make an API request for the individual model', done => { - testContext.collection.find('123'); - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'GET', - path: '/threads/123', - qs: {}, - }); - done(); - }); - - test('should pass any additional params to the request', done => { - testContext.collection.find('123', null, { param: 1 }); - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'GET', - path: '/threads/123', - qs: { param: 1 }, - }); - done(); - }); - - describe('when the request succeeds', () => { - beforeEach(() => { - testContext.item = { id: '123' }; - testContext.connection.request = jest.fn(() => { - return Promise.resolve(testContext.item); - }); - }); - - test('should resolve with the item', done => { - testContext.collection.find('123').then(item => { - expect(item instanceof Thread).toBe(true); - expect(item.id).toBe('123'); - done(); - }); - }); - - test('should call the optional callback with the first item', done => { - testContext.collection.find('123', (err, item) => { - expect(item instanceof Thread).toBe(true); - expect(item.id).toBe('123'); - done(); - }); - }); - }); - - describe('when the request fails', () => { - beforeEach(() => { - testContext.error = new Error('Network error'); - testContext.connection.request = jest.fn(() => { - return Promise.reject(testContext.error); - }); - }); - - test('should reject with any underlying error', done => { - testContext.collection.find('123').catch(err => { - expect(err).toBe(testContext.error); - done(); - }); - }); - - test('should call the optional callback with the underlying error', done => { - testContext.collection - .find('123', (err, item) => { - expect(err).toBe(testContext.error); - done(); - }) - .catch(() => {}); - }); - }); - }); - - describe('search', () => { - test('should reject with an error if a query is not provided', () => { - testContext.collection.search().catch(err => { - expect(err).toBeInstanceOf(Error); - }); - }); - - test('should reject with an error if called on any model but Message or Thread', () => { - testContext.collection = new RestfulModelCollection( - Event, - testContext.connection - ); - testContext.collection.search().catch(err => { - expect(err).toBeInstanceOf(Error); - }); - }); - - test('should make an API request to search with query string', done => { - testContext.collection.search('blah').catch(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'GET', - path: '/threads/search', - qs: { limit: 40, offset: 0, q: 'blah' }, - }); - done(); - }); - }); - - test('should pass user-defined limit and offset to the request', done => { - testContext.collection - .search('blah', { limit: 1, offset: 1 }) - .catch(() => { - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'GET', - path: '/threads/search', - qs: { limit: 1, offset: 1, q: 'blah' }, - }); - done(); - }); - }); - - describe('when the request succeeds', () => { - beforeEach(() => { - testContext.item = { subject: 'Hey, Jackie!' }; - testContext.connection.request = jest.fn(() => { - return Promise.resolve([testContext.item]); - }); - }); - - test('should resolve with the item', done => { - testContext.collection.search('Jackie').then(threads => { - expect(threads[0] instanceof Thread).toBe(true); - expect(threads[0].subject).toContain('Jackie'); - done(); - }); - }); - - test('should call the optional callback with the first item', done => { - testContext.collection - .search('Jackie', {}, (err, threads) => { - expect(threads[0] instanceof Thread).toBe(true); - expect(threads[0].subject).toContain('Jackie'); - }) - .then(() => { - done(); - }); - }); - }); - - describe('when the request fails', () => { - beforeEach(() => { - testContext.error = new Error('Network error'); - testContext.connection.request = jest.fn(() => { - return Promise.reject(testContext.error); - }); - }); - - test('should reject with any underlying error', done => { - testContext.collection.search('Jackie').catch(err => { - expect(err).toBe(testContext.error); - done(); - }); - }); - - test('should call the optional callback with the underlying error', done => { - testContext.collection - .search('Jackie', {}, (err, item) => { - expect(err).toBe(testContext.error); - }) - .catch(() => { - done(); - }); - }); - }); - }); - - describe('delete', () => { - beforeEach(() => { - testContext.item = new Thread(testContext.connection, { - id: '123', - }); - }); - - test('should accept a model object as the first parameter', () => { - testContext.collection.delete(testContext.item); - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'DELETE', - qs: {}, - path: '/threads/123', - }); - }); - - test('should accept a model id as the first parameter', () => { - testContext.collection.delete(testContext.item.id); - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'DELETE', - qs: {}, - path: '/threads/123', - }); - }); - - test('should include params in the request if they were passed in', () => { - testContext.collection.delete(testContext.item.id, { foo: 'bar' }); - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'DELETE', - qs: { foo: 'bar' }, - path: '/threads/123', - }); - }); - - describe('when the api request is successful', () => { - test('should resolve', done => { - testContext.collection.delete(testContext.item.id).then(() => done()); - }); - - test('should call its callback with no error', done => { - testContext.collection.delete(testContext.item.id, err => { - expect(err).toBe(null); - done(); - }); - }); - }); - - describe('when the api request fails', () => { - beforeEach(() => { - testContext.error = new Error('Network error'); - testContext.connection.request = jest.fn(() => { - return Promise.reject(testContext.error); - }); - }); - - test('should reject', done => { - testContext.collection.delete(testContext.item.id).catch(err => { - expect(err).toBe(testContext.error); - done(); - }); - }); - - test('should call its callback with the error', done => { - testContext.collection - .delete(testContext.item.id, err => { - expect(err).toBe(testContext.error); - done(); - }) - .catch(() => {}); - }); - }); - }); - - describe('build', () => { - test('should return a new instance of the model class', () => { - expect(testContext.collection.build() instanceof Thread).toBe(true); - }); - - test('should initialize the new instance with the connection', () => { - expect(testContext.collection.build().connection).toBe( - testContext.connection - ); - }); - - test('should set other attributes provided to the build method', () => { - expect(testContext.collection.build({ subject: '123' }).subject).toEqual( - '123' - ); - }); - }); - - describe('path', () => - test("should return the modelClass' collectionName with no prefix", () => { - expect(testContext.collection.path()).toEqual('/threads'); - })); - - describe('_range', () => { - beforeEach(() => { - const threadsResponses = []; - for (let x = 0; x <= 3; x++) { - const response = []; - const count = x < 3 ? 99 : 12; - for ( - let i = 0, end = count, asc = 0 <= end; - asc ? i <= end : i >= end; - asc ? i++ : i-- - ) { - response.push({ - id: '123', - account_id: undefined, - subject: 'A', - }); - } - threadsResponses.push(response); - } - - testContext.collection._getModelCollection = jest.fn( - (params, offset, limit) => - Promise.resolve(threadsResponses[offset / 100]) - ); - }); - - test('should fetch once if fewer than one page of models are requested', () => { - const params = { from: 'ben@nylas.com' }; - const threads = [ - { - id: '123', - account_id: undefined, - subject: 'A', - }, - ]; - testContext.collection._range({ params, offset: 0, limit: 50 }); - expect(testContext.collection._getModelCollection).toHaveBeenCalledWith( - params, - 0, - 50, - '/threads' - ); - }); - - test('should fetch repeatedly until the requested number of models have been returned', () => { - const params = { from: 'ben@nylas.com' }; - const threads = [ - { - id: '123', - account_id: undefined, - subject: 'A', - }, - ]; - const callback = () => { - expect( - testContext.collection._getModelCollection.mock.calls[0] - ).toEqual([{ from: 'ben@nylas.com' }, 0, 100, '/threads']); - expect( - testContext.collection._getModelCollection.mock.calls[1] - ).toEqual([{ from: 'ben@nylas.com' }, 100, 100, '/threads']); - expect( - testContext.collection._getModelCollection.mock.calls[2] - ).toEqual([{ from: 'ben@nylas.com' }, 200, 100, '/threads']); - }; - testContext.collection._range({ - params, - callback, - offset: 0, - limit: 300, - }); - }); - - test('should stop fetching if fewer than requested models are returned', () => { - const params = { from: 'ben@nylas.com' }; - const callback = () => { - expect( - testContext.collection._getModelCollection.mock.calls[0] - ).toEqual([{ from: 'ben@nylas.com' }, 0, 100, '/threads']); - expect( - testContext.collection._getModelCollection.mock.calls[1] - ).toEqual([{ from: 'ben@nylas.com' }, 100, 100, '/threads']); - expect( - testContext.collection._getModelCollection.mock.calls[2] - ).toEqual([{ from: 'ben@nylas.com' }, 200, 100, '/threads']); - expect( - testContext.collection._getModelCollection.mock.calls[3] - ).toEqual([{ from: 'ben@nylas.com' }, 300, 100, '/threads']); - }; - testContext.collection._range({ - params, - callback, - offset: 0, - limit: 10000, - }); - }); - - test('should call the callback with all of the loaded models', done => { - const params = { from: 'ben@nylas.com' }; - testContext.collection._range({ - params, - offset: 0, - limit: 10000, - callback: (err, models) => { - expect(models.length).toBe(313); - done(); - }, - }); - }); - - test('should resolve with the loaded models', done => { - const params = { from: 'ben@nylas.com' }; - testContext.collection - ._range({ params, offset: 0, limit: 10000 }) - .then(function(models) { - expect(models.length).toBe(313); - done(); - }); - }); - }); -}); diff --git a/__tests__/restful-model-spec.js b/__tests__/restful-model-spec.js deleted file mode 100644 index d2c03918..00000000 --- a/__tests__/restful-model-spec.js +++ /dev/null @@ -1,203 +0,0 @@ -import Promise from 'bluebird'; -import request from 'request'; -import _ from 'underscore'; - -import Nylas from '../src/nylas'; -import NylasConnection from '../src/nylas-connection'; -import RestfulModel from '../src/models/restful-model'; -import Attributes from '../src/models/attributes'; - -class RestfulSubclassA extends RestfulModel {} - -class RestfulSubclassB extends RestfulModel {} - -class RestfulSubclassAttributes extends RestfulModel {} -RestfulSubclassAttributes.attributes = _.extend({}, RestfulModel.attributes, { - testNumber: Attributes.Number({ - modelKey: 'testNumber', - jsonKey: 'test_number', - }), - testBoolean: Attributes.Boolean({ - modelKey: 'testBoolean', - jsonKey: 'test_boolean', - }), -}); - -describe('RestfulModel', () => { - let testContext; - - beforeEach(() => { - testContext = {}; - testContext.connection = new NylasConnection('token'); - }); - - test('should throw an exception unless constructed with a connection', () => { - expect(() => new RestfulModel()).toThrow(); - expect(() => new RestfulModel(testContext.connection)).not.toThrow(); - }); - - test('should accept JSON properties', () => { - const model = new RestfulModel(testContext.connection, { - object: 'thread', - id: '123', - }); - expect(model.object).toBe('thread'); - expect(model.id).toBe('123'); - }); - - describe('attributes', () => - test('should return the attributes attached to the class', () => { - const model = new RestfulModel(testContext.connection, { - object: 'thread', - id: '123', - }); - expect(model.attributes()).toBe(model.constructor.attributes); - })); - - describe('isEqual', () => { - beforeEach(() => { - testContext.model1 = new RestfulModel(testContext.connection, { - object: 'thread', - id: 'A', - }); - testContext.model2 = new RestfulModel(testContext.connection, { - object: 'thread', - id: 'A', - }); - testContext.model3 = new RestfulModel(testContext.connection, { - object: 'thread', - id: 'B', - }); - testContext.model4 = new RestfulSubclassA(testContext.connection, { - object: 'thread', - id: 'B', - }); - testContext.model5 = new RestfulSubclassB(testContext.connection, { - object: 'thread', - id: 'C', - }); - testContext.model6 = new RestfulSubclassB(testContext.connection, { - object: 'thread', - id: 'C', - }); - }); - - test('should return true if the objects are of the same class and have the same id', () => { - expect(testContext.model1.isEqual(testContext.model2)).toBe(true); - expect(testContext.model5.isEqual(testContext.model6)).toBe(true); - }); - - test('should return false otherwise', () => { - expect(testContext.model1.isEqual(testContext.model3)).toBe(false); - expect(testContext.model3.isEqual(testContext.model4)).toBe(false); - }); - }); - - describe('fromJSON', () => { - beforeEach(() => { - testContext.json = { - id: '1234', - account_id: '1234', - test_number: 4, - test_boolean: true, - daysOld: 4, - }; - testContext.m = new RestfulSubclassAttributes(testContext.connection); - }); - - test('should assign attribute values by calling through to attribute fromJSON functions', () => { - const testNumberFromJSON = - RestfulSubclassAttributes.attributes.testNumber.fromJSON; - RestfulSubclassAttributes.attributes.testNumber.fromJSON = jest.fn( - json => 'inflated value!' - ); - testContext.m.fromJSON(testContext.json); - expect( - RestfulSubclassAttributes.attributes.testNumber.fromJSON.mock.calls - .length - ).toBe(1); - expect(testContext.m.testNumber).toBe('inflated value!'); - RestfulSubclassAttributes.attributes.testNumber.fromJSON = testNumberFromJSON; - }); - - test('should not touch attributes that are missing in the json', () => { - testContext.m.fromJSON(testContext.json); - expect(testContext.m.object).toBe(undefined); - - testContext.m.object = 'abc'; - testContext.m.fromJSON(testContext.json); - expect(testContext.m.object).toBe('abc'); - }); - - test('should not do anything with extra JSON keys', () => { - testContext.m.fromJSON(testContext.json); - expect(testContext.m.daysOld).toBe(undefined); - }); - - describe('Attributes.Number', () => - test('should read number attributes and coerce them to numeric values', () => { - testContext.m.fromJSON({ test_number: 4 }); - expect(testContext.m.testNumber).toBe(4); - - testContext.m.fromJSON({ test_number: '4' }); - expect(testContext.m.testNumber).toBe(4); - - testContext.m.fromJSON({ test_number: 'lolz' }); - expect(testContext.m.testNumber).toBe(null); - - testContext.m.fromJSON({ test_number: 0 }); - expect(testContext.m.testNumber).toBe(0); - })); - - describe('Attributes.Boolean', () => - test('should read `true` or true and coerce everything else to false', () => { - testContext.m.fromJSON({ test_boolean: true }); - expect(testContext.m.testBoolean).toBe(true); - - testContext.m.fromJSON({ test_boolean: 'true' }); - expect(testContext.m.testBoolean).toBe(true); - - testContext.m.fromJSON({ test_boolean: 4 }); - expect(testContext.m.testBoolean).toBe(false); - - testContext.m.fromJSON({ test_boolean: '4' }); - expect(testContext.m.testBoolean).toBe(false); - - testContext.m.fromJSON({ test_boolean: false }); - expect(testContext.m.testBoolean).toBe(false); - - testContext.m.fromJSON({ test_boolean: 0 }); - expect(testContext.m.testBoolean).toBe(false); - - testContext.m.fromJSON({ test_boolean: null }); - expect(testContext.m.testBoolean).toBe(false); - })); - }); - - describe('toJSON', () => { - beforeEach(() => { - testContext.model = new RestfulModel(testContext.connection, { - id: '1234', - account_id: 'ACD', - }); - }); - - test('should return a JSON object and call attribute toJSON functions to map values', () => { - RestfulModel.attributes.accountId.toJSON = jest.fn( - json => 'inflated value!' - ); - - const json = testContext.model.toJSON(); - expect(json instanceof Object).toBe(true); - expect(json.id).toBe('1234'); - expect(json.account_id).toBe('inflated value!'); - }); - - test('should surface any exception one of the attribute toJSON functions raises', () => { - RestfulModel.attributes.accountId.toJSON = jest.fn(json => { - throw new Error("Can't convert value into JSON format"); - }); - expect(() => testContext.model.toJSON()).toThrow(); - }); - }); -}); diff --git a/__tests__/thread-spec.js b/__tests__/thread-spec.js deleted file mode 100644 index 3284d50d..00000000 --- a/__tests__/thread-spec.js +++ /dev/null @@ -1,93 +0,0 @@ -import Promise from 'bluebird'; -import request from 'request'; -import _ from 'underscore'; - -import Nylas from '../src/nylas'; -import NylasConnection from '../src/nylas-connection'; -import Thread from '../src/models/thread'; -import Message from '../src/models/message'; -import { Label } from '../src/models/folder'; - -describe('Thread', () => { - let testContext; - - beforeEach(() => { - testContext = {}; - testContext.connection = new NylasConnection('123'); - testContext.connection.request = jest.fn(() => Promise.resolve()); - testContext.thread = new Thread(testContext.connection); - testContext.thread.id = '4333'; - testContext.thread.starred = true; - testContext.thread.unread = false; - return Promise.onPossiblyUnhandledRejection((e, promise) => {}); - }); - - describe('save', () => { - test('should do a PUT request with labels if labels is defined', () => { - const label = new Label(testContext.connection); - label.id = 'label_id'; - testContext.thread.labels = [label]; - testContext.thread.save().then(() => - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'PUT', - body: { - label_ids: ['label_id'], - starred: true, - unread: false, - }, - qs: {}, - path: '/threads/4333', - }) - ); - }); - - test('should do a PUT with folder if folder is defined', () => { - const label = new Label(testContext.connection); - label.id = 'label_id'; - testContext.thread.folder = label; - testContext.thread.save(); - expect(testContext.connection.request).toHaveBeenCalledWith({ - method: 'PUT', - body: { - folder_id: 'label_id', - starred: true, - unread: false, - }, - qs: {}, - path: '/threads/4333', - }); - }); - }); - - describe('fromJSON', () => - test('should populate messages and draft fields when receiving expanded thread', () => { - const m1 = { - id: 'm1', - object: 'message', - to: [{ name: 'Ben Bitdiddle', email: 'ben.bitdiddle@gmail.com' }], - }; - const m2 = { - id: 'm2', - object: 'message', - to: [{ name: 'Alice', email: 'alice@gmail.com' }], - }; - const draft = { - id: 'm3', - object: 'draft', - to: [{ name: 'Bob', email: 'bob@gmail.com' }], - }; - - const t = testContext.thread.fromJSON({ - messages: [m1, m2], - drafts: [draft], - }); - - expect(t.messages).toBeDefined(); - expect(t.messages[0] instanceof Message).toBe(true); - expect(t.messages[0].id).toBe('m1'); - expect(t.messages[1] instanceof Message).toBe(true); - expect(t.messages[1].id).toBe('m2'); - expect(t.drafts[0] instanceof Message).toBe(true); - expect(t.drafts[0].id).toBe('m3'); - })); -}); diff --git a/cjs-wrapper.d.ts b/cjs-wrapper.d.ts new file mode 100644 index 00000000..8ddae4bb --- /dev/null +++ b/cjs-wrapper.d.ts @@ -0,0 +1,14 @@ +/** + * TypeScript definitions for the CommonJS wrapper + * This provides proper typing for CommonJS imports + */ + +// Re-export all types from the main module +export * from './lib/types/models/index.js'; + +// Import the main Nylas class type +import Nylas from './lib/types/nylas.js'; + +// Export as both default and named for maximum compatibility +declare const nylasExport: typeof Nylas; +export = nylasExport; diff --git a/cjs-wrapper.js b/cjs-wrapper.js new file mode 100644 index 00000000..7179adcc --- /dev/null +++ b/cjs-wrapper.js @@ -0,0 +1,13 @@ +/** + * CommonJS wrapper for the Nylas SDK + * This file provides CommonJS compatibility by re-exporting the default export + * as the main module export while preserving named exports + */ + +const nylasModule = require('./lib/cjs/nylas.js'); + +// Export the default export as the main module export for CJS compatibility +module.exports = nylasModule.default; + +// Preserve all named exports +Object.assign(module.exports, nylasModule); diff --git a/diagrams/nylas-logo.png b/diagrams/nylas-logo.png new file mode 100644 index 00000000..87ad1f17 Binary files /dev/null and b/diagrams/nylas-logo.png differ diff --git a/example/authentication/.gitignore b/example/authentication/.gitignore deleted file mode 100644 index 1bf4259a..00000000 --- a/example/authentication/.gitignore +++ /dev/null @@ -1 +0,0 @@ -config.js diff --git a/example/authentication/app.js b/example/authentication/app.js deleted file mode 100644 index d1073971..00000000 --- a/example/authentication/app.js +++ /dev/null @@ -1,55 +0,0 @@ -const express = require('express'); -const path = require('path'); -const favicon = require('serve-favicon'); -const logger = require('morgan'); -const cookieParser = require('cookie-parser'); -const bodyParser = require('body-parser'); -const session = require('express-session'); -// Import secret and other configuration -const config = require('./config'); - -const routes = require('./routes/index'); - -const app = express(); - -app.use(logger('dev')); -app.use(bodyParser.json()); -app.use(bodyParser.urlencoded({ extended: true })); -app.use(cookieParser()); -app.use(session({ secret: config.nylasClientId })); -app.use(express.static(path.join(__dirname, 'public'))); - -app.use('/', routes); - -// catch 404 and forward to error handler -app.use(function(req, res, next) { - const err = new Error('Not Found'); - err.status = 404; - next(err); -}); - -// error handlers - -// development error handler -// will print stacktrace -if (app.get('env') === 'development') { - app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.json({ - message: err.message, - error: err, - }); - }); -} - -// production error handler -// no stacktraces leaked to user -app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.json({ - message: err.message, - error: err, - }); -}); - -module.exports = app; diff --git a/example/authentication/auth.js b/example/authentication/auth.js deleted file mode 100644 index bb18bc79..00000000 --- a/example/authentication/auth.js +++ /dev/null @@ -1,72 +0,0 @@ -const config = require('./config'); -const request = require('request-promise'); -const url = require('url'); - -if (config.nylasClientSecret === '' || config.nylasClientId === '') { - throw 'You need to add your Nylas client secret to config.js first!'; -} - -// setup the Nylas API -global.Nylas = require('nylas').config({ - appId: config.nylasClientId, - appSecret: config.nylasClientSecret, -}); - -// First POST to /connect/authorize to get an authorization code from Nylas -// Then post to /connect/token to get an access_token that can be used to access -// account data -function connectToNylas(data) { - return nylasCode(data) - .then(code => { - const params = { - client_id: config.nylasClientId, - client_secret: config.nylasClientSecret, - code: code, - }; - return nylasToken(params) - .then(token => { - return Promise.resolve(token); - }) - .catch(err => { - return Promise.reject( - new Error(`Could not connect to Nylas. Error: ${err.message}`) - ); - }); - }) - .catch(err => { - return Promise.reject( - new Error(`Could not connect to Nylas. Error: ${err.message}`) - ); - }); -} -module.exports.connectToNylas = connectToNylas; - -function nylasCode(data) { - const connect_uri = config.nylasApi + '/connect/authorize'; - return request - .post({ url: connect_uri, json: data }) - .then(body => { - return Promise.resolve(body.code); - }) - .catch(err => { - return Promise.reject( - new Error(`Could not fetch Nylas code: ${err.message}`) - ); - }); -} - -function nylasToken(data) { - const token_uri = config.nylasApi + '/connect/token'; - return request - .post({ url: token_uri, json: data }) - .then(body => { - return Promise.resolve(body.access_token); - }) - .catch(err => { - return Promise.reject( - new Error(`Could not fetch Nylas access token: ${err.message}`) - ); - }); -} - -config.redirect_uri = 'http://localhost:3000/google/oauth2callback'; diff --git a/example/authentication/bin/www b/example/authentication/bin/www deleted file mode 100755 index a410d55d..00000000 --- a/example/authentication/bin/www +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env node - -/** - * Module dependencies. - */ - -var app = require('../app'); -const auth = require('../auth'); -var debug = require('debug')('authentication:server'); -var http = require('http'); - -/** - * Get port from environment and store in Express. - */ - -var port = normalizePort(process.env.PORT || '3000'); -app.set('port', port); - -/** - * Create HTTP server. - */ - -var server = http.createServer(app); - -/** - * Listen on provided port, on all network interfaces. - */ - -server.listen(port); -server.on('error', onError); -server.on('listening', onListening); - -/** - * Normalize a port into a number, string, or false. - */ - -function normalizePort(val) { - var port = parseInt(val, 10); - - if (isNaN(port)) { - // named pipe - return val; - } - - if (port >= 0) { - // port number - return port; - } - - return false; -} - -/** - * Event listener for HTTP server "error" event. - */ - -function onError(error) { - if (error.syscall !== 'listen') { - throw error; - } - - var bind = typeof port === 'string' - ? 'Pipe ' + port - : 'Port ' + port; - - // handle specific listen errors with friendly messages - switch (error.code) { - case 'EACCES': - console.error(bind + ' requires elevated privileges'); - process.exit(1); - break; - case 'EADDRINUSE': - console.error(bind + ' is already in use'); - process.exit(1); - break; - default: - throw error; - } -} - -/** - * Event listener for HTTP server "listening" event. - */ - -function onListening() { - var addr = server.address(); - var bind = typeof addr === 'string' - ? 'pipe ' + addr - : 'port ' + addr.port; - debug('Listening on ' + bind); -} diff --git a/example/authentication/config.js.template b/example/authentication/config.js.template deleted file mode 100644 index f25f79af..00000000 --- a/example/authentication/config.js.template +++ /dev/null @@ -1,10 +0,0 @@ -const config = {}; - -config.nylasClientId = ''; -config.nylasClientSecret = ''; -config.googleClientId= ''; -config.googleClientSecret = ''; - -config.nylasApi = 'https://api.nylas.com'; - -module.exports = config; diff --git a/example/authentication/package.json b/example/authentication/package.json deleted file mode 100644 index d9967d59..00000000 --- a/example/authentication/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "authentication", - "version": "0.0.0", - "private": true, - "scripts": { - "start": "node ./bin/www" - }, - "dependencies": { - "body-parser": "~1.15.1", - "cookie-parser": "~1.4.3", - "debug": "~2.2.0", - "express": "~4.13.4", - "jade": "~1.11.0", - "morgan": "~1.7.0", - "request-promise": "^4.1.1", - "serve-favicon": "~2.3.0" - }, - "devDependencies": { - "express-session": "^1.14.1", - "nylas": "^2.2.0" - } -} diff --git a/example/authentication/public/stylesheets/style.css b/example/authentication/public/stylesheets/style.css deleted file mode 100644 index bcafeaf5..00000000 --- a/example/authentication/public/stylesheets/style.css +++ /dev/null @@ -1,141 +0,0 @@ -@import url(https://fonts.googleapis.com/css?family=Roboto:300); - -.login-page { - width: 360px; - padding: 8% 0 0; - margin: auto; -} -.form { - position: relative; - z-index: 1; - background: #FFFFFF; - max-width: 360px; - margin: 0 auto 100px; - padding: 45px; - text-align: center; - box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24); -} -.form input { - font-family: "Roboto", sans-serif; - outline: 0; - background: #f2f2f2; - width: 100%; - border: 0; - margin: 0 0 15px; - padding: 15px; - box-sizing: border-box; - font-size: 14px; -} -.form .message { - margin: 15px 0 0; - color: #b3b3b3; - font-size: 12px; -} -.form .message a { - color: #4CAF50; - text-decoration: none; -} -.form .register-form { - display: none; -} -.container { - position: relative; - z-index: 1; - max-width: 300px; - margin: 0 auto; -} -.container:before, .container:after { - content: ""; - display: block; - clear: both; -} -.container .info { - margin: 50px auto; - text-align: center; -} -.container .info h1 { - margin: 0 0 15px; - padding: 0; - font-size: 36px; - font-weight: 300; - color: #1a1a1a; -} -.container .info span { - color: #4d4d4d; - font-size: 12px; -} -.container .info span a { - color: #000000; - text-decoration: none; -} -.container .info span .fa { - color: #EF3B3A; -} - -.exchange { - background: #76b852; /* fallback for old browsers */ - background: -webkit-linear-gradient(right, #76b852, #8DC26F); - background: -moz-linear-gradient(right, #76b852, #8DC26F); - background: -o-linear-gradient(right, #76b852, #8DC26F); - background: linear-gradient(to left, #76b852, #8DC26F); - font-family: "Roboto", sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} -.login { - background: #0B2545; /* fallback for old browsers */ - background: -webkit-linear-gradient(right, #0B2545, #09203D); - background: -moz-linear-gradient(right, #0B2545, #09203D); - background: -o-linear-gradient(right, #0B2545, #09203D); - background: linear-gradient(to left, #0B2545, #09203D); - font-family: "Roboto", sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -} -p { - padding-bottom: 15px; -} -a { - color: #eee; - text-decoration: none; -} - -.login-btn { - font-family: "Roboto", sans-serif; - text-transform: uppercase; - outline: 0; - background: #13315C; - width: 100%; - border: 0; - padding: 15px; - color: #FFFFFF; - font-size: 14px; - -webkit-transition: all 0.3 ease; - transition: all 0.3 ease; - cursor: pointer; - margin-bottom: 5px; -} - -.login-btn:hover, .login-btn:active, .login-btn:focus { - background: #134074; -} - -.exchange-btn { - font-family: "Roboto", sans-serif; - text-transform: uppercase; - outline: 0; - background: #4CAF50; - width: 100%; - border: 0; - padding: 15px; - color: #FFFFFF; - font-size: 14px; - -webkit-transition: all 0.3 ease; - transition: all 0.3 ease; - cursor: pointer; -} - -.exchange-btn:hover, .exchange-btn:active, .exchange-btn:focus { - background: #43A047; -} diff --git a/example/authentication/readme.md b/example/authentication/readme.md deleted file mode 100644 index 6fdee3a1..00000000 --- a/example/authentication/readme.md +++ /dev/null @@ -1,93 +0,0 @@ -# Nylas Connect - -This tiny [Express](https://expressjs.com/) app is a simple example of how to -use Nylas' [Native authentication -APIs](https://www.nylas.com/docs/platform#native_authentication). You can -connect both Exchange accounts and Gmail account's in this example. - -It shows how to receive a `refresh_token` from Google before authenticating with -Nylas. Then it uses the Nylas Ruby SDK to connect an email account and load the -user's latest email. - -While this steps through the Google OAuth flow manually, you can alternatively -use Google API SDKs for node and many other languages. Learn more about that -[here](https://developers.google.com/api-client-library/python/). You can also -learn more about Google OAuth -[here](https://developers.google.com/identity/protocols/OAuth2WebServer). - -Here is an overview of the complete flow when connecting a Google account. - -``` -Your App Google -+------+ +-----+ -| | Redirect user to Oauth Login | | -| +----------------------------------> | | -| | | | -| | Authorization code | | -| | <--(localhost)-<-------------------+ | -| | | | -| | Request refresh token | | -| +----------------------------------> | | -| | | | -| | Refresh & access token | | -| | <----------------------------------+ | -| | +-----+ -| | -| | -| | Nylas -| | Request Authorization code +-----+ -| +----------------------------------> | | -| | | | -| | Authorization code | | -| | <----------------------------------+ | -| | | | -| | Request Access Token | | -| +----------------------------------> | | -| | | | -| | Access Token | | -| | <----------------------------------+ | -+------+ +-----+ -``` - -# Getting Started - -## Dependencies - -### Google Application - -You'll need to have a Nylas [developer account](https://developer.nylas.com), a -Google Application (if you'd like to connect Google accounts), and the -respective `client_id` and `client_secret`s. Learn about how to setup the -Google App to correctly work with Nylas -[here](https://docs.nylas.com/docs/native-auth-google-oauth-setup-guide). - -After you follow that setup doc, you'll have to configure your google client app -to properly redirect to this example app. On the Google developer console, under -the credentials tab, click the edit button for the client ID that you created. -Add `http://localhost:3000/google/oauth2callback` as an authorized redirect URI -and save this change. Now a user will be redirected back to to this example -app after authenticating. - -## Initial Setup - -Add your google and nylas client id's and secrets to a new file `config.js`. -See `config.js.template` for an example. - -Then install dependencies with: -``` -npm install -``` - -# Running the app - -Run the express app. - -```bash -npm start -``` - -Visit http://localhost:3000 in your browser. - -Auth a gmail account. After, you will be redirected back to the example -application. To show a basic use case for what you can do after authing -with Nylas, we added a button to get the authed accounts most recent email! diff --git a/example/authentication/routes/index.js b/example/authentication/routes/index.js deleted file mode 100644 index 1eaa3768..00000000 --- a/example/authentication/routes/index.js +++ /dev/null @@ -1,196 +0,0 @@ -const express = require('express'); -const router = express.Router(); -const path = require('path'); -const querystring = require('querystring'); -const request = require('request-promise'); -const config = require('../config'); -const auth = require('../auth'); - -// These are the permissions your app will ask the user to approve for access -// https://developers.google.com/identity/protocols/OAuth2WebServer#scope -const GOOGLE_SCOPES = [ - 'https://mail.google.com/', - 'https://www.googleapis.com/auth/calendar', - 'https://www.googleapis.com/auth/userinfo.email', - 'https://www.googleapis.com/auth/userinfo.profile', - 'https://www.googleapis.com/auth/calendar', - 'https://www.google.com/m8/feeds/', -].join(' '); - -// This is the path in your Google application that users are redirected to after -// they have authenticated with Google, and it must be authorized through -// Google's developer console -const GOOGLE_OAUTH_TOKEN_VALIDATION_URL = - 'https://www.googleapis.com/oauth2/v2/tokeninfo'; -const GOOGLE_OAUTH_AUTH_URL = 'https://accounts.google.com/o/oauth2/v2/auth'; -const GOOGLE_OAUTH_ACCESS_TOKEN_URL = - 'https://www.googleapis.com/oauth2/v4/token'; - -function get_email_from_access_token(google_access_token) { - const data = { - access_token: google_access_token, - fields: 'email', - }; - return request - .post({ url: GOOGLE_OAUTH_TOKEN_VALIDATION_URL, form: data }) - .then(body => { - return Promise.resolve(JSON.parse(body).email); - }) - .catch(err => { - return Promise.reject(`Error validating Google token: ${err.message}`); - }); -} - -// This is the url Google will call once a user has approved access to their -// account -router.get('/google/oauth2callback', function(req, res, next) { - if (!req.query.code) { - const data = { - response_type: 'code', - access_type: 'offline', - client_id: config.googleClientId, - redirect_uri: config.redirect_uri, - scope: GOOGLE_SCOPES, - // Note: this is only for testing to ensure a refresh token is - // passed everytime, but requires the user to approve offline - // access every time. You should remove this if you don't want - // your user to have to approve access each time they connect - prompt: 'consent', - }; - const auth_uri = GOOGLE_OAUTH_AUTH_URL + '?' + querystring.stringify(data); - res.redirect(auth_uri); - } else { - // The user just successfully authenticated with Google and was redirected - // back here with a Google code - const auth_code = req.query.code; - const data = { - code: auth_code, - client_id: config.googleClientId, - client_secret: config.googleClientSecret, - redirect_uri: config.redirect_uri, - grant_type: 'authorization_code', - }; - - // Using Google's authorization code we can get an access and refresh token - const options = { - uri: GOOGLE_OAUTH_ACCESS_TOKEN_URL, - method: 'POST', - form: data, - }; - - request(options) - .then(body => { - json = JSON.parse(body); - req.session.google_refresh_token = json.refresh_token; - req.session.google_access_token = json.access_token; - res.redirect('/google'); - }) - .catch(err => { - console.log(`Error getting refresh token: ${err.message}`); - }); - } -}); - -router.get('/google', function(req, res, next) { - // User hasn't authorized with google yet, so we should redirect - if (!req.session.google_access_token) { - res.redirect('/google/oauth2callback'); - } - - // The user has authorized with google at this point but we will need to - // connect the account to Nylas - if (!req.session.nylas_access_token) { - const google_access_token = req.session.google_access_token; - get_email_from_access_token(google_access_token) - .then(email => { - const google_refresh_token = req.session.google_refresh_token; - const google_settings = { - google_client_id: config.googleClientId, - google_client_secret: config.googleClientSecret, - google_refresh_token: google_refresh_token, - }; - const data = { - client_id: config.nylasClientId, - name: 'Your Name', - email_address: email, - provider: 'gmail', - settings: google_settings, - }; - auth - .connectToNylas(data) - .then(token => { - // User has succesfully authorized with google and connected to Nylas. Redirect - // to homepage so we can show some emails! - req.session.nylas_access_token = token; - res.redirect('/'); - }) - .catch(err => { - console.log(err); - res.redirect('/google/oauth2callback'); - }); - }) - .catch(err => { - console.log(err); - res.redirect('/google'); - }); - } -}); - -router.post('/exchange', function(req, res, next) { - // User gave us their username and password and submitted the form. Use the - // data now to login with Nylas - if (!req.session.nylas_access_token) { - const json = req.body; - const exchange_settings = { - username: json.email, - password: json.password, - }; - const data = { - client_id: config.nylasClientId, - name: json.name, - email_address: json.email, - provider: 'exchange', - settings: exchange_settings, - }; - auth.connectToNylas(data).then(token => { - req.session.nylas_access_token = token; - res.redirect('/'); - }); - } -}); - -router.get('/exchange', function(req, res, next) { - // Show a login form for a user to enter their information - res.sendFile(path.join(__dirname + '/../views/exchange_login.html')); -}); - -router.get('/choose-login', function(req, res, next) { - res.sendFile(path.join(__dirname + '/../views/choose_login.html')); -}); - -router.get('/logout', function(req, res, next) { - req.session.destroy(); - res.redirect('/'); -}); - -router.get('/get-message', function(req, res, next) { - // Account has been setup, let's use Nylas' Node SDK to retrieve an email - const nylas = Nylas.with(req.session.nylas_access_token); - - // Find the first message matching the filter criteria - nylas.messages.first().then(function(message) { - res.send(message.body); - }); -}); - -router.get('/', function(req, res, next) { - if (!req.session.nylas_access_token) { - // If the user hasn't connected their email account from any provider, send - // them to a login page that will allow them to connect any kind of account - return res.redirect('/choose-login'); - } - - res.sendFile(path.join(__dirname + '/../views/authed_account.html')); -}); - -module.exports = router; diff --git a/example/authentication/views/authed_account.html b/example/authentication/views/authed_account.html deleted file mode 100644 index 5c0b5b8e..00000000 --- a/example/authentication/views/authed_account.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - Nylas Login - - - - - - - - - - diff --git a/example/authentication/views/choose_login.html b/example/authentication/views/choose_login.html deleted file mode 100644 index 20dae5b3..00000000 --- a/example/authentication/views/choose_login.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - Nylas Login - - - - - - - - - - diff --git a/example/authentication/views/exchange_login.html b/example/authentication/views/exchange_login.html deleted file mode 100644 index 9f9cfbad..00000000 --- a/example/authentication/views/exchange_login.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - Nylas Exchange Login - - - - - - - - - diff --git a/example/sample-app/app.js b/example/sample-app/app.js deleted file mode 100644 index 440a1203..00000000 --- a/example/sample-app/app.js +++ /dev/null @@ -1,107 +0,0 @@ -var express = require('express'); -var path = require('path'); -var favicon = require('serve-favicon'); -var logger = require('morgan'); -var cookieParser = require('cookie-parser'); -var bodyParser = require('body-parser'); -var session = require('express-session'); -var assert = require('assert'); - -var routes = require('./routes/index'); -var threads = require('./routes/threads'); -var dashboard = require('./routes/dashboard'); - -var app = express(); - -// view engine setup -app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'pug'); - -var nylasAppConfigs = { - appId: '', - appSecret: '', -}; - -assert.notEqual( - nylasAppConfigs.appId, - '', - 'Please replace with you Nylas App ID' -); -assert.notEqual( - nylasAppConfigs.appSecret, - '', - 'Please replace with your Nylas App Secret' -); - -// setup the Nylas API -global.Nylas = require('nylas').config(nylasAppConfigs); - -app.use(favicon(__dirname + '/public/favicon.ico')); -app.use(logger('dev')); -app.use(bodyParser.json()); -app.use(bodyParser.urlencoded({ extended: false })); -app.use(cookieParser()); - -var sessionSecret = { - secret: '', -}; - -assert.notEqual( - sessionSecret.secret, - '', - 'Please replace with your session secret' -); - -app.use( - session( - Object.assign( - { - resave: false, - saveUninitialized: true, - }, - sessionSecret - ) - ) -); -app.use(express.static(path.join(__dirname, 'public'))); - -function checkAuth(req, res, next) { - if (!req.session.token) res.redirect('/'); - next(); -} -app.use('/', routes); -app.use('/threads', checkAuth, threads); -app.use('/dashboard', checkAuth, dashboard); - -// catch 404 and forward to error handler -app.use(function(req, res, next) { - var err = new Error('Not Found'); - err.status = 404; - next(err); -}); - -// error handlers - -// development error handler -// will print stacktrace -if (app.get('env') === 'development') { - app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: err, - }); - }); -} - -// production error handler -// no stacktraces leaked to user -app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: {}, - }); -}); - -module.exports = app; diff --git a/example/sample-app/bin/www b/example/sample-app/bin/www deleted file mode 100755 index a6550402..00000000 --- a/example/sample-app/bin/www +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env node - -/** - * Module dependencies. - */ - -var app = require('../app'); -var debug = require('debug')('example:server'); -var http = require('http'); -var opn = require('opn'); -/** - * Get port from environment and store in Express. - */ - -var port = normalizePort(process.env.PORT || '3000'); -app.set('port', port); - -/** - * Create HTTP server. - */ - -var server = http.createServer(app); - -/** - * Listen on provided port, on all network interfaces. - */ -var localHost = `http://localhost:${port}`; -server.listen(port, () => console.log(`> Listening on ${localHost}`)); -server.on('error', onError); -server.on('listening', onListening); - -/** - * Normalize a port into a number, string, or false. - */ - -function normalizePort(val) { - var port = parseInt(val, 10); - - if (isNaN(port)) { - // named pipe - return val; - } - - if (port >= 0) { - // port number - return port; - } - - return false; -} - -/** - * Event listener for HTTP server "error" event. - */ - -function onError(error) { - if (error.syscall !== 'listen') { - throw error; - } - - var bind = typeof port === 'string' - ? 'Pipe ' + port - : 'Port ' + port; - - // handle specific listen errors with friendly messages - switch (error.code) { - case 'EACCES': - console.error(bind + ' requires elevated privileges'); - process.exit(1); - break; - case 'EADDRINUSE': - console.error(bind + ' is already in use'); - process.exit(1); - break; - default: - throw error; - } -} - -/** - * Event listener for HTTP server "listening" event. - */ - -function onListening() { - var addr = server.address(); - var bind = typeof addr === 'string' - ? 'pipe ' + addr - : 'port ' + addr.port; - debug('Listening on ' + bind); -} - -if (process.env.NODE_ENV !== 'production') { - try { - opn(localHost) - } catch (err) { - console.error(err) - } -} - -// handle unhandledRejections -process.on("unhandledRejection", (err, promise) => { - console.error("Unhandled promise rejection:\n" + err.stack); -}); \ No newline at end of file diff --git a/example/sample-app/package.json b/example/sample-app/package.json deleted file mode 100644 index ad27cbb4..00000000 --- a/example/sample-app/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "example", - "version": "0.0.0", - "private": true, - "scripts": { - "start": "node ./bin/www", - "mac": "DEBUG=myapp:* npm start", - "win": "set DEBUG=myapp:* & npm start" - }, - "dependencies": { - "assert": "^1.4.1", - "async": "^0.9.0", - "bluebird": "^2.9.13", - "body-parser": "~1.12.0", - "cookie-parser": "~1.3.4", - "debug": "~2.1.1", - "express": "~4.12.0", - "express-session": "^1.15.6", - "morgan": "~1.5.1", - "nylas": "^2.1.0", - "opn": "^5.2.0", - "pug": "^2.0.0-rc.4", - "serve-favicon": "~2.2.0" - } -} diff --git a/example/sample-app/public/favicon.ico b/example/sample-app/public/favicon.ico deleted file mode 100644 index 56507c03..00000000 Binary files a/example/sample-app/public/favicon.ico and /dev/null differ diff --git a/example/sample-app/public/stylesheets/style.css b/example/sample-app/public/stylesheets/style.css deleted file mode 100644 index a153f4cb..00000000 --- a/example/sample-app/public/stylesheets/style.css +++ /dev/null @@ -1,14 +0,0 @@ -body { - padding: 50px; - font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; -} - -a { - color: #00B7FF; -} - -.frame { - border: 1px solid gray; - padding: 10px; - margin-bottom: 20px; -} \ No newline at end of file diff --git a/example/sample-app/readme.md b/example/sample-app/readme.md deleted file mode 100644 index 8e239ca3..00000000 --- a/example/sample-app/readme.md +++ /dev/null @@ -1,42 +0,0 @@ -# Nylas Connect - -This tiny [Express](https://expressjs.com/) app is a simple example of how to -use Nylas NodeJS SDK. You can -connect both Exchange accounts and Gmail accounts in this example. - -# Getting Started - -## Initial Setup -You will need to have a Nylas [developer account](https://dashboard.nylas.com). -On the dashboard, select the application that you want to connect to this sample -app. Copy the application id and secret to the config code on lines 22 and 23 of -`app.js` and then on line 48 of `app.js` enter your own `sessionSecret`. - -Next, you have to add the redirect URI for this sample app to your applications -callbacks. To navigate to the application callback page, go to the all applications -page and then select`edit` for your selected application. The application settings -page has two tabs, one for `Application Settings` and one for `Application Callbacks`. -Click the `Application Callbacks` tab and add the sample apps redirect URI: - -``` -http://localhost:3000/oauth/callback -``` -
-
- -
- -Install dependencies with: -``` -npm install -``` - -# Running the app - -Run the express app. - -``` -npm start -``` - -Visit http://localhost:3000 in your browser. diff --git a/example/sample-app/routes/dashboard.js b/example/sample-app/routes/dashboard.js deleted file mode 100644 index 3cd7171b..00000000 --- a/example/sample-app/routes/dashboard.js +++ /dev/null @@ -1,12 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -router.get('/', function(req, res, next) { - res.render('dashboard', { - title: 'Your account has been linked!', - message: - 'Click the links below to test out some Nylas features for threads!', - }); -}); - -module.exports = router; diff --git a/example/sample-app/routes/index.js b/example/sample-app/routes/index.js deleted file mode 100644 index da5e8adc..00000000 --- a/example/sample-app/routes/index.js +++ /dev/null @@ -1,34 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -router.get('/', function(req, res, next) { - options = { - redirectURI: 'http://localhost:3000/oauth/callback', - trial: false, - }; - res.render('index', { - title: 'Welcome', - message: 'Link your email to get started.', - url: Nylas.urlForAuthentication(options), - }); -}); - -router.get('/oauth/callback', function(req, res, next) { - if (req.query.code) { - Nylas.exchangeCodeForToken(req.query.code).then(function(token) { - req.session.token = token; - res.redirect('/dashboard'); - }); - } else if (req.query.error) { - res.render('error', { - message: req.query.reason, - error: { - status: - 'Please try authenticating again or use a different email account.', - stack: '', - }, - }); - } -}); - -module.exports = router; diff --git a/example/sample-app/routes/threads.js b/example/sample-app/routes/threads.js deleted file mode 100644 index ba16adbc..00000000 --- a/example/sample-app/routes/threads.js +++ /dev/null @@ -1,25 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -router.get('/first', function(req, res, next) { - var nylas = Nylas.with(req.session.token); - var accountP = nylas.account.get(); - var threadP = nylas.threads.first(); - Promise.all([accountP, threadP]).then(function([account, thread]) { - res.render('thread', { - account: account.emailAddress, - thread: thread, - }); - }); -}); - -router.get('/list', function(req, res, next) { - var nylas = Nylas.with(req.session.token); - nylas.threads.list({ limit: 10 }).then(function(threadList) { - res.render('threadList', { - threads: threadList, - }); - }); -}); - -module.exports = router; diff --git a/example/sample-app/views/dashboard.pug b/example/sample-app/views/dashboard.pug deleted file mode 100644 index a022f541..00000000 --- a/example/sample-app/views/dashboard.pug +++ /dev/null @@ -1,12 +0,0 @@ -extends layout - -block content - h1= title - p= message - div - a(class='button', href='/threads/first') First thread - div - a(class='button', href='/threads/list') List of threads - br - div - a(href='/') Try another account diff --git a/example/sample-app/views/error.pug b/example/sample-app/views/error.pug deleted file mode 100644 index 51ec12c6..00000000 --- a/example/sample-app/views/error.pug +++ /dev/null @@ -1,6 +0,0 @@ -extends layout - -block content - h1= message - h2= error.status - pre #{error.stack} diff --git a/example/sample-app/views/index.pug b/example/sample-app/views/index.pug deleted file mode 100644 index 3af4eb59..00000000 --- a/example/sample-app/views/index.pug +++ /dev/null @@ -1,6 +0,0 @@ -extends layout - -block content - h1= title - p= message - a(href=url) Sign In diff --git a/example/sample-app/views/layout.pug b/example/sample-app/views/layout.pug deleted file mode 100644 index 6b75ca17..00000000 --- a/example/sample-app/views/layout.pug +++ /dev/null @@ -1,9 +0,0 @@ -doctype html -html - head - title= title - link(rel='stylesheet', href='/stylesheets/style.css') - link(rel="icon" href="/favicon.ico" type="image/x-icon") - link(rel="shortcut icon" href='https://www.nylas.com/hubfs/favicon64.png?t=1518776714856') - body - block content \ No newline at end of file diff --git a/example/sample-app/views/thread.pug b/example/sample-app/views/thread.pug deleted file mode 100644 index dbf89e5e..00000000 --- a/example/sample-app/views/thread.pug +++ /dev/null @@ -1,8 +0,0 @@ -extends layout - -block content - h1= 'First thread from ' + account - div(class='frame') - h3= thread.subject - p= thread.snippet - a(href='/dashboard') Try Another Function diff --git a/example/sample-app/views/threadList.pug b/example/sample-app/views/threadList.pug deleted file mode 100644 index 6723fa53..00000000 --- a/example/sample-app/views/threadList.pug +++ /dev/null @@ -1,9 +0,0 @@ -extends layout - -block content - h1= '10 Threads' - div(class='frame') - each thread in threads - li= thread.subject - - a(href='/dashboard') Try Another Function diff --git a/example/sample-app/yarn.lock b/example/sample-app/yarn.lock deleted file mode 100644 index 957db3e8..00000000 --- a/example/sample-app/yarn.lock +++ /dev/null @@ -1,1039 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -JSONStream@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.0.4.tgz#aa86d6a89c8e77f206cd542581b563e7eee32459" - dependencies: - jsonparse "~1.0.0" - through ">=2.2.7 <3" - -accepts@~1.2.7: - version "1.2.13" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.2.13.tgz#e5f1f3928c6d95fd96558c36ec3d9d0de4a6ecea" - dependencies: - mime-types "~2.1.6" - negotiator "0.5.3" - -acorn-globals@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-3.1.0.tgz#fd8270f71fbb4996b004fa880ee5d46573a731bf" - dependencies: - acorn "^4.0.4" - -acorn@^3.1.0, acorn@~3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" - -acorn@^4.0.4, acorn@~4.0.2: - version "4.0.13" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" - -ajv@^5.1.0: - version "5.5.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" - dependencies: - co "^4.6.0" - fast-deep-equal "^1.0.0" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" - -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" - -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - -asn1@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - -assert@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" - dependencies: - util "0.10.3" - -async@0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/async/-/async-0.9.0.tgz#ac3613b1da9bed1b47510bb4651b8931e47146c7" - -async@^0.9.0: - version "0.9.2" - resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - -aws4@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" - -backoff@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.4.1.tgz#2f68c50e0dd789dbefe24200a62efb04d2456d68" - dependencies: - precond "0.2" - -basic-auth@~1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-1.0.4.tgz#030935b01de7c9b94a824b29f3fccb750d3a5290" - -bcrypt-pbkdf@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" - dependencies: - tweetnacl "^0.14.3" - -bluebird@^2.9.13: - version "2.11.0" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" - -body-parser@~1.12.0: - version "1.12.4" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.12.4.tgz#090700c4ba28862a8520ef378395fdee5f61c229" - dependencies: - bytes "1.0.0" - content-type "~1.0.1" - debug "~2.2.0" - depd "~1.0.1" - iconv-lite "0.4.8" - on-finished "~2.2.1" - qs "2.4.2" - raw-body "~2.0.1" - type-is "~1.6.2" - -boom@4.x.x: - version "4.3.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" - dependencies: - hoek "4.x.x" - -boom@5.x.x: - version "5.2.0" - resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" - dependencies: - hoek "4.x.x" - -bytes@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-1.0.0.tgz#3569ede8ba34315fab99c3e92cb04c7220de1fa8" - -bytes@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.1.0.tgz#ac93c410e2ffc9cc7cf4b464b38289067f5e47b4" - -camelcase@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - -character-parser@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0" - dependencies: - is-regex "^1.0.3" - -clean-css@^3.3.0: - version "3.4.28" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-3.4.28.tgz#bf1945e82fc808f55695e6ddeaec01400efd03ff" - dependencies: - commander "2.8.x" - source-map "0.4.x" - -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - -clone@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.1.tgz#0b08a631bc6a4a41b89ce2a3d43f8a84d66b4d4b" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - -combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" - dependencies: - delayed-stream "~1.0.0" - -commander@2.8.x: - version "2.8.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" - dependencies: - graceful-readlink ">= 1.0.0" - -constantinople@^3.0.1: - version "3.1.0" - resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-3.1.0.tgz#7569caa8aa3f8d5935d62e1fa96f9f702cd81c79" - dependencies: - acorn "^3.1.0" - is-expression "^2.0.1" - -content-disposition@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.0.tgz#4284fe6ae0630874639e44e80a418c2934135e9e" - -content-type@~1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - -cookie-parser@~1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.3.5.tgz#9d755570fb5d17890771227a02314d9be7cf8356" - dependencies: - cookie "0.1.3" - cookie-signature "1.0.6" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - -cookie@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.1.2.tgz#72fec3d24e48a3432073d90c12642005061004b1" - -cookie@0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.1.3.tgz#e734a5c1417fce472d5aef82c381cabb64d1a435" - -cookie@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - -crc@3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/crc/-/crc-3.2.1.tgz#5d9c8fb77a245cd5eca291e5d2d005334bab0082" - -crc@3.4.4: - version "3.4.4" - resolved "https://registry.yarnpkg.com/crc/-/crc-3.4.4.tgz#9da1e980e3bd44fc5c93bf5ab3da3378d85e466b" - -cryptiles@3.x.x: - version "3.1.2" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" - dependencies: - boom "5.x.x" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - dependencies: - assert-plus "^1.0.0" - -debug@2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - dependencies: - ms "2.0.0" - -debug@~2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.1.3.tgz#ce8ab1b5ee8fbee2bfa3b633cab93d366b63418e" - dependencies: - ms "0.7.0" - -debug@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" - dependencies: - ms "0.7.1" - -decamelize@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - -depd@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.0.1.tgz#80aec64c9d6d97e65cc2a9caa93c0aa6abf73aaa" - -depd@~1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - -destroy@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.3.tgz#b433b4724e71fd8551d9885174851c5fc377e2c9" - -doctypes@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9" - -ecc-jsbn@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" - dependencies: - jsbn "~0.1.0" - -ee-first@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.0.tgz#6a0d7c6221e490feefd92ec3f441c9ce8cd097f4" - -escape-html@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.1.tgz#181a286ead397a39a92857cfb1d43052e356bff0" - -etag@~1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.6.0.tgz#8bcb2c6af1254c481dfc8b997c906ef4e442c207" - dependencies: - crc "3.2.1" - -express-session@^1.15.6: - version "1.15.6" - resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.15.6.tgz#47b4160c88f42ab70fe8a508e31cbff76757ab0a" - dependencies: - cookie "0.3.1" - cookie-signature "1.0.6" - crc "3.4.4" - debug "2.6.9" - depd "~1.1.1" - on-headers "~1.0.1" - parseurl "~1.3.2" - uid-safe "~2.1.5" - utils-merge "1.0.1" - -express@~4.12.0: - version "4.12.4" - resolved "https://registry.yarnpkg.com/express/-/express-4.12.4.tgz#8fec2510255bc6b2e58107c48239c0fa307c1aa2" - dependencies: - accepts "~1.2.7" - content-disposition "0.5.0" - content-type "~1.0.1" - cookie "0.1.2" - cookie-signature "1.0.6" - debug "~2.2.0" - depd "~1.0.1" - escape-html "1.0.1" - etag "~1.6.0" - finalhandler "0.3.6" - fresh "0.2.4" - merge-descriptors "1.0.0" - methods "~1.1.1" - on-finished "~2.2.1" - parseurl "~1.3.0" - path-to-regexp "0.1.3" - proxy-addr "~1.0.8" - qs "2.4.2" - range-parser "~1.0.2" - send "0.12.3" - serve-static "~1.9.3" - type-is "~1.6.2" - utils-merge "1.0.0" - vary "~1.0.0" - -extend@~3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - -fast-deep-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" - -fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - -finalhandler@0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-0.3.6.tgz#daf9c4161b1b06e001466b1411dfdb6973be138b" - dependencies: - debug "~2.2.0" - escape-html "1.0.1" - on-finished "~2.2.1" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - -form-data@~2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" - -forwarded@~0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - -fresh@0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.2.4.tgz#3582499206c9723714190edd74b4604feb4a614c" - -function-bind@^1.0.2: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - dependencies: - assert-plus "^1.0.0" - -"graceful-readlink@>= 1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - -har-validator@~5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" - dependencies: - ajv "^5.1.0" - har-schema "^2.0.0" - -has@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" - dependencies: - function-bind "^1.0.2" - -hawk@~6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" - dependencies: - boom "4.x.x" - cryptiles "3.x.x" - hoek "4.x.x" - sntp "2.x.x" - -hoek@4.x.x: - version "4.2.0" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -iconv-lite@0.4.8: - version "0.4.8" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.8.tgz#c6019a7595f2cefca702eab694a010bcd9298d20" - -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - -ipaddr.js@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.0.5.tgz#5fa78cf301b825c78abc3042d812723049ea23c7" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - -is-expression@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-2.1.0.tgz#91be9d47debcfef077977e9722be6dcfb4465ef0" - dependencies: - acorn "~3.3.0" - object-assign "^4.0.1" - -is-expression@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-3.0.0.tgz#39acaa6be7fd1f3471dc42c7416e61c24317ac9f" - dependencies: - acorn "~4.0.2" - object-assign "^4.0.1" - -is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - -is-regex@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - dependencies: - has "^1.0.1" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - -js-stringify@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - -json-schema-traverse@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - -jsonparse@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.0.0.tgz#2622f4e66c08e1aac7edbeb76053c9b7e1211f76" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -jstransformer@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3" - dependencies: - is-promise "^2.0.0" - promise "^7.0.1" - -kind-of@^3.0.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - dependencies: - is-buffer "^1.1.5" - -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - -merge-descriptors@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.0.tgz#2169cf7538e1b0cc87fb88e1502d8474bbf79864" - -methods@~1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - -mime-db@~1.30.0: - version "1.30.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" - -mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.17, mime-types@~2.1.6: - version "2.1.17" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" - dependencies: - mime-db "~1.30.0" - -mime@1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" - -morgan@~1.5.1: - version "1.5.3" - resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.5.3.tgz#8adb4e72f9e5c5436e5d93f42910835f79da9fdf" - dependencies: - basic-auth "~1.0.1" - debug "~2.2.0" - depd "~1.0.1" - on-finished "~2.2.1" - -ms@0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.0.tgz#865be94c2e7397ad8a57da6a633a6e2f30798b83" - -ms@0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - -negotiator@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.5.3.tgz#269d5c476810ec92edbe7b6c2f28316384f9a7e8" - -nylas@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/nylas/-/nylas-2.2.0.tgz#dcb8903e56bdd2e0d4bdab92032969f896b70b17" - dependencies: - JSONStream "1.0.4" - async "0.9.0" - backoff "2.4.1" - bluebird "^2.9.13" - clone "1.0.1" - request "^2.63.0" - underscore "^1.7.0" - -oauth-sign@~0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - -object-assign@^4.0.1, object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - -on-finished@~2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.2.1.tgz#5c85c1cc36299f78029653f667f27b6b99ebc029" - dependencies: - ee-first "1.1.0" - -on-headers@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" - -opn@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/opn/-/opn-5.2.0.tgz#71fdf934d6827d676cecbea1531f95d354641225" - dependencies: - is-wsl "^1.1.0" - -parseurl@~1.3.0, parseurl@~1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" - -path-parse@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" - -path-to-regexp@0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.3.tgz#21b9ab82274279de25b156ea08fd12ca51b8aecb" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - -precond@0.2: - version "0.2.3" - resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac" - -promise@^7.0.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - dependencies: - asap "~2.0.3" - -proxy-addr@~1.0.8: - version "1.0.10" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.0.10.tgz#0d40a82f801fc355567d2ecb65efe3f077f121c5" - dependencies: - forwarded "~0.1.0" - ipaddr.js "1.0.5" - -pug-attrs@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-2.0.2.tgz#8be2b2225568ffa75d1b866982bff9f4111affcb" - dependencies: - constantinople "^3.0.1" - js-stringify "^1.0.1" - pug-runtime "^2.0.3" - -pug-code-gen@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-2.0.0.tgz#96aea39a9e62f1ec5d2b6a5b42a29d528c70b43d" - dependencies: - constantinople "^3.0.1" - doctypes "^1.1.0" - js-stringify "^1.0.1" - pug-attrs "^2.0.2" - pug-error "^1.3.2" - pug-runtime "^2.0.3" - void-elements "^2.0.1" - with "^5.0.0" - -pug-error@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-1.3.2.tgz#53ae7d9d29bb03cf564493a026109f54c47f5f26" - -pug-filters@^2.1.5: - version "2.1.5" - resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-2.1.5.tgz#66bf6e80d97fbef829bab0aa35eddff33fc964f3" - dependencies: - clean-css "^3.3.0" - constantinople "^3.0.1" - jstransformer "1.0.0" - pug-error "^1.3.2" - pug-walk "^1.1.5" - resolve "^1.1.6" - uglify-js "^2.6.1" - -pug-lexer@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-3.1.0.tgz#fd087376d4a675b4f59f8fef422883434e9581a2" - dependencies: - character-parser "^2.1.1" - is-expression "^3.0.0" - pug-error "^1.3.2" - -pug-linker@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-3.0.3.tgz#25f59eb750237f0368e59c3379764229c0189c41" - dependencies: - pug-error "^1.3.2" - pug-walk "^1.1.5" - -pug-load@^2.0.9: - version "2.0.9" - resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-2.0.9.tgz#ee217c914cc1d9324d44b86c32d1df241d36de7a" - dependencies: - object-assign "^4.1.0" - pug-walk "^1.1.5" - -pug-parser@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-4.0.0.tgz#c9f52322e4eabe4bf5beeba64ed18373bb627801" - dependencies: - pug-error "^1.3.2" - token-stream "0.0.1" - -pug-runtime@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-2.0.3.tgz#98162607b0fce9e254d427f33987a5aee7168bda" - -pug-strip-comments@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-1.0.2.tgz#d313afa01bcc374980e1399e23ebf2eb9bdc8513" - dependencies: - pug-error "^1.3.2" - -pug-walk@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-1.1.5.tgz#90e943acbcf7021e6454cf1b32245891cba6f851" - -pug@^2.0.0-rc.4: - version "2.0.0-rc.4" - resolved "https://registry.yarnpkg.com/pug/-/pug-2.0.0-rc.4.tgz#b7b08f6599bd5302568042b7436984fb28c80a13" - dependencies: - pug-code-gen "^2.0.0" - pug-filters "^2.1.5" - pug-lexer "^3.1.0" - pug-linker "^3.0.3" - pug-load "^2.0.9" - pug-parser "^4.0.0" - pug-runtime "^2.0.3" - pug-strip-comments "^1.0.2" - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - -qs@2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-2.4.2.tgz#f7ce788e5777df0b5010da7f7c4e73ba32470f5a" - -qs@~6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" - -random-bytes@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" - -range-parser@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.0.3.tgz#6872823535c692e2c2a0103826afd82c2e0ff175" - -raw-body@~2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.0.2.tgz#a2c2f98c8531cee99c63d8d238b7de97bb659fca" - dependencies: - bytes "2.1.0" - iconv-lite "0.4.8" - -repeat-string@^1.5.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - -request@^2.63.0: - version "2.83.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.6.0" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.1" - forever-agent "~0.6.1" - form-data "~2.3.1" - har-validator "~5.0.3" - hawk "~6.0.2" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.17" - oauth-sign "~0.8.2" - performance-now "^2.1.0" - qs "~6.5.1" - safe-buffer "^5.1.1" - stringstream "~0.0.5" - tough-cookie "~2.3.3" - tunnel-agent "^0.6.0" - uuid "^3.1.0" - -resolve@^1.1.6: - version "1.5.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" - dependencies: - path-parse "^1.0.5" - -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - dependencies: - align-text "^0.1.1" - -safe-buffer@^5.0.1, safe-buffer@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - -send@0.12.3: - version "0.12.3" - resolved "https://registry.yarnpkg.com/send/-/send-0.12.3.tgz#cd12dc58fde21e4f91902b39b2fda05a7a6d9bdc" - dependencies: - debug "~2.2.0" - depd "~1.0.1" - destroy "1.0.3" - escape-html "1.0.1" - etag "~1.6.0" - fresh "0.2.4" - mime "1.3.4" - ms "0.7.1" - on-finished "~2.2.1" - range-parser "~1.0.2" - -serve-favicon@~2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.2.1.tgz#d97bacc150f66fe0e5cc4c78a84ba15bae5a584a" - dependencies: - etag "~1.6.0" - fresh "0.2.4" - ms "0.7.1" - parseurl "~1.3.0" - -serve-static@~1.9.3: - version "1.9.3" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.9.3.tgz#5f8da07323ad385ff3dc541f1a7917b2e436eb57" - dependencies: - escape-html "1.0.1" - parseurl "~1.3.0" - send "0.12.3" - utils-merge "1.0.0" - -sntp@2.x.x: - version "2.1.0" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" - dependencies: - hoek "4.x.x" - -source-map@0.4.x: - version "0.4.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" - dependencies: - amdefine ">=0.0.4" - -source-map@~0.5.1: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - -sshpk@^1.7.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - dashdash "^1.12.0" - getpass "^0.1.1" - optionalDependencies: - bcrypt-pbkdf "^1.0.0" - ecc-jsbn "~0.1.1" - jsbn "~0.1.0" - tweetnacl "~0.14.0" - -stringstream@~0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" - -"through@>=2.2.7 <3": - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - -token-stream@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-0.0.1.tgz#ceeefc717a76c4316f126d0b9dbaa55d7e7df01a" - -tough-cookie@~2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" - dependencies: - punycode "^1.4.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - -type-is@~1.6.2: - version "1.6.15" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" - dependencies: - media-typer "0.3.0" - mime-types "~2.1.15" - -uglify-js@^2.6.1: - version "2.8.29" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" - dependencies: - source-map "~0.5.1" - yargs "~3.10.0" - optionalDependencies: - uglify-to-browserify "~1.0.0" - -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" - -uid-safe@~2.1.5: - version "2.1.5" - resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a" - dependencies: - random-bytes "~1.0.0" - -underscore@^1.7.0: - version "1.8.3" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" - -util@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - dependencies: - inherits "2.0.1" - -utils-merge@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - -uuid@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" - -vary@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.0.1.tgz#99e4981566a286118dfb2b817357df7993376d10" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -void-elements@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" - -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - -with@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/with/-/with-5.1.1.tgz#fa4daa92daf32c4ea94ed453c81f04686b575dfe" - dependencies: - acorn "^3.1.0" - acorn-globals "^3.0.0" - -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0" diff --git a/example/webhooks/.gitignore b/example/webhooks/.gitignore deleted file mode 100644 index 1bf4259a..00000000 --- a/example/webhooks/.gitignore +++ /dev/null @@ -1 +0,0 @@ -config.js diff --git a/example/webhooks/config.js.template b/example/webhooks/config.js.template deleted file mode 100644 index bee07b8a..00000000 --- a/example/webhooks/config.js.template +++ /dev/null @@ -1,8 +0,0 @@ -// Rename this file to config.js and then add your client secret -const config = {}; - -config.nylasClientSecret = ''; -config.host = '127.0.0.1'; -config.port = 1234; - -module.exports = config; diff --git a/example/webhooks/index.js b/example/webhooks/index.js deleted file mode 100644 index 02395efc..00000000 --- a/example/webhooks/index.js +++ /dev/null @@ -1,90 +0,0 @@ -'use strict'; -const express = require('express'); -const crypto = require('crypto'); -const request = require('request'); -// Import secret and other configuration -const config = require('./config'); - -const app = express(); - -const bodyParser = require('body-parser'); - -// Custom Middleware to compute rawBody. Unfortunately using -// JSON.stringify(req.body) will remove spaces and newlines, so verification -// will fail. We must add this middleware to ensure we're computing the correct -// signature -app.use(function(req, res, next) { - req.rawBody = ''; - req.on('data', function(chunk) { - req.rawBody += chunk; - }); - next(); -}); -app.use(bodyParser.json({ limit: '50000mb' })); // support json encoded bodies -app.use(bodyParser.urlencoded({ limit: '50000mb', extended: true })); // support encoded bodies - -app.get('/webhook', function(req, res) { - // Nylas will check to make sure your webhook is valid by making a GET - // request to your endpoint with a challenge parameter when you add the - // endpoint to the developer dashboard. All you have to do is return the - // value of the challenge parameter in the body of the response. - return res.status(200).send(req.query.challenge); -}); - -app.post('/webhook', function(req, res) { - res.sendStatus(200); - // Verify the request to make sure it's actually from Nylas. - if (!verify_nylas_request(req)) { - console.log('Failed to verify nylas'); - return res.status(401).send('X-Nylas-Signature failed verification 🚷 '); - } - - // Nylas sent us a webhook notification for some kind of event, so we should - // process it! - const data = req.body.deltas; - console.log(JSON.stringify(data, null, 2)); - for (var i = 0; i < data.length; i++) { - // Print some of the information Nylas sent us. This is where you - // would normally process the webhook notification and do things like - // fetch relevant message ids, update your database, etc. - console.log( - '%s at %s with id %s', - data[i].type, - data[i].date, - data[i].object_data.id - ); - } - // Don't forget to let Nylas know that everything was pretty ok. -}); - -// Each request made by Nylas includes an X-Nylas-Signature header. The header -// contains the HMAC-SHA256 signature of the request body, using your client -// secret as the signing key. This allows your app to verify that the -// notification really came from Nylas. -function verify_nylas_request(req) { - const digest = crypto - .createHmac('sha256', config.nylasClientSecret) - .update(req.rawBody) - .digest('hex'); - return digest === req.get('x-nylas-signature'); -} - -var webhook_uri; -// Setup ngrok settings to ensure everything works locally -request('http://localhost:4040/api/tunnels', function(error, response, body) { - if (!error && response.statusCode == 200) { - webhook_uri = JSON.parse(body).tunnels[1].public_url + '/webhook'; - } else { - throw "It looks like ngrok isn't running! Make sure you've started that first with 'ngrok http 1234'"; - } - if (config.nylasClientSecret === '') { - throw 'You need to add your Nylas client secret to config.js first!'; - } - // Start the program - console.log( - '\n%s\n\nAdd the above url to the webhooks page at https://developer.nylas.com', - webhook_uri - ); - console.log(`Server running at http://${config.host}:${config.port}/`); - app.listen(config.port); -}); diff --git a/example/webhooks/package.json b/example/webhooks/package.json deleted file mode 100644 index 44017a1f..00000000 --- a/example/webhooks/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "nylas-webhooks-example", - "version": "1.0.0", - "description": "Example of how to set up a webhook endpoint using node.js that will work with Nylas webhooks", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Mike Pfister", - "license": "ISC", - "dependencies": { - "body-parser": "^1.15.2", - "express": "^4.14.0", - "request": "^2.74.0" - } -} diff --git a/example/webhooks/readme.md b/example/webhooks/readme.md deleted file mode 100644 index 3f8be465..00000000 --- a/example/webhooks/readme.md +++ /dev/null @@ -1,41 +0,0 @@ -# Nylas Webhooks - -This tiny express app is a simple example of how to use Nylas' webhooks feature. -This app correctly responds to Nylas' challenge request when you add a webhook -url to the [developer dashboard](https://developer.nylas.com). It also verifies -any webhook notification POST requests by Nylas and prints out some information -about the notification. - -# Dependencies - -## ngrok - -[ngrok](https://ngrok.com/) makes it really easy to test callback urls that are -running locally on your computer. - -## node / npm - -Make sure `node` and `npm` are installed. - -# Initial Setup - -```bash -npm install -``` - -# Running the app - -First, make sure ngrok is running with the same port that the local express app -is running. - -```bash -ngrok http 1234 -``` - -Next, run the express app. - -```bash -node index.js -``` - -Follow the instructions that are printed to the console. diff --git a/examples/.env.example b/examples/.env.example new file mode 100644 index 00000000..c635ee7f --- /dev/null +++ b/examples/.env.example @@ -0,0 +1,17 @@ +# Nylas API Key +NYLAS_API_KEY=your_nylas_api_key_here + +# Optional: Nylas API URI (defaults to https://api.us.nylas.com) +NYLAS_API_URI=https://api.us.nylas.com + +# Meeting Link (required for notetakers example) +MEETING_LINK=your_meeting_link_here + +# Grant ID (required for calendar operations) +NYLAS_GRANT_ID=your_grant_id_here + +# Calendar ID (required for event creation/updates) +NYLAS_CALENDAR_ID=your_calendar_id_here + +# For testing message sending (optional) +TEST_EMAIL=your-test-email@example.com \ No newline at end of file diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 00000000..808147fd --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1,2 @@ +.env +dist/ \ No newline at end of file diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 00000000..3f7bd55f --- /dev/null +++ b/examples/README.md @@ -0,0 +1,146 @@ +# Nylas Node.js SDK Examples + +This directory contains examples of how to use the Nylas Node.js SDK to interact with the Nylas API. + +## Examples + +### Node.js Examples + +- [Grants](./grants/README.md) - Examples of how to fetch, list, sort, and filter grants (authenticated connections to email/calendar providers). +- [Notetakers](./notetakers/README.md) - Examples of how to use the Nylas Notetakers API to invite a Notetaker bot to meetings, get recordings and transcripts, and more. +- [Messages](./messages/README.md) - Examples of how to use the Nylas Messages API to list, find, send, update messages, and work with new features like tracking options and raw MIME data. +- [Folders](./folders/README.md) - Examples of how to use the Nylas Folders API, including the new `singleLevel` parameter for Microsoft accounts. +- [Calendars](./calendars/README.md) - Examples of how to use the Nylas Calendar API to create and manage calendar events with Notetaker integration. + +### Cloudflare Workers Examples + +- [Cloudflare Vite Calendars](./cloudflare-vite-calendars/README.md) - Modern Cloudflare Workers example using Vite for building a calendar event manager. Showcases listing and creating events with a beautiful web interface. +- [Edge Environment](./edge-environment/README.md) - Standard Cloudflare Workers example for sending email attachments. Demonstrates file upload handling and email sending on the edge. + +### AWS Lambda Examples + +- [AWS Lambda Attachments](./aws-lambda/README.md) - AWS Lambda example for sending email attachments using the Nylas SDK. Demonstrates how to handle multiple file uploads (including 2+ attachments over 3MB total) without Lambda freezing. Includes interactive setup CLI and Serverless Framework deployment. + +### Module System Examples + +- [ESM Only](./esm-only/) - Example of using the SDK with ES Modules +- [CJS Only](./cjs-only/) - Example of using the SDK with CommonJS + +## Running the Examples + +### Node.js Examples + +To run the Node.js examples, you'll need to: + +1. Install dependencies: + ```bash + cd examples + npm install + ``` + +2. Copy the `.env.example` file to `.env` and fill in your API key: + ```bash + cp .env.example .env + # Edit .env with your editor and add your API key + ``` + +3. Set up the required environment variables in the `.env` file: + - `NYLAS_API_KEY` - Your Nylas API key + - `NYLAS_API_URI` (optional) - The Nylas API server URI (defaults to "https://api.us.nylas.com") + - Additional environment variables specific to each example + +4. Run the example: + ```bash + # Using ts-node + npx ts-node grants/grants.ts + npx ts-node notetakers/notetaker.ts + npx ts-node calendars/event_with_notetaker.ts + npx ts-node messages/messages.ts + + # Or using npm scripts + npm run grants + npm run notetakers + npm run calendars + npm run messages + + # Or if you compiled the examples + npm run build + node dist/grants/grants.js + node dist/notetakers/notetaker.js + node dist/calendars/event_with_notetaker.js + node dist/messages/messages.js + ``` + +### Cloudflare Workers Examples + +The Cloudflare Workers examples are self-contained and have their own setup: + +1. Navigate to the example directory: + ```bash + cd examples/cloudflare-vite-calendars + # or + cd examples/edge-environment + ``` + +2. Install dependencies: + ```bash + npm install + ``` + +3. Set up environment variables (see each example's README for details): + ```bash + cp .dev.vars.example .dev.vars + # Edit .dev.vars with your Nylas credentials + ``` + +4. Run the development server: + ```bash + npm run dev + ``` + +5. Deploy to Cloudflare (optional): + ```bash + npm run deploy + ``` + +Each Cloudflare example has its own comprehensive README with detailed instructions. + +### AWS Lambda Examples + +The AWS Lambda example is self-contained and has its own setup: + +1. Navigate to the example directory: + ```bash + cd examples/aws-lambda + ``` + +2. Run the interactive setup: + ```bash + npm run setup + ``` + + This will guide you through: + - Prerequisites checking + - Nylas credentials configuration + - AWS credentials setup + - Environment variable configuration + - Optional immediate deployment + +3. Or set up manually: + ```bash + npm install + # Create .env file with your Nylas credentials + # Configure AWS credentials + npm run deploy + ``` + +4. Test the deployed function: + - Visit the API Gateway URL displayed after deployment + - Upload multiple files and send emails + - Test with files totaling over 3MB to verify the bug fix + +The AWS Lambda example includes a comprehensive README with detailed instructions and troubleshooting. + +## Documentation + +For more information, see the [Nylas API Documentation](https://developer.nylas.com/). \ No newline at end of file diff --git a/examples/aws-lambda/.gitignore b/examples/aws-lambda/.gitignore new file mode 100644 index 00000000..4f2b86f3 --- /dev/null +++ b/examples/aws-lambda/.gitignore @@ -0,0 +1,7 @@ +node_modules/ +dist/ +.env +.serverless/ +*.log +.DS_Store +lambda-package.zip diff --git a/examples/aws-lambda/README.md b/examples/aws-lambda/README.md new file mode 100644 index 00000000..77503f53 --- /dev/null +++ b/examples/aws-lambda/README.md @@ -0,0 +1,405 @@ +# Nylas AWS Lambda - Email Attachments Example + +This example demonstrates how to use the Nylas SDK in an AWS Lambda function to send email attachments. It provides a simple web interface for uploading multiple files and sending them as email attachments. + +## 🎯 Purpose + +This example serves two main purposes: + +1. **Demonstrate Nylas SDK usage in AWS Lambda** - Shows how to integrate the Nylas SDK in a serverless AWS Lambda environment +2. **Prove bug fix** - Demonstrates that the previously reported bug ("Node.js SDK v7.9.0-7.13.3: Lambda freezes when sending emails with 2+ attachments over 3MB total") has been fixed + +## πŸš€ Features + +- **Simple Web UI**: Drag & drop or click to upload multiple files +- **Multiple File Support**: Test sending 2+ attachments simultaneously +- **Size Tracking**: Visual indicator when total attachment size exceeds 3MB +- **Automatic Encoding**: SDK automatically switches between JSON and multipart/form-data based on payload size +- **Real-time Feedback**: Loading states and success/error messages +- **Serverless**: Runs on AWS Lambda with API Gateway + +## πŸ“‹ Prerequisites + +Before getting started, you'll need: + +1. **Nylas Account**: [Sign up for free](https://dashboard.nylas.com/register) +2. **AWS Account**: [Sign up for free](https://aws.amazon.com/free/) +3. **Node.js**: Version 16 or higher +4. **Nylas Application**: Created in your Nylas Dashboard +5. **Connected Email Account**: At least one email account connected to your Nylas application +6. **AWS CLI**: [Install AWS CLI](https://aws.amazon.com/cli/) (optional, but recommended) +7. **Serverless Framework**: Will be installed via npm + +## πŸ› οΈ Quick Start + +### Option 1: Interactive Setup (Recommended) + +The easiest way to get started is using the interactive setup CLI: + +```bash +# Navigate to the aws-lambda directory +cd examples/aws-lambda + +# Run the interactive setup +npm run setup +``` + +This will: +- Check prerequisites (Node.js, npm, AWS CLI, Serverless Framework) +- Guide you through Nylas credentials setup +- Help configure AWS credentials +- Create `.env` file with your configuration +- Optionally deploy to AWS Lambda immediately + +### Option 2: Manual Setup + +#### 1. Install Dependencies + +```bash +cd examples/aws-lambda +npm install +``` + +#### 2. Configure Environment Variables + +Create a `.env` file in the `aws-lambda` directory: + +```bash +NYLAS_API_KEY=your_nylas_api_key_here +NYLAS_API_URI=https://api.us.nylas.com +NYLAS_GRANT_ID=your_grant_id_here +``` + +**How to get these values:** + +- **NYLAS_API_KEY**: Found in your [Nylas Dashboard](https://dashboard.nylas.com/applications) under your application settings +- **NYLAS_GRANT_ID**: The ID of a connected email account (found in Dashboard > Grants) +- **NYLAS_API_URI**: Use `https://api.us.nylas.com` for US region, or your specific region's API URL + +#### 3. Configure AWS Credentials + +Set up AWS credentials using one of these methods: + +**Option A: AWS CLI (Recommended)** +```bash +aws configure +``` + +**Option B: Environment Variables** +```bash +export AWS_ACCESS_KEY_ID=your_access_key +export AWS_SECRET_ACCESS_KEY=your_secret_key +export AWS_REGION=us-east-1 +``` + +**Option C: AWS Credentials File** +Create `~/.aws/credentials`: +```ini +[default] +aws_access_key_id = your_access_key +aws_secret_access_key = your_secret_key +``` + +#### 4. Deploy to AWS Lambda + +```bash +npm run deploy +``` + +This will: +- Build your Lambda function using esbuild +- Upload it to AWS Lambda +- Create an API Gateway endpoint +- Display your function URL + +#### 5. Test the Application + +1. Visit the API Gateway URL displayed after deployment +2. Fill in the email form: + - **Recipient Email**: Enter a valid email address + - **Subject**: Enter an email subject + - **Message**: Enter your message content + - **Attachments**: Upload multiple files (try files totaling over 3MB to test the bug fix) +3. Click "Send Email with Attachments" +4. Check the recipient's inbox for the email + +## πŸ“š How It Works + +### Architecture + +``` +User Browser β†’ API Gateway β†’ AWS Lambda β†’ Nylas API β†’ Email Provider +``` + +1. **File Upload**: User uploads files through the web interface +2. **API Gateway**: Receives HTTP request and forwards to Lambda +3. **Lambda Handler**: Processes multipart form data and prepares attachments +4. **Nylas SDK**: Automatically handles encoding based on payload size +5. **Email Sending**: Nylas SDK sends email with attachments +6. **Response**: User receives confirmation or error message + +### Bug Fix Demonstration + +The SDK automatically handles large attachments by switching encoding methods: + +- **< 3MB total**: Uses JSON encoding (faster, simpler) +- **β‰₯ 3MB total**: Uses multipart/form-data encoding (handles large files) + +This prevents Lambda from freezing when sending multiple attachments over 3MB total. The web interface shows a warning indicator when the total size exceeds 3MB. + +### Key Implementation Details + +**Lambda Handler** (`src/handler.ts`): +- Handles API Gateway events +- Parses multipart form data from API Gateway (basic implementation) +- Uses Buffer attachments (optimal for Lambda) +- Automatically leverages SDK's 3MB threshold handling + +**Note on Multipart Parsing**: The example includes a basic multipart parser for simplicity. For production use with large files or complex requirements, consider using a library like `lambda-multipart-parser` or `busboy` for more robust parsing. + +**SDK Integration**: +```typescript +// The SDK automatically chooses encoding based on total payload size +const response = await nylas.messages.send({ + identifier: env.NYLAS_GRANT_ID, + requestBody: sendRequest, +}); +``` + +The SDK checks `calculateTotalPayloadSize()` internally and switches to multipart/form-data when needed (see `src/resources/messages.ts` in the SDK). + +## πŸ”§ Configuration + +### Serverless Framework (`serverless.yml`) + +Key configuration options: + +- **Memory**: 512MB (adjustable for larger files) +- **Timeout**: 30 seconds (increase for very large attachments) +- **Runtime**: Node.js 20.x +- **Region**: us-east-1 (changeable) + +To modify these settings, edit `serverless.yml`: + +```yaml +provider: + memorySize: 1024 # Increase for larger files + timeout: 60 # Increase timeout + region: eu-west-1 # Change region +``` + +### Environment Variables + +You can also set environment variables in `serverless.yml`: + +```yaml +provider: + environment: + NYLAS_API_KEY: ${env:NYLAS_API_KEY} + NYLAS_API_URI: ${env:NYLAS_API_URI} + NYLAS_GRANT_ID: ${env:NYLAS_GRANT_ID} +``` + +Or use AWS Systems Manager Parameter Store: + +```yaml +provider: + environment: + NYLAS_API_KEY: ${ssm:/nylas/api-key} + NYLAS_GRANT_ID: ${ssm:/nylas/grant-id} +``` + +## πŸ› Troubleshooting + +### Common Issues + +**Error: "Missing required environment variables"** +- Ensure `.env` file exists with all required variables +- Check that variables are set correctly (no extra spaces) +- For production, ensure environment variables are set in AWS Lambda console + +**Error: "AWS credentials not configured"** +- Run `aws configure` to set up credentials +- Or set `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables +- Or create `~/.aws/credentials` file manually + +**Error: "Serverless Framework not found"** +- Run `npm install` to install dependencies +- Use `npx serverless` instead of `serverless` if not installed globally + +**Error: "Lambda timeout"** +- Increase timeout in `serverless.yml` (default: 30 seconds) +- For very large files, consider increasing memory as well + +**Error: "File upload fails"** +- Check API Gateway payload size limits (10MB default) +- Ensure multipart/form-data is being sent correctly +- Check Lambda logs: `npm run logs` + +**Email not received** +- Verify the recipient email address +- Check spam/junk folders +- Verify your Nylas grant has send permissions +- Check Nylas Dashboard for any API errors + +**Lambda freezes with large attachments** +- This bug was fixed in SDK v7.13.4+ +- Ensure you're using the latest SDK version +- The SDK automatically uses multipart/form-data for payloads β‰₯ 3MB + +**Error: "Cannot find module 'index'"** +- This usually means the handler setting is incorrect +- Verify the handler is set to exactly: `handler.handler` (not `index.handler` or `handler`) +- The handler format is: `filename.functionName` +- For this example: file is `handler.js`, function is `handler`, so handler = `handler.handler` +- Check Lambda Configuration β†’ Runtime settings β†’ Handler +- Rebuild and re-upload the zip file if you changed the handler code + +### Debug Mode + +View Lambda logs in real-time: + +```bash +npm run logs +``` + +Or check logs in AWS Console: +1. Go to AWS Lambda Console +2. Select your function +3. Click "Monitor" tab +4. View CloudWatch Logs + +Add logging to the handler for debugging: + +```typescript +console.log('File details:', { + count: files.length, + totalSize: totalSize, + files: files.map(f => ({ name: f.filename, size: f.size })) +}); +``` + +## πŸ“– Related Examples + +- **Cloudflare Workers**: See `../edge-environment/` for a Cloudflare Workers example +- **Local Attachment Examples**: See `../messages/examples/` for Node.js examples +- **Nylas SDK Documentation**: [https://developer.nylas.com](https://developer.nylas.com) +- **AWS Lambda Docs**: [https://docs.aws.amazon.com/lambda/](https://docs.aws.amazon.com/lambda/) +- **Serverless Framework Docs**: [https://www.serverless.com/framework/docs](https://www.serverless.com/framework/docs) + +## πŸ“¦ Manual Upload via AWS Console + +If you prefer to upload the Lambda function manually through the AWS Console instead of using Serverless Framework: + +### 1. Build the Deployment Package + +```bash +npm run build:manual +``` + +This will: +- Install production dependencies +- Bundle your code with esbuild +- Create a `lambda-package.zip` file ready for upload + +### 2. Upload to AWS Lambda Console + +1. **Go to AWS Lambda Console** + - Navigate to [AWS Lambda Console](https://console.aws.amazon.com/lambda/) + - Select your region (e.g., us-west-1) + +2. **Create or Select a Function** + - Click "Create function" or select an existing function + - Choose "Author from scratch" + - Function name: `nylas-attachment-sender` (or your preferred name) + - Runtime: **Node.js 20.x** + - Architecture: x86_64 + +3. **Upload the Package** + - In the function's "Code" tab, click "Upload from" β†’ ".zip file" + - Select the `lambda-package.zip` file created in step 1 + - Click "Save" + +4. **Configure the Handler** + - In the "Runtime settings" section, click "Edit" + - Set Handler to: `handler.handler` + - Click "Save" + +5. **Set Environment Variables** + - Go to the "Configuration" tab β†’ "Environment variables" + - Click "Edit" β†’ "Add environment variable" + - Add the following: + - `NYLAS_API_KEY`: Your Nylas API key + - `NYLAS_GRANT_ID`: Your Nylas Grant ID + - `NYLAS_API_URI`: `https://api.us.nylas.com` (or your region's API URI) + - Click "Save" + +6. **Configure Function Settings** + - Go to "Configuration" β†’ "General configuration" β†’ "Edit" + - Memory: 512 MB (or higher for larger files) + - Timeout: 30 seconds (or higher for larger files) + - Click "Save" + +7. **Create API Gateway HTTP API** + - Go to [API Gateway Console](https://console.aws.amazon.com/apigateway/) + - Click "Create API" β†’ "HTTP API" β†’ "Build" + - Click "Add integration" + - Integration type: Lambda + - Lambda function: Select your function name + - API name: `nylas-attachment-api` (or your preferred name) + - Click "Next" β†’ "Create" + +8. **Configure Routes** + - In your API, go to "Routes" + - Create the following routes (all pointing to your Lambda function): + - **GET /** β†’ Lambda function (serves the HTML interface) + - **POST /send-attachment** β†’ Lambda function (handles file uploads) + - **OPTIONS /{proxy+}** β†’ Lambda function (for CORS preflight requests) + - **ANY /{proxy+}** β†’ Lambda function (catch-all for other routes, returns 404) + - For each route: + - Click "Create" β†’ Enter the path and method + - Select your Lambda function as the integration target + - Click "Create" + +9. **Enable CORS (if not already configured)** + - The Lambda function returns CORS headers, but you may want to configure CORS in API Gateway as well + - Go to "CORS" in your API settings + - Or ensure your Lambda function returns the appropriate CORS headers (already implemented) + +9. **Test Your Function** + - Copy the API Gateway endpoint URL + - Visit it in your browser to see the upload interface + - Test uploading files and sending emails + +### Notes for Manual Upload + +- The zip file includes all production dependencies bundled +- Handler must be set to `handler.handler` (file: `handler.js`, function: `handler`) +- Ensure environment variables are set correctly +- API Gateway timeout should be at least 30 seconds for large attachments +- Consider increasing Lambda memory (1024 MB) for very large files (>10MB) + +## 🧹 Cleanup + +To remove the deployed Lambda function and API Gateway: + +**If using Serverless Framework:** +```bash +npm run remove +``` + +This will delete: +- Lambda function +- API Gateway +- IAM roles and policies +- CloudWatch log groups + +**If uploaded manually:** +- Delete the Lambda function from the Lambda Console +- Delete the API Gateway from the API Gateway Console +- Delete any associated IAM roles and CloudWatch log groups + +## πŸ“„ License + +This example is part of the Nylas Node.js SDK and is licensed under the MIT License. + diff --git a/examples/aws-lambda/build-manual.ts b/examples/aws-lambda/build-manual.ts new file mode 100644 index 00000000..0432c16c --- /dev/null +++ b/examples/aws-lambda/build-manual.ts @@ -0,0 +1,193 @@ +#!/usr/bin/env node + +import * as fs from 'fs'; +import * as path from 'path'; +import * as process from 'process'; +import { execSync } from 'child_process'; + +// Try to load archiver, provide helpful error if not found +let archiver: any; +try { + // @ts-ignore - archiver types may not be available + archiver = require('archiver'); +} catch (error) { + console.error('❌ Error: archiver module not found!'); + console.error('Please run: npm install'); + process.exit(1); +} + +// Get __dirname for CommonJS/TypeScript +// @ts-ignore - __dirname is available in CommonJS context with ts-node +declare const __dirname: string; +const projectDir = __dirname || process.cwd(); + +async function buildForManualUpload(): Promise { + console.log('πŸ”¨ Building Lambda package for manual upload...\n'); + + const distDir = path.join(projectDir, 'dist'); + const zipPath = path.join(projectDir, 'lambda-package.zip'); + + // Clean previous builds + if (fs.existsSync(distDir)) { + fs.rmSync(distDir, { recursive: true, force: true }); + } + if (fs.existsSync(zipPath)) { + fs.unlinkSync(zipPath); + } + + // Create dist directory + fs.mkdirSync(distDir, { recursive: true }); + + try { + // Install all dependencies first (including devDependencies like archiver) + console.log('πŸ“¦ Installing dependencies...'); + execSync('npm install', { stdio: 'inherit', cwd: projectDir }); + + // Now require archiver after installation + // @ts-ignore - archiver types may not be available + const archiverModule = require('archiver'); + + // Install production dependencies for the Lambda package + console.log('\nπŸ“¦ Installing production dependencies for Lambda...'); + execSync('npm install --production', { stdio: 'inherit', cwd: projectDir }); + + // Build with esbuild (bundles everything including Nylas SDK) + console.log('\nπŸ”¨ Bundling code with esbuild...'); + // Bundle everything except aws-sdk (provided by Lambda runtime) + // Use format=cjs to ensure CommonJS exports work correctly + // Note: Not using --minify to avoid potential export issues + execSync( + 'npx esbuild src/handler.ts --bundle --platform=node --target=node20 --format=cjs --outfile=dist/handler.js --external:aws-sdk', + { stdio: 'inherit', cwd: projectDir } + ); + + // Verify handler.js was created + const handlerPath = path.join(distDir, 'handler.js'); + if (!fs.existsSync(handlerPath)) { + throw new Error('handler.js was not created by esbuild'); + } + + // Verify handler export exists in the built file + const handlerContent = fs.readFileSync(handlerPath, 'utf-8'); + // Check for various export patterns that esbuild might generate: + // 1. Direct exports: exports.handler or module.exports.handler + // 2. esbuild pattern: module.exports = __toCommonJS(handler_exports) + // 3. Handler function definition + const hasDirectExport = + handlerContent.includes('exports.handler') || + handlerContent.includes('module.exports.handler') || + handlerContent.match(/exports\.handler\s*=/); + + const hasEsbuildExport = + handlerContent.includes('module.exports = __toCommonJS') && + handlerContent.includes('handler_exports'); + + const hasHandlerFunction = + handlerContent.includes('const handler') || + handlerContent.includes('var handler') || + handlerContent.includes('function handler') || + handlerContent.includes('handler: () => handler'); + + if (!hasDirectExport && !hasEsbuildExport && !hasHandlerFunction) { + console.error('❌ Error: handler export not found in bundled file!'); + console.error( + ' The handler must be exported as: exports.handler or module.exports.handler' + ); + throw new Error('Handler export not found in bundled file'); + } + + console.log('βœ… handler.js created successfully'); + if (hasDirectExport) { + console.log('βœ… Direct handler export verified'); + } else if (hasEsbuildExport) { + console.log('βœ… Handler export verified (esbuild __toCommonJS pattern)'); + } else if (hasHandlerFunction) { + console.log( + 'βœ… Handler function found (export pattern will be resolved at runtime)' + ); + } + + // Note: Since we're bundling with esbuild, all dependencies (including Nylas SDK) + // are included in the handler.js file, so we don't need to copy node_modules + + // Create zip file + console.log('\nπŸ“¦ Creating deployment package...'); + const output = fs.createWriteStream(zipPath); + const archive = archiverModule('zip', { zlib: { level: 9 } }); + + return new Promise((resolve, reject) => { + output.on('close', () => { + const sizeMB = (archive.pointer() / 1024 / 1024).toFixed(2); + console.log(`\nβœ… Build complete!`); + console.log(`πŸ“¦ Package: ${zipPath}`); + console.log(`πŸ“Š Size: ${sizeMB} MB`); + console.log('\nπŸ“ Next steps:'); + console.log('1. Go to AWS Lambda Console'); + console.log('2. Create a new function or select existing one'); + console.log('3. Upload the zip file: lambda-package.zip'); + console.log('4. Set handler to: handler.handler'); + console.log('5. Set runtime to: Node.js 20.x'); + console.log('6. Configure environment variables:'); + console.log(' - NYLAS_API_KEY'); + console.log(' - NYLAS_GRANT_ID'); + console.log( + ' - NYLAS_API_URI (optional, defaults to https://api.us.nylas.com)' + ); + console.log( + '7. Create an API Gateway HTTP API and configure these routes:' + ); + console.log(' - GET / β†’ Lambda function'); + console.log(' - POST /send-attachment β†’ Lambda function'); + console.log( + ' - OPTIONS /{proxy+} β†’ Lambda function (for CORS preflight)' + ); + console.log( + ' - ANY /{proxy+} β†’ Lambda function (catch-all for other routes)' + ); + console.log( + '8. Enable CORS on all routes (or configure in Lambda response headers)' + ); + console.log( + '9. Deploy the API and test using the provided endpoint URL' + ); + resolve(); + }); + + archive.on('error', (err: Error) => { + reject(err); + }); + + archive.pipe(output); + // Add handler.js directly to root of zip (not in dist/ subdirectory) + archive.file(path.join(distDir, 'handler.js'), { name: 'handler.js' }); + + // Create a minimal package.json to ensure proper module resolution + const packageJsonContent = JSON.stringify( + { + name: 'nylas-lambda-handler', + version: '1.0.0', + main: 'handler.js', + type: 'commonjs', + }, + null, + 2 + ); + archive.append(packageJsonContent, { name: 'package.json' }); + + archive.finalize(); + }); + } catch (error) { + console.error('❌ Build failed:', error); + process.exit(1); + } +} + +// Run if executed directly +if (require.main === module) { + buildForManualUpload().catch((error) => { + console.error('Error:', error); + process.exit(1); + }); +} + +export { buildForManualUpload }; diff --git a/examples/aws-lambda/package-lock.json b/examples/aws-lambda/package-lock.json new file mode 100644 index 00000000..8a87574c --- /dev/null +++ b/examples/aws-lambda/package-lock.json @@ -0,0 +1,12785 @@ +{ + "name": "nylas-aws-lambda-attachments", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "nylas-aws-lambda-attachments", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "mime-types": "^2.1.35", + "nylas": "file:../../" + }, + "devDependencies": { + "@types/archiver": "^6.0.2", + "@types/aws-lambda": "^8.10.131", + "@types/mime-types": "^2.1.4", + "archiver": "^7.0.1", + "chalk": "^5.6.2", + "commander": "^14.0.0", + "dotenv": "^17.2.2", + "dotenv-cli": "^7.4.2", + "inquirer": "^12.9.4", + "serverless": "^3.38.0", + "serverless-dotenv-plugin": "^6.0.0", + "serverless-esbuild": "^1.52.0", + "ts-node": "^10.9.2", + "typescript": "^5.8.3" + } + }, + "../..": { + "name": "nylas", + "version": "7.13.3", + "license": "MIT", + "dependencies": { + "change-case": "^4.1.2", + "form-data-encoder": "^4.1.0", + "formdata-node": "^6.0.3", + "mime-types": "^2.1.35", + "uuid": "^8.3.2" + }, + "devDependencies": { + "@babel/core": "^7.3.3", + "@types/jest": "^29.5.2", + "@types/mime-types": "^2.1.2", + "@types/node": "^22.15.21", + "@types/uuid": "^8.3.4", + "@typescript-eslint/eslint-plugin": "^2.25.0", + "@typescript-eslint/parser": "^2.25.0", + "eslint": "^5.14.0", + "eslint-config-prettier": "^4.0.0", + "eslint-plugin-custom-rules": "^0.0.0", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-prettier": "^3.0.1", + "jest": "^29.6.1", + "jest-fetch-mock": "^3.0.3", + "prettier": "^3.5.3", + "ts-jest": "^29.1.1", + "typedoc": "^0.28.4", + "typedoc-plugin-rename-defaults": "^0.7.3", + "typescript": "^5.8.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@aws-crypto/crc32": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", + "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/crc32c": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz", + "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha1-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-5.2.0.tgz", + "integrity": "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-api-gateway": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-api-gateway/-/client-api-gateway-3.943.0.tgz", + "integrity": "sha512-AoFraAZ2neqEMYG2VhDT3U09l9PLrvFUqtXkgbMub/KiTrCTH6zcn6IwuOZGm7CJOe2WKZlCMIhpy6mmvQoNHw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/credential-provider-node": "3.943.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-sdk-api-gateway": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.943.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-stream": "^4.5.6", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-cloudformation": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudformation/-/client-cloudformation-3.943.0.tgz", + "integrity": "sha512-pH7G62afEZuL4R1IQl6R5ZdiV0AtRlWbrPdxJD3MQOjYX+EWsKqgs7Vqk7wO0ovEMmP6QSQOAZi9+7eZWmDSsQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/credential-provider-node": "3.943.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.943.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "@smithy/util-waiter": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity-provider/-/client-cognito-identity-provider-3.943.0.tgz", + "integrity": "sha512-yqOHfm9+sjisAEKvhu56fm7lSUIj4JnLgslZ+c4gbZdfRhbgLN7m5AZUnUTcx0nqgN3+NJM12Tkc38p/qTyJ3g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/credential-provider-node": "3.943.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.943.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-eventbridge": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-eventbridge/-/client-eventbridge-3.943.0.tgz", + "integrity": "sha512-8Z9q1GmVu3BThbQrVDhjw6GHnnQ0h/ciUKK+GWAnfkohw4/Nxk1u3E1ZWLFmj/i4OCDlyWjI4WY0NRDXw2p6ow==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/credential-provider-node": "3.943.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/signature-v4-multi-region": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.943.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-iam": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-iam/-/client-iam-3.943.0.tgz", + "integrity": "sha512-ybGYDpZXa1PhowSh2F7uQlM0Y5C8sbtAfaQ04G3w+04KxbgaIo6GfKvGSIltwgbwS4AohjIAl93whwdagqhEng==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/credential-provider-node": "3.943.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.943.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "@smithy/util-waiter": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.943.0.tgz", + "integrity": "sha512-AjhebQ7yBZ70NvEH7PY37lha6i9cK8BCK56YNN77zPETw3cjkVJFC+wHQz+oSLL5p7X35Ur4JYWKmVuqlgLSNw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/credential-provider-node": "3.943.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.943.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/eventstream-serde-browser": "^4.2.5", + "@smithy/eventstream-serde-config-resolver": "^4.3.5", + "@smithy/eventstream-serde-node": "^4.2.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-stream": "^4.5.6", + "@smithy/util-utf8": "^4.2.0", + "@smithy/util-waiter": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-s3": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.943.0.tgz", + "integrity": "sha512-UOX8/1mmNaRmEkxoIVP2+gxd5joPJqz+fygRqlIXON1cETLGoctinMwQs7qU8g8hghm76TU2G6ZV6sLH8cySMw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha1-browser": "5.2.0", + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/credential-provider-node": "3.943.0", + "@aws-sdk/middleware-bucket-endpoint": "3.936.0", + "@aws-sdk/middleware-expect-continue": "3.936.0", + "@aws-sdk/middleware-flexible-checksums": "3.943.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-location-constraint": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-sdk-s3": "3.943.0", + "@aws-sdk/middleware-ssec": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/signature-v4-multi-region": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.943.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/eventstream-serde-browser": "^4.2.5", + "@smithy/eventstream-serde-config-resolver": "^4.3.5", + "@smithy/eventstream-serde-node": "^4.2.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-blob-browser": "^4.2.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/hash-stream-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/md5-js": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-stream": "^4.5.6", + "@smithy/util-utf8": "^4.2.0", + "@smithy/util-waiter": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-sso": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.943.0.tgz", + "integrity": "sha512-kOTO2B8Ks2qX73CyKY8PAajtf5n39aMe2spoiOF5EkgSzGV7hZ/HONRDyADlyxwfsX39Q2F2SpPUaXzon32IGw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.943.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-sts": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.943.0.tgz", + "integrity": "sha512-DxS7mrDcZpany21o8uy5OC2pBTOstljfzR0KPnCgrMFbL5h31X22QkOvBg5dl+c3sB94gi+SsUEgd2eVVQbueQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/credential-provider-node": "3.943.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.943.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.943.0.tgz", + "integrity": "sha512-8CBy2hI9ABF7RBVQuY1bgf/ue+WPmM/hl0adrXFlhnhkaQP0tFY5zhiy1Y+n7V+5f3/ORoHBmCCQmcHDDYJqJQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@aws-sdk/xml-builder": "3.930.0", + "@smithy/core": "^3.18.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/signature-v4": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.943.0.tgz", + "integrity": "sha512-WnS5w9fK9CTuoZRVSIHLOMcI63oODg9qd1vXMYb7QGLGlfwUm4aG3hdu7i9XvYrpkQfE3dzwWLtXF4ZBuL1Tew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.943.0.tgz", + "integrity": "sha512-SA8bUcYDEACdhnhLpZNnWusBpdmj4Vl67Vxp3Zke7SvoWSYbuxa+tiDiC+c92Z4Yq6xNOuLPW912ZPb9/NsSkA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/util-stream": "^4.5.6", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.943.0.tgz", + "integrity": "sha512-BcLDb8l4oVW+NkuqXMlO7TnM6lBOWW318ylf4FRED/ply5eaGxkQYqdGvHSqGSN5Rb3vr5Ek0xpzSjeYD7C8Kw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/credential-provider-env": "3.943.0", + "@aws-sdk/credential-provider-http": "3.943.0", + "@aws-sdk/credential-provider-login": "3.943.0", + "@aws-sdk/credential-provider-process": "3.943.0", + "@aws-sdk/credential-provider-sso": "3.943.0", + "@aws-sdk/credential-provider-web-identity": "3.943.0", + "@aws-sdk/nested-clients": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/credential-provider-imds": "^4.2.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-login": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.943.0.tgz", + "integrity": "sha512-9iCOVkiRW+evxiJE94RqosCwRrzptAVPhRhGWv4osfYDhjNAvUMyrnZl3T1bjqCoKNcETRKEZIU3dqYHnUkcwQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/nested-clients": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.943.0.tgz", + "integrity": "sha512-14eddaH/gjCWoLSAELVrFOQNyswUYwWphIt+PdsJ/FqVfP4ay2HsiZVEIYbQtmrKHaoLJhiZKwBQRjcqJDZG0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.943.0", + "@aws-sdk/credential-provider-http": "3.943.0", + "@aws-sdk/credential-provider-ini": "3.943.0", + "@aws-sdk/credential-provider-process": "3.943.0", + "@aws-sdk/credential-provider-sso": "3.943.0", + "@aws-sdk/credential-provider-web-identity": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/credential-provider-imds": "^4.2.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.943.0.tgz", + "integrity": "sha512-GIY/vUkthL33AdjOJ8r9vOosKf/3X+X7LIiACzGxvZZrtoOiRq0LADppdiKIB48vTL63VvW+eRIOFAxE6UDekw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.943.0.tgz", + "integrity": "sha512-1c5G11syUrru3D9OO6Uk+ul5e2lX1adb+7zQNyluNaLPXP6Dina6Sy6DFGRLu7tM8+M7luYmbS3w63rpYpaL+A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-sso": "3.943.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/token-providers": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.943.0.tgz", + "integrity": "sha512-VtyGKHxICSb4kKGuaqotxso8JVM8RjCS3UYdIMOxUt9TaFE/CZIfZKtjTr+IJ7M0P7t36wuSUb/jRLyNmGzUUA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/nested-clients": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-bucket-endpoint": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.936.0.tgz", + "integrity": "sha512-XLSVVfAorUxZh6dzF+HTOp4R1B5EQcdpGcPliWr0KUj2jukgjZEcqbBmjyMF/p9bmyQsONX80iURF1HLAlW0qg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-arn-parser": "3.893.0", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-config-provider": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-expect-continue": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.936.0.tgz", + "integrity": "sha512-Eb4ELAC23bEQLJmUMYnPWcjD3FZIsmz2svDiXEcxRkQU9r7NRID7pM7C5NPH94wOfiCk0b2Y8rVyFXW0lGQwbA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-flexible-checksums": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.943.0.tgz", + "integrity": "sha512-J2oYbAQXTFEezs5m2Vij6H3w71K1hZfCtb85AsR/2Ovp/FjABMnK+Es1g1edRx6KuMTc9HkL/iGU4e+ek+qCZw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@aws-crypto/crc32c": "5.2.0", + "@aws-crypto/util": "5.2.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/is-array-buffer": "^4.2.0", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-stream": "^4.5.6", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.936.0.tgz", + "integrity": "sha512-tAaObaAnsP1XnLGndfkGWFuzrJYuk9W0b/nLvol66t8FZExIAf/WdkT2NNAWOYxljVs++oHnyHBCxIlaHrzSiw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-location-constraint": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.936.0.tgz", + "integrity": "sha512-SCMPenDtQMd9o5da9JzkHz838w3327iqXk3cbNnXWqnNRx6unyW8FL0DZ84gIY12kAyVHz5WEqlWuekc15ehfw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.936.0.tgz", + "integrity": "sha512-aPSJ12d3a3Ea5nyEnLbijCaaYJT2QjQ9iW+zGh5QcZYXmOGWbKVyPSxmVOboZQG+c1M8t6d2O7tqrwzIq8L8qw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.936.0.tgz", + "integrity": "sha512-l4aGbHpXM45YNgXggIux1HgsCVAvvBoqHPkqLnqMl9QVapfuSTjJHfDYDsx1Xxct6/m7qSMUzanBALhiaGO2fA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@aws/lambda-invoke-store": "^0.2.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-api-gateway": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-api-gateway/-/middleware-sdk-api-gateway-3.936.0.tgz", + "integrity": "sha512-j5sE0+7QX1khzy2tm08tYZjRvIYfhtFLNDYk7Ogs1bO9oCxDPkKvzaNcnazVReaO1uRCNRlsm7iDwRDGnraF0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.943.0.tgz", + "integrity": "sha512-kd2mALfthU+RS9NsPS+qvznFcPnVgVx9mgmStWCPn5Qc5BTnx4UAtm+HPA+XZs+zxOopp+zmAfE4qxDHRVONBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-arn-parser": "3.893.0", + "@smithy/core": "^3.18.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/signature-v4": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/util-config-provider": "^4.2.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-stream": "^4.5.6", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-ssec": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.936.0.tgz", + "integrity": "sha512-/GLC9lZdVp05ozRik5KsuODR/N7j+W+2TbfdFL3iS+7un+gnP6hC8RDOZd6WhpZp7drXQ9guKiTAxkZQwzS8DA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.943.0.tgz", + "integrity": "sha512-956n4kVEwFNXndXfhSAN5wO+KRgqiWEEY+ECwLvxmmO8uQ0NWOa8l6l65nTtyuiWzMX81c9BvlyNR5EgUeeUvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@smithy/core": "^3.18.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.943.0.tgz", + "integrity": "sha512-anFtB0p2FPuyUnbOULwGmKYqYKSq1M73c9uZ08jR/NCq6Trjq9cuF5TFTeHwjJyPRb4wMf2Qk859oiVfFqnQiw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.943.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.936.0.tgz", + "integrity": "sha512-wOKhzzWsshXGduxO4pqSiNyL9oUtk4BEvjWm9aaq6Hmfdoydq6v6t0rAGHWPjFwy9z2haovGRi3C8IxdMB4muw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.943.0.tgz", + "integrity": "sha512-KKvmxNQ/FZbM6ml6nKd8ltDulsUojsXnMJNgf1VHTcJEbADC/6mVWOq0+e9D0WP1qixUBEuMjlS2HqD5KoqwEg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-sdk-s3": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/signature-v4": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.943.0.tgz", + "integrity": "sha512-cRKyIzwfkS+XztXIFPoWORuaxlIswP+a83BJzelX4S1gUZ7FcXB4+lj9Jxjn8SbQhR4TPU3Owbpu+S7pd6IRbQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/nested-clients": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.936.0.tgz", + "integrity": "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-arn-parser": { + "version": "3.893.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.893.0.tgz", + "integrity": "sha512-u8H4f2Zsi19DGnwj5FSZzDMhytYF/bCh37vAtBsn3cNDL3YG578X5oc+wSX54pM3tOxS+NY7tvOAo52SW7koUA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.936.0.tgz", + "integrity": "sha512-0Zx3Ntdpu+z9Wlm7JKUBOzS9EunwKAb4KdGUQQxDqh5Lc3ta5uBoub+FgmVuzwnmBu9U1Os8UuwVTH0Lgu+P5w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-endpoints": "^3.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.893.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.893.0.tgz", + "integrity": "sha512-T89pFfgat6c8nMmpI8eKjBcDcgJq36+m9oiXbcUzeU55MP9ZuGgBomGjGnHaEyF36jenW9gmg3NfZDm0AO2XPg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.936.0.tgz", + "integrity": "sha512-eZ/XF6NxMtu+iCma58GRNRxSq4lHo6zHQLOZRIeL/ghqYJirqHdenMOwrzPettj60KWlv827RVebP9oNVrwZbw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.943.0.tgz", + "integrity": "sha512-gn+ILprVRrgAgTIBk2TDsJLRClzIOdStQFeFTcN0qpL8Z4GBCqMFhw7O7X+MM55Stt5s4jAauQ/VvoqmCADnQg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.930.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.930.0.tgz", + "integrity": "sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "fast-xml-parser": "5.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws/lambda-invoke-store": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.2.tgz", + "integrity": "sha512-C0NBLsIqzDIae8HFw9YIrIBsbc0xTiOtt7fAukGPnqQ/+zZNaq+4jhuccltK0QuWHBnNm/a6kLIRA6GFiM10eg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@effect/platform": { + "version": "0.65.5", + "resolved": "https://registry.npmjs.org/@effect/platform/-/platform-0.65.5.tgz", + "integrity": "sha512-FAORK6KoMQbd2VyLq/BMwcViy1txYd7XD9eYd5IGrXFpoOgWrSjp4zaSDlFPIEGgm68+n8fN0RelkbuMHCkSsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-my-way-ts": "^0.1.5", + "multipasta": "^0.2.5" + }, + "peerDependencies": { + "@effect/schema": "^0.73.4", + "effect": "^3.8.3" + } + }, + "node_modules/@effect/platform-node": { + "version": "0.60.5", + "resolved": "https://registry.npmjs.org/@effect/platform-node/-/platform-node-0.60.5.tgz", + "integrity": "sha512-//VG5MSdqzV2WzuzYal5Q9d/U/g0gnSbZms7LIEWZKIuybth4n1dQzQs+4V3C0OZVPm5N+8Kd8alrbJiRTNVJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@effect/platform-node-shared": "^0.15.5", + "mime": "^3.0.0", + "undici": "^6.19.7", + "ws": "^8.18.0" + }, + "peerDependencies": { + "@effect/platform": "^0.65.5", + "effect": "^3.8.3" + } + }, + "node_modules/@effect/platform-node-shared": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@effect/platform-node-shared/-/platform-node-shared-0.15.5.tgz", + "integrity": "sha512-PXFdIHMNzv19+aaKBo99KVsqJ65il8j7ejze/srkzOkNu4WK/GGpQuYF32NZLirFgXJe/4aYMRgwD+uJ4mCyuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/watcher": "^2.4.1", + "multipasta": "^0.2.5" + }, + "peerDependencies": { + "@effect/platform": "^0.65.5", + "effect": "^3.8.3" + } + }, + "node_modules/@effect/platform-node/node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@effect/schema": { + "version": "0.73.4", + "resolved": "https://registry.npmjs.org/@effect/schema/-/schema-0.73.4.tgz", + "integrity": "sha512-Vjgu+EuG6eyh3oB21jpHv0l9ZgGZCyVZf3lXs+2X18UEUOkppvpw11heHiK02iJCVchgp3Qjw/GDPUqhQvKpSg==", + "deprecated": "this package has been merged into the main effect package", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-check": "^3.21.0" + }, + "peerDependencies": { + "effect": "^3.8.3" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.1.tgz", + "integrity": "sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.1.tgz", + "integrity": "sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.1.tgz", + "integrity": "sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.1.tgz", + "integrity": "sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.1.tgz", + "integrity": "sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.1.tgz", + "integrity": "sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.1.tgz", + "integrity": "sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.1.tgz", + "integrity": "sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.1.tgz", + "integrity": "sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.1.tgz", + "integrity": "sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.1.tgz", + "integrity": "sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.1.tgz", + "integrity": "sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.1.tgz", + "integrity": "sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.1.tgz", + "integrity": "sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.1.tgz", + "integrity": "sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.1.tgz", + "integrity": "sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.1.tgz", + "integrity": "sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.1.tgz", + "integrity": "sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.1.tgz", + "integrity": "sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.1.tgz", + "integrity": "sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.1.tgz", + "integrity": "sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.1.tgz", + "integrity": "sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.1.tgz", + "integrity": "sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.1.tgz", + "integrity": "sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.1.tgz", + "integrity": "sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.1.tgz", + "integrity": "sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/ansi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz", + "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.2.tgz", + "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.1.21", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.21.tgz", + "integrity": "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz", + "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.23", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.23.tgz", + "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/external-editor": "^1.0.3", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.23.tgz", + "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", + "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.3.1.tgz", + "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.23.tgz", + "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.23.tgz", + "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.10.1.tgz", + "integrity": "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.3.2", + "@inquirer/confirm": "^5.1.21", + "@inquirer/editor": "^4.2.23", + "@inquirer/expand": "^4.0.23", + "@inquirer/input": "^4.3.1", + "@inquirer/number": "^3.0.23", + "@inquirer/password": "^4.0.23", + "@inquirer/rawlist": "^4.1.11", + "@inquirer/search": "^3.2.2", + "@inquirer/select": "^4.4.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.11.tgz", + "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.2.tgz", + "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.2.tgz", + "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz", + "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "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/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/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1" + } + }, + "node_modules/@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "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/@paralleldrive/cuid2": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.3.1.tgz", + "integrity": "sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "^1.1.5" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@serverless/dashboard-plugin": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@serverless/dashboard-plugin/-/dashboard-plugin-7.2.3.tgz", + "integrity": "sha512-Vu4TKJLEQ5F8ZipfCvd8A/LMIdH8kNGe448sX9mT4/Z0JVUaYmMc3BwkQ+zkNIh3QdBKAhocGn45TYjHV6uPWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@aws-sdk/client-cloudformation": "^3.410.0", + "@aws-sdk/client-sts": "^3.410.0", + "@serverless/event-mocks": "^1.1.1", + "@serverless/platform-client": "^4.5.1", + "@serverless/utils": "^6.14.0", + "child-process-ext": "^3.0.1", + "chokidar": "^3.5.3", + "flat": "^5.0.2", + "fs-extra": "^9.1.0", + "js-yaml": "^4.1.0", + "jszip": "^3.10.1", + "lodash": "^4.17.21", + "memoizee": "^0.4.15", + "ncjsm": "^4.3.2", + "node-dir": "^0.1.17", + "node-fetch": "^2.6.8", + "open": "^7.4.2", + "semver": "^7.3.8", + "simple-git": "^3.16.0", + "timers-ext": "^0.1.7", + "type": "^2.7.2", + "uuid": "^8.3.2", + "yamljs": "^0.3.0" + }, + "engines": { + "node": ">=12.0" + } + }, + "node_modules/@serverless/dashboard-plugin/node_modules/child-process-ext": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/child-process-ext/-/child-process-ext-3.0.2.tgz", + "integrity": "sha512-oBePsLbQpTJFxzwyCvs9yWWF0OEM6vGGepHwt1stqmX7QQqOuDc8j2ywdvAs9Tvi44TT7d9ackqhR4Q10l1u8w==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.3", + "es5-ext": "^0.10.62", + "log": "^6.3.1", + "split2": "^3.2.2", + "stream-promise": "^3.2.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/@serverless/dashboard-plugin/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@serverless/dashboard-plugin/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@serverless/dashboard-plugin/node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@serverless/event-mocks": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@serverless/event-mocks/-/event-mocks-1.1.1.tgz", + "integrity": "sha512-YAV5V/y+XIOfd+HEVeXfPWZb8C6QLruFk9tBivoX2roQLWVq145s4uxf8D0QioCueuRzkukHUS4JIj+KVoS34A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/lodash": "^4.14.123", + "lodash": "^4.17.11" + } + }, + "node_modules/@serverless/platform-client": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@serverless/platform-client/-/platform-client-4.5.1.tgz", + "integrity": "sha512-XltmO/029X76zi0LUFmhsnanhE2wnqH1xf+WBt5K8gumQA9LnrfwLgPxj+VA+mm6wQhy+PCp7H5SS0ZPu7F2Cw==", + "dev": true, + "license": "ISC", + "dependencies": { + "adm-zip": "^0.5.5", + "archiver": "^5.3.0", + "axios": "^1.6.2", + "fast-glob": "^3.2.7", + "https-proxy-agent": "^5.0.0", + "ignore": "^5.1.8", + "isomorphic-ws": "^4.0.1", + "js-yaml": "^3.14.1", + "jwt-decode": "^2.2.0", + "minimatch": "^3.0.4", + "querystring": "^0.2.1", + "run-parallel-limit": "^1.1.0", + "throat": "^5.0.0", + "traverse": "^0.6.6", + "ws": "^7.5.3" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/@serverless/platform-client/node_modules/archiver": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^2.1.0", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@serverless/platform-client/node_modules/archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@serverless/platform-client/node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/@serverless/platform-client/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@serverless/platform-client/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/@serverless/platform-client/node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/@serverless/platform-client/node_modules/compress-commons": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@serverless/platform-client/node_modules/crc32-stream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@serverless/platform-client/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", + "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/@serverless/platform-client/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@serverless/platform-client/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@serverless/platform-client/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/@serverless/platform-client/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@serverless/platform-client/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@serverless/platform-client/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/@serverless/platform-client/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@serverless/platform-client/node_modules/zip-stream": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@serverless/platform-client/node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@serverless/utils": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@serverless/utils/-/utils-6.15.0.tgz", + "integrity": "sha512-7eDbqKv/OBd11jjdZjUwFGN8sHWkeUqLeHXHQxQ1azja2IM7WIH+z/aLgzR6LhB3/MINNwtjesDpjGqTMj2JKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "archive-type": "^4.0.0", + "chalk": "^4.1.2", + "ci-info": "^3.8.0", + "cli-progress-footer": "^2.3.2", + "content-disposition": "^0.5.4", + "d": "^1.0.1", + "decompress": "^4.2.1", + "event-emitter": "^0.3.5", + "ext": "^1.7.0", + "ext-name": "^5.0.0", + "file-type": "^16.5.4", + "filenamify": "^4.3.0", + "get-stream": "^6.0.1", + "got": "^11.8.6", + "inquirer": "^8.2.5", + "js-yaml": "^4.1.0", + "jwt-decode": "^3.1.2", + "lodash": "^4.17.21", + "log": "^6.3.1", + "log-node": "^8.0.3", + "make-dir": "^4.0.0", + "memoizee": "^0.4.15", + "ms": "^2.1.3", + "ncjsm": "^4.3.2", + "node-fetch": "^2.6.11", + "open": "^8.4.2", + "p-event": "^4.2.0", + "supports-color": "^8.1.1", + "timers-ext": "^0.1.7", + "type": "^2.7.2", + "uni-global": "^1.0.0", + "uuid": "^8.3.2", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": ">=12.0" + } + }, + "node_modules/@serverless/utils/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/@serverless/utils/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/@serverless/utils/node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@serverless/utils/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@serverless/utils/node_modules/inquirer": { + "version": "8.2.7", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.7.tgz", + "integrity": "sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/external-editor": "^1.0.0", + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@serverless/utils/node_modules/jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@serverless/utils/node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true, + "license": "ISC" + }, + "node_modules/@serverless/utils/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@serverless/utils/node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/@serverless/utils/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==", + "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/@serverless/utils/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/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@smithy/abort-controller": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.5.tgz", + "integrity": "sha512-j7HwVkBw68YW8UmFRcjZOmssE77Rvk0GWAIN1oFBhsaovQmZWYCIcGa9/pwRB0ExI8Sk9MWNALTjftjHZea7VA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/chunked-blob-reader": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.2.0.tgz", + "integrity": "sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/chunked-blob-reader-native": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.2.1.tgz", + "integrity": "sha512-lX9Ay+6LisTfpLid2zZtIhSEjHMZoAR5hHCR4H7tBz/Zkfr5ea8RcQ7Tk4mi0P76p4cN+Btz16Ffno7YHpKXnQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-base64": "^4.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/config-resolver": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.3.tgz", + "integrity": "sha512-ezHLe1tKLUxDJo2LHtDuEDyWXolw8WGOR92qb4bQdWq/zKenO5BvctZGrVJBK08zjezSk7bmbKFOXIVyChvDLw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-config-provider": "^4.2.0", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "3.18.6", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.18.6.tgz", + "integrity": "sha512-8Q/ugWqfDUEU1Exw71+DoOzlONJ2Cn9QA8VeeDzLLjzO/qruh9UKFzbszy4jXcIYgGofxYiT0t1TT6+CT/GupQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/middleware-serde": "^4.2.6", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-stream": "^4.5.6", + "@smithy/util-utf8": "^4.2.0", + "@smithy/uuid": "^1.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.5.tgz", + "integrity": "sha512-BZwotjoZWn9+36nimwm/OLIcVe+KYRwzMjfhd4QT7QxPm9WY0HiOV8t/Wlh+HVUif0SBVV7ksq8//hPaBC/okQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-codec": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.5.tgz", + "integrity": "sha512-Ogt4Zi9hEbIP17oQMd68qYOHUzmH47UkK7q7Gl55iIm9oKt27MUGrC5JfpMroeHjdkOliOA4Qt3NQ1xMq/nrlA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^4.9.0", + "@smithy/util-hex-encoding": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-browser": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.5.tgz", + "integrity": "sha512-HohfmCQZjppVnKX2PnXlf47CW3j92Ki6T/vkAT2DhBR47e89pen3s4fIa7otGTtrVxmj7q+IhH0RnC5kpR8wtw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-config-resolver": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.5.tgz", + "integrity": "sha512-ibjQjM7wEXtECiT6my1xfiMH9IcEczMOS6xiCQXoUIYSj5b1CpBbJ3VYbdwDy8Vcg5JHN7eFpOCGk8nyZAltNQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-node": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.5.tgz", + "integrity": "sha512-+elOuaYx6F2H6x1/5BQP5ugv12nfJl66GhxON8+dWVUEDJ9jah/A0tayVdkLRP0AeSac0inYkDz5qBFKfVp2Gg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-universal": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.5.tgz", + "integrity": "sha512-G9WSqbST45bmIFaeNuP/EnC19Rhp54CcVdX9PDL1zyEB514WsDVXhlyihKlGXnRycmHNmVv88Bvvt4EYxWef/Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-codec": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.6.tgz", + "integrity": "sha512-3+RG3EA6BBJ/ofZUeTFJA7mHfSYrZtQIrDP9dI8Lf7X6Jbos2jptuLrAAteDiFVrmbEmLSuRG/bUKzfAXk7dhg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.5", + "@smithy/querystring-builder": "^4.2.5", + "@smithy/types": "^4.9.0", + "@smithy/util-base64": "^4.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-blob-browser": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.2.6.tgz", + "integrity": "sha512-8P//tA8DVPk+3XURk2rwcKgYwFvwGwmJH/wJqQiSKwXZtf/LiZK+hbUZmPj/9KzM+OVSwe4o85KTp5x9DUZTjw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/chunked-blob-reader": "^5.2.0", + "@smithy/chunked-blob-reader-native": "^4.2.1", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-node": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.5.tgz", + "integrity": "sha512-DpYX914YOfA3UDT9CN1BM787PcHfWRBB43fFGCYrZFUH0Jv+5t8yYl+Pd5PW4+QzoGEDvn5d5QIO4j2HyYZQSA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-stream-node": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.2.5.tgz", + "integrity": "sha512-6+do24VnEyvWcGdHXomlpd0m8bfZePpUKBy7m311n+JuRwug8J4dCanJdTymx//8mi0nlkflZBvJe+dEO/O12Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.5.tgz", + "integrity": "sha512-2L2erASEro1WC5nV+plwIMxrTXpvpfzl4e+Nre6vBVRR2HKeGGcvpJyyL3/PpiSg+cJG2KpTmZmq934Olb6e5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.0.tgz", + "integrity": "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/md5-js": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.5.tgz", + "integrity": "sha512-Bt6jpSTMWfjCtC0s79gZ/WZ1w90grfmopVOWqkI2ovhjpD5Q2XRXuecIPB9689L2+cCySMbaXDhBPU56FKNDNg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.5.tgz", + "integrity": "sha512-Y/RabVa5vbl5FuHYV2vUCwvh/dqzrEY/K2yWPSqvhFUwIY0atLqO4TienjBXakoy4zrKAMCZwg+YEqmH7jaN7A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "4.3.13", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.3.13.tgz", + "integrity": "sha512-X4za1qCdyx1hEVVXuAWlZuK6wzLDv1uw1OY9VtaYy1lULl661+frY7FeuHdYdl7qAARUxH2yvNExU2/SmRFfcg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.18.6", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-middleware": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.13.tgz", + "integrity": "sha512-RzIDF9OrSviXX7MQeKOm8r/372KTyY8Jmp6HNKOOYlrguHADuM3ED/f4aCyNhZZFLG55lv5beBin7nL0Nzy1Dw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/service-error-classification": "^4.2.5", + "@smithy/smithy-client": "^4.9.9", + "@smithy/types": "^4.9.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/uuid": "^1.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.6.tgz", + "integrity": "sha512-VkLoE/z7e2g8pirwisLz8XJWedUSY8my/qrp81VmAdyrhi94T+riBfwP+AOEEFR9rFTSonC/5D2eWNmFabHyGQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.5.tgz", + "integrity": "sha512-bYrutc+neOyWxtZdbB2USbQttZN0mXaOyYLIsaTbJhFsfpXyGWUxJpEuO1rJ8IIJm2qH4+xJT0mxUSsEDTYwdQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.5.tgz", + "integrity": "sha512-UTurh1C4qkVCtqggI36DGbLB2Kv8UlcFdMXDcWMbqVY2uRg0XmT9Pb4Vj6oSQ34eizO1fvR0RnFV4Axw4IrrAg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.5.tgz", + "integrity": "sha512-CMnzM9R2WqlqXQGtIlsHMEZfXKJVTIrqCNoSd/QpAyp+Dw0a1Vps13l6ma1fH8g7zSPNsA59B/kWgeylFuA/lw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/querystring-builder": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.5.tgz", + "integrity": "sha512-8iLN1XSE1rl4MuxvQ+5OSk/Zb5El7NJZ1td6Tn+8dQQHIjp59Lwl6bd0+nzw6SKm2wSSriH2v/I9LPzUic7EOg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.5.tgz", + "integrity": "sha512-RlaL+sA0LNMp03bf7XPbFmT5gN+w3besXSWMkA8rcmxLSVfiEXElQi4O2IWwPfxzcHkxqrwBFMbngB8yx/RvaQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-builder": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.5.tgz", + "integrity": "sha512-y98otMI1saoajeik2kLfGyRp11e5U/iJYH/wLCh3aTV/XutbGT9nziKGkgCaMD1ghK7p6htHMm6b6scl9JRUWg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "@smithy/util-uri-escape": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-parser": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.5.tgz", + "integrity": "sha512-031WCTdPYgiQRYNPXznHXof2YM0GwL6SeaSyTH/P72M1Vz73TvCNH2Nq8Iu2IEPq9QP2yx0/nrw5YmSeAi/AjQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/service-error-classification": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.5.tgz", + "integrity": "sha512-8fEvK+WPE3wUAcDvqDQG1Vk3ANLR8Px979te96m84CbKAjBVf25rPYSzb4xU4hlTyho7VhOGnh5i62D/JVF0JQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.0.tgz", + "integrity": "sha512-5WmZ5+kJgJDjwXXIzr1vDTG+RhF9wzSODQBfkrQ2VVkYALKGvZX1lgVSxEkgicSAFnFhPj5rudJV0zoinqS0bA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.5.tgz", + "integrity": "sha512-xSUfMu1FT7ccfSXkoLl/QRQBi2rOvi3tiBZU2Tdy3I6cgvZ6SEi9QNey+lqps/sJRnogIS+lq+B1gxxbra2a/w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^4.2.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-hex-encoding": "^4.2.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-uri-escape": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "4.9.9", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.9.9.tgz", + "integrity": "sha512-SUnZJMMo5yCmgjopJbiNeo1vlr8KvdnEfIHV9rlD77QuOGdRotIVBcOrBuMr+sI9zrnhtDtLP054bZVbpZpiQA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.18.6", + "@smithy/middleware-endpoint": "^4.3.13", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-stream": "^4.5.6", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.9.0.tgz", + "integrity": "sha512-MvUbdnXDTwykR8cB1WZvNNwqoWVaTRA0RLlLmf/cIFNMM2cKWz01X4Ly6SMC4Kks30r8tT3Cty0jmeWfiuyHTA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/url-parser": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.5.tgz", + "integrity": "sha512-VaxMGsilqFnK1CeBX+LXnSuaMx4sTL/6znSZh2829txWieazdVxr54HmiyTsIbpOTLcf5nYpq9lpzmwRdxj6rQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/querystring-parser": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-base64": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.0.tgz", + "integrity": "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-browser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.0.tgz", + "integrity": "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.1.tgz", + "integrity": "sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.0.tgz", + "integrity": "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-config-provider": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.0.tgz", + "integrity": "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "4.3.12", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.12.tgz", + "integrity": "sha512-TKc6FnOxFULKxLgTNHYjcFqdOYzXVPFFVm5JhI30F3RdhT7nYOtOsjgaOwfDRmA/3U66O9KaBQ3UHoXwayRhAg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.2.5", + "@smithy/smithy-client": "^4.9.9", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "4.2.15", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.15.tgz", + "integrity": "sha512-94NqfQVo+vGc5gsQ9SROZqOvBkGNMQu6pjXbnn8aQvBUhc31kx49gxlkBEqgmaZQHUUfdRUin5gK/HlHKmbAwg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/config-resolver": "^4.4.3", + "@smithy/credential-provider-imds": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/smithy-client": "^4.9.9", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.5.tgz", + "integrity": "sha512-3O63AAWu2cSNQZp+ayl9I3NapW1p1rR5mlVHcF6hAB1dPZUQFfRPYtplWX/3xrzWthPGj5FqB12taJJCfH6s8A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-hex-encoding": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.0.tgz", + "integrity": "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-middleware": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.5.tgz", + "integrity": "sha512-6Y3+rvBF7+PZOc40ybeZMcGln6xJGVeY60E7jy9Mv5iKpMJpHgRE6dKy9ScsVxvfAYuEX4Q9a65DQX90KaQ3bA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-retry": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.5.tgz", + "integrity": "sha512-GBj3+EZBbN4NAqJ/7pAhsXdfzdlznOh8PydUijy6FpNIMnHPSMO2/rP4HKu+UFeikJxShERk528oy7GT79YiJg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-stream": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.6.tgz", + "integrity": "sha512-qWw/UM59TiaFrPevefOZ8CNBKbYEP6wBAIlLqxn3VAIo9rgnTNc4ASbVrqDmhuwI87usnjhdQrxodzAGFFzbRQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/types": "^4.9.0", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-hex-encoding": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-uri-escape": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.0.tgz", + "integrity": "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.0.tgz", + "integrity": "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-waiter": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.5.tgz", + "integrity": "sha512-Dbun99A3InifQdIrsXZ+QLcC0PGBPAdrl4cj1mTgJvyc9N2zf7QSxg8TBkzsCmGJdE3TLbO9ycwpY0EkWahQ/g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/uuid": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.0.tgz", + "integrity": "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", + "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/archiver": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-6.0.4.tgz", + "integrity": "sha512-ULdQpARQ3sz9WH4nb98mJDYA0ft2A8C4f4fovvUcFwINa1cgGjY36JCAYuP5YypRq4mco1lJp1/7jEMS2oR0Hg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/readdir-glob": "*" + } + }, + "node_modules/@types/aws-lambda": { + "version": "8.10.159", + "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.159.tgz", + "integrity": "sha512-SAP22WSGNN12OQ8PlCzGzRCZ7QDCwI85dQZbmpz7+mAk+L7j+wI7qnvmdKh+o7A5LaOp6QnOZ2NJphAZQTTHQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime-types": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.4.tgz", + "integrity": "sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", + "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/readdir-glob": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@types/readdir-glob/-/readdir-glob-1.1.5.tgz", + "integrity": "sha512-raiuEPUYqXu+nvtY2Pe8s8FEmZ3x5yAH4VkLdihcPdalvsHltomrRC9BzuStrJ9yk06470hS0Crw0f1pXqD+Hg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/2-thenable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/2-thenable/-/2-thenable-1.0.0.tgz", + "integrity": "sha512-HqiDzaLDFCXkcCO/SwoyhRwqYtINFHF7t9BDRq4x90TOKNAJpiqUt9X5lQ08bwxYzc067HUywDjGySpebHcUpw==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.47" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "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-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adm-zip": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz", + "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "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": "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/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/archive-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", + "integrity": "sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "file-type": "^4.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/archive-type/node_modules/file-type": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", + "integrity": "sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/archiver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^5.0.2", + "async": "^3.2.4", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^3.0.0", + "zip-stream": "^6.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/archiver-utils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^10.0.0", + "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", + "lazystream": "^1.0.0", + "lodash": "^4.17.15", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, + "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-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, + "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-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sdk": { + "version": "2.1692.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1692.0.tgz", + "integrity": "sha512-x511uiJ/57FIsbgUe5csJ13k3uzu25uWQE+XqfBis/sB0SFoiElJWXRkgEAUh0U6n40eT3ay5Ue4oPkRMu1LYw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.16.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "util": "^0.12.4", + "uuid": "8.0.0", + "xml2js": "0.6.2" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/aws-sdk/node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/aws-sdk/node_modules/events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/aws-sdk/node_modules/ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/aws-sdk/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/aws-sdk/node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/aws-sdk/node_modules/uuid": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", + "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/axios": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/b4a": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "dev": true, + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } + }, + "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/bare-events": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", + "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", + "dev": true, + "license": "Apache-2.0", + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "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/bestzip": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bestzip/-/bestzip-2.2.1.tgz", + "integrity": "sha512-XdAb87RXqOqF7C6UgQG9IqpEHJvS6IOUo0bXWEAebjSSdhDjsbcqFKdHpn5Q7QHz2pGr3Zmw4wgG3LlzdyDz7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver": "^5.3.0", + "async": "^3.2.0", + "glob": "^7.1.6", + "which": "^2.0.2", + "yargs": "^16.2.0" + }, + "bin": { + "bestzip": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/bestzip/node_modules/archiver": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^2.1.0", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/bestzip/node_modules/archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bestzip/node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/bestzip/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/bestzip/node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/bestzip/node_modules/compress-commons": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/bestzip/node_modules/crc32-stream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/bestzip/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", + "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/bestzip/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bestzip/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/bestzip/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bestzip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/bestzip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/bestzip/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/bestzip/node_modules/zip-stream": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/bestzip/node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "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": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/bowser": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.13.1.tgz", + "integrity": "sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==", + "dev": true, + "license": "MIT" + }, + "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/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "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": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cachedir": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", + "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "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/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/chardet": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", + "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/child-process-ext": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/child-process-ext/-/child-process-ext-2.1.1.tgz", + "integrity": "sha512-0UQ55f51JBkOFa+fvR76ywRzxiPwQS3Xe8oe5bZRphpv+dIMeerW5Zn5e4cUy4COJwVtJyU0R79RMnw+aCqmGA==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^6.0.5", + "es5-ext": "^0.10.53", + "log": "^6.0.0", + "split2": "^3.1.1", + "stream-promise": "^3.2.0" + } + }, + "node_modules/child-process-ext/node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/child-process-ext/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/child-process-ext/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/child-process-ext/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/child-process-ext/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/child-process-ext/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-color": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", + "integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.64", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-progress-footer": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/cli-progress-footer/-/cli-progress-footer-2.3.3.tgz", + "integrity": "sha512-p+hyTPxSZWG1c3Qy1DLBoGZhpeA3Y6AMlKrtbGpMMSKpezbSLel8gW4e5You4FNlHb3wS/M1JU594OAWe/Totg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cli-color": "^2.0.4", + "d": "^1.0.1", + "es5-ext": "^0.10.64", + "mute-stream": "0.0.8", + "process-utils": "^4.0.0", + "timers-ext": "^0.1.7", + "type": "^2.7.2" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/cli-progress-footer/node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true, + "license": "ISC" + }, + "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-sprintf-format": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cli-sprintf-format/-/cli-sprintf-format-1.1.1.tgz", + "integrity": "sha512-BbEjY9BEdA6wagVwTqPvmAwGB24U93rQPBFZUT8lNCDxXzre5LFHQUTJc70czjgUomVg8u8R5kW8oY9DYRFNeg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cli-color": "^2.0.1", + "es5-ext": "^0.10.53", + "sprintf-kit": "^2.0.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/cli-sprintf-format/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-sprintf-format/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "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": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "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/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/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==", + "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/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", + "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/compress-commons": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "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/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "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/d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "dev": true, + "license": "ISC", + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dayjs": { + "version": "1.11.19", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz", + "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==", + "dev": true, + "license": "MIT" + }, + "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/decompress": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", + "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-tar": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", + "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tar/node_modules/bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/decompress-tar/node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tar/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-tar/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/decompress-tar/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/decompress-tar/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/decompress-tar/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/decompress-tar/node_modules/tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/decompress-tarbz2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", + "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tarbz2/node_modules/file-type": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", + "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tarbz2/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-targz": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", + "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-targz/node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-targz/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-unzip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-unzip/node_modules/file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-unzip/node_modules/get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress/node_modules/make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress/node_modules/make-dir/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/deferred": { + "version": "0.7.11", + "resolved": "https://registry.npmjs.org/deferred/-/deferred-0.7.11.tgz", + "integrity": "sha512-8eluCl/Blx4YOGwMapBvXRKxHXhA8ejDXYzEaK8+/gtcm8hRMhSLmXSqDmNUKNc/C8HNSmuyyp/hflhqDAvK2A==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.50", + "event-emitter": "^0.3.5", + "next-tick": "^1.0.0", + "timers-ext": "^0.1.7" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, + "license": "ISC", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "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/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/dotenv-cli": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-7.4.4.tgz", + "integrity": "sha512-XkBYCG0tPIes+YZr4SpfFv76SQrV/LeCE8CI7JSEMi3VR9MvTihCGTOtbIexD6i2mXF+6px7trb1imVCXSNMDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.6", + "dotenv": "^16.3.0", + "dotenv-expand": "^10.0.0", + "minimist": "^1.2.6" + }, + "bin": { + "dotenv": "cli.js" + } + }, + "node_modules/dotenv-cli/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", + "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duration": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/duration/-/duration-0.2.2.tgz", + "integrity": "sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.46" + } + }, + "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/effect": { + "version": "3.19.8", + "resolved": "https://registry.npmjs.org/effect/-/effect-3.19.8.tgz", + "integrity": "sha512-OmLw8EfH02vdmyU2fO4uY9He/wepwKI5E/JNpE2pseaWWUbaYOK9UlxIiKP20ZEqQr+S/jSqRDGmpiqD/2DeCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "fast-check": "^3.23.1" + } + }, + "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/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "dev": true, + "hasInstallScript": true, + "license": "ISC", + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "license": "MIT", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-set": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.6.tgz", + "integrity": "sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "es6-iterator": "~2.0.3", + "es6-symbol": "^3.1.3", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/esbuild": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.1.tgz", + "integrity": "sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.1", + "@esbuild/android-arm": "0.27.1", + "@esbuild/android-arm64": "0.27.1", + "@esbuild/android-x64": "0.27.1", + "@esbuild/darwin-arm64": "0.27.1", + "@esbuild/darwin-x64": "0.27.1", + "@esbuild/freebsd-arm64": "0.27.1", + "@esbuild/freebsd-x64": "0.27.1", + "@esbuild/linux-arm": "0.27.1", + "@esbuild/linux-arm64": "0.27.1", + "@esbuild/linux-ia32": "0.27.1", + "@esbuild/linux-loong64": "0.27.1", + "@esbuild/linux-mips64el": "0.27.1", + "@esbuild/linux-ppc64": "0.27.1", + "@esbuild/linux-riscv64": "0.27.1", + "@esbuild/linux-s390x": "0.27.1", + "@esbuild/linux-x64": "0.27.1", + "@esbuild/netbsd-arm64": "0.27.1", + "@esbuild/netbsd-x64": "0.27.1", + "@esbuild/openbsd-arm64": "0.27.1", + "@esbuild/openbsd-x64": "0.27.1", + "@esbuild/openharmony-arm64": "0.27.1", + "@esbuild/sunos-x64": "0.27.1", + "@esbuild/win32-arm64": "0.27.1", + "@esbuild/win32-ia32": "0.27.1", + "@esbuild/win32-x64": "0.27.1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "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==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/essentials": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/essentials/-/essentials-1.2.0.tgz", + "integrity": "sha512-kP/j7Iw7KeNE8b/o7+tr9uX2s1wegElGOoGZ2Xm35qBr4BbbEcH3/bxR2nfH9l9JANCq9AUrvKw+gRuHtZp0HQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "uni-global": "^1.0.0" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "license": "ISC", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.28.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-check": { + "version": "3.23.2", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.23.2.tgz", + "integrity": "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT", + "dependencies": { + "pure-rand": "^6.1.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true, + "license": "MIT" + }, + "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/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fast-xml-parser": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.2.5.tgz", + "integrity": "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^2.1.0" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "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/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-type": { + "version": "16.5.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", + "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-web-to-node-stream": "^3.0.0", + "strtok3": "^6.2.4", + "token-types": "^4.1.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/filesize": { + "version": "10.1.6", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.6.tgz", + "integrity": "sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 10.4.0" + } + }, + "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-my-way-ts": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/find-my-way-ts/-/find-my-way-ts-0.1.6.tgz", + "integrity": "sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/find-requires": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-requires/-/find-requires-1.0.0.tgz", + "integrity": "sha512-UME7hNwBfzeISSFQcBEDemEEskpOjI/shPrpJM5PI4DSdn6hX0dmz+2dL70blZER2z8tSnTRL+2rfzlYgtbBoQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "es5-ext": "^0.10.49", + "esniff": "^1.1.0" + }, + "bin": { + "find-requires": "bin/find-requires.js" + } + }, + "node_modules/find-requires/node_modules/esniff": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-1.1.3.tgz", + "integrity": "sha512-SLBLpfE7xWgF/HbzhVuAwqnJDRqSCNZqcqaIMVm+f+PbTp1kFRWu6BuT83SATb4Tp+ovr+S+u7vDH7/UErAOkw==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "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.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formidable": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.5.tgz", + "integrity": "sha512-Oz5Hwvwak/DCaXVVUtPn4oLMLLy1CdclLKO1LFgU7XzDpVMUU5UjlSLpGMocyQNNk8F6IJW9M/YdooSn2MRI+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@paralleldrive/cuid2": "^2.2.2", + "dezalgo": "^1.0.4", + "once": "^1.4.0", + "qs": "^6.11.0" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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" + }, + "node_modules/fs2": { + "version": "0.3.16", + "resolved": "https://registry.npmjs.org/fs2/-/fs2-0.3.16.tgz", + "integrity": "sha512-gf/9tXLWI7qKmHDrMz55TRrTj12iceKuwo30CG1+Vbae719LT4uFc++GwDG8y/4vZJ34a6pzhgY23bgg88cZDg==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.2", + "deferred": "^0.7.11", + "es5-ext": "^0.10.64", + "event-emitter": "^0.3.5", + "ext": "^1.7.0", + "ignore": "^5.3.2", + "memoizee": "^0.4.17", + "type": "^2.7.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphlib": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", + "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.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/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "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": "BSD-3-Clause" + }, + "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/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true, + "license": "MIT" + }, + "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/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", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/inquirer": { + "version": "12.11.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-12.11.1.tgz", + "integrity": "sha512-9VF7mrY+3OmsAfjH3yKz/pLbJ5z22E23hENKw3/LNSaA/sAt3v49bDRY+Ygct1xwuKT+U+cBfTzjCPySna69Qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/prompts": "^7.10.1", + "@inquirer/type": "^3.0.10", + "mute-stream": "^2.0.0", + "run-async": "^4.0.6", + "rxjs": "^7.8.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "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-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "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-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-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "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-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-natural-number": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", + "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "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-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT", + "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-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "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/isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "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==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "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-colorizer": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/json-colorizer/-/json-colorizer-2.2.2.tgz", + "integrity": "sha512-56oZtwV1piXrQnRNTtJeqRv+B9Y/dXAYLqBBaYl/COcUdoZxgLBLAO88+CnkbT6MxNs0c5E9mPBIb2sFcNz3vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.1", + "lodash.get": "^4.4.2" + } + }, + "node_modules/json-colorizer/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-colorizer/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-colorizer/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/json-colorizer/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-colorizer/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/json-colorizer/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-cycle": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/json-cycle/-/json-cycle-1.5.0.tgz", + "integrity": "sha512-GOehvd5PO2FeZ5T4c+RxobeT5a1PiGpF4u9/3+UvrMU4bhnVqzJY7hm39wg8PDCqkU91fWGH8qjWR4bn+wgq9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/json-refs": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/json-refs/-/json-refs-3.0.15.tgz", + "integrity": "sha512-0vOQd9eLNBL18EGl5yYaO44GhixmImes2wiYn9Z3sag3QnehWrYWlB9AFtMxCL2Bj3fyxgDYkxGFEU/chlYssw==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "~4.1.1", + "graphlib": "^2.1.8", + "js-yaml": "^3.13.1", + "lodash": "^4.17.15", + "native-promise-only": "^0.8.1", + "path-loader": "^1.0.10", + "slash": "^3.0.0", + "uri-js": "^4.2.2" + }, + "bin": { + "json-refs": "bin/json-refs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/json-refs/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/json-refs/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/json-refs/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dev": true, + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/jwt-decode": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz", + "integrity": "sha512-86GgN2vzfUu7m9Wcj63iUkuDzFNYFVmjeDm2GzWpUk+opB0pEpMsw6ePCMrhYkumz2C1ihqtZzOMAg7FiXcNoQ==", + "dev": true, + "license": "MIT" + }, + "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/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", + "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.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/log": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/log/-/log-6.3.2.tgz", + "integrity": "sha512-ek8NRg/OPvS9ISOJNWNAz5vZcpYacWNFDWNJjj5OXsc6YuKacfey6wF04cXz/tOJIVrZ2nGSkHpAY5qKtF6ISg==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.2", + "duration": "^0.2.2", + "es5-ext": "^0.10.64", + "event-emitter": "^0.3.5", + "sprintf-kit": "^2.0.2", + "type": "^2.7.3", + "uni-global": "^1.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/log-node": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/log-node/-/log-node-8.0.3.tgz", + "integrity": "sha512-1UBwzgYiCIDFs8A0rM2QdBFo8Wd8UQ0HrSTu/MNI+/2zN3NoHRj2fhplurAyuxTYUXu3Oohugq1jAn5s05u1MQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "ansi-regex": "^5.0.1", + "cli-color": "^2.0.1", + "cli-sprintf-format": "^1.1.1", + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "sprintf-kit": "^2.0.1", + "supports-color": "^8.1.1", + "type": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "peerDependencies": { + "log": "^6.0.0" + } + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/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/log-symbols/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/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es5-ext": "~0.10.2" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/memoizee": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz", + "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.2", + "es5-ext": "^0.10.64", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.12" + } + }, + "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/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "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", + "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", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "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/multipasta": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/multipasta/-/multipasta-0.2.7.tgz", + "integrity": "sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA==", + "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/native-promise-only": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", + "integrity": "sha512-zkVhZUA3y8mbz652WrL5x0fB0ehrBkulWT3TomAQ9iDtyXZvzKeEA6GPxAItBYeNYl5yngKRX612qHOhvMkDeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ncjsm": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ncjsm/-/ncjsm-4.3.2.tgz", + "integrity": "sha512-6d1VWA7FY31CpI4Ki97Fpm36jfURkVbpktizp8aoVViTZRQgr/0ddmlKerALSSlzfwQRBeSq1qwwVcBJK4Sk7Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "builtin-modules": "^3.3.0", + "deferred": "^0.7.11", + "es5-ext": "^0.10.62", + "es6-set": "^0.1.6", + "ext": "^1.7.0", + "find-requires": "^1.0.0", + "fs2": "^0.3.9", + "type": "^2.7.2" + } + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-dir": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", + "integrity": "sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.2" + }, + "engines": { + "node": ">= 0.10.5" + } + }, + "node_modules/node-dir/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/node-dir/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/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-registry-utilities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/npm-registry-utilities/-/npm-registry-utilities-1.0.0.tgz", + "integrity": "sha512-9xYfSJy2IFQw1i6462EJzjChL9e65EfSo2Cw6kl0EFeDp05VvU+anrQk3Fc0d1MbVCq7rWIxeer89O9SUQ/uOg==", + "dev": true, + "license": "ISC", + "dependencies": { + "ext": "^1.6.0", + "fs2": "^0.3.9", + "memoizee": "^0.4.15", + "node-fetch": "^2.6.7", + "semver": "^7.3.5", + "type": "^2.6.0", + "validate-npm-package-name": "^3.0.0" + }, + "engines": { + "node": ">=12.0" + } + }, + "node_modules/npm-registry-utilities/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nylas": { + "resolved": "../..", + "link": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "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/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", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/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/ora/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/ora/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/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-timeout": "^3.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true, + "license": "(MIT AND Zlib)" + }, + "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", + "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-loader": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/path-loader/-/path-loader-1.0.12.tgz", + "integrity": "sha512-n7oDG8B+k/p818uweWrOixY9/Dsr89o2TkCm6tOTex3fpdo2+BFDgR+KpB37mGKBRsBAlR8CIJMFN0OEy/7hIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "native-promise-only": "^0.8.1", + "superagent": "^7.1.6" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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/path2": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/path2/-/path2-0.1.0.tgz", + "integrity": "sha512-TX+cz8Jk+ta7IvRy2FAej8rdlbrP0+uBIkP/5DTODez/AuL/vSb30KuAdDxGVREXzn8QfAiu5mJYJ1XjbOhEPA==", + "dev": true, + "license": "MIT" + }, + "node_modules/peek-readable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", + "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, + "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/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/process-utils": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/process-utils/-/process-utils-4.0.0.tgz", + "integrity": "sha512-fMyMQbKCxX51YxR7YGCzPjLsU3yDzXFkP4oi1/Mt5Ixnk7GO/7uUTj8mrCHUwuvozWzI+V7QSJR9cZYnwNOZPg==", + "dev": true, + "license": "ISC", + "dependencies": { + "ext": "^1.4.0", + "fs2": "^0.3.9", + "memoizee": "^0.4.14", + "type": "^2.1.0" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/promise-queue": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/promise-queue/-/promise-queue-2.2.5.tgz", + "integrity": "sha512-p/iXrPSVfnqPft24ZdNNLECw/UrtLTpT3jpAAMzl/o5/rDsGCPo3/CQS2611flL6LkoEJ3oQZw7C8Q80ZISXRQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "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/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "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/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystring": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", + "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.x" + } + }, + "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/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ramda": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.28.0.tgz", + "integrity": "sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dev": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/readable-web-to-node-stream": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz", + "integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^4.7.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/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/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "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/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/run-parallel-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", + "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", + "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-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==", + "dev": true, + "license": "ISC" + }, + "node_modules/seek-bzip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", + "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^2.8.1" + }, + "bin": { + "seek-bunzip": "bin/seek-bunzip", + "seek-table": "bin/seek-bzip-table" + } + }, + "node_modules/seek-bzip/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "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/serverless": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/serverless/-/serverless-3.40.0.tgz", + "integrity": "sha512-6vUSIUqBkhZeIpFz0howqKlT1BNjYxOrucvvSICKCEsxVS9MbTJokGkykDrpr/k4Io3WI8tcvrf25+U5Ynf3lw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@aws-sdk/client-api-gateway": "^3.588.0", + "@aws-sdk/client-cognito-identity-provider": "^3.588.0", + "@aws-sdk/client-eventbridge": "^3.588.0", + "@aws-sdk/client-iam": "^3.588.0", + "@aws-sdk/client-lambda": "^3.588.0", + "@aws-sdk/client-s3": "^3.588.0", + "@serverless/dashboard-plugin": "^7.2.0", + "@serverless/platform-client": "^4.5.1", + "@serverless/utils": "^6.13.1", + "abort-controller": "^3.0.0", + "ajv": "^8.12.0", + "ajv-formats": "^2.1.1", + "archiver": "^5.3.1", + "aws-sdk": "^2.1404.0", + "bluebird": "^3.7.2", + "cachedir": "^2.3.0", + "chalk": "^4.1.2", + "child-process-ext": "^2.1.1", + "ci-info": "^3.8.0", + "cli-progress-footer": "^2.3.2", + "d": "^1.0.1", + "dayjs": "^1.11.8", + "decompress": "^4.2.1", + "dotenv": "^16.3.1", + "dotenv-expand": "^10.0.0", + "essentials": "^1.2.0", + "ext": "^1.7.0", + "fastest-levenshtein": "^1.0.16", + "filesize": "^10.0.7", + "fs-extra": "^10.1.0", + "get-stdin": "^8.0.0", + "globby": "^11.1.0", + "graceful-fs": "^4.2.11", + "https-proxy-agent": "^5.0.1", + "is-docker": "^2.2.1", + "js-yaml": "^4.1.0", + "json-colorizer": "^2.2.2", + "json-cycle": "^1.5.0", + "json-refs": "^3.0.15", + "lodash": "^4.17.21", + "memoizee": "^0.4.15", + "micromatch": "^4.0.5", + "node-fetch": "^2.6.11", + "npm-registry-utilities": "^1.0.0", + "object-hash": "^3.0.0", + "open": "^8.4.2", + "path2": "^0.1.0", + "process-utils": "^4.0.0", + "promise-queue": "^2.2.5", + "require-from-string": "^2.0.2", + "semver": "^7.5.3", + "signal-exit": "^3.0.7", + "stream-buffers": "^3.0.2", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "tar": "^6.1.15", + "timers-ext": "^0.1.7", + "type": "^2.7.2", + "untildify": "^4.0.0", + "uuid": "^9.0.0", + "ws": "^7.5.9", + "yaml-ast-parser": "0.0.43" + }, + "bin": { + "serverless": "bin/serverless.js", + "sls": "bin/serverless.js" + }, + "engines": { + "node": ">=12.0" + } + }, + "node_modules/serverless-dotenv-plugin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serverless-dotenv-plugin/-/serverless-dotenv-plugin-6.0.0.tgz", + "integrity": "sha512-8tLVNwHfDO0sBz6+m+DLTZquRk0AZq9rzqk3kphm1iIWKfan9R7RKt4hdq3eQ0kmDoqzudjPYBEXAJ5bUNKeGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "dotenv": "^16.0.3", + "dotenv-expand": "^10.0.0" + }, + "peerDependencies": { + "serverless": "1 || 2 || pre-3 || 3" + } + }, + "node_modules/serverless-dotenv-plugin/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/serverless-dotenv-plugin/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/serverless-dotenv-plugin/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/serverless-esbuild": { + "version": "1.56.1", + "resolved": "https://registry.npmjs.org/serverless-esbuild/-/serverless-esbuild-1.56.1.tgz", + "integrity": "sha512-EjreAvwkAZ1IVTIOxOqPCmZkKeTPdmQufhnfvOhfJhj6paT0SiAG3ubLXdX1mzXwKiQl15p3T7ZBmzA4KYGnGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@effect/platform": "^0.65.5", + "@effect/platform-node": "^0.60.5", + "@effect/schema": "^0.73.4", + "acorn": "^8.8.1", + "acorn-walk": "^8.2.0", + "anymatch": "^3.1.3", + "archiver": "^5.3.1", + "bestzip": "^2.2.1", + "chokidar": "^3.5.3", + "effect": "^3.8.3", + "execa": "^5.1.1", + "fs-extra": "^11.1.0", + "globby": "^11.0.4", + "p-map": "^4.0.0", + "ramda": "^0.28.0", + "semver": "^7.3.8" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "esbuild": "0.8 - 0.27", + "esbuild-node-externals": "^1.0.0" + }, + "peerDependenciesMeta": { + "esbuild-node-externals": { + "optional": true + } + } + }, + "node_modules/serverless-esbuild/node_modules/archiver": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^2.1.0", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/serverless-esbuild/node_modules/archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/serverless-esbuild/node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/serverless-esbuild/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/serverless-esbuild/node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/serverless-esbuild/node_modules/compress-commons": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/serverless-esbuild/node_modules/crc32-stream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/serverless-esbuild/node_modules/fs-extra": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", + "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/serverless-esbuild/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", + "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/serverless-esbuild/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/serverless-esbuild/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/serverless-esbuild/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/serverless-esbuild/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/serverless-esbuild/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/serverless-esbuild/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/serverless-esbuild/node_modules/zip-stream": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/serverless-esbuild/node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/serverless/node_modules/archiver": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^2.1.0", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/serverless/node_modules/archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/serverless/node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/serverless/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/serverless/node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/serverless/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/serverless/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/serverless/node_modules/compress-commons": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/serverless/node_modules/crc32-stream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/serverless/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/serverless/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", + "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/serverless/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/serverless/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/serverless/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/serverless/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/serverless/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/serverless/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/serverless/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/serverless/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/serverless/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/serverless/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/serverless/node_modules/zip-stream": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/serverless/node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true, + "license": "MIT" + }, + "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/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/simple-git": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.30.0.tgz", + "integrity": "sha512-q6lxyDsCmEal/MEGhP1aVyQ3oxnagGlBDOVSIB4XUVLl1iZh0Pah6ebC9V4xBap/RfgP2WlI8EKs0WS0rMEJHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/git-js?sponsor=1" + } + }, + "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/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "license": "ISC", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/split2/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/sprintf-kit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/sprintf-kit/-/sprintf-kit-2.0.2.tgz", + "integrity": "sha512-lnapdj6W4LflHZGKvl9eVkz5YF0xaTrqpRWVA4cNVOTedwqifIP8ooGImldzT/4IAN5KXFQAyXTdLidYVQdyag==", + "dev": true, + "license": "ISC", + "dependencies": { + "es5-ext": "^0.10.64" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/stream-buffers": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.3.tgz", + "integrity": "sha512-pqMqwQCso0PBJt2PQmDO0cFj0lyqmiwOMiMSkVtRokl7e+ZTRYgDHKnuZNbqjiJXgsg4nuqtD/zxuo9KqTp0Yw==", + "dev": true, + "license": "Unlicense", + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/stream-promise": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/stream-promise/-/stream-promise-3.2.0.tgz", + "integrity": "sha512-P+7muTGs2C8yRcgJw/PPt61q7O517tDHiwYEzMWo1GSBCcZedUMT/clz7vUNsSxFphIlJ6QUL4GexQKlfJoVtA==", + "dev": true, + "license": "ISC", + "dependencies": { + "2-thenable": "^1.0.0", + "es5-ext": "^0.10.49", + "is-stream": "^1.1.0" + } + }, + "node_modules/stream-promise/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/streamx": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "events-universal": "^1.0.0", + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "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/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/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==", + "dev": true, + "license": "MIT" + }, + "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.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/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/strip-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", + "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-natural-number": "^4.0.1" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strnum": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.1.tgz", + "integrity": "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/strtok3": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^4.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/superagent": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-7.1.6.tgz", + "integrity": "sha512-gZkVCQR1gy/oUXr+kxJMLDjla434KmSOKbx5iGD30Ql+AkJQ/YlPKECJy2nhqOsHLjGHzoDTXNSjhnvWhzKk7g==", + "deprecated": "Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net", + "dev": true, + "license": "MIT", + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.3", + "debug": "^4.3.4", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.0", + "formidable": "^2.0.1", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.10.3", + "readable-stream": "^3.6.0", + "semver": "^7.3.7" + }, + "engines": { + "node": ">=6.4.0 <13 || >=14" + } + }, + "node_modules/superagent/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/superagent/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "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/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true, + "license": "MIT" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/timers-ext": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.8.tgz", + "integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==", + "dev": true, + "license": "ISC", + "dependencies": { + "es5-ext": "^0.10.64", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/to-buffer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", + "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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/token-types": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", + "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/traverse": { + "version": "0.6.11", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.11.tgz", + "integrity": "sha512-vxXDZg8/+p3gblxB6BhhG5yWVn1kGRlaL8O78UDXc3wRnPizB5g83dcvWV1jpDMIPnjZjOFuxlMmE82XJ4407w==", + "dev": true, + "license": "MIT", + "dependencies": { + "gopd": "^1.2.0", + "typedarray.prototype.slice": "^1.0.5", + "which-typed-array": "^1.1.18" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "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==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", + "dev": true, + "license": "ISC" + }, + "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/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray.prototype.slice": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typedarray.prototype.slice/-/typedarray.prototype.slice-1.0.5.tgz", + "integrity": "sha512-q7QNVDGTdl702bVFiI5eY4l/HkgCM6at9KhcFbgUAzezHFbOVy4+0O/lCjsABEQwbZPravVfBIiBVGo89yzHFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "math-intrinsics": "^1.1.0", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-offset": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/unbzip2-stream/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "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": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/undici": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.22.0.tgz", + "integrity": "sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/uni-global": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/uni-global/-/uni-global-1.0.0.tgz", + "integrity": "sha512-WWM3HP+siTxzIWPNUg7hZ4XO8clKi6NoCAJJWnuRL+BAqyFXF8gC03WNyTefGoUXYc47uYgXxpKLIEvo65PEHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "type": "^2.5.0" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/url/node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "node_modules/validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==", + "dev": true, + "license": "ISC", + "dependencies": { + "builtins": "^1.0.3" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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/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/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/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/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==", + "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/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/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "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/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==", + "dev": true, + "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" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml-ast-parser": { + "version": "0.0.43", + "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", + "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/yamljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", + "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "glob": "^7.0.5" + }, + "bin": { + "json2yaml": "bin/json2yaml", + "yaml2json": "bin/yaml2json" + } + }, + "node_modules/yamljs/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/yamljs/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/yamljs/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", + "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/yamljs/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/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "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/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yauzl/node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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/zip-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + } + } +} diff --git a/examples/aws-lambda/package.json b/examples/aws-lambda/package.json new file mode 100644 index 00000000..657d5467 --- /dev/null +++ b/examples/aws-lambda/package.json @@ -0,0 +1,38 @@ +{ + "name": "nylas-aws-lambda-attachments", + "version": "1.0.0", + "description": "AWS Lambda example for sending email attachments using Nylas SDK", + "main": "src/handler.ts", + "scripts": { + "setup": "ts-node setup-cli.ts", + "deploy": "dotenv -e .env -- serverless deploy", + "remove": "dotenv -e .env -- serverless remove", + "logs": "dotenv -e .env -- serverless logs -f sendAttachment -t", + "build:manual": "ts-node build-manual.ts", + "type-check": "tsc --noEmit" + }, + "keywords": ["aws", "lambda", "nylas", "email", "attachments", "serverless"], + "author": "Nylas", + "license": "MIT", + "dependencies": { + "nylas": "file:../../", + "mime-types": "^2.1.35" + }, + "devDependencies": { + "serverless": "^3.38.0", + "serverless-esbuild": "^1.52.0", + "serverless-dotenv-plugin": "^6.0.0", + "dotenv-cli": "^7.4.2", + "archiver": "^7.0.1", + "@types/archiver": "^6.0.2", + "@types/aws-lambda": "^8.10.131", + "@types/mime-types": "^2.1.4", + "chalk": "^5.6.2", + "commander": "^14.0.0", + "inquirer": "^12.9.4", + "dotenv": "^17.2.2", + "typescript": "^5.8.3", + "ts-node": "^10.9.2" + } +} + diff --git a/examples/aws-lambda/serverless.yml b/examples/aws-lambda/serverless.yml new file mode 100644 index 00000000..4aa368f6 --- /dev/null +++ b/examples/aws-lambda/serverless.yml @@ -0,0 +1,48 @@ +service: nylas-lambda-attachments + +frameworkVersion: '3' + +provider: + name: aws + runtime: nodejs20.x + region: us-west-1 + memorySize: 512 + timeout: 30 + environment: + NYLAS_API_KEY: ${env:NYLAS_API_KEY} + NYLAS_API_URI: ${env:NYLAS_API_URI, 'https://api.us.nylas.com'} + NYLAS_GRANT_ID: ${env:NYLAS_GRANT_ID} + httpApi: + cors: true + +plugins: + - serverless-dotenv-plugin + - serverless-esbuild + +custom: + dotenv: + path: .env + esbuild: + bundle: true + minify: false + sourcemap: false + exclude: + - aws-sdk + target: node20 + platform: node + concurrency: 10 + +functions: + sendAttachment: + handler: src/handler.handler + events: + - httpApi: + path: / + method: GET + - httpApi: + path: /send-attachment + method: POST + - httpApi: + path: /{proxy+} + method: ANY + diff --git a/examples/aws-lambda/setup-cli.ts b/examples/aws-lambda/setup-cli.ts new file mode 100644 index 00000000..19fa37f3 --- /dev/null +++ b/examples/aws-lambda/setup-cli.ts @@ -0,0 +1,437 @@ +#!/usr/bin/env node + +import chalk from 'chalk'; +import { Command } from 'commander'; +import * as dotenv from 'dotenv'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as process from 'process'; +import { execSync } from 'child_process'; +import inquirer from 'inquirer'; + +interface SetupConfig { + nylasApiKey: string; + nylasApiUri: string; + nylasGrantId: string; + awsProfile?: string; + awsRegion?: string; + deployNow?: boolean; +} + +// Check if a command exists +function commandExists(command: string): boolean { + try { + execSync(`which ${command}`, { stdio: 'ignore' }); + return true; + } catch { + return false; + } +} + +// Get version of a command +function getVersion(command: string): string { + try { + const output = execSync(`${command} --version`, { encoding: 'utf-8' }); + return output.trim().split('\n')[0]; + } catch { + return 'unknown'; + } +} + +// Check prerequisites +function checkPrerequisites(): boolean { + console.log(chalk.blue.bold('\nπŸ” Checking Prerequisites\n')); + + let allGood = true; + + // Check Node.js + if (!commandExists('node')) { + console.log(chalk.red('❌ Node.js is not installed')); + console.log(chalk.yellow(' Install from: https://nodejs.org/')); + allGood = false; + } else { + const nodeVersion = getVersion('node'); + const majorVersion = parseInt(nodeVersion.replace('v', '').split('.')[0]); + if (majorVersion < 16) { + console.log(chalk.red(`❌ Node.js ${nodeVersion} is too old (need 16+)`)); + allGood = false; + } else { + console.log(chalk.green(`βœ… Node.js ${nodeVersion}`)); + } + } + + // Check npm + if (!commandExists('npm')) { + console.log(chalk.red('❌ npm is not installed')); + allGood = false; + } else { + console.log(chalk.green(`βœ… npm ${getVersion('npm')}`)); + } + + // Check AWS CLI + if (!commandExists('aws')) { + console.log(chalk.yellow('⚠️ AWS CLI is not installed')); + console.log(chalk.yellow(' Install from: https://aws.amazon.com/cli/')); + console.log( + chalk.yellow(' Or use AWS credentials in ~/.aws/credentials') + ); + } else { + console.log(chalk.green(`βœ… AWS CLI ${getVersion('aws')}`)); + } + + // Check Serverless Framework + if (!commandExists('serverless')) { + console.log(chalk.yellow('⚠️ Serverless Framework not found globally')); + console.log(chalk.yellow(' Will use npx serverless instead')); + } else { + console.log( + chalk.green(`βœ… Serverless Framework ${getVersion('serverless')}`) + ); + } + + console.log(''); + return allGood; +} + +// Check AWS credentials +async function checkAwsCredentials(): Promise<{ + profile?: string; + region?: string; +}> { + const awsDir = path.join(process.env.HOME || '', '.aws'); + const credentialsFile = path.join(awsDir, 'credentials'); + const configFile = path.join(awsDir, 'config'); + + let hasCredentials = false; + let profile = 'default'; + let region = 'us-east-1'; + + if (fs.existsSync(credentialsFile)) { + hasCredentials = true; + console.log(chalk.green('βœ… AWS credentials file found')); + } else { + console.log(chalk.yellow('⚠️ AWS credentials file not found')); + } + + if (fs.existsSync(configFile)) { + const configContent = fs.readFileSync(configFile, 'utf-8'); + const regionMatch = configContent.match(/region\s*=\s*(\S+)/); + if (regionMatch) { + region = regionMatch[1]; + } + } + + // Check if AWS credentials are configured via environment variables + if (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) { + hasCredentials = true; + console.log( + chalk.green('βœ… AWS credentials found in environment variables') + ); + } + + if (!hasCredentials) { + const { setupAws } = await inquirer.prompt([ + { + type: 'confirm', + name: 'setupAws', + message: 'Would you like to set up AWS credentials now?', + default: false, + }, + ]); + + if (setupAws) { + console.log(chalk.blue('\nπŸ“ AWS Credentials Setup')); + console.log(chalk.yellow('You can set up AWS credentials by:')); + console.log(chalk.yellow('1. Running: aws configure')); + console.log( + chalk.yellow( + '2. Or setting AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables' + ) + ); + console.log( + chalk.yellow('3. Or creating ~/.aws/credentials file manually\n') + ); + + const answers = await inquirer.prompt([ + { + type: 'input', + name: 'profile', + message: 'AWS Profile name (default: default):', + default: 'default', + }, + { + type: 'input', + name: 'region', + message: 'AWS Region (default: us-east-1):', + default: 'us-east-1', + }, + ]); + + profile = answers.profile; + region = answers.region; + } + } else { + const answers = await inquirer.prompt([ + { + type: 'input', + name: 'profile', + message: 'AWS Profile name (default: default):', + default: 'default', + }, + { + type: 'input', + name: 'region', + message: 'AWS Region (default: us-east-1):', + default: region, + }, + ]); + + profile = answers.profile; + region = answers.region; + } + + return { profile, region }; +} + +// Interactive setup +async function interactiveSetup(): Promise { + console.log(chalk.blue.bold('\nπŸš€ Nylas AWS Lambda Setup\n')); + console.log( + chalk.gray( + 'This will guide you through setting up the AWS Lambda example.\n' + ) + ); + + // Check prerequisites + const prerequisitesOk = checkPrerequisites(); + if (!prerequisitesOk) { + console.log( + chalk.red('\n❌ Please install missing prerequisites before continuing.') + ); + process.exit(1); + } + + // Nylas credentials + console.log(chalk.blue.bold('\nπŸ“‹ Nylas Configuration\n')); + console.log(chalk.gray('Get these from: https://dashboard.nylas.com\n')); + + const nylasAnswers = await inquirer.prompt([ + { + type: 'input', + name: 'nylasApiKey', + message: 'Nylas API Key:', + validate: (input: string) => input.length > 0 || 'API Key is required', + }, + { + type: 'list', + name: 'nylasApiUri', + message: 'Nylas API Region:', + choices: [ + { + name: 'US (https://api.us.nylas.com)', + value: 'https://api.us.nylas.com', + }, + { + name: 'EU (https://api.eu.nylas.com)', + value: 'https://api.eu.nylas.com', + }, + { name: 'Custom', value: 'custom' }, + ], + }, + { + type: 'input', + name: 'customApiUri', + message: 'Custom Nylas API URI:', + when: (answers) => answers.nylasApiUri === 'custom', + validate: (input: string) => + input.startsWith('http') || 'Must be a valid URL', + }, + { + type: 'input', + name: 'nylasGrantId', + message: 'Nylas Grant ID (connected account ID):', + validate: (input: string) => input.length > 0 || 'Grant ID is required', + }, + ]); + + // AWS configuration + console.log(chalk.blue.bold('\n☁️ AWS Configuration\n')); + const awsConfig = await checkAwsCredentials(); + + // Deployment + const deployAnswer = await inquirer.prompt([ + { + type: 'confirm', + name: 'deployNow', + message: 'Deploy to AWS Lambda now?', + default: false, + }, + ]); + + return { + nylasApiKey: nylasAnswers.nylasApiKey, + nylasApiUri: nylasAnswers.customApiUri || nylasAnswers.nylasApiUri, + nylasGrantId: nylasAnswers.nylasGrantId, + awsProfile: awsConfig.profile, + awsRegion: awsConfig.region, + deployNow: deployAnswer.deployNow, + }; +} + +// Create .env file +function createEnvFile(config: SetupConfig): void { + const envPath = path.join(__dirname, '.env'); + const envContent = `# Nylas Configuration +NYLAS_API_KEY=${config.nylasApiKey} +NYLAS_API_URI=${config.nylasApiUri} +NYLAS_GRANT_ID=${config.nylasGrantId} + +# AWS Configuration (optional - can also use AWS credentials file) +AWS_PROFILE=${config.awsProfile || 'default'} +AWS_REGION=${config.awsRegion || 'us-east-1'} +`; + + fs.writeFileSync(envPath, envContent); + console.log(chalk.green(`βœ… Created .env file at ${envPath}`)); +} + +// Update serverless.yml with region +function updateServerlessConfig(region: string): void { + const serverlessPath = path.join(__dirname, 'serverless.yml'); + if (fs.existsSync(serverlessPath)) { + let content = fs.readFileSync(serverlessPath, 'utf-8'); + + // Update provider region if it exists + if (content.includes('region:')) { + content = content.replace(/region:\s*\S+/g, `region: ${region}`); + } else { + // Add region after provider name + content = content.replace(/(provider:\s*\n)/, `$1 region: ${region}\n`); + } + + fs.writeFileSync(serverlessPath, content); + console.log( + chalk.green(`βœ… Updated serverless.yml with region: ${region}`) + ); + } +} + +// Deploy function +async function deploy(): Promise { + console.log(chalk.blue.bold('\nπŸš€ Deploying to AWS Lambda\n')); + + try { + // Check if .env file exists + const envPath = path.join(__dirname, '.env'); + if (!fs.existsSync(envPath)) { + console.log(chalk.red('❌ .env file not found!')); + console.log(chalk.yellow('Please run: npm run setup')); + process.exit(1); + } + + // Load .env file to verify it has required variables + dotenv.config({ path: envPath }); + if (!process.env.NYLAS_API_KEY || !process.env.NYLAS_GRANT_ID) { + console.log( + chalk.red('❌ Missing required environment variables in .env file!') + ); + console.log( + chalk.yellow('Please ensure NYLAS_API_KEY and NYLAS_GRANT_ID are set') + ); + process.exit(1); + } + + // Install dependencies first + console.log(chalk.blue('πŸ“¦ Installing dependencies...')); + execSync('npm install', { stdio: 'inherit', cwd: __dirname }); + + // Deploy with serverless using dotenv-cli to ensure .env is loaded + console.log(chalk.blue('\n☁️ Deploying to AWS...')); + execSync('npx dotenv-cli -e .env -- npx serverless deploy', { + stdio: 'inherit', + cwd: __dirname, + }); + + console.log(chalk.green.bold('\nβœ… Deployment successful!')); + console.log(chalk.blue('\nNext steps:')); + console.log( + chalk.gray('1. Check the deployment output for your API Gateway URL') + ); + console.log( + chalk.gray( + '2. Visit the URL in your browser to test the attachment sender' + ) + ); + console.log( + chalk.gray( + '3. Try uploading multiple files totaling over 3MB to test the bug fix' + ) + ); + } catch (error) { + console.log(chalk.red('\n❌ Deployment failed')); + console.log( + chalk.yellow('Make sure AWS credentials are configured correctly') + ); + console.log(chalk.yellow('Run: aws configure')); + process.exit(1); + } +} + +// Main CLI +async function main() { + const program = new Command(); + + program + .name('setup') + .description('Setup CLI for Nylas AWS Lambda example') + .version('1.0.0'); + + program + .command('interactive', { isDefault: true }) + .description('Run interactive setup') + .action(async () => { + const config = await interactiveSetup(); + createEnvFile(config); + if (config.awsRegion) { + updateServerlessConfig(config.awsRegion); + } + + console.log(chalk.green.bold('\nβœ… Setup complete!\n')); + + if (config.deployNow) { + await deploy(); + } else { + console.log(chalk.blue('Next steps:')); + console.log(chalk.gray('1. Review the .env file')); + console.log(chalk.gray('2. Run: npm install')); + console.log(chalk.gray('3. Run: npm run deploy')); + console.log(chalk.gray('4. Or run: npm run setup (to deploy now)')); + } + }); + + program + .command('deploy') + .description('Deploy to AWS Lambda') + .action(async () => { + await deploy(); + }); + + program + .command('check') + .description('Check prerequisites only') + .action(() => { + checkPrerequisites(); + }); + + await program.parseAsync(); +} + +// Run if executed directly +if (require.main === module) { + main().catch((error) => { + console.error(chalk.red('Error:'), error.message); + process.exit(1); + }); +} + +export { main as setup }; diff --git a/examples/aws-lambda/src/handler.ts b/examples/aws-lambda/src/handler.ts new file mode 100644 index 00000000..565cb6d3 --- /dev/null +++ b/examples/aws-lambda/src/handler.ts @@ -0,0 +1,760 @@ +import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda'; +import Nylas, { SendMessageRequest } from 'nylas'; +import * as mimeTypes from 'mime-types'; + +// Environment variables interface +interface LambdaEnv { + NYLAS_API_KEY: string; + NYLAS_API_URI?: string; + NYLAS_GRANT_ID: string; +} + +// HTML interface for file upload with multiple file support +const HTML_INTERFACE = ` + + + + + + Nylas Attachment Sender - AWS Lambda + + + +
+

πŸ“§ Nylas Attachment Sender

+

+ Upload multiple files and send them as email attachments using the Nylas SDK in AWS Lambda
+ Test the fix for: "Lambda freezes when sending emails with 2+ attachments over 3MB total" +

+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ +
+ πŸ“Ž Click to select files
+ or drag and drop here
+ Select multiple files to test 2+ attachments over 3MB +
+
+
+
+ + +
+ +
+
+ + + + +`; + +// Helper function to get content type +function getContentType(filename: string): string { + return mimeTypes.lookup(filename) || 'application/octet-stream'; +} + +// Helper function to parse multipart form data from API Gateway +// Note: For production use, consider using a library like 'lambda-multipart-parser' +// or 'busboy' for more robust multipart parsing +async function parseFormData( + body: string, + contentType: string +): Promise<{ [key: string]: any }> { + // API Gateway HTTP API sends multipart data as a string (or base64 if isBase64Encoded is true) + // We parse it manually here for simplicity + // For production, use a library like 'lambda-multipart-parser' + + // Extract boundary from Content-Type header + const boundaryMatch = contentType.match(/boundary=([^;]+)/); + if (!boundaryMatch) { + throw new Error(`Invalid multipart content type: ${contentType}`); + } + const boundary = boundaryMatch[1].trim(); + + // Split by boundary (with -- prefix) + const parts = body.split(`--${boundary}`); + const result: { [key: string]: any } = { files: [] }; + + for (const part of parts) { + // Skip empty parts and closing boundary + const trimmedPart = part.trim(); + if (!trimmedPart || trimmedPart === '--' || trimmedPart === '') continue; + + // Split headers and content (multipart uses \r\n\r\n as separator) + const headerEndIndex = trimmedPart.indexOf('\r\n\r\n'); + if (headerEndIndex === -1) { + // Try \n\n as fallback + const headerEndIndexAlt = trimmedPart.indexOf('\n\n'); + if (headerEndIndexAlt === -1) continue; + const headers = trimmedPart.substring(0, headerEndIndexAlt); + const content = trimmedPart.substring(headerEndIndexAlt + 2); + processPart(headers, content, result); + } else { + const headers = trimmedPart.substring(0, headerEndIndex); + const content = trimmedPart.substring(headerEndIndex + 4); + processPart(headers, content, result); + } + } + + return result; +} + +function processPart( + headers: string, + content: string, + result: { [key: string]: any } +): void { + // Extract field name + const nameMatch = headers.match(/name="([^"]+)"/); + if (!nameMatch) return; + + const name = nameMatch[1]; + + // Check if it's a file (has filename attribute) + const filenameMatch = headers.match(/filename="([^"]+)"/); + const contentTypeMatch = headers.match(/Content-Type:\s*([^\r\n]+)/i); + + // Remove trailing \r\n from content + const trimmedContent = content.replace(/\r\n$/, '').replace(/\n$/, ''); + + if (filenameMatch) { + // It's a file + const filename = filenameMatch[1]; + const fileContentType = contentTypeMatch + ? contentTypeMatch[1].trim() + : getContentType(filename); + + // Convert content to buffer (handle both binary and base64 if needed) + const buffer = Buffer.from(trimmedContent, 'binary'); + + if (!result.files) { + result.files = []; + } + result.files.push({ + filename, + contentType: fileContentType, + content: buffer, + size: buffer.length, + }); + } else { + // It's a regular form field + result[name] = trimmedContent; + } +} + +// Main Lambda handler +// Export as const so esbuild can properly convert to CommonJS exports.handler +export const handler = async ( + event: APIGatewayProxyEvent +): Promise => { + // CORS headers + const corsHeaders = { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type', + }; + + try { + // Handle CORS preflight + if (event.httpMethod === 'OPTIONS') { + return { + statusCode: 200, + headers: corsHeaders, + body: '', + }; + } + + // Validate environment variables + const env: LambdaEnv = { + NYLAS_API_KEY: process.env.NYLAS_API_KEY || '', + NYLAS_API_URI: process.env.NYLAS_API_URI || 'https://api.us.nylas.com', + NYLAS_GRANT_ID: process.env.NYLAS_GRANT_ID || '', + }; + + if (!env.NYLAS_API_KEY || !env.NYLAS_GRANT_ID) { + console.error('Missing environment variables:', { + hasApiKey: !!env.NYLAS_API_KEY, + hasGrantId: !!env.NYLAS_GRANT_ID, + }); + return { + statusCode: 500, + headers: { 'Content-Type': 'application/json', ...corsHeaders }, + body: JSON.stringify({ + error: + 'Missing required environment variables (NYLAS_API_KEY, NYLAS_GRANT_ID)', + }), + }; + } + + // Get the request path (API Gateway HTTP API uses rawPath, REST API uses path) + const requestPath = (event as any).rawPath || event.path || '/'; + const httpMethod = + event.httpMethod || (event as any).requestContext?.http?.method || 'GET'; + + console.log('Request received:', { + httpMethod, + requestPath, + hasBody: !!event.body, + }); + + // Serve HTML interface on GET / + if (httpMethod === 'GET' && requestPath === '/') { + return { + statusCode: 200, + headers: { + 'Content-Type': 'text/html', + ...corsHeaders, + }, + body: HTML_INTERFACE, + }; + } + + // Handle file upload and email sending on POST /send-attachment + if (httpMethod === 'POST' && requestPath === '/send-attachment') { + try { + // Parse multipart form data + const contentType = + event.headers['Content-Type'] || event.headers['content-type'] || ''; + + if (!contentType.includes('multipart/form-data')) { + return { + statusCode: 400, + headers: { 'Content-Type': 'application/json', ...corsHeaders }, + body: JSON.stringify({ + error: 'Content-Type must be multipart/form-data', + }), + }; + } + + // API Gateway sends body as base64 if isBase64Encoded is true + const body = event.isBase64Encoded + ? Buffer.from(event.body || '', 'base64').toString('binary') + : event.body || ''; + + if (!body) { + return { + statusCode: 400, + headers: { 'Content-Type': 'application/json', ...corsHeaders }, + body: JSON.stringify({ error: 'Request body is empty' }), + }; + } + + let formData; + try { + formData = await parseFormData(body, contentType); + console.log('Parsed form data keys:', Object.keys(formData)); + console.log('Files count:', formData.files?.length || 0); + console.log( + 'Recipient email:', + formData.recipientEmail ? 'present' : 'missing' + ); + console.log('Subject:', formData.subject ? 'present' : 'missing'); + console.log('Message:', formData.message ? 'present' : 'missing'); + } catch (parseError) { + console.error('Error parsing form data:', parseError); + console.error('Content-Type:', contentType); + console.error('Body length:', body.length); + console.error( + 'Body preview (first 500 chars):', + body.substring(0, 500) + ); + return { + statusCode: 400, + headers: { 'Content-Type': 'application/json', ...corsHeaders }, + body: JSON.stringify({ + error: 'Failed to parse form data', + details: + parseError instanceof Error + ? parseError.message + : String(parseError), + }), + }; + } + const recipientEmail = formData.recipientEmail as string; + const subject = formData.subject as string; + const message = formData.message as string; + const files = formData.files as Array<{ + filename: string; + contentType: string; + content: Buffer; + size: number; + }>; + + // Validate required fields with detailed error + const missingFields: string[] = []; + if (!recipientEmail) missingFields.push('recipientEmail'); + if (!subject) missingFields.push('subject'); + if (!message) missingFields.push('message'); + if (!files || files.length === 0) missingFields.push('files'); + + if (missingFields.length > 0) { + console.error('Missing required fields:', missingFields); + console.error('Form data keys:', Object.keys(formData)); + console.error('Form data values:', { + recipientEmail: formData.recipientEmail ? 'present' : 'missing', + subject: formData.subject ? 'present' : 'missing', + message: formData.message ? 'present' : 'missing', + filesCount: formData.files?.length || 0, + }); + return { + statusCode: 400, + headers: { 'Content-Type': 'application/json', ...corsHeaders }, + body: JSON.stringify({ + error: 'Missing required fields', + missingFields: missingFields, + receivedFields: Object.keys(formData), + }), + }; + } + + // Initialize Nylas client + const nylas = new Nylas({ + apiKey: env.NYLAS_API_KEY, + apiUri: env.NYLAS_API_URI, + timeout: 3, + }); + + // Prepare attachments + // The SDK automatically uses multipart/form-data when total payload size >= 3MB + // This fixes the bug where Lambda would freeze with 2+ attachments over 3MB total + const attachments = files.map((file) => ({ + filename: file.filename, + contentType: file.contentType, + content: file.content, + size: file.size, + })); + + // Calculate total size for logging + const totalSize = attachments.reduce((sum, att) => sum + att.size, 0); + const threeMB = 3 * 1024 * 1024; + + console.log( + `Sending email with ${attachments.length} attachment(s), total size: ${totalSize} bytes (${totalSize >= threeMB ? '>= 3MB, will use multipart/form-data' : '< 3MB, will use JSON'})` + ); + + // Output the attachments json without the content + console.log( + 'Attachments JSON:', + JSON.stringify( + attachments.map((att) => ({ + filename: att.filename, + contentType: att.contentType, + size: att.size, + })), + null, + 2 + ) + ); + + // Prepare the email request + const sendRequest: SendMessageRequest = { + to: [{ email: recipientEmail }], + subject: subject, + body: ` +
+

Email from AWS Lambda

+

${message.replace(/\n/g, '
')}

+
+

+ This email was sent from an AWS Lambda function using the Nylas SDK.
+ Attachments: ${attachments.length} file(s) (${(totalSize / 1024 / 1024).toFixed(2)} MB total) +

+
+ `, + attachments, + }; + + // Send the email using the Nylas SDK + // The SDK automatically handles the 3MB threshold: + // - If total payload < 3MB: uses JSON encoding + // - If total payload >= 3MB: uses multipart/form-data encoding + // This prevents Lambda from freezing with large attachments + const response = await nylas.messages.send({ + identifier: env.NYLAS_GRANT_ID, + requestBody: sendRequest, + overrides: { + timeout: 3000, + }, + }); + + console.log('Nylas API response received:', { + hasResponse: !!response, + hasData: !!response?.data, + responseKeys: response ? Object.keys(response) : [], + dataKeys: response?.data ? Object.keys(response.data) : [], + messageId: response?.data?.id, + }); + + // Extract message ID safely (response.data is the Message object) + const messageId = response?.data?.id || 'unknown'; + + // Return success response + const successResponse = { + success: true, + messageId: messageId, + message: 'Email sent successfully', + attachmentsCount: attachments.length, + totalSize: totalSize, + }; + + console.log('Returning success response:', successResponse); + + return { + statusCode: 200, + headers: { 'Content-Type': 'application/json', ...corsHeaders }, + body: JSON.stringify(successResponse), + }; + } catch (error) { + console.error('Error sending email:', error); + + return { + statusCode: 500, + headers: { 'Content-Type': 'application/json', ...corsHeaders }, + body: JSON.stringify({ + error: + error instanceof Error ? error.message : 'Unknown error occurred', + }), + }; + } + } + + // 404 for other routes + return { + statusCode: 404, + headers: corsHeaders, + body: JSON.stringify({ error: 'Not Found' }), + }; + } catch (error) { + console.error('Unhandled error in handler:', error); + return { + statusCode: 500, + headers: { 'Content-Type': 'application/json', ...corsHeaders }, + body: JSON.stringify({ + error: error instanceof Error ? error.message : 'Internal server error', + details: error instanceof Error ? error.stack : String(error), + }), + }; + } +}; + +// With --format=cjs, esbuild will convert "export const handler" to "exports.handler = handler" +// This is the correct format for Lambda handlers +// No need for additional exports - esbuild handles the CommonJS conversion diff --git a/examples/aws-lambda/tsconfig.json b/examples/aws-lambda/tsconfig.json new file mode 100644 index 00000000..82528106 --- /dev/null +++ b/examples/aws-lambda/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "commonjs", + "lib": ["ES2020"], + "declaration": false, + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "outDir": "dist", + "rootDir": "." + }, + "include": [ + "**/*.ts" + ], + "exclude": [ + "node_modules", + "dist" + ] +} + diff --git a/examples/calendars/README.md b/examples/calendars/README.md new file mode 100644 index 00000000..33f500a5 --- /dev/null +++ b/examples/calendars/README.md @@ -0,0 +1,50 @@ +# Nylas Calendar API Examples + +This directory contains examples of how to use the Nylas Calendar API with the Nylas Node.js SDK. + +## Examples + +- [event_with_notetaker.ts](./event_with_notetaker.ts) - A complete example showing how to create calendar events with Notetaker integration, retrieve events with their associated Notetakers, and update both events and Notetakers. + +## Running the Examples + +To run these examples, you'll need to: + +1. Install dependencies from the examples directory: + ```bash + cd examples + npm install + ``` + +2. Copy the `.env.example` file to `.env` if you haven't already and add your credentials: + ```bash + cp .env.example .env + # Edit .env with your editor + ``` + +3. Edit the `.env` file to include: + - `NYLAS_API_KEY` - Your Nylas API key + - `NYLAS_API_URI` (optional) - The Nylas API server URI (defaults to "https://api.us.nylas.com") + - `NYLAS_GRANT_ID` - The Grant ID to use for calendar operations + - `NYLAS_CALENDAR_ID` - The Calendar ID to use for creating and updating events + +4. Run the example: + ```bash + # From the examples directory + npm run calendars + + # Or directly with ts-node + npx ts-node calendars/event_with_notetaker.ts + ``` + +## Understanding the Example + +This example demonstrates: + +1. **Creating an Event with a Notetaker**: Creating a calendar event with an integrated Notetaker bot. +2. **Retrieving Event Notetaker**: Finding the Notetaker associated with a specific event. +3. **Updating Event and Notetaker**: Modifying both an event's details and its associated Notetaker settings. + +## Documentation + +For more information, see the [Nylas API Documentation](https://developer.nylas.com/). \ No newline at end of file diff --git a/examples/calendars/event_with_notetaker.ts b/examples/calendars/event_with_notetaker.ts new file mode 100644 index 00000000..efeb2b7a --- /dev/null +++ b/examples/calendars/event_with_notetaker.ts @@ -0,0 +1,286 @@ +import dotenv from 'dotenv'; +import path from 'path'; +import * as process from 'process'; +import Nylas from 'nylas'; +import { + Notetaker, + Event, + NylasResponse, + NylasApiError, + CreateEventRequest, + UpdateEventRequest, + NotetakerSettings, +} from 'nylas'; + +// Load environment variables from .env file +dotenv.config({ path: path.resolve(__dirname, '../.env') }); + +// Check for required environment variables +const apiKey: string = process.env.NYLAS_API_KEY || ''; +const grantId: string = process.env.NYLAS_GRANT_ID || ''; +const calendarId: string = process.env.NYLAS_CALENDAR_ID || ''; + +if (!apiKey) { + throw new Error('NYLAS_API_KEY environment variable is not set'); +} +if (!grantId) { + throw new Error('NYLAS_GRANT_ID environment variable is not set'); +} +if (!calendarId) { + throw new Error('NYLAS_CALENDAR_ID environment variable is not set'); +} + +// Initialize the Nylas client +const nylas = new Nylas({ + apiKey, + apiUri: process.env.NYLAS_API_URI || 'https://api.us.nylas.com', +}); + +/** + * Creates a calendar event with a Notetaker + * @returns The created event + */ +async function createEventWithNotetaker(): Promise> { + console.log('\n=== Creating Event with Notetaker ==='); + + try { + // Calculate start and end times (1 day from now, 1 hour duration) + const startTime = Math.floor(Date.now() / 1000) + 24 * 60 * 60; // 24 hours from now + const endTime = startTime + 60 * 60; // 1 hour later + + // Create the request body + const requestBody: CreateEventRequest = { + title: 'Project Planning Meeting', + description: 'Initial project planning and resource allocation', + when: { + startTime, + endTime, + }, + metadata: { + project_id: 'PROJ-123', + priority: 'high', + }, + conferencing: { + provider: 'Google Meet', + autocreate: {}, + }, + notetaker: { + name: 'Nylas Notetaker', + meetingSettings: { + videoRecording: true, + audioRecording: true, + transcription: true, + }, + }, + }; + + console.log(`Request body: ${JSON.stringify(requestBody, null, 2)}`); + + // Create the event + const event = await nylas.events.create({ + identifier: grantId, + requestBody, + queryParams: { + calendarId, + }, + }); + + console.log(`Created event with ID: ${event.data.id}`); + if (event.data.notetaker) { + console.log(`Event Notetaker ID: ${event.data.notetaker.id}`); + } + + return event; + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`Error creating event: ${error.message}`); + console.error(`Error details: ${JSON.stringify(error, null, 2)}`); + } else if (error instanceof Error) { + console.error( + `Unexpected error in createEventWithNotetaker: ${error.message}` + ); + console.error(`Error type: ${error.constructor.name}`); + } + throw error; + } +} + +/** + * Retrieves the Notetaker associated with an event + * @param eventId The ID of the event to retrieve the Notetaker for + * @returns The Notetaker associated with the event, or null if none found + */ +async function getEventNotetaker( + eventId: string +): Promise | null> { + console.log('\n=== Retrieving Event Notetaker ==='); + + try { + // First, retrieve the event to get the Notetaker ID + const event = await nylas.events.find({ + identifier: grantId, + eventId, + queryParams: { + calendarId, + }, + }); + + if (!event.data.notetaker || !event.data.notetaker.id) { + console.log(`No Notetaker found for event ${eventId}`); + return null; + } + + // Get the Notetaker details + const notetaker = await nylas.notetakers.find({ + identifier: grantId, + notetakerId: event.data.notetaker.id, + }); + + console.log(`Found Notetaker for event ${eventId}:`); + console.log(`- ID: ${notetaker.data.id}`); + console.log(`- State: ${notetaker.data.state}`); + console.log(`- Meeting Provider: ${notetaker.data.meetingProvider}`); + console.log(`- Meeting Settings:`); + console.log( + ` - Video Recording: ${notetaker.data.meetingSettings.videoRecording}` + ); + console.log( + ` - Audio Recording: ${notetaker.data.meetingSettings.audioRecording}` + ); + console.log( + ` - Transcription: ${notetaker.data.meetingSettings.transcription}` + ); + + return notetaker; + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`Error retrieving event notetaker: ${error.message}`); + console.error(`Error details: ${JSON.stringify(error, null, 2)}`); + } else if (error instanceof Error) { + console.error(`Unexpected error in getEventNotetaker: ${error.message}`); + console.error(`Error type: ${error.constructor.name}`); + } + return null; + } +} + +/** + * Updates both an event and its Notetaker + * @param eventId The ID of the event to update + * @param notetakerId The ID of the Notetaker to update + * @returns The updated event + */ +async function updateEventAndNotetaker( + eventId: string, + notetakerId: string +): Promise> { + console.log('\n=== Updating Event and Notetaker ==='); + + try { + // Create the request body with updated event details and Notetaker settings + const requestBody: UpdateEventRequest = { + title: 'Updated Project Planning Meeting', + description: 'Revised project planning with new timeline', + metadata: { + project_id: 'PROJ-123', + priority: 'urgent', + }, + notetaker: { + id: notetakerId, + name: 'Updated Nylas Notetaker', + meetingSettings: { + videoRecording: false, + audioRecording: true, + transcription: false, + }, + }, + }; + + console.log(`Request body: ${JSON.stringify(requestBody, null, 2)}`); + + // Update the event + const updatedEvent = await nylas.events.update({ + identifier: grantId, + eventId, + requestBody, + queryParams: { + calendarId, + }, + }); + + console.log(`Updated event with ID: ${updatedEvent.data.id}`); + if (updatedEvent.data.notetaker) { + console.log( + `Updated Event Notetaker ID: ${updatedEvent.data.notetaker.id}` + ); + } + + return updatedEvent; + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`Error updating event: ${error.message}`); + console.error(`Error details: ${JSON.stringify(error, null, 2)}`); + } else if (error instanceof Error) { + console.error( + `Unexpected error in updateEventAndNotetaker: ${error.message}` + ); + console.error(`Error type: ${error.constructor.name}`); + } + throw error; + } +} + +/** + * Main function to run all demo examples + */ +async function main(): Promise { + try { + // Log API key (first few characters only) + console.log(`Using API key: ${apiKey.substring(0, 5)}...`); + console.log(`Using Grant ID: ${grantId.substring(0, 5)}...`); + console.log(`Using Calendar ID: ${calendarId.substring(0, 5)}...`); + + // Create an event with a Notetaker + const event = await createEventWithNotetaker(); + if (!event || !event.data.id) { + console.error('Failed to create event'); + return; + } + + // Get the Notetaker for the event + const notetaker = await getEventNotetaker(event.data.id); + if (!notetaker || !notetaker.data.id) { + console.error(`Failed to get Notetaker for event ${event.data.id}`); + return; + } + + // Update both the event and its Notetaker + const updatedEvent = await updateEventAndNotetaker( + event.data.id, + notetaker.data.id + ); + if (!updatedEvent) { + console.error(`Failed to update event ${event.data.id}`); + return; + } + + console.log( + '\n=== Calendar Event with Notetaker Demo Completed Successfully ===' + ); + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`\nNylas API Error: ${error.message}`); + console.error(`Error details: ${JSON.stringify(error, null, 2)}`); + process.exit(1); + } else if (error instanceof Error) { + console.error(`\nUnexpected Error: ${error.message}`); + console.error(`Error type: ${error.constructor.name}`); + process.exit(1); + } + } +} + +// Run the main function +if (require.main === module) { + main().catch(console.error); +} diff --git a/examples/cjs-only/README.md b/examples/cjs-only/README.md new file mode 100644 index 00000000..f247f73b --- /dev/null +++ b/examples/cjs-only/README.md @@ -0,0 +1,78 @@ +# CommonJS-Only Nylas SDK Example + +This example demonstrates how to use the Nylas Node.js SDK in a pure CommonJS (CJS) environment without ES module syntax. + +## Purpose + +- Shows CommonJS `require()` syntax with the Nylas SDK +- Demonstrates environment variable handling in CommonJS +- Provides a simple messages listing example +- Serves as a reference for projects that must use CommonJS + +## Key Differences from ESM + +This example showcases the CommonJS equivalent of the ESM-only example: + +| ESM Syntax | CommonJS Syntax | +|------------|-----------------| +| `import Nylas from 'nylas'` | `const Nylas = require('nylas')` | +| `import dotenv from 'dotenv'` | `const dotenv = require('dotenv')` | +| `import path from 'node:path'` | `const path = require('path')` | +| `import.meta.dirname` | `__dirname` | +| `export { logger }` | `module.exports = { logger }` | + +## Setup + +1. **Install dependencies:** + ```bash + cd examples/cjs-only + npm install + ``` + +2. **Set up environment variables:** + - Copy `examples/.env.example` to `examples/.env` + - Fill in your `NYLAS_API_KEY` and `NYLAS_GRANT_ID` + +3. **Run the example:** + ```bash + npm start + # or + node index.js + ``` + +## Requirements + +- Node.js (any version - CommonJS is supported in all Node.js versions) +- Valid Nylas API credentials +- A grant with message access permissions + +## What This Example Does + +1. Loads environment variables using `dotenv` +2. Validates required API credentials +3. Initializes the Nylas client +4. Lists messages from the specified grant +5. Logs the results with proper error handling + +## File Structure + +``` +cjs-only/ +β”œβ”€β”€ index.js # Main example file (CommonJS) +β”œβ”€β”€ package.json # Package configuration (no "type": "module") +β”œβ”€β”€ utils/ +β”‚ └── logger.js # Logger utility (CommonJS exports) +└── README.md # This file +``` + +## Troubleshooting + +- **"NYLAS_API_KEY environment variable is not set"**: Make sure you've created the `.env` file in the `examples/` directory with your API key +- **"NYLAS_GRANT_ID environment variable is not set"**: Add your grant ID to the `.env` file +- **Module not found errors**: Run `npm install` to install dependencies +- **Permission errors**: Ensure your API key and grant have the necessary permissions to list messages + +## Related Examples + +- `../esm-only/` - ESM version of this same example +- `../messages/` - More comprehensive message handling examples diff --git a/examples/cjs-only/index.js b/examples/cjs-only/index.js new file mode 100644 index 00000000..379f6acc --- /dev/null +++ b/examples/cjs-only/index.js @@ -0,0 +1,82 @@ +/** + * CommonJS-Only Nylas SDK Example + * + * This example demonstrates how to use the Nylas Node.js SDK in a pure CommonJS + * (CJS) environment without ES module syntax. + * + * Purpose: + * - Shows CommonJS require() syntax with the Nylas SDK + * - Demonstrates environment variable handling in CommonJS + * - Provides a simple messages listing example + * + * Usage: + * 1. Copy the parent examples/.env.example to examples/.env + * 2. Fill in your NYLAS_API_KEY and NYLAS_GRANT_ID in the .env file + * 3. Run: node index.js (or npm start) + * + * Requirements: + * - Node.js with CommonJS support (any Node.js version) + * - Valid Nylas API credentials + * - A grant with message access permissions + */ + +const dotenv = require('dotenv'); +const path = require('path'); +const Nylas = require('nylas'); +const { logger, maskSecret } = require('./utils/logger.js'); + +// Load from parent directory since this example lives in a subdirectory +dotenv.config({ path: path.resolve(__dirname, '../.env') }); + +// Fail fast if credentials are missing to provide clear error messages +const apiKey = process.env.NYLAS_API_KEY || ''; +if (!apiKey) { + throw new Error('NYLAS_API_KEY environment variable is not set'); +} + +const grantId = process.env.NYLAS_GRANT_ID || ''; +if (!grantId) { + throw new Error('NYLAS_GRANT_ID environment variable is not set'); +} + +// Initialize the Nylas client +const nylas = new Nylas({ + apiKey, + apiUri: process.env.NYLAS_API_URI || 'https://api.us.nylas.com', +}); + +/** + * Main function to demonstrate basic Nylas SDK usage in CommonJS environment + */ +async function main() { + try { + logger.info('Listing messages...'); + + // Log runtime config for debugging without exposing sensitive data + logger.debug('Runtime config', { + apiKey: maskSecret(apiKey), + grantId, + apiUri: process.env.NYLAS_API_URI || 'https://api.us.nylas.com', + }); + + // Use basic list operation to verify SDK functionality and connectivity + const messages = await nylas.messages.list({ + identifier: grantId, + }); + + logger.success('Messages listed successfully'); + + // Extract only essential fields to avoid logging sensitive message content + logger.info( + 'Message subjects and ids', + messages.data.map((m) => ({ id: m.id, subject: m.subject })) + ); + } catch (error) { + logger.error('Failed to list messages'); + logger.debug('Error details', error); + // Exit with error code to indicate failure for automation/CI purposes + process.exit(1); + } +} + +main(); diff --git a/examples/cjs-only/package-lock.json b/examples/cjs-only/package-lock.json new file mode 100644 index 00000000..354d551e --- /dev/null +++ b/examples/cjs-only/package-lock.json @@ -0,0 +1,70 @@ +{ + "name": "cjs-only", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "cjs-only", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "dotenv": "^17.2.2", + "nylas": "file:../../" + } + }, + "../..": { + "name": "nylas", + "version": "7.13.0", + "license": "MIT", + "dependencies": { + "change-case": "^4.1.2", + "form-data-encoder": "^4.1.0", + "formdata-node": "^6.0.3", + "mime-types": "^2.1.35", + "node-fetch": "^3.3.2", + "uuid": "^8.3.2" + }, + "devDependencies": { + "@babel/core": "^7.3.3", + "@types/jest": "^29.5.2", + "@types/mime-types": "^2.1.2", + "@types/node": "^22.15.21", + "@types/uuid": "^8.3.4", + "@typescript-eslint/eslint-plugin": "^2.25.0", + "@typescript-eslint/parser": "^2.25.0", + "eslint": "^5.14.0", + "eslint-config-prettier": "^4.0.0", + "eslint-plugin-custom-rules": "^0.0.0", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-prettier": "^3.0.1", + "jest": "^29.6.1", + "jest-fetch-mock": "^3.0.3", + "prettier": "^3.5.3", + "ts-jest": "^29.1.1", + "typedoc": "^0.28.4", + "typedoc-plugin-rename-defaults": "^0.7.3", + "typescript": "^5.8.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/dotenv": { + "version": "17.2.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.2.tgz", + "integrity": "sha512-Sf2LSQP+bOlhKWWyhFsn0UsfdK/kCWRv1iuA2gXAwt3dyNabr6QSj00I2V10pidqz69soatm9ZwZvpQMTIOd5Q==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/nylas": { + "resolved": "../..", + "link": true + } + } +} diff --git a/examples/cjs-only/package.json b/examples/cjs-only/package.json new file mode 100644 index 00000000..df5f68d0 --- /dev/null +++ b/examples/cjs-only/package.json @@ -0,0 +1,16 @@ +{ + "name": "cjs-only", + "version": "1.0.0", + "description": "A CommonJS-only example of the Nylas NodeJS SDK usage", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node index.js" + }, + "author": "", + "license": "ISC", + "dependencies": { + "nylas": "file:../../", + "dotenv": "^17.2.2" + } +} diff --git a/examples/cjs-only/utils/logger.js b/examples/cjs-only/utils/logger.js new file mode 100644 index 00000000..c19796d6 --- /dev/null +++ b/examples/cjs-only/utils/logger.js @@ -0,0 +1,46 @@ +// Pretty logger for CommonJS +const COLORS = { + reset: '\x1b[0m', + dim: '\x1b[2m', + gray: '\x1b[90m', + bold: '\x1b[1m', + info: '\x1b[36m', + success: '\x1b[32m', + warn: '\x1b[33m', + error: '\x1b[31m', + debug: '\x1b[35m', +}; + +function ts() { + return new Date().toISOString(); +} + +function maskSecret(value, visibleStart = 8, visibleEnd = 0) { + if (!value) return ''; + const start = value.slice(0, visibleStart); + const end = visibleEnd ? value.slice(-visibleEnd) : ''; + const hidden = Math.max(0, value.length - start.length - end.length); + return `${start}${'β€’'.repeat(hidden)}${end}`; +} + +function print(level, symbol, message, meta) { + const color = COLORS[level] || COLORS.info; + const time = `${COLORS.dim}${ts()}${COLORS.reset}`; + const label = `${color}${symbol} ${level.toUpperCase()}${COLORS.reset}`; + const line = + typeof message === 'string' ? message : JSON.stringify(message, null, 2); + console.log(`${time} ${label} ${line}`); + if (meta !== undefined) { + console.dir(meta, { depth: null, colors: true, maxArrayLength: 100 }); + } +} + +const logger = { + info: (msg, meta) => print('info', 'β„Ή', msg, meta), + success: (msg, meta) => print('success', 'βœ”', msg, meta), + warn: (msg, meta) => print('warn', '⚠', msg, meta), + error: (msg, meta) => print('error', 'βœ–', msg, meta), + debug: (msg, meta) => print('debug', 'πŸ›', msg, meta), +}; + +module.exports = { logger, maskSecret }; diff --git a/examples/cloudflare-vite-calendars/.dev.vars.example b/examples/cloudflare-vite-calendars/.dev.vars.example new file mode 100644 index 00000000..76abd7a0 --- /dev/null +++ b/examples/cloudflare-vite-calendars/.dev.vars.example @@ -0,0 +1,15 @@ +# Nylas API Configuration +# Copy this file to .dev.vars and fill in your actual values + +# Your Nylas API key (found in Nylas Dashboard > Applications) +NYLAS_API_KEY=your_api_key_here + +# Nylas API URI (use your region's API URL) +NYLAS_API_URI=https://api.us.nylas.com + +# Grant ID for the connected email account +NYLAS_GRANT_ID=your_grant_id_here + +# Calendar ID to manage events +NYLAS_CALENDAR_ID=your_calendar_id_here + diff --git a/examples/cloudflare-vite-calendars/.gitignore b/examples/cloudflare-vite-calendars/.gitignore new file mode 100644 index 00000000..859ffc0c --- /dev/null +++ b/examples/cloudflare-vite-calendars/.gitignore @@ -0,0 +1,26 @@ +# Dependencies +node_modules/ +.pnpm-debug.log + +# Environment variables +.dev.vars + +# Build output +dist/ +.wrangler/ + +# Editor +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# Logs +*.log +npm-debug.log* + diff --git a/examples/cloudflare-vite-calendars/FEATURES.md b/examples/cloudflare-vite-calendars/FEATURES.md new file mode 100644 index 00000000..2fe881c2 --- /dev/null +++ b/examples/cloudflare-vite-calendars/FEATURES.md @@ -0,0 +1,270 @@ +# Features Overview + +This example demonstrates a modern Cloudflare Workers application built with Vite that integrates the Nylas SDK for calendar management. + +## 🎯 Core Features + +### Calendar Event Management + +#### 1. List Calendar Events +- **Endpoint**: `GET /api/events` +- **Features**: + - Fetches up to 50 events from your connected calendar + - Returns complete event details including: + - Event ID and title + - Description + - Start and end times (Unix timestamps) + - Location + - Calendar ID + - Handles pagination for large event lists + - Error handling with detailed messages + +#### 2. Create Calendar Events +- **Endpoint**: `POST /api/events` +- **Features**: + - Creates new calendar events with full details + - Supports: + - Title (required) + - Description (optional) + - Start and end date/time + - Location (optional) + - Busy status (default: true) + - Automatic time conversion from ISO to Unix timestamps + - Returns complete event object upon creation + - Validates event data before creation + +### User Interface + +#### Modern Web Interface +- **Beautiful Design**: + - Gradient color scheme (purple/blue) + - Responsive layout that works on mobile and desktop + - Smooth animations and transitions + - Loading states with spinners + - Success/error messages with color coding + +- **Events List View**: + - Card-based layout for easy reading + - Shows all event details at a glance + - Formatted dates and times + - Empty state when no events exist + - Hover effects for better UX + +- **Create Event Form**: + - Clean, organized form layout + - Date/time pickers for easy input + - Default values (tomorrow at 10 AM) + - Two-column layout for dates + - Clear labels and placeholders + - Form validation + - Auto-refresh events list after creation + +## πŸ”§ Technical Features + +### Vite Integration +- **Fast Development**: + - Hot Module Replacement (HMR) + - Instant updates without page refresh + - Optimized build process + - Modern JavaScript/TypeScript support + +- **@cloudflare/vite-plugin**: + - Seamless Cloudflare Workers integration + - Automatic Workers configuration + - Local development server + - Built-in Node.js compatibility + +### Cloudflare Workers +- **Edge Computing**: + - Global deployment + - Low latency responses + - Automatic scaling + - High availability + +- **Node.js Compatibility**: + - `nodejs_compat` flag enabled + - Support for Node.js built-ins (crypto, buffer, stream) + - Full Nylas SDK compatibility + +### TypeScript Support +- **Type Safety**: + - Full TypeScript implementation + - Interface definitions for all data structures + - Type checking during development + - Better IDE support with autocomplete + +### Error Handling +- **Comprehensive Error Management**: + - Try-catch blocks for all API calls + - Specific error types (NylasApiError) + - User-friendly error messages + - Console logging for debugging + - HTTP status codes for different error types + +### CORS Support +- **Cross-Origin Requests**: + - CORS headers on all responses + - OPTIONS preflight handling + - Allows access from any origin (configurable) + - Supports standard HTTP methods + +## 🎨 UI/UX Features + +### Interactive Elements +1. **Load Events Button**: + - Refreshes event list on demand + - Shows loading state + - Disabled during loading + - Success message with event count + +2. **Create Event Form**: + - Real-time validation + - Loading state during submission + - Success confirmation with event ID + - Form reset after successful creation + - Auto-populated default dates + +3. **Status Messages**: + - Color-coded (success: green, error: red, loading: blue) + - Slide-in animation + - Clear, descriptive messages + - Automatically shown/hidden + +### Responsive Design +- **Mobile-First Approach**: + - Works on all screen sizes + - Touch-friendly buttons and inputs + - Readable fonts at all sizes + - Proper spacing and padding + +- **Desktop Optimizations**: + - Two-column date picker layout + - Hover effects on cards + - Optimal reading width (900px max) + - Smooth scrolling for long lists + +## πŸ” Security Features + +### Environment Variables +- **Secure Configuration**: + - API keys stored in environment variables + - `.dev.vars` for local development + - Wrangler secrets for production + - No hardcoded credentials + +### Validation +- **Input Validation**: + - Required field checking + - Date validation (start before end) + - File type and size validation + - Sanitized user input + +## πŸ“Š Data Handling + +### Time Management +- **Timezone Handling**: + - Browser local time for UI + - Unix timestamps for API + - Automatic conversion between formats + - Consistent date formatting + +### Response Format +- **Standardized API Responses**: + ```json + { + "success": true, + "events": [...], + "count": 10 + } + ``` + ```json + { + "success": true, + "event": {...}, + "message": "Event created successfully" + } + ``` + ```json + { + "success": false, + "error": "Error message" + } + ``` + +## πŸš€ Deployment Features + +### Development +- **npm run dev**: Local development with HMR +- **npm run build**: Production build +- **npm run preview**: Preview production build +- **npm run type-check**: TypeScript validation + +### Production +- **npm run deploy**: Build and deploy to Cloudflare +- **wrangler secret**: Manage production secrets +- **Custom domains**: Support for custom domain routing +- **Environment separation**: Development and production configs + +## πŸ“ˆ Extensibility + +The example is designed to be easily extended: + +1. **Add Event Operations**: + - Update events + - Delete events + - Search events + - Filter by date range + +2. **Add Event Features**: + - Participants/attendees + - Reminders + - Recurring events + - Conferencing (Zoom, Google Meet) + - Attachments + +3. **UI Enhancements**: + - Calendar view (month/week/day) + - Event editing modal + - Drag-and-drop rescheduling + - Event color coding + - Categories/tags + +4. **Advanced Features**: + - Multi-calendar support + - Event sharing + - Availability checking + - Time zone conversion + - Email notifications + +## πŸ“š Learning Value + +This example teaches: + +1. **Cloudflare Workers Development**: + - Setting up Vite with Cloudflare plugin + - Using Node.js APIs in Workers + - Environment variable management + - Deployment strategies + +2. **Nylas SDK Integration**: + - SDK initialization + - Calendar API usage + - Event creation and retrieval + - Error handling + +3. **Modern Web Development**: + - TypeScript best practices + - REST API design + - Frontend/backend integration + - Responsive design + +4. **Production Readiness**: + - Security considerations + - Error handling patterns + - Environment configuration + - Documentation practices + +--- + +This example provides a solid foundation for building production-ready calendar applications on Cloudflare Workers with the Nylas SDK. + diff --git a/examples/cloudflare-vite-calendars/QUICKSTART.md b/examples/cloudflare-vite-calendars/QUICKSTART.md new file mode 100644 index 00000000..35beb777 --- /dev/null +++ b/examples/cloudflare-vite-calendars/QUICKSTART.md @@ -0,0 +1,112 @@ +# Quick Start Guide + +Get up and running with the Nylas Calendar Manager on Cloudflare Workers + Vite in 5 minutes! + +## Prerequisites + +- Node.js 18+ installed +- A Nylas account with API key +- A connected calendar (Google, Microsoft, etc.) + +## Setup Steps + +### 1. Navigate to the example directory + +```bash +cd examples/cloudflare-vite-calendars +``` + +### 2. Install dependencies + +```bash +npm install +``` + +### 3. Configure environment variables + +```bash +# Copy the example file +cp .dev.vars.example .dev.vars + +# Edit .dev.vars with your credentials +# You'll need: +# - NYLAS_API_KEY: From Nylas Dashboard > Applications +# - NYLAS_GRANT_ID: From Nylas Dashboard > Grants +# - NYLAS_CALENDAR_ID: Get by calling GET /v3/grants/{grantId}/calendars +``` + +**Getting your Calendar ID:** + +```bash +# Replace with your actual values +curl -X GET "https://api.us.nylas.com/v3/grants/YOUR_GRANT_ID/calendars" \ + -H "Authorization: Bearer YOUR_API_KEY" +``` + +### 4. Start the development server + +```bash +npm run dev +``` + +The server will start on `http://localhost:5173` (or another port if 5173 is in use). + +### 5. Use the app + +1. Open `http://localhost:5173` in your browser +2. Click "Load Events" to see your calendar events +3. Fill out the form to create a new event +4. Watch as the calendar updates in real-time! + +## What You Can Do + +- βœ… **List Events**: View all your calendar events with details +- βœ… **Create Events**: Add new events with title, description, time, and location +- βœ… **Real-time Updates**: See changes immediately after creating events +- βœ… **Beautiful UI**: Modern, responsive interface + +## Next Steps + +### Deploy to Production + +```bash +# Set production secrets +wrangler secret put NYLAS_API_KEY +wrangler secret put NYLAS_GRANT_ID +wrangler secret put NYLAS_CALENDAR_ID + +# Deploy +npm run deploy +``` + +### Customize the Example + +Check out the [full README](./README.md) for: +- Customizing the UI +- Adding more event fields (participants, conferencing, reminders) +- Filtering events by date range +- Implementing event updates and deletion + +## Troubleshooting + +**Port already in use?** +- Vite will automatically try the next available port + +**Can't see events?** +- Verify your `NYLAS_CALENDAR_ID` is correct +- Check that your grant has calendar permissions + +**Can't create events?** +- Ensure start time is before end time +- Verify your grant has write permissions + +## Learn More + +- [Full README](./README.md) - Complete documentation +- [Nylas Calendar API](https://developer.nylas.com/docs/api/v3/calendars/) - API reference +- [Cloudflare Vite Plugin](https://developers.cloudflare.com/workers/vite-plugin/) - Vite integration docs + +--- + +**Need help?** Check the [Nylas Developer Forum](https://forums.nylas.com/) or open an issue on [GitHub](https://github.com/nylas/nylas-nodejs). + diff --git a/examples/cloudflare-vite-calendars/README.md b/examples/cloudflare-vite-calendars/README.md new file mode 100644 index 00000000..b60e4d89 --- /dev/null +++ b/examples/cloudflare-vite-calendars/README.md @@ -0,0 +1,378 @@ +# Nylas Calendar Manager - Cloudflare Workers + Vite Example + +This example demonstrates how to use the Nylas SDK with Cloudflare Workers and Vite to manage calendar events. It showcases a modern development workflow using the `@cloudflare/vite-plugin` for building and deploying Cloudflare Workers. + +## πŸš€ Features + +- **List Calendar Events**: View all upcoming events from your connected calendar +- **Create Events**: Add new events with title, description, time, and location +- **Beautiful UI**: Modern, responsive web interface with real-time feedback +- **Vite Integration**: Fast development with Hot Module Replacement (HMR) +- **Edge Computing**: Runs on Cloudflare's global edge network +- **Node.js Compatibility**: Uses `nodejs_compat` flag for seamless Nylas SDK integration + +## πŸ“‹ Prerequisites + +Before getting started, you'll need: + +1. **Nylas Account**: [Sign up for free](https://dashboard.nylas.com/register) +2. **Cloudflare Account**: [Sign up for free](https://dash.cloudflare.com/sign-up) +3. **Node.js**: Version 18 or higher +4. **Nylas Application**: Created in your Nylas Dashboard with at least one connected calendar +5. **Calendar Access**: At least one email account connected with calendar permissions + +## πŸ› οΈ Setup + +### 1. Install Dependencies + +```bash +# Navigate to the cloudflare-vite-calendars directory +cd examples/cloudflare-vite-calendars + +# Install dependencies +npm install +``` + +### 2. Configure Environment Variables + +Create a `.dev.vars` file from the example template: + +```bash +cp .dev.vars.example .dev.vars +``` + +Update `.dev.vars` with your Nylas credentials: + +```bash +NYLAS_API_KEY=your_nylas_api_key_here +NYLAS_API_URI=https://api.us.nylas.com +NYLAS_GRANT_ID=your_grant_id_here +NYLAS_CALENDAR_ID=your_calendar_id_here +``` + +**How to get these values:** + +- **NYLAS_API_KEY**: Found in your [Nylas Dashboard](https://dashboard.nylas.com/applications) under your application settings +- **NYLAS_GRANT_ID**: The ID of a connected email account (Dashboard > Grants) +- **NYLAS_CALENDAR_ID**: The ID of a calendar from the connected account. You can get this by: + - Using the [Nylas API](https://developer.nylas.com/docs/api/v3/calendars/#get-/v3/grants/-grant_id-/calendars) to list calendars + - Or run: `curl -X GET "https://api.us.nylas.com/v3/grants/{GRANT_ID}/calendars" -H "Authorization: Bearer {API_KEY}"` +- **NYLAS_API_URI**: Use `https://api.us.nylas.com` for US region, or your specific region's API URL + +### 3. Update Wrangler Configuration (Optional) + +Edit `wrangler.toml` to customize your worker name: + +```toml +name = "your-worker-name" # Choose a unique name for your worker +``` + +## πŸ—οΈ Development + +### Start Local Development Server + +```bash +npm run dev +``` + +This will: +- Start the Vite development server with Cloudflare Workers support +- Make your worker available at `http://localhost:5173` (or another port if 5173 is in use) +- Enable Hot Module Replacement for instant updates +- Load environment variables from `.dev.vars` + +### Test the Application + +1. Open `http://localhost:5173` in your browser +2. **Load Events**: Click "Load Events" to see your existing calendar events +3. **Create Event**: Fill in the form to create a new event: + - **Event Title**: Required (e.g., "Team Standup") + - **Description**: Optional details about the event + - **Start Date/Time**: When the event starts + - **End Date/Time**: When the event ends + - **Location**: Optional location information +4. Click "Create Event" to add it to your calendar +5. The events list will automatically refresh to show your new event + +### Development Tips + +- **Hot Reload**: Code changes automatically reload the worker +- **Error Handling**: Check the browser console and terminal for debugging +- **API Limits**: Be mindful of Nylas API rate limits during development +- **Time Zones**: Dates are handled in the local browser timezone + +## πŸš€ Deployment + +### Option 1: Deploy to Cloudflare Workers (Recommended) + +#### 1. Set Production Secrets + +For security, use Wrangler secrets instead of environment variables in production: + +```bash +# Set your API key as a secret +wrangler secret put NYLAS_API_KEY +# Enter your API key when prompted + +# Set your Grant ID as a secret +wrangler secret put NYLAS_GRANT_ID +# Enter your Grant ID when prompted + +# Set your Calendar ID as a secret +wrangler secret put NYLAS_CALENDAR_ID +# Enter your Calendar ID when prompted +``` + +#### 2. Deploy to Production + +```bash +npm run deploy +``` + +This will: +- Build your worker using Vite +- Upload it to Cloudflare +- Make it available at `https://your-worker-name.your-subdomain.workers.dev` + +#### 3. Test Production Deployment + +Visit your worker's URL and test the calendar functionality. + +### Option 2: Deploy with Custom Domain + +If you have a custom domain managed by Cloudflare: + +1. **Add a route in `wrangler.toml`:** +```toml +[[routes]] +pattern = "calendar.yourdomain.com/*" +zone_name = "yourdomain.com" +``` + +2. **Deploy with the route:** +```bash +npm run deploy +``` + +## πŸ“š How It Works + +### Architecture + +``` +User Browser β†’ Cloudflare Worker (Vite) β†’ Nylas API β†’ Calendar Provider +``` + +1. **Web Interface**: User interacts with the modern HTML/CSS/JS interface +2. **API Endpoints**: Worker provides REST endpoints for calendar operations +3. **Nylas SDK**: Handles authentication and communication with Nylas API +4. **Calendar Sync**: Nylas syncs with your calendar provider (Google, Microsoft, etc.) + +### Key Files + +- **`src/worker.ts`**: Main worker logic with request handling and Nylas SDK integration +- **`vite.config.ts`**: Vite configuration with Cloudflare plugin +- **`wrangler.toml`**: Cloudflare Worker configuration with Node.js compatibility +- **`package.json`**: Dependencies and scripts +- **`.dev.vars`**: Development environment variables + +### API Endpoints + +- **`GET /`**: Serves the HTML interface +- **`GET /api/events`**: Lists calendar events +- **`POST /api/events`**: Creates a new calendar event +- **`OPTIONS /*`**: Handles CORS preflight requests + +### Technical Implementation + +This worker uses: + +- **Vite**: Modern build tool with fast HMR and optimized builds +- **@cloudflare/vite-plugin**: Official Cloudflare plugin for Vite +- **Nylas SDK**: Official Node.js SDK for Nylas API +- **Node.js Compatibility**: Uses `compatibility_date = "2024-09-23"` and `nodejs_compat` flag + +The Cloudflare Workers runtime provides Node.js built-in modules like `crypto`, `buffer`, and `stream` that are required by the Nylas SDK. + +### Event Data Format + +Events are stored with Unix timestamps: + +```typescript +{ + title: "Team Meeting", + description: "Discuss Q1 goals", + when: { + startTime: 1704110400, // Unix timestamp + endTime: 1704114000 + }, + location: "Conference Room A" +} +``` + +## πŸ”§ Customization + +### Modify Event Limits + +Update the event limit in `src/worker.ts`: + +```typescript +const events = await nylas.events.list({ + identifier: env.NYLAS_GRANT_ID, + queryParams: { + calendarId: env.NYLAS_CALENDAR_ID, + limit: 100, // Change this value + }, +}); +``` + +### Add Event Filtering + +Add date range filtering: + +```typescript +const events = await nylas.events.list({ + identifier: env.NYLAS_GRANT_ID, + queryParams: { + calendarId: env.NYLAS_CALENDAR_ID, + startsAfter: Math.floor(Date.now() / 1000), // Only future events + endsBefore: Math.floor(Date.now() / 1000) + (30 * 24 * 60 * 60), // Next 30 days + }, +}); +``` + +### Customize the UI + +Modify the `HTML_INTERFACE` constant in `src/worker.ts` to change the appearance: + +```typescript +const HTML_INTERFACE = ` + + + + +`; +``` + +### Add More Event Fields + +Extend the event creation to include additional fields like participants, reminders, or conferencing: + +```typescript +const requestBody: CreateEventRequest = { + title: eventData.title, + description: eventData.description, + when: { startTime, endTime }, + location: eventData.location, + participants: [ + { email: 'team@example.com', name: 'Team' } + ], + conferencing: { + provider: 'Google Meet', + autocreate: {} + }, + reminders: { + useDefault: false, + overrides: [ + { reminderMinutes: 15, reminderMethod: 'email' } + ] + } +}; +``` + +## πŸ› Troubleshooting + +### Common Issues + +**Error: "Missing required environment variables"** +- Ensure all environment variables are set in `.dev.vars` (development) or as secrets (production) +- Verify variable names match exactly as shown in `.dev.vars.example` +- For production, use `wrangler secret put` commands + +**Error: "Could not resolve [module]"** +- Ensure `compatibility_date = "2024-09-23"` or later is set in `wrangler.toml` +- Ensure `compatibility_flags = ["nodejs_compat"]` is set +- These settings enable Node.js built-in modules required by the Nylas SDK + +**Error: "Failed to list events"** +- Verify your `NYLAS_GRANT_ID` has access to the calendar +- Check that `NYLAS_CALENDAR_ID` is correct and accessible +- Ensure your Nylas grant has calendar read permissions + +**Error: "Failed to create event"** +- Verify start time is before end time +- Check that your Nylas grant has calendar write permissions +- Ensure the calendar exists and is writable + +**Events not showing up** +- Wait a few seconds for calendar sync +- Check Nylas Dashboard for any API errors +- Verify the calendar provider's status + +**Port already in use** +- Vite will automatically try the next available port +- You can specify a port: `vite dev --port 3000` + +### Debug Mode + +Add logging to the worker for debugging: + +```typescript +console.log('Event data:', eventData); +console.log('Nylas response:', response); +``` + +View logs with: +```bash +wrangler tail +``` + +Or in development, check your browser console and terminal output. + +## 🎯 What's Different from Regular Wrangler? + +This example uses **Vite** with the Cloudflare plugin, which provides several advantages: + +1. **Faster Development**: Hot Module Replacement (HMR) for instant updates +2. **Modern Tooling**: Leverage Vite's ecosystem and plugins +3. **Better DX**: Improved error messages and debugging +4. **Code Splitting**: Automatic optimization for production builds +5. **TypeScript**: First-class TypeScript support out of the box + +Traditional Wrangler workflow: +```bash +wrangler dev # Start development +wrangler deploy # Deploy +``` + +With Vite: +```bash +npm run dev # Vite dev server with Workers support +npm run deploy # Vite build + Wrangler deploy +``` + +## πŸ“– Related Resources + +- **Nylas Calendar API Documentation**: [https://developer.nylas.com/docs/api/v3/calendars/](https://developer.nylas.com/docs/api/v3/calendars/) +- **Nylas Events API**: [https://developer.nylas.com/docs/api/v3/events/](https://developer.nylas.com/docs/api/v3/events/) +- **Cloudflare Vite Plugin**: [https://developers.cloudflare.com/workers/vite-plugin/](https://developers.cloudflare.com/workers/vite-plugin/) +- **Cloudflare Workers Docs**: [https://developers.cloudflare.com/workers/](https://developers.cloudflare.com/workers/) +- **Vite Documentation**: [https://vitejs.dev/](https://vitejs.dev/) + +## πŸ“š Related Examples + +- **Edge Environment Example**: See `../edge-environment/` for a standard Wrangler example with email attachments +- **Calendar Examples**: See `../calendars/` for Node.js calendar examples +- **Nylas SDK Examples**: Browse other examples in the `examples/` directory + +## 🀝 Contributing + +Found an issue or want to improve this example? Please: + +1. Check existing issues in the [Nylas Node.js SDK repository](https://github.com/nylas/nylas-nodejs) +2. Create a new issue or pull request +3. Follow the contributing guidelines in the repository + +## πŸ“„ License + +This example is part of the Nylas Node.js SDK and is licensed under the MIT License. + diff --git a/examples/cloudflare-vite-calendars/package-lock.json b/examples/cloudflare-vite-calendars/package-lock.json new file mode 100644 index 00000000..b6feded9 --- /dev/null +++ b/examples/cloudflare-vite-calendars/package-lock.json @@ -0,0 +1,3386 @@ +{ + "name": "cloudflare-vite-calendars", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "cloudflare-vite-calendars", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "nylas": "file:../../" + }, + "devDependencies": { + "@cloudflare/vite-plugin": "^1.13.0", + "@cloudflare/workers-types": "^4.20231218.0", + "typescript": "^5.3.0", + "vite": "^6.4.1", + "wrangler": "^4.53.0" + } + }, + "../..": { + "name": "nylas", + "version": "7.13.3", + "license": "MIT", + "dependencies": { + "change-case": "^4.1.2", + "form-data-encoder": "^4.1.0", + "formdata-node": "^6.0.3", + "mime-types": "^2.1.35", + "uuid": "^8.3.2" + }, + "devDependencies": { + "@babel/core": "^7.3.3", + "@types/jest": "^29.5.2", + "@types/mime-types": "^2.1.2", + "@types/node": "^22.15.21", + "@types/uuid": "^8.3.4", + "@typescript-eslint/eslint-plugin": "^2.25.0", + "@typescript-eslint/parser": "^2.25.0", + "eslint": "^5.14.0", + "eslint-config-prettier": "^4.0.0", + "eslint-plugin-custom-rules": "^0.0.0", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-prettier": "^3.0.1", + "jest": "^29.6.1", + "jest-fetch-mock": "^3.0.3", + "prettier": "^3.5.3", + "ts-jest": "^29.1.1", + "typedoc": "^0.28.4", + "typedoc-plugin-rename-defaults": "^0.7.3", + "typescript": "^5.8.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/kv-asset-handler": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.1.tgz", + "integrity": "sha512-Nu8ahitGFFJztxUml9oD/DLb7Z28C8cd8F46IVQ7y5Btz575pvMY8AqZsXkX7Gds29eCKdMgIHjIvzskHgPSFg==", + "dev": true, + "license": "MIT OR Apache-2.0", + "dependencies": { + "mime": "^3.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@cloudflare/unenv-preset": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.7.6.tgz", + "integrity": "sha512-ykG2nd3trk6jbknRCH69xL3RpGLLbKCrbTbWSOvKEq7s4jH06yLrQlRr/q9IU+dK9p1JY1EXqhFK7VG5KqhzmQ==", + "dev": true, + "license": "MIT OR Apache-2.0", + "peerDependencies": { + "unenv": "2.0.0-rc.21", + "workerd": "^1.20250927.0" + }, + "peerDependenciesMeta": { + "workerd": { + "optional": true + } + } + }, + "node_modules/@cloudflare/vite-plugin": { + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@cloudflare/vite-plugin/-/vite-plugin-1.13.10.tgz", + "integrity": "sha512-zQaCbzGDAMhjZqXfulpUgBL/D4qsoP1oHVk2LyseKJ47PMq2cHWnbISOi3RONvKxpGyct7ACjA4JEhbFlu5GNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cloudflare/unenv-preset": "2.7.6", + "@remix-run/node-fetch-server": "^0.8.0", + "get-port": "^7.1.0", + "miniflare": "4.20251001.0", + "picocolors": "^1.1.1", + "tinyglobby": "^0.2.12", + "unenv": "2.0.0-rc.21", + "wrangler": "4.42.0", + "ws": "8.18.0" + }, + "peerDependencies": { + "vite": "^6.1.0 || ^7.0.0", + "wrangler": "^4.42.0" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@cloudflare/kv-asset-handler": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.0.tgz", + "integrity": "sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==", + "dev": true, + "license": "MIT OR Apache-2.0", + "dependencies": { + "mime": "^3.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", + "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/android-arm": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", + "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/android-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", + "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/android-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", + "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", + "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/darwin-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", + "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", + "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", + "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/linux-arm": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", + "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/linux-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", + "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/linux-ia32": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", + "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/linux-loong64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", + "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", + "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", + "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", + "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/linux-s390x": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", + "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/linux-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", + "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", + "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", + "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", + "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", + "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/sunos-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", + "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/win32-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", + "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/win32-ia32": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", + "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/@esbuild/win32-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", + "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/esbuild": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", + "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.4", + "@esbuild/android-arm": "0.25.4", + "@esbuild/android-arm64": "0.25.4", + "@esbuild/android-x64": "0.25.4", + "@esbuild/darwin-arm64": "0.25.4", + "@esbuild/darwin-x64": "0.25.4", + "@esbuild/freebsd-arm64": "0.25.4", + "@esbuild/freebsd-x64": "0.25.4", + "@esbuild/linux-arm": "0.25.4", + "@esbuild/linux-arm64": "0.25.4", + "@esbuild/linux-ia32": "0.25.4", + "@esbuild/linux-loong64": "0.25.4", + "@esbuild/linux-mips64el": "0.25.4", + "@esbuild/linux-ppc64": "0.25.4", + "@esbuild/linux-riscv64": "0.25.4", + "@esbuild/linux-s390x": "0.25.4", + "@esbuild/linux-x64": "0.25.4", + "@esbuild/netbsd-arm64": "0.25.4", + "@esbuild/netbsd-x64": "0.25.4", + "@esbuild/openbsd-arm64": "0.25.4", + "@esbuild/openbsd-x64": "0.25.4", + "@esbuild/sunos-x64": "0.25.4", + "@esbuild/win32-arm64": "0.25.4", + "@esbuild/win32-ia32": "0.25.4", + "@esbuild/win32-x64": "0.25.4" + } + }, + "node_modules/@cloudflare/vite-plugin/node_modules/wrangler": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.42.0.tgz", + "integrity": "sha512-OZXiUSfGD66OVkncDbjZtqrsH6bWPRQMYc6RmMbkzYm/lEvJ8lvARKcqDgEyq8zDAgJAivlMQLyPtKQoVjQ/4g==", + "dev": true, + "license": "MIT OR Apache-2.0", + "dependencies": { + "@cloudflare/kv-asset-handler": "0.4.0", + "@cloudflare/unenv-preset": "2.7.6", + "blake3-wasm": "2.1.5", + "esbuild": "0.25.4", + "miniflare": "4.20251001.0", + "path-to-regexp": "6.3.0", + "unenv": "2.0.0-rc.21", + "workerd": "1.20251001.0" + }, + "bin": { + "wrangler": "bin/wrangler.js", + "wrangler2": "bin/wrangler.js" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@cloudflare/workers-types": "^4.20251001.0" + }, + "peerDependenciesMeta": { + "@cloudflare/workers-types": { + "optional": true + } + } + }, + "node_modules/@cloudflare/workerd-darwin-64": { + "version": "1.20251001.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20251001.0.tgz", + "integrity": "sha512-y1ST/cCscaRewWRnsHZdWbgiLJbki5UMGd0hMo/FLqjlztwPeDgQ5CGm5jMiCDdw/IBCpWxEukftPYR34rWNog==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-darwin-arm64": { + "version": "1.20251001.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20251001.0.tgz", + "integrity": "sha512-+z4QHHZ/Yix82zLFYS+ZS2UV09IENFPwDCEKUWfnrM9Km2jOOW3Ua4hJNob1EgQUYs8fFZo7k5O/tpwxMsSbbQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-linux-64": { + "version": "1.20251001.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20251001.0.tgz", + "integrity": "sha512-hGS+O2V9Mm2XjJUaB9ZHMA5asDUaDjKko42e+accbew0PQR7zrAl1afdII6hMqCLV4tk4GAjvhv281pN4g48rg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-linux-arm64": { + "version": "1.20251001.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20251001.0.tgz", + "integrity": "sha512-QYaMK+pRgt28N7CX1JlJ+ToegJF9LxzqdT7MjWqPgVj9D2WTyIhBVYl3wYjJRcgOlnn+DRt42+li4T64CPEeuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-windows-64": { + "version": "1.20251001.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20251001.0.tgz", + "integrity": "sha512-ospnDR/FlyRvrv9DSHuxDAXmzEBLDUiAHQrQHda1iUH9HqxnNQ8giz9VlPfq7NIRc7bQ1ZdIYPGLJOY4Q366Ng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workers-types": { + "version": "4.20251209.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20251209.0.tgz", + "integrity": "sha512-O+cbUVwgb4NgUB39R1cITbRshlAAPy1UQV0l8xEy2xcZ3wTh3fMl9f5oBwLsVmE9JRhIZx6llCLOBVf53eI5xA==", + "dev": true, + "license": "MIT OR Apache-2.0", + "peer": true + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "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/@esbuild/aix-ppc64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", + "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", + "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", + "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", + "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", + "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", + "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", + "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", + "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", + "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", + "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", + "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", + "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", + "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", + "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", + "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", + "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", + "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", + "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", + "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", + "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", + "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", + "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", + "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", + "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", + "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", + "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@poppinss/colors": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.5.tgz", + "integrity": "sha512-FvdDqtcRCtz6hThExcFOgW0cWX+xwSMWcRuQe5ZEb2m7cVQOAVZOIMt+/v9RxGiD9/OY16qJBXK4CVKWAPalBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^4.1.5" + } + }, + "node_modules/@poppinss/dumper": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.4.tgz", + "integrity": "sha512-iG0TIdqv8xJ3Lt9O8DrPRxw1MRLjNpoqiSGU03P/wNLP/s0ra0udPJ1J2Tx5M0J3H/cVyEgpbn8xUKRY9j59kQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@sindresorhus/is": "^7.0.2", + "supports-color": "^10.0.0" + } + }, + "node_modules/@poppinss/exception": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.2.tgz", + "integrity": "sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@remix-run/node-fetch-server": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@remix-run/node-fetch-server/-/node-fetch-server-0.8.1.tgz", + "integrity": "sha512-J1dev372wtJqmqn9U/qbpbZxbJSQrogNN2+Qv1lKlpATpe/WQ9aCZfl/xSb9d2Rgh1IyLSvNxZAXPZxruO6Xig==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz", + "integrity": "sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.4.tgz", + "integrity": "sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.4.tgz", + "integrity": "sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.4.tgz", + "integrity": "sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.4.tgz", + "integrity": "sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.4.tgz", + "integrity": "sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.4.tgz", + "integrity": "sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.4.tgz", + "integrity": "sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.4.tgz", + "integrity": "sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.4.tgz", + "integrity": "sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.4.tgz", + "integrity": "sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.4.tgz", + "integrity": "sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.4.tgz", + "integrity": "sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.4.tgz", + "integrity": "sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.4.tgz", + "integrity": "sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.4.tgz", + "integrity": "sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.4.tgz", + "integrity": "sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.4.tgz", + "integrity": "sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.4.tgz", + "integrity": "sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.4.tgz", + "integrity": "sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.4.tgz", + "integrity": "sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.4.tgz", + "integrity": "sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sindresorhus/is": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.1.0.tgz", + "integrity": "sha512-7F/yz2IphV39hiS2zB4QYVkivrptHHh0K8qJJd9HhuWSdvf8AN7NpebW3CcDZDBQsUPMoDKWsY2WWgW7bqOcfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@speed-highlight/core": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.7.tgz", + "integrity": "sha512-0dxmVj4gxg3Jg879kvFS/msl4s9F3T9UXC1InxgOf7t5NvcPD97u/WTA5vL/IxWHMn7qSxBozqrnnE2wvl1m8g==", + "dev": true, + "license": "CC0-1.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/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/blake3-wasm": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz", + "integrity": "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==", + "dev": true, + "license": "MIT" + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "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/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/error-stack-parser-es": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", + "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/esbuild": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", + "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.10", + "@esbuild/android-arm": "0.25.10", + "@esbuild/android-arm64": "0.25.10", + "@esbuild/android-x64": "0.25.10", + "@esbuild/darwin-arm64": "0.25.10", + "@esbuild/darwin-x64": "0.25.10", + "@esbuild/freebsd-arm64": "0.25.10", + "@esbuild/freebsd-x64": "0.25.10", + "@esbuild/linux-arm": "0.25.10", + "@esbuild/linux-arm64": "0.25.10", + "@esbuild/linux-ia32": "0.25.10", + "@esbuild/linux-loong64": "0.25.10", + "@esbuild/linux-mips64el": "0.25.10", + "@esbuild/linux-ppc64": "0.25.10", + "@esbuild/linux-riscv64": "0.25.10", + "@esbuild/linux-s390x": "0.25.10", + "@esbuild/linux-x64": "0.25.10", + "@esbuild/netbsd-arm64": "0.25.10", + "@esbuild/netbsd-x64": "0.25.10", + "@esbuild/openbsd-arm64": "0.25.10", + "@esbuild/openbsd-x64": "0.25.10", + "@esbuild/openharmony-arm64": "0.25.10", + "@esbuild/sunos-x64": "0.25.10", + "@esbuild/win32-arm64": "0.25.10", + "@esbuild/win32-ia32": "0.25.10", + "@esbuild/win32-x64": "0.25.10" + } + }, + "node_modules/exit-hook": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-2.2.1.tgz", + "integrity": "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "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/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/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-port": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz", + "integrity": "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/miniflare": { + "version": "4.20251001.0", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20251001.0.tgz", + "integrity": "sha512-OHd31D2LT8JH+85nVXClV0Z18jxirCohzKNAcZs/fgt4mIkUDtidX3VqR3ovAM0jWooNxrFhB9NSs3iDbiJF7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "0.8.1", + "acorn": "8.14.0", + "acorn-walk": "8.3.2", + "exit-hook": "2.2.1", + "glob-to-regexp": "0.4.1", + "sharp": "^0.33.5", + "stoppable": "1.1.0", + "undici": "7.14.0", + "workerd": "1.20251001.0", + "ws": "8.18.0", + "youch": "4.1.0-beta.10", + "zod": "3.22.3" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/nylas": { + "resolved": "../..", + "link": true + }, + "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/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "dev": true, + "license": "MIT" + }, + "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/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/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz", + "integrity": "sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.4", + "@rollup/rollup-android-arm64": "4.52.4", + "@rollup/rollup-darwin-arm64": "4.52.4", + "@rollup/rollup-darwin-x64": "4.52.4", + "@rollup/rollup-freebsd-arm64": "4.52.4", + "@rollup/rollup-freebsd-x64": "4.52.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.4", + "@rollup/rollup-linux-arm-musleabihf": "4.52.4", + "@rollup/rollup-linux-arm64-gnu": "4.52.4", + "@rollup/rollup-linux-arm64-musl": "4.52.4", + "@rollup/rollup-linux-loong64-gnu": "4.52.4", + "@rollup/rollup-linux-ppc64-gnu": "4.52.4", + "@rollup/rollup-linux-riscv64-gnu": "4.52.4", + "@rollup/rollup-linux-riscv64-musl": "4.52.4", + "@rollup/rollup-linux-s390x-gnu": "4.52.4", + "@rollup/rollup-linux-x64-gnu": "4.52.4", + "@rollup/rollup-linux-x64-musl": "4.52.4", + "@rollup/rollup-openharmony-arm64": "4.52.4", + "@rollup/rollup-win32-arm64-msvc": "4.52.4", + "@rollup/rollup-win32-ia32-msvc": "4.52.4", + "@rollup/rollup-win32-x64-gnu": "4.52.4", + "@rollup/rollup-win32-x64-msvc": "4.52.4", + "fsevents": "~2.3.2" + } + }, + "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/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", + "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4", + "npm": ">=6" + } + }, + "node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "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/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/undici": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.14.0.tgz", + "integrity": "sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/unenv": { + "version": "2.0.0-rc.21", + "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.21.tgz", + "integrity": "sha512-Wj7/AMtE9MRnAXa6Su3Lk0LNCfqDYgfwVjwRFVum9U7wsto1imuHqk4kTm7Jni+5A0Hn7dttL6O/zjvUvoo+8A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "defu": "^6.1.4", + "exsolve": "^1.0.7", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "ufo": "^1.6.1" + } + }, + "node_modules/vite": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/workerd": { + "version": "1.20251001.0", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20251001.0.tgz", + "integrity": "sha512-oT/K4YWNhmwpVmGeaHNmF7mLRfgjszlVr7lJtpS4jx5khmxmMzWZEEQRrJEpgzeHP6DOq9qWLPNT0bjMK7TchQ==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "workerd": "bin/workerd" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "@cloudflare/workerd-darwin-64": "1.20251001.0", + "@cloudflare/workerd-darwin-arm64": "1.20251001.0", + "@cloudflare/workerd-linux-64": "1.20251001.0", + "@cloudflare/workerd-linux-arm64": "1.20251001.0", + "@cloudflare/workerd-windows-64": "1.20251001.0" + } + }, + "node_modules/wrangler": { + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.53.0.tgz", + "integrity": "sha512-/wvnHlRnlHsqaeIgGbmcEJE5NFYdTUWHCKow+U5Tv2XwQXI9vXUqBwCLAGy/BwqyS5nnycRt2kppqCzgHgyb7Q==", + "dev": true, + "license": "MIT OR Apache-2.0", + "dependencies": { + "@cloudflare/kv-asset-handler": "0.4.1", + "@cloudflare/unenv-preset": "2.7.13", + "blake3-wasm": "2.1.5", + "esbuild": "0.27.0", + "miniflare": "4.20251202.1", + "path-to-regexp": "6.3.0", + "unenv": "2.0.0-rc.24", + "workerd": "1.20251202.0" + }, + "bin": { + "wrangler": "bin/wrangler.js", + "wrangler2": "bin/wrangler.js" + }, + "engines": { + "node": ">=20.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@cloudflare/workers-types": "^4.20251202.0" + }, + "peerDependenciesMeta": { + "@cloudflare/workers-types": { + "optional": true + } + } + }, + "node_modules/wrangler/node_modules/@cloudflare/unenv-preset": { + "version": "2.7.13", + "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.7.13.tgz", + "integrity": "sha512-NulO1H8R/DzsJguLC0ndMuk4Ufv0KSlN+E54ay9rn9ZCQo0kpAPwwh3LhgpZ96a3Dr6L9LqW57M4CqC34iLOvw==", + "dev": true, + "license": "MIT OR Apache-2.0", + "peerDependencies": { + "unenv": "2.0.0-rc.24", + "workerd": "^1.20251202.0" + }, + "peerDependenciesMeta": { + "workerd": { + "optional": true + } + } + }, + "node_modules/wrangler/node_modules/@cloudflare/workerd-darwin-64": { + "version": "1.20251202.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20251202.0.tgz", + "integrity": "sha512-/uvEAWEukTWb1geHhbjGUeZqcSSSyYzp0mvoPUBl+l0ont4NVGao3fgwM0q8wtKvgoKCHSG6zcG23wj9Opj3Nw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/wrangler/node_modules/@cloudflare/workerd-darwin-arm64": { + "version": "1.20251202.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20251202.0.tgz", + "integrity": "sha512-f52xRvcI9cWRd6400EZStRtXiRC5XKEud7K5aFIbbUv0VeINltujFQQ9nHWtsF6g1quIXWkjhh5u01gPAYNNXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/wrangler/node_modules/@cloudflare/workerd-linux-64": { + "version": "1.20251202.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20251202.0.tgz", + "integrity": "sha512-HYXinF5RBH7oXbsFUMmwKCj+WltpYbf5mRKUBG5v3EuPhUjSIFB84U+58pDyfBJjcynHdy3EtvTWcvh/+lcgow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/wrangler/node_modules/@cloudflare/workerd-linux-arm64": { + "version": "1.20251202.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20251202.0.tgz", + "integrity": "sha512-++L02Jdoxz7hEA9qDaQjbVU1RzQS+S+eqIi22DkPe2Tgiq2M3UfNpeu+75k5L9DGRIkZPYvwMBMbcmKvQqdIIg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/wrangler/node_modules/@cloudflare/workerd-windows-64": { + "version": "1.20251202.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20251202.0.tgz", + "integrity": "sha512-gzeU6eDydTi7ib+Q9DD/c0hpXtqPucnHk2tfGU03mljPObYxzMkkPGgB5qxpksFvub3y4K0ChjqYxGJB4F+j3g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/wrangler/node_modules/@esbuild/aix-ppc64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz", + "integrity": "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/android-arm": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.0.tgz", + "integrity": "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/android-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.0.tgz", + "integrity": "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/android-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.0.tgz", + "integrity": "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/darwin-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.0.tgz", + "integrity": "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/darwin-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.0.tgz", + "integrity": "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.0.tgz", + "integrity": "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/freebsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.0.tgz", + "integrity": "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-arm": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.0.tgz", + "integrity": "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.0.tgz", + "integrity": "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-ia32": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.0.tgz", + "integrity": "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-loong64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.0.tgz", + "integrity": "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-mips64el": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.0.tgz", + "integrity": "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-ppc64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.0.tgz", + "integrity": "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-riscv64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.0.tgz", + "integrity": "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-s390x": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.0.tgz", + "integrity": "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.0.tgz", + "integrity": "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.0.tgz", + "integrity": "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/netbsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.0.tgz", + "integrity": "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.0.tgz", + "integrity": "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/openbsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.0.tgz", + "integrity": "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.0.tgz", + "integrity": "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/sunos-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.0.tgz", + "integrity": "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/win32-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.0.tgz", + "integrity": "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/win32-ia32": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.0.tgz", + "integrity": "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/@esbuild/win32-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.0.tgz", + "integrity": "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/wrangler/node_modules/esbuild": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.0.tgz", + "integrity": "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.0", + "@esbuild/android-arm": "0.27.0", + "@esbuild/android-arm64": "0.27.0", + "@esbuild/android-x64": "0.27.0", + "@esbuild/darwin-arm64": "0.27.0", + "@esbuild/darwin-x64": "0.27.0", + "@esbuild/freebsd-arm64": "0.27.0", + "@esbuild/freebsd-x64": "0.27.0", + "@esbuild/linux-arm": "0.27.0", + "@esbuild/linux-arm64": "0.27.0", + "@esbuild/linux-ia32": "0.27.0", + "@esbuild/linux-loong64": "0.27.0", + "@esbuild/linux-mips64el": "0.27.0", + "@esbuild/linux-ppc64": "0.27.0", + "@esbuild/linux-riscv64": "0.27.0", + "@esbuild/linux-s390x": "0.27.0", + "@esbuild/linux-x64": "0.27.0", + "@esbuild/netbsd-arm64": "0.27.0", + "@esbuild/netbsd-x64": "0.27.0", + "@esbuild/openbsd-arm64": "0.27.0", + "@esbuild/openbsd-x64": "0.27.0", + "@esbuild/openharmony-arm64": "0.27.0", + "@esbuild/sunos-x64": "0.27.0", + "@esbuild/win32-arm64": "0.27.0", + "@esbuild/win32-ia32": "0.27.0", + "@esbuild/win32-x64": "0.27.0" + } + }, + "node_modules/wrangler/node_modules/miniflare": { + "version": "4.20251202.1", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20251202.1.tgz", + "integrity": "sha512-cRp2QNgnt9wpLMoNs4MOzzomyfe9UTS9sPRxIpUvxMl+mweCZ0FHpWWQvCnU7wWlfAP8VGZrHwqSsV5ERA6ahQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "0.8.1", + "acorn": "8.14.0", + "acorn-walk": "8.3.2", + "exit-hook": "2.2.1", + "glob-to-regexp": "0.4.1", + "sharp": "^0.33.5", + "stoppable": "1.1.0", + "undici": "7.14.0", + "workerd": "1.20251202.0", + "ws": "8.18.0", + "youch": "4.1.0-beta.10", + "zod": "3.22.3" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/wrangler/node_modules/unenv": { + "version": "2.0.0-rc.24", + "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz", + "integrity": "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "pathe": "^2.0.3" + } + }, + "node_modules/wrangler/node_modules/workerd": { + "version": "1.20251202.0", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20251202.0.tgz", + "integrity": "sha512-p08YfrUMHkjCECNdT36r+6DpJIZX4kixbZ4n6GMUcLR5Gh18fakSCsiQrh72iOm4M9QHv/rM7P8YvCrUPWT5sg==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "workerd": "bin/workerd" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "@cloudflare/workerd-darwin-64": "1.20251202.0", + "@cloudflare/workerd-darwin-arm64": "1.20251202.0", + "@cloudflare/workerd-linux-64": "1.20251202.0", + "@cloudflare/workerd-linux-arm64": "1.20251202.0", + "@cloudflare/workerd-windows-64": "1.20251202.0" + } + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/youch": { + "version": "4.1.0-beta.10", + "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz", + "integrity": "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@poppinss/dumper": "^0.6.4", + "@speed-highlight/core": "^1.2.7", + "cookie": "^1.0.2", + "youch-core": "^0.3.3" + } + }, + "node_modules/youch-core": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/youch-core/-/youch-core-0.3.3.tgz", + "integrity": "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@poppinss/exception": "^1.2.2", + "error-stack-parser-es": "^1.0.5" + } + }, + "node_modules/zod": { + "version": "3.22.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.3.tgz", + "integrity": "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/examples/cloudflare-vite-calendars/package.json b/examples/cloudflare-vite-calendars/package.json new file mode 100644 index 00000000..8ac5debf --- /dev/null +++ b/examples/cloudflare-vite-calendars/package.json @@ -0,0 +1,36 @@ +{ + "name": "cloudflare-vite-calendars", + "private": true, + "version": "1.0.0", + "description": "Cloudflare Workers + Vite example for managing calendar events using Nylas SDK", + "type": "module", + "scripts": { + "dev": "vite dev", + "dev:vite": "vite dev", + "build": "vite build", + "preview": "npm run build && vite preview", + "deploy": "npm run build && wrangler deploy", + "type-check": "tsc --noEmit" + }, + "keywords": [ + "cloudflare", + "vite", + "workers", + "nylas", + "calendar", + "events" + ], + "author": "Nylas", + "license": "MIT", + "devDependencies": { + "@cloudflare/vite-plugin": "^1.13.0", + "@cloudflare/workers-types": "^4.20231218.0", + "typescript": "^5.3.0", + "vite": "^6.4.1", + "wrangler": "^4.53.0" + }, + "dependencies": { + "nylas": "file:../../" + } +} + diff --git a/examples/cloudflare-vite-calendars/src/worker.ts b/examples/cloudflare-vite-calendars/src/worker.ts new file mode 100644 index 00000000..2906bd5a --- /dev/null +++ b/examples/cloudflare-vite-calendars/src/worker.ts @@ -0,0 +1,590 @@ +import Nylas, { CreateEventRequest, Event, NylasApiError } from 'nylas'; + +// Define the environment interface for TypeScript +interface Env { + NYLAS_API_KEY: string; + NYLAS_API_URI: string; + NYLAS_GRANT_ID: string; + NYLAS_CALENDAR_ID: string; +} + +// HTML interface for calendar management +const HTML_INTERFACE = ` + + + + + + Nylas Calendar Events Manager + + + +
+
+

πŸ“… Nylas Calendar Manager

+

Manage your calendar events using Nylas SDK on Cloudflare Workers with Vite

+
+ + +
+

πŸ“‹ Your Calendar Events

+ +
+
+
+ + +
+

✨ Create New Event

+
+
+ + +
+ +
+ + +
+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+ + +
+
+
+
+ + + + +`; + +/** + * List calendar events + */ +async function listEvents(nylas: Nylas, env: Env): Promise { + try { + const events = await nylas.events.list({ + identifier: env.NYLAS_GRANT_ID, + queryParams: { + calendarId: env.NYLAS_CALENDAR_ID, + limit: 50, + }, + }); + + return new Response( + JSON.stringify({ + success: true, + events: events.data, + count: events.data.length, + }), + { + headers: { 'Content-Type': 'application/json' }, + } + ); + } catch (error) { + console.error('Error listing events:', error); + + const errorMessage = + error instanceof NylasApiError + ? error.message + : error instanceof Error + ? error.message + : 'Unknown error occurred'; + + return new Response( + JSON.stringify({ + success: false, + error: errorMessage, + }), + { + status: 500, + headers: { 'Content-Type': 'application/json' }, + } + ); + } +} + +/** + * Create a new calendar event + */ +async function createEvent( + nylas: Nylas, + env: Env, + eventData: any +): Promise { + try { + // Convert ISO dates to Unix timestamps + const startTime = Math.floor( + new Date(eventData.startDate).getTime() / 1000 + ); + const endTime = Math.floor(new Date(eventData.endDate).getTime() / 1000); + + // Prepare the event request + const requestBody: CreateEventRequest = { + title: eventData.title, + description: eventData.description || '', + when: { + startTime, + endTime, + }, + location: eventData.location || '', + busy: true, + }; + + // Create the event + const response = await nylas.events.create({ + identifier: env.NYLAS_GRANT_ID, + requestBody, + queryParams: { + calendarId: env.NYLAS_CALENDAR_ID, + }, + }); + + return new Response( + JSON.stringify({ + success: true, + event: response.data, + message: 'Event created successfully', + }), + { + headers: { 'Content-Type': 'application/json' }, + } + ); + } catch (error) { + console.error('Error creating event:', error); + + const errorMessage = + error instanceof NylasApiError + ? error.message + : error instanceof Error + ? error.message + : 'Unknown error occurred'; + + return new Response( + JSON.stringify({ + success: false, + error: errorMessage, + }), + { + status: 500, + headers: { 'Content-Type': 'application/json' }, + } + ); + } +} + +/** + * Main request handler + */ +export default { + async fetch(request: Request, env: Env): Promise { + const url = new URL(request.url); + + // CORS headers + const corsHeaders = { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type', + }; + + // Handle CORS preflight + if (request.method === 'OPTIONS') { + return new Response(null, { headers: corsHeaders }); + } + + // Validate environment variables + if (!env.NYLAS_API_KEY || !env.NYLAS_GRANT_ID || !env.NYLAS_CALENDAR_ID) { + return new Response( + JSON.stringify({ + error: + 'Missing required environment variables (NYLAS_API_KEY, NYLAS_GRANT_ID, NYLAS_CALENDAR_ID)', + }), + { + status: 500, + headers: { 'Content-Type': 'application/json', ...corsHeaders }, + } + ); + } + + // Initialize Nylas client + const nylas = new Nylas({ + apiKey: env.NYLAS_API_KEY, + apiUri: env.NYLAS_API_URI || 'https://api.us.nylas.com', + }); + + // Serve HTML interface + if (request.method === 'GET' && url.pathname === '/') { + return new Response(HTML_INTERFACE, { + headers: { + 'Content-Type': 'text/html', + ...corsHeaders, + }, + }); + } + + // List events endpoint + if (request.method === 'GET' && url.pathname === '/api/events') { + return listEvents(nylas, env); + } + + // Create event endpoint + if (request.method === 'POST' && url.pathname === '/api/events') { + try { + const eventData = await request.json(); + return createEvent(nylas, env, eventData); + } catch (error) { + return new Response( + JSON.stringify({ + success: false, + error: 'Invalid request body', + }), + { + status: 400, + headers: { 'Content-Type': 'application/json', ...corsHeaders }, + } + ); + } + } + + // 404 for other routes + return new Response('Not Found', { + status: 404, + headers: corsHeaders, + }); + }, +}; diff --git a/examples/cloudflare-vite-calendars/tsconfig.json b/examples/cloudflare-vite-calendars/tsconfig.json new file mode 100644 index 00000000..40928b1c --- /dev/null +++ b/examples/cloudflare-vite-calendars/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "lib": ["ES2022"], + "types": ["@cloudflare/workers-types"], + "moduleResolution": "bundler", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "preserve" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", ".wrangler"] +} + diff --git a/examples/cloudflare-vite-calendars/vite.config.ts b/examples/cloudflare-vite-calendars/vite.config.ts new file mode 100644 index 00000000..590556a5 --- /dev/null +++ b/examples/cloudflare-vite-calendars/vite.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from 'vite'; +import { cloudflare } from '@cloudflare/vite-plugin'; + +export default defineConfig({ + plugins: [ + cloudflare({ + // Enable Node.js compatibility for full Node.js API support + configPath: './wrangler.toml', + }), + ], +}); diff --git a/examples/cloudflare-vite-calendars/wrangler.toml b/examples/cloudflare-vite-calendars/wrangler.toml new file mode 100644 index 00000000..fa0e95c4 --- /dev/null +++ b/examples/cloudflare-vite-calendars/wrangler.toml @@ -0,0 +1,21 @@ +name = "nylas-calendar-vite-worker" +main = "src/worker.ts" +compatibility_date = "2024-09-23" +compatibility_flags = ["nodejs_compat"] + +# Environment variables for development +[env.development.vars] +NYLAS_API_KEY = "" +NYLAS_API_URI = "https://api.us.nylas.com" +NYLAS_GRANT_ID = "" +NYLAS_CALENDAR_ID = "" + +# Environment variables for production +[env.production.vars] +NYLAS_API_URI = "https://api.us.nylas.com" + +# For production, use wrangler secret to set these: +# wrangler secret put NYLAS_API_KEY +# wrangler secret put NYLAS_GRANT_ID +# wrangler secret put NYLAS_CALENDAR_ID + diff --git a/examples/edge-environment/.gitignore b/examples/edge-environment/.gitignore new file mode 100644 index 00000000..64ead2b7 --- /dev/null +++ b/examples/edge-environment/.gitignore @@ -0,0 +1,53 @@ +# Dependencies +node_modules/ + +# Wrangler output +dist/ +.wrangler/ + +# Environment variables (keep .dev.vars.example but not .dev.vars) +.dev.vars + +# Logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Coverage directory used by tools like istanbul +coverage/ + +# nyc test coverage +.nyc_output + +# Dependency directories +jspm_packages/ + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# macOS +.DS_Store + +# Windows +Thumbs.db +ehthumbs.db + +# IDE +.vscode/ +.idea/ +*.swp +*.swo + +# vars +.*.vars \ No newline at end of file diff --git a/examples/edge-environment/README.md b/examples/edge-environment/README.md new file mode 100644 index 00000000..c11f36dd --- /dev/null +++ b/examples/edge-environment/README.md @@ -0,0 +1,320 @@ +# Nylas Cloudflare Worker - Email Attachments Example + +This example demonstrates how to use the Nylas SDK in a Cloudflare Worker to send email attachments. It provides a simple web interface for uploading files and sending them as email attachments. + +## πŸš€ Features + +- **Simple Web UI**: Drag & drop or click to upload files +- **File Validation**: Automatic file size and type validation (10MB max) +- **Real-time Feedback**: Loading states and success/error messages +- **Email Sending**: Uses the Nylas SDK to send emails with attachments +- **Edge Computing**: Runs on Cloudflare's global edge network +- **Node.js Compatibility**: Uses `nodejs_compat` flag for seamless Node.js module support + +## πŸ“‹ Prerequisites + +Before getting started, you'll need: + +1. **Nylas Account**: [Sign up for free](https://dashboard.nylas.com/register) +2. **Cloudflare Account**: [Sign up for free](https://dash.cloudflare.com/sign-up) +3. **Node.js**: Version 16 or higher +4. **Nylas Application**: Created in your Nylas Dashboard +5. **Connected Email Account**: At least one email account connected to your Nylas application + +## πŸ› οΈ Setup + +### 1. Install Dependencies + +```bash +# Navigate to the edge-environment directory +cd examples/edge-environment + +# Install dependencies +npm install +``` + +### 2. Configure Environment Variables + +Copy the `.dev.vars` file and update it with your Nylas credentials: + +```bash +# Update .dev.vars with your actual values +NYLAS_API_KEY=your_nylas_api_key_here +NYLAS_API_URI=https://api.us.nylas.com +NYLAS_GRANT_ID=your_grant_id_here +TEST_EMAIL=test@example.com +``` + +**How to get these values:** + +- **NYLAS_API_KEY**: Found in your [Nylas Dashboard](https://dashboard.nylas.com/applications) under your application settings +- **NYLAS_GRANT_ID**: The ID of a connected email account (found in Dashboard > Grants) +- **NYLAS_API_URI**: Use `https://api.us.nylas.com` for US region, or your specific region's API URL + +### 3. Update Wrangler Configuration + +Edit `wrangler.toml` and update the name and environment variables as needed: + +```toml +name = "your-worker-name" # Choose a unique name for your worker + +[env.development.vars] +NYLAS_API_KEY = "your_api_key" +NYLAS_GRANT_ID = "your_grant_id" +# ... other variables +``` + +## πŸ—οΈ Development + +### Start Local Development Server + +```bash +npm run dev +``` + +This will: +- Start the Wrangler development server +- Make your worker available at `http://localhost:8787` +- Enable hot-reloading for code changes +- Load environment variables from `.dev.vars` + +### Test the Application + +1. Open `http://localhost:8787` in your browser +2. Fill in the email form: + - **Recipient Email**: Enter a valid email address + - **Subject**: Enter an email subject + - **Message**: Enter your message content + - **Attachment**: Upload a file (max 10MB) +3. Click "Send Email with Attachment" +4. Check the recipient's inbox for the email + +### Development Tips + +- **File Size Limit**: The worker is configured with a 10MB file size limit +- **Supported Files**: All file types are supported (PDFs, images, documents, etc.) +- **Error Handling**: Check the browser console and worker logs for debugging +- **Hot Reloading**: Code changes will automatically reload the worker + +## πŸš€ Deployment + +### Option 1: Deploy to Cloudflare Workers (Recommended) + +#### 1. Set Production Secrets + +For security, use Wrangler secrets instead of environment variables in production: + +```bash +# Set your API key as a secret +wrangler secret put NYLAS_API_KEY +# Enter your API key when prompted + +# Set your Grant ID as a secret +wrangler secret put NYLAS_GRANT_ID +# Enter your Grant ID when prompted + +# Set default recipient email (optional) +wrangler secret put TEST_EMAIL +# Enter default email when prompted +``` + +#### 2. Deploy to Production + +```bash +npm run deploy +``` + +This will: +- Build and upload your worker to Cloudflare +- Make it available at `https://your-worker-name.your-subdomain.workers.dev` +- Use the production environment configuration + +#### 3. Test Production Deployment + +Visit your worker's URL and test the file upload functionality. + +### Option 2: Deploy with Custom Domain + +If you have a custom domain managed by Cloudflare: + +1. **Add a route in `wrangler.toml`:** +```toml +[[routes]] +pattern = "attachments.yourdomain.com/*" +zone_name = "yourdomain.com" +``` + +2. **Deploy with the route:** +```bash +wrangler deploy +``` + +## πŸ“š How It Works + +### Architecture + +``` +User Browser β†’ Cloudflare Worker β†’ Nylas API β†’ Email Provider +``` + +1. **File Upload**: User uploads a file through the web interface +2. **Form Processing**: Worker receives multipart form data +3. **File Processing**: File is converted to Buffer for efficient binary transfer +4. **Email Sending**: Nylas SDK processes and sends the email with attachment +5. **Response**: User receives confirmation or error message + +### Key Files + +- **`src/worker.ts`**: Main worker logic and request handling +- **`wrangler.toml`**: Cloudflare Worker configuration with Node.js compatibility +- **`package.json`**: Dependencies and scripts +- **`.dev.vars`**: Development environment variables + +### Technical Implementation + +This worker uses the **Nylas SDK** with optimizations for Cloudflare Workers: + +- **SDK Integration**: Uses the official Nylas Node.js SDK +- **Buffer Attachments**: Uses native Buffer objects for efficient binary data handling +- **Direct Binary Transfer**: No base64 encoding overhead (33% smaller than base64) +- **Edge Optimized**: Designed specifically for Cloudflare Workers runtime + +### Node.js Compatibility + +This worker uses: +- **`compatibility_date = "2024-09-23"`**: Enables automatic Node.js built-in module support +- **`nodejs_compat` compatibility flag**: Additional Node.js compatibility features + +These settings enable Node.js built-in modules like `crypto`, `path`, `fs`, and `stream` that are required by the Nylas SDK. The Buffer attachment approach ensures optimal performance and compatibility with the Cloudflare Workers edge environment. + +### API Endpoints + +- **`GET /`**: Serves the HTML upload interface +- **`POST /send-attachment`**: Handles file upload and email sending +- **`OPTIONS /*`**: Handles CORS preflight requests + +## πŸ”§ Customization + +### Modify File Size Limits + +Update the file size limit in `src/worker.ts`: + +```typescript +// Check file size (10MB limit) +const maxSize = 10 * 1024 * 1024; // Change this value +``` + +### Use ReadableStream for Very Large Files + +For extremely large files (>25MB), you can use ReadableStream instead of Buffer: + +```typescript +// Alternative: Use ReadableStream for very large files +const stream = file.stream(); +const sendRequest: SendMessageRequest = { + // ... other fields + attachments: [{ + filename: file.name, + contentType: getContentType(file.name), + content: stream, // Use stream instead of buffer + size: file.size, + }], +}; +``` + +### Customize Email Template + +Modify the email HTML template in `src/worker.ts`: + +```typescript +body: ` +
+

Your Custom Email Template

+

${message}

+ +
+`, +``` + +### Add File Type Restrictions + +Add file type validation in the worker: + +```typescript +// Validate file type +const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf']; +if (!allowedTypes.includes(getContentType(file.name))) { + return new Response( + JSON.stringify({ error: 'File type not allowed' }), + { status: 400, headers: { 'Content-Type': 'application/json' } } + ); +} +``` + +## πŸ› Troubleshooting + +### Common Issues + +**Error: "Missing required environment variables"** +- Ensure all environment variables are set in `.dev.vars` (development) or as secrets (production) +- Check variable names match exactly + +**Error: "Could not resolve [module]" (crypto, path, fs, stream)** +- Ensure `compatibility_date = "2024-09-23"` or later is set in `wrangler.toml` +- Ensure `compatibility_flags = ["nodejs_compat"]` is also set +- These settings enable Node.js built-in modules required by the Nylas SDK +- The worker uses Buffer objects for efficient binary attachment handling + +**Error: "File size exceeds 10MB limit"** +- Reduce file size or increase the limit in the worker code +- Note: Cloudflare Workers have memory and CPU time limits + +**Error: "Invalid file upload"** +- Ensure you're uploading a valid file +- Check that the form is submitting properly + +**Error: "optionParams.form.getHeaders is not a function"** +- This was an old SDK compatibility issue, now resolved +- The worker uses Buffer attachments instead of problematic form-data +- This error should not occur with the current implementation + +**Email not received** +- Verify the recipient email address +- Check spam/junk folders +- Verify your Nylas grant has send permissions +- Check Nylas Dashboard for any API errors + +### Debug Mode + +Add logging to the worker for debugging: + +```typescript +console.log('File details:', { + name: file.name, + size: file.size, + type: file.type +}); +``` + +View logs with: +```bash +wrangler tail +``` + +## πŸ“– Related Examples + +- **Local Attachment Examples**: See `../messages/examples/` for Node.js examples +- **Nylas SDK Documentation**: [https://developer.nylas.com](https://developer.nylas.com) +- **Cloudflare Workers Docs**: [https://developers.cloudflare.com/workers/](https://developers.cloudflare.com/workers/) + +## 🀝 Contributing + +Found an issue or want to improve this example? Please: + +1. Check existing issues in the [Nylas Node.js SDK repository](https://github.com/nylas/nylas-nodejs) +2. Create a new issue or pull request +3. Follow the contributing guidelines + +## πŸ“„ License + +This example is part of the Nylas Node.js SDK and is licensed under the MIT License. \ No newline at end of file diff --git a/examples/edge-environment/package-lock.json b/examples/edge-environment/package-lock.json new file mode 100644 index 00000000..79c343a6 --- /dev/null +++ b/examples/edge-environment/package-lock.json @@ -0,0 +1,1645 @@ +{ + "name": "nylas-cloudflare-worker-attachments", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "nylas-cloudflare-worker-attachments", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "mime-types": "^2.1.35", + "nylas": "file:../../" + }, + "devDependencies": { + "@cloudflare/workers-types": "^4.20231218.0", + "@types/mime-types": "^2.1.4", + "typescript": "^5.3.0", + "wrangler": "^4.27.0" + } + }, + "../..": { + "name": "nylas", + "version": "7.13.0", + "license": "MIT", + "dependencies": { + "change-case": "^4.1.2", + "form-data-encoder": "^4.1.0", + "formdata-node": "^6.0.3", + "mime-types": "^2.1.35", + "node-fetch": "^3.3.2", + "uuid": "^8.3.2" + }, + "devDependencies": { + "@babel/core": "^7.3.3", + "@types/jest": "^29.5.2", + "@types/mime-types": "^2.1.2", + "@types/node": "^22.15.21", + "@types/uuid": "^8.3.4", + "@typescript-eslint/eslint-plugin": "^2.25.0", + "@typescript-eslint/parser": "^2.25.0", + "eslint": "^5.14.0", + "eslint-config-prettier": "^4.0.0", + "eslint-plugin-custom-rules": "^0.0.0", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-prettier": "^3.0.1", + "jest": "^29.6.1", + "jest-fetch-mock": "^3.0.3", + "prettier": "^3.5.3", + "ts-jest": "^29.1.1", + "typedoc": "^0.28.4", + "typedoc-plugin-rename-defaults": "^0.7.3", + "typescript": "^5.8.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/kv-asset-handler": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.0.tgz", + "integrity": "sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==", + "dev": true, + "license": "MIT OR Apache-2.0", + "dependencies": { + "mime": "^3.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@cloudflare/unenv-preset": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.5.0.tgz", + "integrity": "sha512-CZe9B2VbjIQjBTyc+KoZcN1oUcm4T6GgCXoel9O7647djHuSRAa6sM6G+NdxWArATZgeMMbsvn9C50GCcnIatA==", + "dev": true, + "license": "MIT OR Apache-2.0", + "peerDependencies": { + "unenv": "2.0.0-rc.19", + "workerd": "^1.20250722.0" + }, + "peerDependenciesMeta": { + "workerd": { + "optional": true + } + } + }, + "node_modules/@cloudflare/workerd-darwin-64": { + "version": "1.20250730.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20250730.0.tgz", + "integrity": "sha512-X3egNyTjLQaECYe34x8Al7r4oXAhcN3a8+8qcpNCcq1sgtuHIeAwS9potgRR/mwkGfmrJn7nfAyDKC4vrkniQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-darwin-arm64": { + "version": "1.20250730.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20250730.0.tgz", + "integrity": "sha512-/4bvcaGY/9v0rghgKboGiyPKKGQTbDnQ1EeY0oN0SSQH0Cp3OBzqwni/JRvh8TEaD+5azJnSFLlFZj9w7fo+hw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-linux-64": { + "version": "1.20250730.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20250730.0.tgz", + "integrity": "sha512-I4ZsXYdNkqkJnzNFKADMufiLIzRdIRsN7dSH8UCPw2fYp1BbKA10AkKVqitFwBxIY8eOzQ6Vf7c41AjLQmtJqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-linux-arm64": { + "version": "1.20250730.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20250730.0.tgz", + "integrity": "sha512-tTpO6139jFQ5vxgtBZgS8Y8R1jVidS4n7s37x5xO9bCWLZoL0kTj38UGZ8FENkTeaMxE9Mm//nbQol7TfJ2nZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-windows-64": { + "version": "1.20250730.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20250730.0.tgz", + "integrity": "sha512-paVHgocuilMzOU+gEyKR/86j/yI+QzmSHRnqdd8OdQ37Hf6SyPX7kQj6VVNRXbzVHWix1WxaJsXfTGK1LK05wA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workers-types": { + "version": "4.20250731.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20250731.0.tgz", + "integrity": "sha512-J8tz6dQ0gZKzDKNLl3LW7Uvj7rRllKw5UD61fBDf8IGizH9CKznjrdvqRQHB9Qb8yopqjylcx2lxiC3angF4Pw==", + "dev": true, + "license": "MIT OR Apache-2.0" + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz", + "integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", + "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", + "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", + "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", + "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", + "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", + "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", + "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", + "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", + "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", + "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", + "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", + "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", + "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", + "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", + "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", + "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", + "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", + "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", + "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", + "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", + "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", + "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", + "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", + "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", + "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@poppinss/colors": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.5.tgz", + "integrity": "sha512-FvdDqtcRCtz6hThExcFOgW0cWX+xwSMWcRuQe5ZEb2m7cVQOAVZOIMt+/v9RxGiD9/OY16qJBXK4CVKWAPalBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^4.1.5" + } + }, + "node_modules/@poppinss/dumper": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.4.tgz", + "integrity": "sha512-iG0TIdqv8xJ3Lt9O8DrPRxw1MRLjNpoqiSGU03P/wNLP/s0ra0udPJ1J2Tx5M0J3H/cVyEgpbn8xUKRY9j59kQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@sindresorhus/is": "^7.0.2", + "supports-color": "^10.0.0" + } + }, + "node_modules/@poppinss/exception": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.2.tgz", + "integrity": "sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sindresorhus/is": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.0.2.tgz", + "integrity": "sha512-d9xRovfKNz1SKieM0qJdO+PQonjnnIfSNWfHYnBSJ9hkjm0ZPw6HlxscDXYstp3z+7V2GOFHc+J0CYrYTjqCJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@speed-highlight/core": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.7.tgz", + "integrity": "sha512-0dxmVj4gxg3Jg879kvFS/msl4s9F3T9UXC1InxgOf7t5NvcPD97u/WTA5vL/IxWHMn7qSxBozqrnnE2wvl1m8g==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/@types/mime-types": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.4.tgz", + "integrity": "sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/blake3-wasm": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz", + "integrity": "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==", + "dev": true, + "license": "MIT" + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "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/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/error-stack-parser-es": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", + "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/esbuild": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", + "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.4", + "@esbuild/android-arm": "0.25.4", + "@esbuild/android-arm64": "0.25.4", + "@esbuild/android-x64": "0.25.4", + "@esbuild/darwin-arm64": "0.25.4", + "@esbuild/darwin-x64": "0.25.4", + "@esbuild/freebsd-arm64": "0.25.4", + "@esbuild/freebsd-x64": "0.25.4", + "@esbuild/linux-arm": "0.25.4", + "@esbuild/linux-arm64": "0.25.4", + "@esbuild/linux-ia32": "0.25.4", + "@esbuild/linux-loong64": "0.25.4", + "@esbuild/linux-mips64el": "0.25.4", + "@esbuild/linux-ppc64": "0.25.4", + "@esbuild/linux-riscv64": "0.25.4", + "@esbuild/linux-s390x": "0.25.4", + "@esbuild/linux-x64": "0.25.4", + "@esbuild/netbsd-arm64": "0.25.4", + "@esbuild/netbsd-x64": "0.25.4", + "@esbuild/openbsd-arm64": "0.25.4", + "@esbuild/openbsd-x64": "0.25.4", + "@esbuild/sunos-x64": "0.25.4", + "@esbuild/win32-arm64": "0.25.4", + "@esbuild/win32-ia32": "0.25.4", + "@esbuild/win32-x64": "0.25.4" + } + }, + "node_modules/exit-hook": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-2.2.1.tgz", + "integrity": "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "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/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "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", + "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", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/miniflare": { + "version": "4.20250730.0", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20250730.0.tgz", + "integrity": "sha512-avGXBStHQSqcJr8ra1mJ3/OQvnLZ49B1uAILQapAha1DHNZZvXWLIgUVre/WGY6ZOlNGFPh5CJ+dXLm4yuV3Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "0.8.1", + "acorn": "8.14.0", + "acorn-walk": "8.3.2", + "exit-hook": "2.2.1", + "glob-to-regexp": "0.4.1", + "sharp": "^0.33.5", + "stoppable": "1.1.0", + "undici": "^7.10.0", + "workerd": "1.20250730.0", + "ws": "8.18.0", + "youch": "4.1.0-beta.10", + "zod": "3.22.3" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/nylas": { + "resolved": "../..", + "link": true + }, + "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/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "dev": true, + "license": "MIT" + }, + "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/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/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4", + "npm": ">=6" + } + }, + "node_modules/supports-color": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.0.0.tgz", + "integrity": "sha512-HRVVSbCCMbj7/kdWF9Q+bbckjBHLtHMEoJWlkmYzzdwhYMkjkOwubLM6t7NbWKjgKamGDrWL1++KrjUO1t9oAQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "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==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/undici": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.13.0.tgz", + "integrity": "sha512-l+zSMssRqrzDcb3fjMkjjLGmuiiK2pMIcV++mJaAc9vhjSGpvM7h43QgP+OAMb1GImHmbPyG2tBXeuyG5iY4gA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/unenv": { + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.19.tgz", + "integrity": "sha512-t/OMHBNAkknVCI7bVB9OWjUUAwhVv9vsPIAGnNUxnu3FxPQN11rjh0sksLMzc3g7IlTgvHmOTl4JM7JHpcv5wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "defu": "^6.1.4", + "exsolve": "^1.0.7", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "ufo": "^1.6.1" + } + }, + "node_modules/workerd": { + "version": "1.20250730.0", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20250730.0.tgz", + "integrity": "sha512-w6e0WM2YGfYQGmg0dewZeLUYIxAzMYK1R31vaS4HHHjgT32Xqj0eVQH+leegzY51RZPNCvw5pe8DFmW4MGf8Fg==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "bin": { + "workerd": "bin/workerd" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "@cloudflare/workerd-darwin-64": "1.20250730.0", + "@cloudflare/workerd-darwin-arm64": "1.20250730.0", + "@cloudflare/workerd-linux-64": "1.20250730.0", + "@cloudflare/workerd-linux-arm64": "1.20250730.0", + "@cloudflare/workerd-windows-64": "1.20250730.0" + } + }, + "node_modules/wrangler": { + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.27.0.tgz", + "integrity": "sha512-YNHZyMNWebFt9jD6dc20tQrCmnSzJj3SoB0FFa90w11Cx4lbP3d+rUZYjb18Zt+OGSMay1wT2PzwT2vCTskkmg==", + "dev": true, + "license": "MIT OR Apache-2.0", + "dependencies": { + "@cloudflare/kv-asset-handler": "0.4.0", + "@cloudflare/unenv-preset": "2.5.0", + "blake3-wasm": "2.1.5", + "esbuild": "0.25.4", + "miniflare": "4.20250730.0", + "path-to-regexp": "6.3.0", + "unenv": "2.0.0-rc.19", + "workerd": "1.20250730.0" + }, + "bin": { + "wrangler": "bin/wrangler.js", + "wrangler2": "bin/wrangler.js" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@cloudflare/workers-types": "^4.20250730.0" + }, + "peerDependenciesMeta": { + "@cloudflare/workers-types": { + "optional": true + } + } + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/youch": { + "version": "4.1.0-beta.10", + "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz", + "integrity": "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@poppinss/dumper": "^0.6.4", + "@speed-highlight/core": "^1.2.7", + "cookie": "^1.0.2", + "youch-core": "^0.3.3" + } + }, + "node_modules/youch-core": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/youch-core/-/youch-core-0.3.3.tgz", + "integrity": "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@poppinss/exception": "^1.2.2", + "error-stack-parser-es": "^1.0.5" + } + }, + "node_modules/zod": { + "version": "3.22.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.3.tgz", + "integrity": "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/examples/edge-environment/package.json b/examples/edge-environment/package.json new file mode 100644 index 00000000..ce5cb18c --- /dev/null +++ b/examples/edge-environment/package.json @@ -0,0 +1,25 @@ +{ + "name": "nylas-cloudflare-worker-attachments", + "version": "1.0.0", + "description": "Cloudflare Worker example for sending email attachments using Nylas SDK", + "main": "src/worker.ts", + "scripts": { + "dev": "wrangler dev", + "deploy": "wrangler deploy", + "build": "tsc && wrangler deploy --dry-run", + "type-check": "tsc --noEmit" + }, + "keywords": ["cloudflare", "worker", "nylas", "email", "attachments"], + "author": "Nylas", + "license": "MIT", + "devDependencies": { + "@cloudflare/workers-types": "^4.20231218.0", + "@types/mime-types": "^2.1.4", + "typescript": "^5.3.0", + "wrangler": "^4.27.0" + }, + "dependencies": { + "nylas": "file:../../", + "mime-types": "^2.1.35" + } +} \ No newline at end of file diff --git a/examples/edge-environment/setup.sh b/examples/edge-environment/setup.sh new file mode 100755 index 00000000..21f007e2 --- /dev/null +++ b/examples/edge-environment/setup.sh @@ -0,0 +1,113 @@ +#!/bin/bash + +# Nylas Cloudflare Worker Setup Script +# This script helps you set up the environment for the Nylas attachment worker + +echo "πŸš€ Nylas Cloudflare Worker Setup" +echo "==================================" +echo "" + +# Check if required tools are installed +echo "πŸ“‹ Checking prerequisites..." + +# Check Node.js +if ! command -v node &> /dev/null; then + echo "❌ Node.js is not installed. Please install Node.js 16+ and try again." + exit 1 +fi + +NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1) +if [ "$NODE_VERSION" -lt 16 ]; then + echo "❌ Node.js version $NODE_VERSION is too old. Please install Node.js 16+ and try again." + exit 1 +fi + +echo "βœ… Node.js $(node -v) is installed" + +# Check npm +if ! command -v npm &> /dev/null; then + echo "❌ npm is not installed. Please install npm and try again." + exit 1 +fi + +echo "βœ… npm $(npm -v) is installed" + +# Install dependencies if not already installed +if [ ! -d "node_modules" ]; then + echo "" + echo "πŸ“¦ Installing dependencies..." + npm install + if [ $? -ne 0 ]; then + echo "❌ Failed to install dependencies" + exit 1 + fi + echo "βœ… Dependencies installed successfully" +else + echo "βœ… Dependencies already installed" +fi + +# Check if wrangler is available +if ! command -v npx wrangler &> /dev/null; then + echo "❌ Wrangler is not available. Dependencies may not be installed correctly." + exit 1 +fi + +echo "βœ… Wrangler is available" + +echo "" +echo "πŸ”§ Configuration Setup" +echo "======================" + +# Check if .dev.vars exists and has the required variables +if [ ! -f ".dev.vars" ]; then + echo "❌ .dev.vars file not found" + echo "" + echo "Please create a .dev.vars file with your Nylas credentials:" + echo "" + cat << EOF +NYLAS_API_KEY=your_nylas_api_key_here +NYLAS_API_URI=https://api.us.nylas.com +NYLAS_GRANT_ID=your_grant_id_here +TEST_EMAIL=test@example.com +EOF + echo "" + exit 1 +fi + +echo "βœ… .dev.vars file found" + +# Check if the required environment variables are set (not just empty) +if grep -q "your_nylas_api_key_here" .dev.vars || grep -q "your_grant_id_here" .dev.vars; then + echo "⚠️ WARNING: .dev.vars still contains placeholder values" + echo "" + echo "Please update .dev.vars with your actual Nylas credentials:" + echo "- NYLAS_API_KEY: Get this from your Nylas Dashboard" + echo "- NYLAS_GRANT_ID: Get this from your connected accounts" + echo "" + echo "You can find these values at: https://dashboard.nylas.com" + echo "" +fi + +# Check wrangler.toml +if [ ! -f "wrangler.toml" ]; then + echo "❌ wrangler.toml not found" + exit 1 +fi + +echo "βœ… wrangler.toml found" + +echo "" +echo "πŸŽ‰ Setup Complete!" +echo "==================" +echo "" +echo "Next steps:" +echo "1. Update .dev.vars with your actual Nylas credentials" +echo "2. Run 'npm run dev' to start the development server" +echo "3. Open http://localhost:8787 in your browser" +echo "4. Test uploading a file and sending an email" +echo "" +echo "For deployment:" +echo "1. Set production secrets: wrangler secret put NYLAS_API_KEY" +echo "2. Deploy: npm run deploy" +echo "" +echo "Need help? Check the README.md for detailed instructions." \ No newline at end of file diff --git a/examples/edge-environment/src/worker.ts b/examples/edge-environment/src/worker.ts new file mode 100644 index 00000000..73adce2b --- /dev/null +++ b/examples/edge-environment/src/worker.ts @@ -0,0 +1,447 @@ +import Nylas, { SendMessageRequest } from 'nylas'; +import * as mimeTypes from 'mime-types'; + +// Define the environment interface for TypeScript +interface Env { + NYLAS_API_KEY: string; + NYLAS_API_URI: string; + NYLAS_GRANT_ID: string; + TEST_EMAIL: string; +} + +// Simple HTML interface for file upload +const HTML_INTERFACE = ` + + + + + + Nylas Attachment Sender + + + +
+

πŸ“§ Nylas Attachment Sender

+

+ Upload a file and send it as an email attachment using the Nylas SDK in a Cloudflare Worker +

+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ +
+ πŸ“Ž Click to select a file
+ or drag and drop here
+ Max size: 10MB +
+
+
+
+ + +
+ +
+
+ + + + +`; + +// Helper function to parse multipart form data +async function parseFormData( + request: Request +): Promise<{ [key: string]: any }> { + const formData = await request.formData(); + const result: { [key: string]: any } = {}; + + for (const [key, value] of formData.entries()) { + result[key] = value; + } + + return result; +} + +// Helper function to get file content type +function getContentType(filename: string): string { + return mimeTypes.lookup(filename) || 'application/octet-stream'; +} + +// Main request handler +export default { + async fetch(request: Request, env: Env): Promise { + const url = new URL(request.url); + + // CORS headers for the response + const corsHeaders = { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type', + }; + + // Handle CORS preflight requests + if (request.method === 'OPTIONS') { + return new Response(null, { headers: corsHeaders }); + } + + // Serve the HTML interface on GET requests + if (request.method === 'GET' && url.pathname === '/') { + return new Response(HTML_INTERFACE, { + headers: { + 'Content-Type': 'text/html', + ...corsHeaders, + }, + }); + } + + // Handle file upload and email sending on POST requests + if (request.method === 'POST' && url.pathname === '/send-attachment') { + try { + // Validate environment variables + if (!env.NYLAS_API_KEY || !env.NYLAS_GRANT_ID) { + return new Response( + JSON.stringify({ + error: + 'Missing required environment variables (NYLAS_API_KEY, NYLAS_GRANT_ID)', + }), + { + status: 500, + headers: { 'Content-Type': 'application/json', ...corsHeaders }, + } + ); + } + + // Parse form data + const formData = await parseFormData(request); + const recipientEmail = formData.recipientEmail as string; + const subject = formData.subject as string; + const message = formData.message as string; + const file = formData.file; + + // Validate that file is actually a File object + if (typeof file === 'string' || !file) { + return new Response( + JSON.stringify({ error: 'Invalid file upload' }), + { + status: 400, + headers: { 'Content-Type': 'application/json', ...corsHeaders }, + } + ); + } + + // Validate required fields + if (!recipientEmail || !subject || !message || !file) { + return new Response( + JSON.stringify({ error: 'Missing required fields' }), + { + status: 400, + headers: { 'Content-Type': 'application/json', ...corsHeaders }, + } + ); + } + + // Check file size (10MB limit) + const maxSize = 10 * 1024 * 1024; // 10MB + if (file.size > maxSize) { + return new Response( + JSON.stringify({ error: 'File size exceeds 10MB limit' }), + { + status: 400, + headers: { 'Content-Type': 'application/json', ...corsHeaders }, + } + ); + } + + // Initialize Nylas client + const nylas = new Nylas({ + apiKey: env.NYLAS_API_KEY, + apiUri: env.NYLAS_API_URI || 'https://api.us.nylas.com', + }); + + // Convert file to Buffer for SDK + const fileBuffer = await file.arrayBuffer(); + const buffer = Buffer.from(fileBuffer); + + // Prepare the email request using the SDK + const sendRequest: SendMessageRequest = { + to: [{ email: recipientEmail }], + subject: subject, + body: ` +
+

Email from Cloudflare Worker

+

${message.replace(/\n/g, '
')}

+
+

+ This email was sent from a Cloudflare Worker using the Nylas SDK.
+ Attachment: ${file.name} (${(file.size / 1024 / 1024).toFixed(2)} MB) +

+
+ `, + attachments: [ + { + filename: file.name, + contentType: getContentType(file.name), + content: buffer, + size: file.size, + }, + ], + }; + + // Send the email using the Nylas SDK + const response = await nylas.messages.send({ + identifier: env.NYLAS_GRANT_ID, + requestBody: sendRequest, + }); + + // Return success response + return new Response( + JSON.stringify({ + success: true, + messageId: response.data.id, + message: 'Email sent successfully', + }), + { + headers: { 'Content-Type': 'application/json', ...corsHeaders }, + } + ); + } catch (error) { + console.error('Error sending email:', error); + + return new Response( + JSON.stringify({ + error: + error instanceof Error ? error.message : 'Unknown error occurred', + }), + { + status: 500, + headers: { 'Content-Type': 'application/json', ...corsHeaders }, + } + ); + } + } + + // 404 for other routes + return new Response('Not Found', { + status: 404, + headers: corsHeaders, + }); + }, +}; diff --git a/examples/edge-environment/tsconfig.json b/examples/edge-environment/tsconfig.json new file mode 100644 index 00000000..f92d08de --- /dev/null +++ b/examples/edge-environment/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "ESNext", + "moduleResolution": "bundler", + "types": ["@cloudflare/workers-types"], + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} \ No newline at end of file diff --git a/examples/edge-environment/wrangler.toml b/examples/edge-environment/wrangler.toml new file mode 100644 index 00000000..c52714b2 --- /dev/null +++ b/examples/edge-environment/wrangler.toml @@ -0,0 +1,24 @@ +name = "nylas-attachment-worker" +main = "src/worker.ts" +compatibility_date = "2024-09-23" +compatibility_flags = ["nodejs_compat"] + +# Environment variables for development +[env.development.vars] +NYLAS_API_KEY = "" +NYLAS_API_URI = "https://api.us.nylas.com" +NYLAS_GRANT_ID = "" +TEST_EMAIL = "" + +# Environment variables for production +[env.production.vars] +NYLAS_API_URI = "https://api.us.nylas.com" + +# For production, use wrangler secret to set these: +# wrangler secret put NYLAS_API_KEY +# wrangler secret put NYLAS_GRANT_ID +# wrangler secret put TEST_EMAIL + +# File size limits (10MB max for attachments) +[limits] +cpu_ms = 10000 \ No newline at end of file diff --git a/examples/esm-only/indes.mjs b/examples/esm-only/indes.mjs new file mode 100644 index 00000000..775dcd52 --- /dev/null +++ b/examples/esm-only/indes.mjs @@ -0,0 +1,81 @@ +/** + * ESM-Only Nylas SDK Example + * + * This example demonstrates how to use the Nylas Node.js SDK in a pure ESM + * (ECMAScript Modules) environment without CommonJS compatibility. + * + * Purpose: + * - Shows ESM import syntax with the Nylas SDK + * - Demonstrates environment variable handling in ESM + * - Provides a simple messages listing example + * + * Usage: + * 1. Copy the parent examples/.env.example to examples/.env + * 2. Fill in your NYLAS_API_KEY and NYLAS_GRANT_ID in the .env file + * 3. Run: node indes.mjs + * + * Requirements: + * - Node.js with ESM support (Node 14+) + * - Valid Nylas API credentials + * - A grant with message access permissions + */ + +import dotenv from 'dotenv'; +import path from 'node:path'; +import Nylas from 'nylas'; +import { logger, maskSecret } from '../utils/logger.mjs'; + +// Load from parent directory since this example lives in a subdirectory +dotenv.config({ path: path.resolve(import.meta.dirname, '../.env') }); + +// Fail fast if credentials are missing to provide clear error messages +const apiKey = process.env.NYLAS_API_KEY || ''; +if (!apiKey) { + throw new Error('NYLAS_API_KEY environment variable is not set'); +} + +const grantId = process.env.NYLAS_GRANT_ID || ''; +if (!grantId) { + throw new Error('NYLAS_GRANT_ID environment variable is not set'); +} + +// Initialize the Nylas client +const nylas = new Nylas({ + apiKey, + apiUri: process.env.NYLAS_API_URI || 'https://api.us.nylas.com' +}); + + +/** + * Main function to demonstrate basic Nylas SDK usage in ESM environment + */ +async function main() { + try { + logger.info('Listing messages...'); + + // Log runtime config for debugging without exposing sensitive data + logger.debug('Runtime config', { + apiKey: maskSecret(apiKey), + grantId, + apiUri: process.env.NYLAS_API_URI || 'https://api.us.nylas.com' + }); + + // Use basic list operation to verify SDK functionality and connectivity + const messages = await nylas.messages.list({ + identifier: grantId, + }); + + logger.success('Messages listed successfully'); + + // Extract only essential fields to avoid logging sensitive message content + logger.info('Message subjects and ids', messages.data.map(m => ({ id: m.id, subject: m.subject }))); + + } catch (error) { + logger.error('Failed to list messages'); + logger.debug('Error details', error); + // Exit with error code to indicate failure for automation/CI purposes + process.exit(1); + } +} + +main(); \ No newline at end of file diff --git a/examples/esm-only/package-lock.json b/examples/esm-only/package-lock.json new file mode 100644 index 00000000..dd04519c --- /dev/null +++ b/examples/esm-only/package-lock.json @@ -0,0 +1,70 @@ +{ + "name": "esm-only", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "esm-only", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "dotenv": "^17.2.2", + "nylas": "file:../../" + } + }, + "../..": { + "name": "nylas", + "version": "7.13.0", + "license": "MIT", + "dependencies": { + "change-case": "^4.1.2", + "form-data-encoder": "^4.1.0", + "formdata-node": "^6.0.3", + "mime-types": "^2.1.35", + "node-fetch": "^3.3.2", + "uuid": "^8.3.2" + }, + "devDependencies": { + "@babel/core": "^7.3.3", + "@types/jest": "^29.5.2", + "@types/mime-types": "^2.1.2", + "@types/node": "^22.15.21", + "@types/uuid": "^8.3.4", + "@typescript-eslint/eslint-plugin": "^2.25.0", + "@typescript-eslint/parser": "^2.25.0", + "eslint": "^5.14.0", + "eslint-config-prettier": "^4.0.0", + "eslint-plugin-custom-rules": "^0.0.0", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-prettier": "^3.0.1", + "jest": "^29.6.1", + "jest-fetch-mock": "^3.0.3", + "prettier": "^3.5.3", + "ts-jest": "^29.1.1", + "typedoc": "^0.28.4", + "typedoc-plugin-rename-defaults": "^0.7.3", + "typescript": "^5.8.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/dotenv": { + "version": "17.2.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.2.tgz", + "integrity": "sha512-Sf2LSQP+bOlhKWWyhFsn0UsfdK/kCWRv1iuA2gXAwt3dyNabr6QSj00I2V10pidqz69soatm9ZwZvpQMTIOd5Q==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/nylas": { + "resolved": "../..", + "link": true + } + } +} diff --git a/examples/esm-only/package.json b/examples/esm-only/package.json new file mode 100644 index 00000000..f94ea3bd --- /dev/null +++ b/examples/esm-only/package.json @@ -0,0 +1,16 @@ +{ + "name": "esm-only", + "version": "1.0.0", + "description": "An esm-only example of the Nylas NodeJS SDK usage", + "main": "index.js", + "type": "module", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "nylas": "file:../../", + "dotenv": "^17.2.2" + } +} diff --git a/examples/folders/README.md b/examples/folders/README.md new file mode 100644 index 00000000..240293a5 --- /dev/null +++ b/examples/folders/README.md @@ -0,0 +1,176 @@ +# Folders Example + +This example demonstrates how to use the Nylas Node.js SDK to work with folders. + +## Features Demonstrated + +- List all folders for a grant +- Use the `includeHiddenFolders` parameter (Microsoft only) to include hidden folders in the response +- Filter folders by parent/child relationship +- Display folder attributes and metadata + +## Setup + +1. Copy `.env.example` to `.env` in the examples directory +2. Add your Nylas API credentials and grant ID: + ``` + NYLAS_API_KEY=your_api_key_here + NYLAS_GRANT_ID=your_grant_id_here + NYLAS_API_URI=https://api.us.nylas.com # or your specific Nylas region + ``` + +## Running the Example + +```bash +npm install +npm run folders +``` + +Or run directly with ts-node: +```bash +npx ts-node folders.ts +``` + +## Microsoft-Specific Features + +The `includeHiddenFolders` parameter is specific to Microsoft accounts: + +```typescript +const foldersWithHidden = await nylas.folders.list({ + identifier: GRANT_ID, + queryParams: { + includeHiddenFolders: true, // Microsoft only - includes hidden folders + }, +}); +``` + +This parameter defaults to `false` and when set to `true`, includes folders that are typically hidden from the user interface, such as system folders used by Microsoft Exchange for internal operations. + +## Expected Output + +The example will output: +1. A list of all visible folders +2. A list of all folders including hidden ones (if using a Microsoft account) +3. A filtered list showing only parent folders with their metadata + +## Error Handling + +The example includes proper error handling and will display helpful error messages if: +- Environment variables are not set +- API requests fail +- Authentication issues occur +======= +# Nylas Folders API Examples + +This directory contains examples of how to use the Nylas Folders API with the Nylas Node.js SDK, including the new `singleLevel` query parameter. + +## What is the singleLevel Parameter? + +The `singleLevel` parameter is a new query parameter for the "list all folders" endpoint that controls folder hierarchy traversal: + +- **`singleLevel: true`** - Retrieves folders from a single-level hierarchy only (direct children) +- **`singleLevel: false`** - Retrieves folders across a multi-level hierarchy (all descendants, default behavior) +- **Microsoft accounts only** - This parameter is ignored for other providers + +## Examples + +- [folders.ts](./folders.ts) - A comprehensive example showing how to use the `singleLevel` parameter in various scenarios + +## Running the Examples + +To run these examples, you'll need to: + +1. Install dependencies from the examples directory: + ```bash + cd examples + npm install + ``` + +2. Copy the `.env.example` file to `.env` if you haven't already and add your credentials: + ```bash + cp .env.example .env + # Edit .env with your editor + ``` + +3. Edit the `.env` file to include: + - `NYLAS_API_KEY` - Your Nylas API key + - `NYLAS_API_URI` (optional) - The Nylas API server URI (defaults to "https://api.us.nylas.com") + - `NYLAS_GRANT_ID` - The Grant ID for a Microsoft account to see the `singleLevel` parameter in action + +4. Run the example: + ```bash + # From the examples directory + npx ts-node folders/folders.ts + + # Or if you add it to package.json scripts + npm run folders + ``` + +## Understanding the Example + +This example demonstrates: + +1. **Default Behavior**: Listing all folders with multi-level hierarchy (default) +2. **Single-Level Listing**: Using `singleLevel: true` to get only direct children +3. **Combined Parameters**: Using `singleLevel` with `parentId` to control the starting point +4. **Comparison**: Side-by-side comparison of single-level vs multi-level results +5. **Parameter Variations**: All possible combinations of the `singleLevel` parameter + +## Use Cases + +The `singleLevel` parameter is particularly useful when: + +- **Building UI Navigation**: You want to show only immediate child folders in a tree view +- **Performance Optimization**: Reducing the amount of data returned when you only need direct children +- **Hierarchical Processing**: Processing folder structures level by level rather than all at once +- **Microsoft-Specific Features**: Taking advantage of Microsoft's folder hierarchy capabilities + +## API Reference + +### ListFolderQueryParams Interface + +```typescript +interface ListFolderQueryParams extends ListQueryParams { + /** + * (Microsoft and EWS only.) Use the ID of a folder to find all child folders it contains. + */ + parentId?: string; + + /** + * (Microsoft only) If true, retrieves folders from a single-level hierarchy only. + * If false, retrieves folders across a multi-level hierarchy. + * @default false + */ + singleLevel?: boolean; +} +``` + +### Example Usage + +```typescript +import Nylas from 'nylas'; + +const nylas = new Nylas({ apiKey: 'your-api-key' }); + +// Get only direct children of a specific folder +const singleLevelFolders = await nylas.folders.list({ + identifier: 'grant-id', + queryParams: { + parentId: 'parent-folder-id', + singleLevel: true + } +}); + +// Get all descendants (default behavior) +const allFolders = await nylas.folders.list({ + identifier: 'grant-id', + queryParams: { + parentId: 'parent-folder-id', + singleLevel: false // or omit this parameter + } +}); +``` + +## Documentation + +For more information, see the [Nylas API Documentation](https://developer.nylas.com/). diff --git a/examples/folders/folders.ts b/examples/folders/folders.ts new file mode 100644 index 00000000..8a7ca062 --- /dev/null +++ b/examples/folders/folders.ts @@ -0,0 +1,93 @@ +import 'dotenv/config'; + +import Nylas from '../../src/nylas'; + +const GRANT_ID = process.env.NYLAS_GRANT_ID || ''; + +const nylas = new Nylas({ + apiKey: process.env.NYLAS_API_KEY || '', + apiUri: process.env.NYLAS_API_URI || 'https://api.us.nylas.com', +}); + +/** + * This example shows how to list folders using the Nylas Node.js SDK. + * + * For Microsoft accounts, you can use the includeHiddenFolders parameter + * to include hidden folders in the response. + */ +async function listFolders() { + try { + console.log('Listing all folders...\n'); + + // List all folders + const folders = await nylas.folders.list({ + identifier: GRANT_ID, + }); + + console.log('Found', folders.data.length, 'folders'); + + folders.data.forEach((folder, index) => { + console.log(`${index + 1}. ${folder.name} (ID: ${folder.id})`); + if (folder.parentId) { + console.log(` Parent ID: ${folder.parentId}`); + } + if (folder.attributes && folder.attributes.length > 0) { + console.log(` Attributes: ${folder.attributes.join(', ')}`); + } + console.log(''); + }); + + // For Microsoft accounts: List folders including hidden ones + console.log('\n--- Microsoft Only: Including Hidden Folders ---\n'); + + const foldersWithHidden = await nylas.folders.list({ + identifier: GRANT_ID, + queryParams: { + includeHiddenFolders: true, + }, + }); + + console.log( + 'Found', + foldersWithHidden.data.length, + 'folders (including hidden)' + ); + + // List only parent folders (no parentId) + console.log('\n--- Parent Folders Only ---\n'); + + const parentFoldersWithHidden = await nylas.folders.list({ + identifier: GRANT_ID, + queryParams: { + includeHiddenFolders: true, + }, + }); + + const parentFolders = parentFoldersWithHidden.data.filter( + (folder) => !folder.parentId + ); + console.log('Found', parentFolders.length, 'parent folders'); + + parentFolders.forEach((folder, index) => { + console.log(`${index + 1}. ${folder.name} (ID: ${folder.id})`); + if (folder.childCount) { + console.log(` Child folders: ${folder.childCount}`); + } + if (folder.totalCount) { + console.log(` Total items: ${folder.totalCount}`); + } + if (folder.unreadCount) { + console.log(` Unread items: ${folder.unreadCount}`); + } + console.log(''); + }); + } catch (error) { + console.error('Error listing folders:', error); + } +} + +if (!GRANT_ID) { + console.error('Please set NYLAS_GRANT_ID in your environment variables'); +} else { + listFolders().catch(console.error); +} diff --git a/examples/grants/README.md b/examples/grants/README.md new file mode 100644 index 00000000..9f2af0ac --- /dev/null +++ b/examples/grants/README.md @@ -0,0 +1,263 @@ +# Nylas Grants Examples + +This directory contains examples demonstrating how to work with grants using the Nylas Node.js SDK. Grants represent authenticated connections between your application and email/calendar providers like Gmail, Outlook, Yahoo, and others. + +## What are Grants? + +In the Nylas API, a **Grant** represents an authenticated connection to a user's email or calendar account. Each grant contains: + +- **Authentication details** - OAuth tokens and provider information +- **Scope permissions** - What data your app can access (email, calendar, contacts, etc.) +- **Account metadata** - Email address, provider type, creation/update timestamps +- **Status information** - Whether the grant is valid or needs re-authentication + +## Examples Overview + +The `grants.ts` file demonstrates comprehensive grant management including: + +### πŸ“‹ **Basic Operations** +- **List all grants** - Retrieve all authenticated accounts +- **Fetch specific grant** - Get detailed information about a single grant +- **Pagination** - Handle large numbers of grants efficiently + +### πŸ”„ **Sorting & Filtering** +- **Sort by creation date** - See newest or oldest grants first +- **Sort by update date** - Find recently modified grants +- **Filter by provider** - Show only Gmail, Outlook, etc. +- **Filter by status** - Find valid, invalid, or expired grants +- **Filter by date range** - Grants created in specific time periods + +### 🎯 **Advanced Features** +- **Multiple filters** - Combine provider, status, and date filters +- **Client-side grouping** - Organize grants by provider or other criteria +- **Scope analysis** - Find grants with specific permissions +- **Rate limit monitoring** - Track API usage limits + +## Quick Start + +### 1. Set up environment +Create a `.env` file in the `examples` directory: +```bash +NYLAS_API_KEY=your_api_key_here +NYLAS_API_URI=https://api.us.nylas.com # Optional: defaults to US API +``` + +### 2. Install dependencies +```bash +cd examples +npm install +``` + +### 3. Run the example +```bash +# Using ts-node (recommended for development) +npx ts-node grants/grants.ts + +# Or compile and run +npm run build +node dist/grants/grants.js +``` + +## Example Functions + +### Basic Listing +```typescript +// List all grants +const grants = await nylas.grants.list(); + +// List with pagination +const grants = await nylas.grants.list({ + queryParams: { + limit: 10, + offset: 0, + }, +}); +``` + +### Sorting +```typescript +// Sort by creation date (newest first) +const grants = await nylas.grants.list({ + queryParams: { + sortBy: 'created_at', + orderBy: 'desc', + }, +}); + +// Sort by update date (most recently updated first) +const grants = await nylas.grants.list({ + queryParams: { + sortBy: 'updated_at', + orderBy: 'desc', + }, +}); +``` + +### Filtering +```typescript +// Filter by provider +const gmailGrants = await nylas.grants.list({ + queryParams: { + provider: 'google', + }, +}); + +// Filter by status +const validGrants = await nylas.grants.list({ + queryParams: { + grantStatus: 'valid', + }, +}); + +// Filter by date range (last 30 days) +const thirtyDaysAgo = Math.floor((Date.now() - (30 * 24 * 60 * 60 * 1000)) / 1000); +const recentGrants = await nylas.grants.list({ + queryParams: { + since: thirtyDaysAgo, + }, +}); +``` + +### Fetching Individual Grants +```typescript +// Fetch a specific grant by ID +const grant = await nylas.grants.find({ + grantId: 'grant-id-here', +}); + +console.log(`Grant for ${grant.data.email} (${grant.data.provider})`); +console.log(`Scopes: ${grant.data.scope.join(', ')}`); +console.log(`Status: ${grant.data.grantStatus}`); +``` + +## Grant Object Properties + +Each grant object contains the following key properties: + +```typescript +interface Grant { + id: string; // Unique grant identifier + provider: string; // 'google', 'microsoft', 'yahoo', etc. + email?: string; // Associated email address + name?: string; // User's display name + grantStatus?: string; // 'valid', 'invalid', 'expired' + scope: string[]; // Permissions: ['email', 'calendar', 'contacts'] + createdAt: number; // Unix timestamp + updatedAt?: number; // Unix timestamp of last update + providerUserId?: string; // Provider's internal user ID + ip?: string; // IP address during authentication + userAgent?: string; // Browser/client used for auth + settings?: Record; // Provider-specific settings +} +``` + +## Available Query Parameters + +When listing grants, you can use these parameters: + +- **`limit`** (number) - Maximum results to return (default: 10, max: 200) +- **`offset`** (number) - Skip this many results for pagination +- **`sortBy`** - Sort field: `'created_at'` or `'updated_at'` +- **`orderBy`** - Sort direction: `'asc'` or `'desc'` +- **`since`** (number) - Unix timestamp to filter grants created after +- **`before`** (number) - Unix timestamp to filter grants created before +- **`email`** (string) - Filter by email address +- **`grantStatus`** (string) - Filter by status: `'valid'`, `'invalid'`, etc. +- **`ip`** (string) - Filter by IP address +- **`provider`** (string) - Filter by provider: `'google'`, `'microsoft'`, etc. + +## Common Use Cases + +### 1. **Health Check Dashboard** +```typescript +// Get overview of all grants and their status +const allGrants = await nylas.grants.list(); +const grantsByStatus = allGrants.data.reduce((acc, grant) => { + const status = grant.grantStatus || 'valid'; + acc[status] = (acc[status] || 0) + 1; + return acc; +}, {}); +console.log('Grant Status Overview:', grantsByStatus); +``` + +### 2. **Find Grants Needing Re-authentication** +```typescript +// Find invalid or expired grants +const invalidGrants = await nylas.grants.list({ + queryParams: { + grantStatus: 'invalid', + }, +}); +console.log(`${invalidGrants.data.length} grants need re-authentication`); +``` + +### 3. **Provider Distribution Analysis** +```typescript +// See which providers your users prefer +const grants = await nylas.grants.list(); +const providerCounts = grants.data.reduce((acc, grant) => { + acc[grant.provider] = (acc[grant.provider] || 0) + 1; + return acc; +}, {}); +console.log('Provider Distribution:', providerCounts); +``` + +### 4. **Recent Activity Monitoring** +```typescript +// Find grants created or updated in the last week +const weekAgo = Math.floor((Date.now() - (7 * 24 * 60 * 60 * 1000)) / 1000); +const recentActivity = await nylas.grants.list({ + queryParams: { + since: weekAgo, + sortBy: 'created_at', + orderBy: 'desc', + }, +}); +``` + +## Rate Limiting + +The Nylas API includes rate limiting. You can monitor your usage: + +```typescript +const response = await nylas.grants.list(); +if (response.rawHeaders) { + const limit = response.rawHeaders['x-rate-limit-limit']; + const remaining = response.rawHeaders['x-rate-limit-remaining']; + console.log(`Rate Limit: ${remaining}/${limit} requests remaining`); +} +``` + +## Error Handling + +Always wrap grant operations in try-catch blocks: + +```typescript +try { + const grants = await nylas.grants.list(); + // Process grants... +} catch (error) { + if (error.status === 401) { + console.error('Invalid API key'); + } else if (error.status === 429) { + console.error('Rate limit exceeded'); + } else { + console.error('Error listing grants:', error); + } +} +``` + +## Next Steps + +After exploring grants, you might want to: + +1. **Use grants to access data** - Use grant IDs to list messages, events, or contacts +2. **Monitor grant health** - Set up automated checks for invalid grants +3. **Implement re-authentication** - Handle expired grants gracefully +4. **Build user dashboards** - Show users their connected accounts + +## Related Documentation + +- [Nylas Authentication Guide](https://developer.nylas.com/docs/the-basics/authentication/) +- [Grant Management API](https://developer.nylas.com/docs/api/v3/admin/#tag--Grants) +- [OAuth Scopes Reference](https://developer.nylas.com/docs/the-basics/authentication/oauth-scopes/) diff --git a/examples/grants/grants.ts b/examples/grants/grants.ts new file mode 100644 index 00000000..8ef3c935 --- /dev/null +++ b/examples/grants/grants.ts @@ -0,0 +1,457 @@ +import Nylas from 'nylas'; +import dotenv from 'dotenv'; +import path from 'path'; +import { Grant } from 'nylas'; + +// Load environment variables from .env file +dotenv.config({ path: path.resolve(__dirname, '../.env') }); + +// Check for required environment variables +const apiKey: string = process.env.NYLAS_API_KEY || ''; + +if (!apiKey) { + throw new Error('NYLAS_API_KEY environment variable is not set'); +} + +// Initialize the Nylas client +const nylas = new Nylas({ + apiKey, + apiUri: process.env.NYLAS_API_URI || 'https://api.us.nylas.com', +}); + +/** + * Demonstrates how to list all grants with basic parameters + */ +async function listAllGrants(): Promise { + console.log('\n=== Listing All Grants ==='); + + try { + const grants = await nylas.grants.list(); + + console.log(`Found ${grants.data.length} grants`); + + if (grants.data.length > 0) { + console.log('\nGrant Summary:'); + grants.data.forEach((grant: Grant, index: number) => { + console.log(`${index + 1}. ID: ${grant.id}`); + console.log(` Provider: ${grant.provider}`); + console.log(` Email: ${grant.email || 'N/A'}`); + console.log(` Status: ${grant.grantStatus || 'N/A'}`); + console.log( + ` Created: ${new Date(grant.createdAt * 1000).toISOString()}` + ); + console.log( + ` Updated: ${grant.updatedAt ? new Date(grant.updatedAt * 1000).toISOString() : 'N/A'}` + ); + console.log(` Scopes: ${grant.scope.join(', ')}`); + console.log(''); + }); + } else { + console.log('No grants found'); + } + } catch (error) { + console.error('Error listing grants:', error); + throw error; + } +} + +/** + * Demonstrates how to list grants with pagination + */ +async function listGrantsWithPagination(): Promise { + console.log('\n=== Listing Grants with Pagination ==='); + + try { + const grants = await nylas.grants.list({ + queryParams: { + limit: 5, + offset: 0, + }, + }); + + console.log(`Retrieved ${grants.data.length} grants (limit: 5, offset: 0)`); + + grants.data.forEach((grant: Grant, index: number) => { + console.log( + `${index + 1}. ${grant.email || grant.id} (${grant.provider})` + ); + }); + + // Demonstrate accessing response metadata + console.log('\nResponse metadata:'); + console.log(`Request ID: ${grants.requestId}`); + + // Access rate limit headers if available + if (grants.rawHeaders) { + const rateLimit = grants.rawHeaders['x-rate-limit-limit']; + const rateLimitRemaining = grants.rawHeaders['x-rate-limit-remaining']; + if (rateLimit && rateLimitRemaining) { + console.log(`Rate Limit: ${rateLimitRemaining}/${rateLimit} remaining`); + } + } + } catch (error) { + console.error('Error listing grants with pagination:', error); + throw error; + } +} + +/** + * Demonstrates how to sort grants by creation date (newest first) + */ +async function listGrantsSortedByCreationDate(): Promise { + console.log( + '\n=== Listing Grants Sorted by Creation Date (Newest First) ===' + ); + + try { + const grants = await nylas.grants.list({ + queryParams: { + sortBy: 'created_at', + orderBy: 'desc', + limit: 10, + }, + }); + + console.log( + `Found ${grants.data.length} grants, sorted by creation date (newest first)` + ); + + grants.data.forEach((grant: Grant, index: number) => { + const createdDate = new Date(grant.createdAt * 1000); + console.log(`${index + 1}. ${grant.email || grant.id}`); + console.log(` Provider: ${grant.provider}`); + console.log( + ` Created: ${createdDate.toLocaleDateString()} ${createdDate.toLocaleTimeString()}` + ); + console.log(` Status: ${grant.grantStatus || 'Active'}`); + console.log(''); + }); + } catch (error) { + console.error('Error listing grants sorted by creation date:', error); + throw error; + } +} + +/** + * Demonstrates how to sort grants by last update date (most recently updated first) + */ +async function listGrantsSortedByUpdateDate(): Promise { + console.log( + '\n=== Listing Grants Sorted by Update Date (Most Recently Updated First) ===' + ); + + try { + const grants = await nylas.grants.list({ + queryParams: { + sortBy: 'updated_at', + orderBy: 'desc', + limit: 10, + }, + }); + + console.log( + `Found ${grants.data.length} grants, sorted by update date (most recently updated first)` + ); + + grants.data.forEach((grant: Grant, index: number) => { + const createdDate = new Date(grant.createdAt * 1000); + const updatedDate = grant.updatedAt + ? new Date(grant.updatedAt * 1000) + : null; + + console.log(`${index + 1}. ${grant.email || grant.id}`); + console.log(` Provider: ${grant.provider}`); + console.log( + ` Created: ${createdDate.toLocaleDateString()} ${createdDate.toLocaleTimeString()}` + ); + console.log( + ` Updated: ${updatedDate ? `${updatedDate.toLocaleDateString()} ${updatedDate.toLocaleTimeString()}` : 'Never'}` + ); + console.log(` Status: ${grant.grantStatus || 'Active'}`); + console.log(''); + }); + } catch (error) { + console.error('Error listing grants sorted by update date:', error); + throw error; + } +} + +/** + * Demonstrates how to filter grants by provider + */ +async function listGrantsByProvider( + provider: string = 'google' +): Promise { + console.log(`\n=== Listing Grants Filtered by Provider: ${provider} ===`); + + try { + const grants = await nylas.grants.list({ + queryParams: { + provider: provider as any, // Cast to satisfy TypeScript - provider accepts Provider enum + sortBy: 'created_at', + orderBy: 'desc', + }, + }); + + console.log(`Found ${grants.data.length} ${provider} grants`); + + if (grants.data.length > 0) { + grants.data.forEach((grant: Grant, index: number) => { + console.log(`${index + 1}. ${grant.email || grant.id}`); + console.log(` Scopes: ${grant.scope.join(', ')}`); + console.log(` Status: ${grant.grantStatus || 'Active'}`); + console.log( + ` Created: ${new Date(grant.createdAt * 1000).toLocaleDateString()}` + ); + console.log(''); + }); + } else { + console.log(`No ${provider} grants found`); + } + } catch (error) { + console.error(`Error listing ${provider} grants:`, error); + throw error; + } +} + +/** + * Demonstrates how to filter grants by status + */ +async function listGrantsByStatus(status: string = 'valid'): Promise { + console.log(`\n=== Listing Grants Filtered by Status: ${status} ===`); + + try { + const grants = await nylas.grants.list({ + queryParams: { + grantStatus: status, + sortBy: 'created_at', + orderBy: 'desc', + }, + }); + + console.log(`Found ${grants.data.length} grants with status: ${status}`); + + grants.data.forEach((grant: Grant, index: number) => { + console.log(`${index + 1}. ${grant.email || grant.id}`); + console.log(` Provider: ${grant.provider}`); + console.log(` Status: ${grant.grantStatus || 'Active'}`); + console.log( + ` Created: ${new Date(grant.createdAt * 1000).toLocaleDateString()}` + ); + console.log(''); + }); + } catch (error) { + console.error(`Error listing grants with status ${status}:`, error); + throw error; + } +} + +/** + * Demonstrates how to fetch a specific grant by ID + */ +async function fetchSpecificGrant(grantId?: string): Promise { + console.log('\n=== Fetching Specific Grant ==='); + + try { + // If no grant ID provided, get the first grant from the list + if (!grantId) { + console.log('No grant ID provided, fetching first available grant...'); + const grants = await nylas.grants.list({ queryParams: { limit: 1 } }); + + if (grants.data.length === 0) { + console.log('No grants available to fetch'); + return; + } + + grantId = grants.data[0].id; + console.log(`Using grant ID: ${grantId}`); + } + + const grant = await nylas.grants.find({ grantId }); + + console.log('\nGrant Details:'); + console.log(`ID: ${grant.data.id}`); + console.log(`Provider: ${grant.data.provider}`); + console.log(`Email: ${grant.data.email || 'N/A'}`); + console.log(`Name: ${grant.data.name || 'N/A'}`); + console.log(`Status: ${grant.data.grantStatus || 'Active'}`); + console.log(`Scopes: ${grant.data.scope.join(', ')}`); + console.log( + `Created: ${new Date(grant.data.createdAt * 1000).toISOString()}` + ); + console.log( + `Updated: ${grant.data.updatedAt ? new Date(grant.data.updatedAt * 1000).toISOString() : 'Never'}` + ); + console.log(`Provider User ID: ${grant.data.providerUserId || 'N/A'}`); + console.log(`IP Address: ${grant.data.ip || 'N/A'}`); + console.log(`User Agent: ${grant.data.userAgent || 'N/A'}`); + + if (grant.data.settings && Object.keys(grant.data.settings).length > 0) { + console.log('\nProvider Settings:'); + console.log(JSON.stringify(grant.data.settings, null, 2)); + } + + console.log(`\nRequest ID: ${grant.requestId}`); + } catch (error) { + console.error('Error fetching specific grant:', error); + throw error; + } +} + +/** + * Demonstrates how to filter grants by date range + */ +async function listGrantsByDateRange(): Promise { + console.log('\n=== Listing Grants by Date Range (Last 30 Days) ==='); + + try { + // Calculate timestamps for last 30 days + const thirtyDaysAgo = Math.floor( + (Date.now() - 30 * 24 * 60 * 60 * 1000) / 1000 + ); + const now = Math.floor(Date.now() / 1000); + + const grants = await nylas.grants.list({ + queryParams: { + since: thirtyDaysAgo, + before: now, + sortBy: 'created_at', + orderBy: 'desc', + }, + }); + + console.log( + `Found ${grants.data.length} grants created in the last 30 days` + ); + + grants.data.forEach((grant: Grant, index: number) => { + const createdDate = new Date(grant.createdAt * 1000); + const daysAgo = Math.floor( + (Date.now() - grant.createdAt * 1000) / (24 * 60 * 60 * 1000) + ); + + console.log(`${index + 1}. ${grant.email || grant.id}`); + console.log(` Provider: ${grant.provider}`); + console.log( + ` Created: ${createdDate.toLocaleDateString()} (${daysAgo} days ago)` + ); + console.log(` Status: ${grant.grantStatus || 'Active'}`); + console.log(''); + }); + } catch (error) { + console.error('Error listing grants by date range:', error); + throw error; + } +} + +/** + * Demonstrates advanced grant listing with multiple filters and custom sorting + */ +async function advancedGrantListing(): Promise { + console.log('\n=== Advanced Grant Listing with Multiple Filters ==='); + + try { + // Get all grants first to demonstrate client-side sorting/filtering + const allGrants = await nylas.grants.list({ + queryParams: { + sortBy: 'created_at', + orderBy: 'desc', + }, + }); + + console.log(`\nTotal grants: ${allGrants.data.length}`); + + // Group grants by provider + const grantsByProvider = allGrants.data.reduce( + (acc: Record, grant: Grant) => { + if (!acc[grant.provider]) { + acc[grant.provider] = []; + } + acc[grant.provider].push(grant); + return acc; + }, + {} + ); + + console.log('\nGrants by Provider:'); + Object.entries(grantsByProvider).forEach(([provider, grants]) => { + console.log(` ${provider}: ${grants.length} grants`); + }); + + // Find grants with specific scopes + const grantsWithCalendarScope = allGrants.data.filter((grant) => + grant.scope.some((scope) => scope.toLowerCase().includes('calendar')) + ); + + console.log( + `\nGrants with calendar scope: ${grantsWithCalendarScope.length}` + ); + + // Find recently updated grants (within last 7 days) + const sevenDaysAgo = Math.floor( + (Date.now() - 7 * 24 * 60 * 60 * 1000) / 1000 + ); + const recentlyUpdated = allGrants.data.filter( + (grant) => grant.updatedAt && grant.updatedAt > sevenDaysAgo + ); + + console.log(`\nGrants updated in last 7 days: ${recentlyUpdated.length}`); + + if (recentlyUpdated.length > 0) { + console.log('\nRecently Updated Grants:'); + recentlyUpdated.forEach((grant: Grant, index: number) => { + const updatedDate = new Date(grant.updatedAt! * 1000); + console.log( + ` ${index + 1}. ${grant.email || grant.id} - Updated: ${updatedDate.toLocaleDateString()}` + ); + }); + } + } catch (error) { + console.error('Error in advanced grant listing:', error); + throw error; + } +} + +/** + * Main function to run all examples + */ +async function main(): Promise { + console.log('πŸš€ Nylas Grants API Examples'); + console.log('============================='); + + try { + // Run all the example functions + await listAllGrants(); + await listGrantsWithPagination(); + await listGrantsSortedByCreationDate(); + await listGrantsSortedByUpdateDate(); + await listGrantsByProvider('google'); + await listGrantsByStatus('valid'); + await fetchSpecificGrant(); + await listGrantsByDateRange(); + await advancedGrantListing(); + + console.log('\nβœ… All examples completed successfully!'); + } catch (error) { + console.error('\n❌ Error running examples:', error); + process.exit(1); + } +} + +// Run the examples if this file is executed directly +if (require.main === module) { + main(); +} + +// Export functions for use in other files +export { + listAllGrants, + listGrantsWithPagination, + listGrantsSortedByCreationDate, + listGrantsSortedByUpdateDate, + listGrantsByProvider, + listGrantsByStatus, + fetchSpecificGrant, + listGrantsByDateRange, + advancedGrantListing, +}; diff --git a/examples/messages/.gitignore b/examples/messages/.gitignore new file mode 100644 index 00000000..fbf51c73 --- /dev/null +++ b/examples/messages/.gitignore @@ -0,0 +1 @@ +test-*.* \ No newline at end of file diff --git a/examples/messages/ENVIRONMENT.md b/examples/messages/ENVIRONMENT.md new file mode 100644 index 00000000..afd6f8ef --- /dev/null +++ b/examples/messages/ENVIRONMENT.md @@ -0,0 +1,45 @@ +# Environment Setup for Messages Example + +## Required Environment Variables + +Create a `.env` file in the `examples` directory with the following variables: + +```bash +# Required +NYLAS_API_KEY=your_api_key_here +NYLAS_GRANT_ID=your_grant_id_here + +# Optional +NYLAS_API_URI=https://api.us.nylas.com + +# For testing message sending (optional) +TEST_EMAIL=your-test-email@example.com +``` + +## Getting Your API Key and Grant ID + +1. **API Key**: Get your API key from the [Nylas Dashboard](https://dashboard.nylas.com) +2. **Grant ID**: After connecting an email account, you'll get a grant ID that represents that connection + +## Testing Message Sending + +If you want to test the message sending functionality, set the `TEST_EMAIL` environment variable to an email address you control. The example will skip message sending if this variable is not set. + +## Running the Example + +Once your environment variables are set: + +```bash +cd examples +npm install +npm run messages +``` + +## What the Example Demonstrates + +- **Message Fields**: Different ways to query messages with various field options +- **Tracking Options**: How tracking data appears in message responses +- **Raw MIME**: Getting raw MIME data for messages +- **Message Operations**: Listing, finding, updating, and sending messages +- **Scheduled Messages**: Working with scheduled message functionality +- **Message Cleaning**: Using the clean messages API \ No newline at end of file diff --git a/examples/messages/README.md b/examples/messages/README.md new file mode 100644 index 00000000..3dde23cf --- /dev/null +++ b/examples/messages/README.md @@ -0,0 +1,184 @@ +# Nylas Messages Examples + +This directory contains examples demonstrating how to work with messages using the Nylas Node.js SDK. + +## Examples + +### Send Attachments (`send-attachments-cli.ts`) +**🎯 Core attachment examples with optional CLI interface** + +This file demonstrates the four main ways to send attachments with the Nylas SDK: + +1. **File Path Attachments** - Most common and efficient approach +2. **Stream Attachments** - For more control over streams +3. **Buffer Attachments** - When you need to process content in memory +4. **String Content Attachments** - For dynamically generated text content + +The file is structured with: +- **Core examples at the top** - Focus on Nylas SDK integration +- **CLI interface at the bottom** - Optional interactive/batch modes + +### Basic Messages (`messages.ts`) +Shows basic message operations including reading, sending, and drafting messages. + +### Accessing Rate Limit Headers +All SDK responses now expose a non-enumerable `rawHeaders` with dashed lowercase keys so you can read rate limit information: + +```ts +const res = await nylas.messages.list({ identifier: process.env.NYLAS_GRANT_ID!, queryParams: { limit: 1 } }); +const limit = res.rawHeaders?.['x-rate-limit-limit']; +const remaining = res.rawHeaders?.['x-rate-limit-remaining']; +``` + +## Quick Start + +### 1. Set up environment +Create a `.env` file in the `examples` directory: +```bash +NYLAS_API_KEY=your_api_key_here +NYLAS_GRANT_ID=your_grant_id_here +TEST_EMAIL=recipient@example.com # Optional: for testing message sending +NYLAS_API_URI=https://api.us.nylas.com # Optional: defaults to US API +``` + +### 2. Install dependencies +```bash +cd examples +npm install +``` + +### 3. Ensure test files exist +The examples expect test files in the `attachments/` subdirectory: +- `test-small-26B.txt` (small text file) +- `test-image-19KB.jpg` (small image) +- `test-document-12MB.pdf` (large PDF) +- `test-image-10MB.jpg` (large image) + +### 4. Run the examples + +**Attachment examples (interactive mode):** +```bash +npm run send-attachments +``` + +**Attachment examples (batch mode):** +```bash +npm run send-attachments small --format file --email test@example.com +npm run send-attachments large --format stream --email test@example.com +``` + +**Basic messages:** +```bash +npm run messages +``` + +## Understanding Attachment Methods + +The core examples demonstrate four different approaches to sending attachments: + +### 1. File Path Method (Recommended) +```typescript +const attachment = createFileRequestBuilder('test-image.jpg'); +``` +- Most efficient and common approach +- Uses streams internally for memory efficiency +- Perfect for files on disk + +### 2. Stream Method +```typescript +const attachment = { + filename: 'file.jpg', + contentType: 'image/jpeg', + content: fs.createReadStream('path/to/file.jpg'), + size: fileSize +}; +``` +- Good when you already have a stream +- Useful for processing files from other sources +- Memory efficient for large files + +### 3. Buffer Method +```typescript +const attachment = { + filename: 'file.jpg', + contentType: 'image/jpeg', + content: fs.readFileSync('path/to/file.jpg'), + size: buffer.length +}; +``` +- Loads entire file into memory +- Good for small files or when you need to process content +- Simple but uses more memory + +### 4. String Content Method +```typescript +const attachment = { + filename: 'data.txt', + contentType: 'text/plain', + content: 'Your text content here', + size: Buffer.byteLength(content, 'utf8') +}; +``` +- Perfect for dynamically generated content +- Works for text files, JSON, XML, etc. +- Great for reports, logs, or generated data + +## File Structure + +``` +messages/ +β”œβ”€β”€ send-attachments-cli.ts # 🎯 Attachment examples + CLI tool +β”œβ”€β”€ utils/ +β”‚ └── attachment-file-manager.ts # File utilities (extracted for reusability) +β”œβ”€β”€ attachments/ # Test files directory +β”‚ β”œβ”€β”€ test-small-26B.txt +β”‚ β”œβ”€β”€ test-image-19KB.jpg +β”‚ β”œβ”€β”€ test-document-12MB.pdf +β”‚ └── test-image-10MB.jpg +β”œβ”€β”€ messages.ts # Basic message operations +└── README.md # This file +``` + +## CLI Tool Features + +The attachment examples include an optional CLI interface for easy testing: + +- **Interactive Mode**: Guided prompts for choosing examples +- **Batch Mode**: Non-interactive commands for automation +- **File Status Checking**: Verify test files are available +- **Multiple Formats**: Test all attachment processing methods + +**Interactive mode (default):** +```bash +npm run send-attachments +``` + +**Batch mode examples:** +```bash +npm run send-attachments small --format stream --email test@example.com +npm run send-attachments large --format buffer --email test@example.com +npm run send-attachments status # Check file availability +``` + +## Best Practices + +1. **Use file paths** for most cases - it's the most efficient method +2. **Use streams** when working with large files or when you already have streams +3. **Use buffers** for small files when you need to process the content +4. **Use strings** for dynamically generated text content +5. **Always handle errors** appropriately with try/catch blocks +6. **Check file existence** before creating attachments from file paths + +## Troubleshooting + +**"File not found" errors:** +- Ensure test files exist in the `attachments/` directory +- Run `npm run send-attachments-cli status` to check file availability + +**"Environment variable not set" errors:** +- Create a `.env` file in the `examples` directory with required variables +- See the environment setup section above + +**TypeScript import errors:** +- Ensure you've run `npm install` in the examples directory +- The utils are properly exported from the attachment-file-manager module \ No newline at end of file diff --git a/examples/messages/cli-interface.ts b/examples/messages/cli-interface.ts new file mode 100644 index 00000000..7dac24be --- /dev/null +++ b/examples/messages/cli-interface.ts @@ -0,0 +1,255 @@ +import chalk from 'chalk'; +import { Command } from 'commander'; +import inquirer from 'inquirer'; +import { Message, NylasApiError, NylasResponse } from 'nylas'; +import type { SendAttachmentsExamples } from './examples'; +import { FileFormat, TestFileManager } from './utils/attachment-file-manager'; + +interface CliOptions { + attachmentSize: 'small' | 'large'; + format: FileFormat; + testEmail?: string; + isPlaintext: boolean; +} + +async function getCliOptions( + fileManager: TestFileManager +): Promise { + console.log(chalk.blue.bold('\nπŸš€ Nylas Send Attachments Examples\n')); + + fileManager.checkFileStatus(); + + const smallFiles = fileManager.getSmallFiles(); + const largeFiles = fileManager.getLargeFiles(); + + if (smallFiles.length === 0 && largeFiles.length === 0) { + console.log( + chalk.red( + '\n❌ No test files found! Please create the required test files in attachments/' + ) + ); + process.exit(1); + } + + const answers = await inquirer.prompt([ + { + type: 'list', + name: 'format', + message: 'Which attachment method would you like to demonstrate?', + choices: [ + { name: 'πŸ“ File paths (recommended)', value: 'file' }, + { name: '🌊 Streams (advanced)', value: 'stream' }, + { name: 'πŸ’Ύ Buffers (small files)', value: 'buffer' }, + { name: 'πŸ“ String content (dynamic)', value: 'string' }, + ], + }, + { + type: 'list', + name: 'attachmentSize', + message: 'What size attachments?', + choices: [ + { + name: `πŸ“Ž Small (${smallFiles.length} available)`, + value: 'small', + disabled: smallFiles.length === 0, + }, + { + name: `πŸ“‹ Large (${largeFiles.length} available)`, + value: 'large', + disabled: largeFiles.length === 0, + }, + ], + }, + { + type: 'input', + name: 'testEmail', + message: 'Recipient email address:', + default: process.env.TEST_EMAIL || '', + validate: (input: string) => + input.includes('@') || 'Please enter a valid email address', + }, + { + type: 'confirm', + name: 'isPlaintext', + message: 'Send as plaintext (no HTML rendering)?', + default: false, + }, + ]); + + return answers as CliOptions; +} + +async function runExample( + examples: SendAttachmentsExamples, + fileManager: TestFileManager, + options: CliOptions +): Promise { + const { format, testEmail, attachmentSize, isPlaintext } = options; + + if (!testEmail) { + console.log(chalk.yellow('⚠️ No email provided. Skipping send.')); + return; + } + + try { + console.log( + chalk.blue( + `\nπŸ“€ Running ${format} attachment example (${attachmentSize} files)${isPlaintext ? ' in plaintext mode' : ''}...\n` + ) + ); + + let result: NylasResponse; + const isLarge = attachmentSize === 'large'; + + // Route to the appropriate example based on format + switch (format) { + case 'file': + result = await examples.sendFilePathAttachments( + fileManager, + testEmail, + isLarge, + isPlaintext + ); + break; + case 'stream': + result = await examples.sendStreamAttachments( + fileManager, + testEmail, + isLarge, + isPlaintext + ); + break; + case 'buffer': + result = await examples.sendBufferAttachments( + fileManager, + testEmail, + isLarge, + isPlaintext + ); + break; + case 'string': + result = await examples.sendStringAttachments( + fileManager, + testEmail, + isLarge, + isPlaintext + ); + break; + default: + result = await examples.sendAttachmentsByFormat( + fileManager, + format, + testEmail, + attachmentSize, + isPlaintext + ); + } + + console.log(chalk.green.bold('\nβœ… Message sent successfully!')); + console.log(chalk.green(`πŸ“§ Message ID: ${result.data.id}`)); + console.log( + chalk.green(`πŸ“Ž Attachments: ${result.data.attachments?.length || 0}`) + ); + } catch (error) { + console.log(chalk.red.bold('\n❌ Error sending message:')); + if (error instanceof NylasApiError) { + console.log(chalk.red(` ${error.message} (${error.statusCode})`)); + } else if (error instanceof Error) { + console.log(chalk.red(` ${error.message}`)); + } + } +} + +async function runBatchMode( + examples: SendAttachmentsExamples, + fileManager: TestFileManager, + size: 'small' | 'large', + format: FileFormat, + email?: string, + isPlaintext: boolean = false +): Promise { + const options: CliOptions = { + attachmentSize: size, + format, + testEmail: email, + isPlaintext, + }; + + console.log(chalk.blue.bold('\nπŸš€ Nylas Send Attachments (Batch Mode)\n')); + fileManager.checkFileStatus(); + + await runExample(examples, fileManager, options); +} + +export async function startCli( + examples: SendAttachmentsExamples, + fileManager: TestFileManager, + testEmail: string +): Promise { + const program = new Command(); + + program + .name('send-attachments') + .description('Nylas SDK attachment examples') + .version('1.0.0'); + + program + .command('interactive', { isDefault: true }) + .description('Run interactive examples') + .action(async () => { + const options = await getCliOptions(fileManager); + await runExample(examples, fileManager, options); + }); + + program + .command('small') + .description('Send small attachments') + .option( + '-f, --format ', + 'format (file|stream|buffer|string)', + 'file' + ) + .option('-e, --email ', 'recipient email') + .option('--plaintext', 'send as plaintext', false) + .action(async (options) => { + await runBatchMode( + examples, + fileManager, + 'small', + options.format as FileFormat, + options.email || testEmail, + Boolean(options.plaintext) + ); + }); + + program + .command('large') + .description('Send large attachment') + .option( + '-f, --format ', + 'format (file|stream|buffer|string)', + 'file' + ) + .option('-e, --email ', 'recipient email') + .option('--plaintext', 'send as plaintext', false) + .action(async (options) => { + await runBatchMode( + examples, + fileManager, + 'large', + options.format as FileFormat, + options.email || testEmail, + Boolean(options.plaintext) + ); + }); + + program + .command('status') + .description('Check test files') + .action(() => { + console.log(chalk.blue.bold('\nπŸ“ Test Files Status\n')); + fileManager.checkFileStatus(); + }); + + await program.parseAsync(); +} diff --git a/examples/messages/examples/buffer-attachments.ts b/examples/messages/examples/buffer-attachments.ts new file mode 100644 index 00000000..2e87b682 --- /dev/null +++ b/examples/messages/examples/buffer-attachments.ts @@ -0,0 +1,75 @@ +import * as dotenv from 'dotenv'; +import Nylas, { NylasResponse, Message, SendMessageRequest } from 'nylas'; +import * as path from 'path'; +import * as process from 'process'; +import { TestFileManager } from '../utils/attachment-file-manager'; + +// Load environment variables from .env file +dotenv.config({ path: path.resolve(__dirname, '../../.env') }); + +// Initialize the Nylas client +const nylas = new Nylas({ + apiKey: process.env.NYLAS_API_KEY || '', + apiUri: process.env.NYLAS_API_URI || 'https://api.us.nylas.com', +}); + +const grantId: string = process.env.NYLAS_GRANT_ID || ''; + +/** + * Example 3: Buffer Attachments (For Small Files) + * + * Loads the entire file into memory as a Buffer. + * Good for small files or when you need to process content. + */ +export async function sendBufferAttachments( + fileManager: TestFileManager, + recipientEmail: string, + large: boolean = false, + isPlaintext: boolean = false +): Promise> { + console.log('πŸ’Ύ Sending attachments using buffers...'); + + let sizeDescription; + + let files; + if (large) { + // Send one large attachment + files = [fileManager.getLargeFiles()[0]]; + sizeDescription = 'large'; + } else { + // Send multiple small attachments + files = fileManager.getSmallFiles().slice(0, 2); + sizeDescription = 'small'; + } + + // Create attachment using a buffer and use file info for name/type + const bufferAttachments = files.map((file) => ({ + filename: file.filename, + contentType: file.contentType, + content: file.asBuffer(), + size: file.size, + })); + + const requestBody: SendMessageRequest = { + to: [{ name: 'Test Recipient', email: recipientEmail }], + subject: 'Nylas SDK - Buffer Attachments', + body: isPlaintext + ? 'Buffer Attachments Example\nThis demonstrates sending attachments using Node.js Buffer objects.' + : ` +

Buffer Attachments Example

+

This demonstrates sending attachments using Node.js Buffer objects.

+

Good for small files when you need the content in memory.

+ `, + attachments: bufferAttachments, + isPlaintext, + }; + + // For large files, use a longer timeout (5 minutes) + const overrides = large ? { timeout: 300 } : undefined; + + return await nylas.messages.send({ + identifier: grantId, + requestBody, + overrides, + }); +} diff --git a/examples/messages/examples/file-path-attachments.ts b/examples/messages/examples/file-path-attachments.ts new file mode 100644 index 00000000..abb9a534 --- /dev/null +++ b/examples/messages/examples/file-path-attachments.ts @@ -0,0 +1,73 @@ +import * as dotenv from 'dotenv'; +import Nylas, { NylasResponse, Message, SendMessageRequest } from 'nylas'; +import * as path from 'path'; +import * as process from 'process'; +import { + createFileRequestBuilder, + TestFileManager, +} from '../utils/attachment-file-manager'; + +// Load environment variables from .env file +dotenv.config({ path: path.resolve(__dirname, '../../.env') }); + +// Initialize the Nylas client +const nylas = new Nylas({ + apiKey: process.env.NYLAS_API_KEY || '', + apiUri: process.env.NYLAS_API_URI || 'https://api.us.nylas.com', +}); + +const grantId: string = process.env.NYLAS_GRANT_ID || ''; + +/** + * Example 1: File Path Attachments (Most Common & Efficient) + * + * This is the recommended approach for most use cases. + * Uses streams internally for memory efficiency. + */ +export async function sendFilePathAttachments( + fileManager: TestFileManager, + recipientEmail: string, + large: boolean = false, + isPlaintext: boolean = false +): Promise> { + console.log('πŸ“ Sending attachments using file paths...'); + + let attachments; + let sizeDescription; + + if (large) { + // Send one large attachment + const file = fileManager.getLargeFiles()[0]; + attachments = [createFileRequestBuilder(file.path)]; + sizeDescription = 'large'; + } else { + // Send multiple small attachments + const files = fileManager.getSmallFiles().slice(0, 2); + attachments = files.map((file) => createFileRequestBuilder(file.path)); + sizeDescription = 'small'; + } + + const requestBody: SendMessageRequest = { + to: [{ name: 'Test Recipient', email: recipientEmail }], + subject: `Nylas SDK - File Path Attachments (${sizeDescription})`, + body: isPlaintext + ? `File Path Attachments Example\nThis demonstrates sending attachments using file paths.\nAttachment size: ${sizeDescription} (${attachments.length} file${attachments.length > 1 ? 's' : ''})` + : ` +

File Path Attachments Example

+

This demonstrates the most common way to send attachments using file paths.

+

The SDK uses streams internally for memory efficiency.

+

Attachment size: ${sizeDescription} (${attachments.length} file${attachments.length > 1 ? 's' : ''})

+ `, + attachments, + isPlaintext, + }; + + // For large files, use a longer timeout (5 minutes) + const overrides = large ? { timeout: 300 } : undefined; + + return await nylas.messages.send({ + identifier: grantId, + requestBody, + overrides, + }); +} diff --git a/examples/messages/examples/flexible-attachments.ts b/examples/messages/examples/flexible-attachments.ts new file mode 100644 index 00000000..a3cf8893 --- /dev/null +++ b/examples/messages/examples/flexible-attachments.ts @@ -0,0 +1,79 @@ +import * as dotenv from 'dotenv'; +import Nylas, { + NylasResponse, + Message, + SendMessageRequest, + CreateAttachmentRequest, +} from 'nylas'; +import * as path from 'path'; +import * as process from 'process'; +import { TestFileManager, FileFormat } from '../utils/attachment-file-manager'; + +// Load environment variables from .env file +dotenv.config({ path: path.resolve(__dirname, '../../.env') }); + +// Initialize the Nylas client +const nylas = new Nylas({ + apiKey: process.env.NYLAS_API_KEY || '', + apiUri: process.env.NYLAS_API_URI || 'https://api.us.nylas.com', +}); + +const grantId: string = process.env.NYLAS_GRANT_ID || ''; + +/** + * Flexible attachment sending based on format choice + */ +export async function sendAttachmentsByFormat( + fileManager: TestFileManager, + format: FileFormat, + recipientEmail: string, + attachmentSize: 'small' | 'large' = 'small', + isPlaintext: boolean = false +): Promise> { + let attachments: CreateAttachmentRequest[] = []; + let subject: string; + + if (attachmentSize === 'small') { + // Send two small attachments + const files = fileManager.getSmallFiles().slice(0, 2); + for (const file of files) { + attachments.push( + fileManager.createAttachmentRequest(file.filename, format) + ); + } + subject = `Nylas SDK - Small Attachments (${format} format)`; + } else { + // Send one large attachment + const file = fileManager.getLargeFiles()[0]; + attachments.push( + fileManager.createAttachmentRequest(file.filename, format) + ); + subject = `Nylas SDK - Large Attachment (${format} format)`; + } + + const requestBody: SendMessageRequest = { + to: [{ name: 'Test Recipient', email: recipientEmail }], + subject, + body: isPlaintext + ? `Attachment Format Test: ${format}\nThis message demonstrates sending attachments using the ${format} format.\nFiles attached: ${attachments.length}` + : ` +

Attachment Format Test: ${format}

+

This message demonstrates sending attachments using the ${format} format.

+

Files attached: ${attachments.length}

+
    + ${attachments.map((att) => `
  • ${att.filename} (${att.size} bytes)
  • `).join('')} +
+ `, + attachments, + isPlaintext, + }; + + // For large files, use a longer timeout (5 minutes) + const overrides = attachmentSize === 'large' ? { timeout: 300 } : undefined; + + return await nylas.messages.send({ + identifier: grantId, + requestBody, + overrides, + }); +} diff --git a/examples/messages/examples/index.ts b/examples/messages/examples/index.ts new file mode 100644 index 00000000..96ff842a --- /dev/null +++ b/examples/messages/examples/index.ts @@ -0,0 +1,39 @@ +import { sendFilePathAttachments } from './file-path-attachments'; +import { sendStreamAttachments } from './stream-attachments'; +import { sendBufferAttachments } from './buffer-attachments'; +import { sendStringAttachments } from './string-attachments'; +import { sendAttachmentsByFormat } from './flexible-attachments'; + +export type SendAttachmentsExamples = { + sendFilePathAttachments: ( + fileManager: Parameters[0], + recipientEmail: string, + large?: boolean, + isPlaintext?: boolean + ) => ReturnType; + sendStreamAttachments: ( + fileManager: Parameters[0], + recipientEmail: string, + large?: boolean, + isPlaintext?: boolean + ) => ReturnType; + sendBufferAttachments: ( + fileManager: Parameters[0], + recipientEmail: string, + large?: boolean, + isPlaintext?: boolean + ) => ReturnType; + sendStringAttachments: ( + fileManager: Parameters[0], + recipientEmail: string, + large?: boolean, + isPlaintext?: boolean + ) => ReturnType; + sendAttachmentsByFormat: ( + fileManager: Parameters[0], + format: Parameters[1], + recipientEmail: string, + attachmentSize?: Parameters[3], + isPlaintext?: boolean + ) => ReturnType; +}; diff --git a/examples/messages/examples/stream-attachments.ts b/examples/messages/examples/stream-attachments.ts new file mode 100644 index 00000000..a1436673 --- /dev/null +++ b/examples/messages/examples/stream-attachments.ts @@ -0,0 +1,87 @@ +import * as dotenv from 'dotenv'; +import Nylas, { + NylasResponse, + Message, + SendMessageRequest, + CreateAttachmentRequest, +} from 'nylas'; +import * as path from 'path'; +import * as process from 'process'; +import { TestFileManager } from '../utils/attachment-file-manager'; + +// Load environment variables from .env file +dotenv.config({ path: path.resolve(__dirname, '../../.env') }); + +// Initialize the Nylas client +const nylas = new Nylas({ + apiKey: process.env.NYLAS_API_KEY || '', + apiUri: process.env.NYLAS_API_URI || 'https://api.us.nylas.com', +}); + +const grantId: string = process.env.NYLAS_GRANT_ID || ''; + +/** + * Example 2: Stream Attachments (For More Control) + * + * Useful when you're working with streams from other sources + * or need more control over the stream processing. + */ +export async function sendStreamAttachments( + fileManager: TestFileManager, + recipientEmail: string, + large: boolean = false, + isPlaintext: boolean = false +): Promise> { + console.log('🌊 Sending attachments using streams...'); + + let attachments: CreateAttachmentRequest[] = []; + let sizeDescription; + + if (large) { + // Send one large attachment + const file = fileManager.getLargeFiles()[0]; + attachments = [ + { + filename: file.filename, + contentType: file.contentType, + content: file.asStream(), + size: file.size, + }, + ]; + sizeDescription = 'large'; + } else { + // Send multiple small attachments + const files = fileManager.getSmallFiles().slice(0, 2); + attachments = files.map((file) => ({ + filename: file.filename, + contentType: file.contentType, + content: file.asStream(), + size: file.size, + })); + sizeDescription = 'small'; + } + + const requestBody: SendMessageRequest = { + to: [{ name: 'Test Recipient', email: recipientEmail }], + subject: `Nylas SDK - Stream Attachments (${sizeDescription})`, + body: isPlaintext + ? `Stream Attachments Example\nThis demonstrates sending attachments using readable streams.\nAttachment size: ${sizeDescription} (${attachments.length} file${attachments.length > 1 ? 's' : ''})` + : ` +

Stream Attachments Example

+

This demonstrates sending attachments using readable streams.

+

Useful when you have streams from other sources.

+

Attachment size: ${sizeDescription} (${attachments.length} file${attachments.length > 1 ? 's' : ''})

+ `, + attachments, + isPlaintext, + }; + + // For large files, use a longer timeout (5 minutes) + const overrides = large ? { timeout: 300 } : undefined; + + return await nylas.messages.send({ + identifier: grantId, + requestBody, + overrides, + }); +} diff --git a/examples/messages/examples/string-attachments.ts b/examples/messages/examples/string-attachments.ts new file mode 100644 index 00000000..932fb909 --- /dev/null +++ b/examples/messages/examples/string-attachments.ts @@ -0,0 +1,116 @@ +import * as dotenv from 'dotenv'; +import Nylas, { + NylasResponse, + Message, + SendMessageRequest, + CreateAttachmentRequest, +} from 'nylas'; +import { TestFileManager } from '../utils/attachment-file-manager'; +import * as path from 'path'; +import * as process from 'process'; + +// Load environment variables from .env file +dotenv.config({ path: path.resolve(__dirname, '../../.env') }); + +// Initialize the Nylas client +const nylas = new Nylas({ + apiKey: process.env.NYLAS_API_KEY || '', + apiUri: process.env.NYLAS_API_URI || 'https://api.us.nylas.com', +}); + +const grantId: string = process.env.NYLAS_GRANT_ID || ''; + +/** + * Example 4: String Content Attachments (Base64 Encoded Files) + * + * Perfect for sending existing files as base64 encoded strings. + * This example pulls the same files used by other examples but encodes them as base64 strings. + */ +export async function sendStringAttachments( + fileManager: TestFileManager, + recipientEmail: string, + large: boolean = false, + isPlaintext: boolean = false +): Promise> { + console.log('πŸ“ Sending base64 encoded file attachments as strings...'); + + let stringAttachments: CreateAttachmentRequest[] = []; + let sizeDescription = ''; + + if (large) { + // Send one large attachment - use the large PDF file + const largeFiles = fileManager.getLargeFiles(); + if (largeFiles.length > 0) { + const file = + largeFiles.find((f) => f.filename.includes('pdf')) || largeFiles[0]; + const fileBuffer = file.asBuffer(); + const base64Content = fileBuffer.toString('base64'); + + stringAttachments = [ + { + filename: file.filename, + contentType: file.contentType, + content: base64Content, + size: Buffer.byteLength(base64Content, 'utf8'), + }, + ]; + sizeDescription = 'large'; + } else { + throw new Error('No large files available for testing'); + } + } else { + // Send multiple small attachments - use text file and image file + const smallFiles = fileManager.getSmallFiles(); + if (smallFiles.length >= 2) { + // Get the text file and image file + const textFile = + smallFiles.find((f) => f.filename.includes('.txt')) || smallFiles[0]; + const imageFile = + smallFiles.find((f) => f.filename.includes('.jpg')) || smallFiles[1]; + + const files = [textFile, imageFile]; + + stringAttachments = files.map((file) => { + const fileBuffer = file.asBuffer(); + const base64Content = fileBuffer.toString('base64'); + + return { + filename: file.filename, + contentType: file.contentType, + content: base64Content, + size: Buffer.byteLength(base64Content, 'utf8'), + }; + }); + sizeDescription = 'small'; + } else { + throw new Error('Not enough small files available for testing'); + } + } + + const requestBody: SendMessageRequest = { + to: [{ name: 'Test Recipient', email: recipientEmail }], + subject: `Nylas SDK - Base64 String Attachments (${sizeDescription})`, + body: isPlaintext + ? `Base64 String Attachments Example\nThis demonstrates sending existing files as base64 encoded strings.\nAttachment size: ${sizeDescription} (${stringAttachments.length} file${stringAttachments.length > 1 ? 's' : ''})` + : ` +

Base64 String Attachments Example

+

This demonstrates sending existing files as base64 encoded strings.

+

Files are converted from the same test files used in other examples.

+

Attachment size: ${sizeDescription} (${stringAttachments.length} file${stringAttachments.length > 1 ? 's' : ''})

+
    + ${stringAttachments.map((att) => `
  • ${att.filename} (${att.size} bytes base64 encoded)
  • `).join('')} +
+ `, + attachments: stringAttachments, + isPlaintext, + }; + + // For large files, use a longer timeout (5 minutes) + const overrides = large ? { timeout: 300 } : undefined; + + return await nylas.messages.send({ + identifier: grantId, + requestBody, + overrides, + }); +} diff --git a/examples/messages/messages.ts b/examples/messages/messages.ts new file mode 100644 index 00000000..f1f6c946 --- /dev/null +++ b/examples/messages/messages.ts @@ -0,0 +1,610 @@ +import * as dotenv from 'dotenv'; +import Nylas, { + CleanMessagesRequest, + Message, + MessageFields, + NylasApiError, + NylasResponse, + SendMessageRequest, + UpdateMessageRequest, +} from 'nylas'; +import * as path from 'path'; +import * as process from 'process'; + +// Load environment variables from .env file +dotenv.config({ path: path.resolve(__dirname, '../.env') }); + +// Check for required environment variables +const apiKey: string = process.env.NYLAS_API_KEY || ''; +const grantId: string = process.env.NYLAS_GRANT_ID || ''; + +if (!apiKey) { + throw new Error('NYLAS_API_KEY environment variable is not set'); +} +if (!grantId) { + throw new Error('NYLAS_GRANT_ID environment variable is not set'); +} + +// Initialize the Nylas client +const nylas = new Nylas({ + apiKey, + apiUri: process.env.NYLAS_API_URI || 'https://api.us.nylas.com', +}); + +/** + * Demonstrates listing messages with different field options + */ +async function demonstrateMessageFields(): Promise { + console.log('\n=== Demonstrating Message Fields ==='); + + try { + // 1. List messages with standard fields + console.log('\n--- Listing messages with standard fields ---'); + const standardMessages = await nylas.messages.list({ + identifier: grantId, + queryParams: { + fields: MessageFields.STANDARD, + limit: 2, + }, + }); + + console.log( + `Found ${standardMessages.data.length} messages with standard fields` + ); + for (const message of standardMessages.data) { + console.log(`- ${message.id}: ${message.subject || '(no subject)'}`); + console.log( + ` From: ${message.from?.map((f) => `${f.name} <${f.email}>`).join(', ') || 'Unknown'}` + ); + console.log( + ` Tracking Options: ${message.trackingOptions ? 'Present' : 'Not present'}` + ); + console.log(` Headers: ${message.headers ? 'Present' : 'Not present'}`); + console.log(` Raw MIME: ${message.rawMime ? 'Present' : 'Not present'}`); + } + + // 2. List messages with tracking options + console.log('\n--- Listing messages with tracking options ---'); + const trackingMessages = await nylas.messages.list({ + identifier: grantId, + queryParams: { + fields: MessageFields.INCLUDE_TRACKING_OPTIONS, + limit: 2, + }, + }); + + console.log( + `Found ${trackingMessages.data.length} messages with tracking options` + ); + for (const message of trackingMessages.data) { + console.log(`- ${message.id}: ${message.subject || '(no subject)'}`); + if (message.trackingOptions) { + console.log(` Tracking Options:`); + console.log(` Opens: ${message.trackingOptions.opens}`); + console.log( + ` Thread Replies: ${message.trackingOptions.threadReplies}` + ); + console.log(` Links: ${message.trackingOptions.links}`); + console.log(` Label: ${message.trackingOptions.label}`); + } else { + console.log(` No tracking options available`); + } + } + + // 3. List messages with headers + console.log('\n--- Listing messages with headers ---'); + const headerMessages = await nylas.messages.list({ + identifier: grantId, + queryParams: { + fields: MessageFields.INCLUDE_HEADERS, + limit: 2, + }, + }); + + console.log(`Found ${headerMessages.data.length} messages with headers`); + for (const message of headerMessages.data) { + console.log(`- ${message.id}: ${message.subject || '(no subject)'}`); + if (message.headers && message.headers.length > 0) { + console.log(` Headers (showing first 3):`); + message.headers.slice(0, 3).forEach((header) => { + console.log( + ` ${header.name}: ${header.value.substring(0, 100)}${header.value.length > 100 ? '...' : ''}` + ); + }); + if (message.headers.length > 3) { + console.log(` ... and ${message.headers.length - 3} more headers`); + } + } else { + console.log(` No headers available`); + } + } + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`Error demonstrating message fields: ${error.message}`); + console.error(`Error details: ${JSON.stringify(error, null, 2)}`); + } else if (error instanceof Error) { + console.error( + `Unexpected error in demonstrateMessageFields: ${error.message}` + ); + } + throw error; + } +} + +/** + * Demonstrates getting raw MIME data for a message + */ +async function demonstrateRawMime(): Promise { + console.log('\n=== Demonstrating Raw MIME Data ==='); + + try { + // First, get a message ID + const messages = await nylas.messages.list({ + identifier: grantId, + queryParams: { + limit: 1, + }, + }); + + if (messages.data.length === 0) { + console.log('No messages available to demonstrate raw MIME'); + return; + } + + const messageId = messages.data[0].id; + console.log(`Getting raw MIME data for message: ${messageId}`); + + // Get the message with raw MIME data + const rawMessage = await nylas.messages.find({ + identifier: grantId, + messageId, + queryParams: { + fields: MessageFields.RAW_MIME, + }, + }); + + console.log('Raw MIME Response:'); + console.log(`- ID: ${rawMessage.data.id}`); + console.log(`- Grant ID: ${rawMessage.data.grantId}`); + console.log(`- Object: ${rawMessage.data.object}`); + + if (rawMessage.data.rawMime) { + console.log( + `- Raw MIME Data: ${rawMessage.data.rawMime.substring(0, 100)}... (truncated)` + ); + console.log( + `- Raw MIME Length: ${rawMessage.data.rawMime.length} characters` + ); + + // Note: When requesting raw_mime, only grant_id, object, id, and raw_mime fields are returned + console.log( + '\nNote: When requesting raw_mime, only specific fields are returned:' + ); + console.log(`- Subject: ${rawMessage.data.subject || 'Not included'}`); + console.log( + `- Body: ${rawMessage.data.body ? 'Present' : 'Not included'}` + ); + console.log( + `- From: ${rawMessage.data.from ? 'Present' : 'Not included'}` + ); + } else { + console.log('- Raw MIME Data: Not available'); + } + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`Error demonstrating raw MIME: ${error.message}`); + } else if (error instanceof Error) { + console.error(`Unexpected error in demonstrateRawMime: ${error.message}`); + } + throw error; + } +} + +/** + * Demonstrates sending a message with tracking enabled + */ +async function demonstrateMessageSending(): Promise | null> { + console.log('\n=== Demonstrating Message Sending ==='); + + try { + const testEmail = process.env.TEST_EMAIL; + if (!testEmail) { + console.log( + 'TEST_EMAIL environment variable not set. Skipping message sending demo.' + ); + console.log( + 'Set TEST_EMAIL=your-email@example.com to test message sending.' + ); + return null; + } + + console.log(`Sending test message to: ${testEmail}`); + + const requestBody: SendMessageRequest = { + to: [ + { + name: 'Test Recipient', + email: testEmail, + }, + ], + subject: 'Nylas SDK Messages Example - Testing New Features', + body: ` + + +

Nylas SDK Messages Example

+

This message demonstrates the new tracking features in the Nylas Node.js SDK.

+

Features being tested:

+
    +
  • Message tracking options
  • +
  • Raw MIME data support
  • +
  • Enhanced field querying
  • +
+

Visit Nylas Developer Docs for more information.

+

Best regards,
The Nylas SDK Team

+ + + `, + // Note: Tracking options are configured at the API/provider level, not in the request + }; + + console.log('Sending message with tracking...'); + const sentMessage = await nylas.messages.send({ + identifier: grantId, + requestBody, + }); + + console.log(`Message sent successfully!`); + console.log(`- Message ID: ${sentMessage.data.id}`); + console.log(`- Subject: ${sentMessage.data.subject}`); + console.log( + `- To: ${sentMessage.data.to?.map((t) => `${t.name} <${t.email}>`).join(', ')}` + ); + + return sentMessage; + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`Error sending message: ${error.message}`); + console.error(`Error details: ${JSON.stringify(error, null, 2)}`); + } else if (error instanceof Error) { + console.error( + `Unexpected error in demonstrateMessageSending: ${error.message}` + ); + } + return null; + } +} + +/** + * Demonstrates sending a plaintext-only message (no attachments) + */ +async function demonstratePlaintextMessageSending(): Promise | null> { + console.log('\n=== Demonstrating Plaintext Message Sending ==='); + try { + const testEmail = process.env.TEST_EMAIL; + if (!testEmail) { + console.log( + 'TEST_EMAIL environment variable not set. Skipping plaintext message sending demo.' + ); + return null; + } + + const requestBody: SendMessageRequest = { + to: [{ name: 'Plaintext Recipient', email: testEmail }], + subject: 'Nylas SDK Messages Example - Plaintext', + body: 'This message is sent as plain text only.', + isPlaintext: true, + }; + + const sentMessage = await nylas.messages.send({ + identifier: grantId, + requestBody, + }); + + console.log('Plaintext message sent successfully!'); + console.log(`- Message ID: ${sentMessage.data.id}`); + console.log(`- Subject: ${sentMessage.data.subject}`); + console.log( + `- To: ${sentMessage.data.to?.map((t) => `${t.name} <${t.email}>`).join(', ')}` + ); + + return sentMessage; + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`Error sending plaintext message: ${error.message}`); + console.error(`Error details: ${JSON.stringify(error, null, 2)}`); + } else if (error instanceof Error) { + console.error( + `Unexpected error in demonstratePlaintextMessageSending: ${error.message}` + ); + } + return null; + } +} + +/** + * Demonstrates updating a message + */ +async function demonstrateMessageUpdate(messageId: string): Promise { + console.log('\n=== Demonstrating Message Update ==='); + + try { + console.log(`Updating message: ${messageId}`); + + const updateRequest: UpdateMessageRequest = { + starred: true, + unread: false, + metadata: { + example_type: 'sdk_demo', + feature_test: 'tracking_and_mime', + updated_at: new Date().toISOString(), + status: 'processed', + }, + }; + + const updatedMessage = await nylas.messages.update({ + identifier: grantId, + messageId, + requestBody: updateRequest, + }); + + console.log('Message updated successfully!'); + console.log(`- Message ID: ${updatedMessage.data.id}`); + console.log(`- Starred: ${updatedMessage.data.starred}`); + console.log(`- Unread: ${updatedMessage.data.unread}`); + console.log( + `- Metadata: ${JSON.stringify(updatedMessage.data.metadata, null, 2)}` + ); + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`Error updating message: ${error.message}`); + } else if (error instanceof Error) { + console.error( + `Unexpected error in demonstrateMessageUpdate: ${error.message}` + ); + } + throw error; + } +} + +/** + * Demonstrates scheduled messages + */ +async function demonstrateScheduledMessages(): Promise { + console.log('\n=== Demonstrating Scheduled Messages ==='); + + try { + // List scheduled messages + console.log('Listing scheduled messages...'); + const scheduledMessages = await nylas.messages.listScheduledMessages({ + identifier: grantId, + }); + + // Handle case where schedules might be undefined or empty + const schedules = scheduledMessages.data.schedules || []; + console.log(`Found ${schedules.length} scheduled messages`); + + if (schedules.length === 0) { + console.log( + "No scheduled messages found. This is normal if you haven't scheduled any messages." + ); + return; + } + + for (const schedule of schedules) { + console.log(`- Schedule ID: ${schedule.scheduleId}`); + console.log( + ` Status: ${schedule.status.code} - ${schedule.status.description}` + ); + if (schedule.closeTime) { + console.log( + ` Close Time: ${new Date(schedule.closeTime * 1000).toISOString()}` + ); + } + } + + // If there are scheduled messages, demonstrate finding one + const firstSchedule = schedules[0]; + console.log( + `\nGetting details for scheduled message: ${firstSchedule.scheduleId}` + ); + + const scheduleDetails = await nylas.messages.findScheduledMessage({ + identifier: grantId, + scheduleId: firstSchedule.scheduleId.toString(), + }); + + console.log('Scheduled message details:'); + console.log(`- Schedule ID: ${scheduleDetails.data.scheduleId}`); + console.log( + `- Status: ${scheduleDetails.data.status.code} - ${scheduleDetails.data.status.description}` + ); + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`Error with scheduled messages: ${error.message}`); + } else if (error instanceof Error) { + console.error( + `Unexpected error in demonstrateScheduledMessages: ${error.message}` + ); + } + throw error; + } +} + +/** + * Demonstrates message cleaning + */ +async function demonstrateMessageCleaning(): Promise { + console.log('\n=== Demonstrating Message Cleaning ==='); + + try { + // Get a few message IDs for cleaning + const messages = await nylas.messages.list({ + identifier: grantId, + queryParams: { + limit: 2, + }, + }); + + if (messages.data.length === 0) { + console.log('No messages available for cleaning demonstration'); + return; + } + + const messageIds = messages.data.map((m) => m.id); + console.log(`Cleaning ${messageIds.length} messages...`); + + const cleanRequest: CleanMessagesRequest = { + messageId: messageIds, + ignoreLinks: true, + ignoreImages: true, + ignoreTables: false, + imagesAsMarkdown: false, + removeConclusionPhrases: true, + }; + + const cleanedMessages = await nylas.messages.cleanMessages({ + identifier: grantId, + requestBody: cleanRequest, + }); + + console.log(`Successfully cleaned ${cleanedMessages.data.length} messages`); + for (const cleanedMessage of cleanedMessages.data) { + console.log(`- Message ID: ${cleanedMessage.id}`); + console.log( + ` Original body length: ${cleanedMessage.body?.length || 0} characters` + ); + console.log( + ` Cleaned conversation length: ${cleanedMessage.conversation?.length || 0} characters` + ); + if (cleanedMessage.conversation) { + const preview = cleanedMessage.conversation.substring(0, 100); + console.log( + ` Cleaned preview: ${preview}${cleanedMessage.conversation.length > 100 ? '...' : ''}` + ); + } + } + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`Error cleaning messages: ${error.message}`); + } else if (error instanceof Error) { + console.error( + `Unexpected error in demonstrateMessageCleaning: ${error.message}` + ); + } + throw error; + } +} + +/** + * Demonstrates querying messages with various filters + */ +async function demonstrateMessageQuerying(): Promise { + console.log('\n=== Demonstrating Message Querying ==='); + + try { + // Query recent unread messages + console.log('\n--- Finding recent unread messages ---'); + const unreadMessages = await nylas.messages.list({ + identifier: grantId, + queryParams: { + unread: true, + limit: 5, + fields: MessageFields.INCLUDE_TRACKING_OPTIONS, + }, + }); + + console.log(`Found ${unreadMessages.data.length} unread messages`); + for (const message of unreadMessages.data) { + console.log(`- ${message.id}: ${message.subject || '(no subject)'}`); + console.log(` Date: ${new Date(message.date * 1000).toISOString()}`); + console.log( + ` From: ${message.from?.map((f) => `${f.name} <${f.email}>`).join(', ') || 'Unknown'}` + ); + } + + // Query messages with attachments + console.log('\n--- Finding messages with attachments ---'); + const attachmentMessages = await nylas.messages.list({ + identifier: grantId, + queryParams: { + hasAttachment: true, + limit: 3, + }, + }); + + console.log( + `Found ${attachmentMessages.data.length} messages with attachments` + ); + for (const message of attachmentMessages.data) { + console.log(`- ${message.id}: ${message.subject || '(no subject)'}`); + console.log(` Attachments: ${message.attachments?.length || 0}`); + if (message.attachments && message.attachments.length > 0) { + message.attachments.forEach((att) => { + console.log( + ` - ${att.filename} (${att.contentType}, ${att.size} bytes)` + ); + }); + } + } + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`Error querying messages: ${error.message}`); + } else if (error instanceof Error) { + console.error( + `Unexpected error in demonstrateMessageQuerying: ${error.message}` + ); + } + throw error; + } +} + +/** + * Main function to run all message examples + */ +async function main(): Promise { + try { + console.log('=== Nylas Messages API Examples ==='); + console.log(`API Key: ${apiKey.substring(0, 8)}...`); + console.log(`Grant ID: ${grantId}`); + console.log( + `API URI: ${process.env.NYLAS_API_URI || 'https://api.us.nylas.com'}` + ); + + // Run all demonstrations + await demonstrateMessageFields(); + await demonstratePlaintextMessageSending(); + await demonstrateRawMime(); + await demonstrateMessageQuerying(); + + // Send a message if TEST_EMAIL is provided + const sentMessage = await demonstrateMessageSending(); + + // If we sent a message, demonstrate updating it + if (sentMessage) { + await demonstrateMessageUpdate(sentMessage.data.id); + } + + await demonstrateScheduledMessages(); + await demonstrateMessageCleaning(); + + console.log('\n=== All message examples completed successfully! ==='); + } catch (error) { + console.error('\n=== Error running message examples ==='); + if (error instanceof NylasApiError) { + console.error(`Nylas API Error: ${error.message}`); + console.error(`Status Code: ${error.statusCode}`); + console.error(`Request ID: ${error.requestId}`); + } else if (error instanceof Error) { + console.error(`Error: ${error.message}`); + console.error(`Stack: ${error.stack}`); + } else { + console.error('Unknown error:', error); + } + process.exit(1); + } +} + +// Run the main function +if (require.main === module) { + main(); +} diff --git a/examples/messages/send-attachments-cli.ts b/examples/messages/send-attachments-cli.ts new file mode 100644 index 00000000..b8f91d46 --- /dev/null +++ b/examples/messages/send-attachments-cli.ts @@ -0,0 +1,76 @@ +import * as dotenv from 'dotenv'; +import * as path from 'path'; +import * as process from 'process'; +import { TestFileManager } from './utils/attachment-file-manager'; + +// ============================================================================= +// 🎯 NYLAS SDK ATTACHMENT EXAMPLES - Import clean, focused examples +// ============================================================================= + +// Example 1: File Path Attachments (Most Common & Efficient) +import { sendFilePathAttachments } from './examples/file-path-attachments'; + +// Example 2: Stream Attachments (For More Control) +import { sendStreamAttachments } from './examples/stream-attachments'; + +// Example 3: Buffer Attachments (For Small Files) +import { sendBufferAttachments } from './examples/buffer-attachments'; + +// Example 4: String Content Attachments (For Dynamic Content) +import { sendStringAttachments } from './examples/string-attachments'; + +// Flexible format-based attachment sending +import { sendAttachmentsByFormat } from './examples/flexible-attachments'; + +// ============================================================================= +// πŸ“‚ File Manager - Manage test files +// ============================================================================= +// Available test files in the examples/messages/attachments directory +const testFileManager = new TestFileManager( + path.resolve(__dirname, './attachments'), + [ + 'test-small-26B.txt', + 'test-image-512KB.jpg', + 'test-document-12MB.pdf', + 'test-image-10MB.jpg', + ] +); + +// ============================================================================= +// πŸ› οΈ CLI Interface - Start CLI when run directly +// ============================================================================= + +import { startCli } from './cli-interface'; +import type { SendAttachmentsExamples } from './examples'; + +const sendAttachmentsExamples: SendAttachmentsExamples = { + sendFilePathAttachments, + sendStreamAttachments, + sendBufferAttachments, + sendStringAttachments, + sendAttachmentsByFormat, +}; +const grantId: string = process.env.NYLAS_GRANT_ID || ''; + +// Check for required environment variables +if (!process.env.NYLAS_API_KEY) { + throw new Error('NYLAS_API_KEY environment variable is not set'); +} +if (!grantId) { + throw new Error('NYLAS_GRANT_ID environment variable is not set'); +} + +// Load environment variables from .env file +dotenv.config({ path: path.resolve(__dirname, '../.env') }); + +// Run the CLI +if (require.main === module) { + startCli( + sendAttachmentsExamples, + testFileManager, + process.env.TEST_EMAIL || '' + ).catch((error) => { + console.error('Error:', error.message); + process.exit(1); + }); +} diff --git a/examples/messages/utils/attachment-file-manager.ts b/examples/messages/utils/attachment-file-manager.ts new file mode 100644 index 00000000..9b9c1822 --- /dev/null +++ b/examples/messages/utils/attachment-file-manager.ts @@ -0,0 +1,261 @@ +import * as path from 'path'; +import * as fs from 'fs'; +import * as mime from 'mime-types'; +import { CreateAttachmentRequest } from 'nylas'; + +/** + * File format types for different ways to handle attachments + */ +export type FileFormat = 'file' | 'stream' | 'buffer' | 'string'; + +/** + * Maximum size for small files + */ +export const MAX_SMALL_FILE_SIZE_LIMIT = 1024 * 1024 * 3; // 3MB + +/** + * Interface for file information and content access + */ +interface FileHandler { + path: string; + exists: boolean; + filename: string; + size: number; + contentType: string; + + // Methods to get content in different formats + asFileRequest(): CreateAttachmentRequest; + asStream(): fs.ReadStream; + asBuffer(): Buffer; + asString(): string; +} + +/** + * Common utility class for handling test files in different formats + */ +export class TestFileHandler implements FileHandler { + public readonly path: string; + public readonly exists: boolean; + public readonly filename: string; + public readonly size: number; + public readonly contentType: string; + + constructor(fileName: string, baseDir?: string) { + // Default to attachments subdirectory relative to the messages folder + const attachmentsDir = baseDir || path.resolve(__dirname, '../attachments'); + this.path = path.resolve(attachmentsDir, fileName); + this.exists = fs.existsSync(this.path); + this.filename = path.basename(this.path); + + if (this.exists) { + const stats = fs.statSync(this.path); + this.size = stats.size; + this.contentType = mime.lookup(this.path) || 'application/octet-stream'; + } else { + this.size = 0; + this.contentType = 'application/octet-stream'; + } + } + + /** + * Get file as CreateAttachmentRequest using file stream (original method) + */ + asFileRequest(): CreateAttachmentRequest { + if (!this.exists) { + throw new Error(`File not found: ${this.filename}`); + } + + return { + filename: this.filename, + contentType: this.contentType, + content: fs.createReadStream(this.path), + size: this.size, + }; + } + + /** + * Get file as a readable stream + */ + asStream(): fs.ReadStream { + if (!this.exists) { + throw new Error(`File not found: ${this.filename}`); + } + return fs.createReadStream(this.path); + } + + /** + * Get file as a Buffer + */ + asBuffer(): Buffer { + if (!this.exists) { + throw new Error(`File not found: ${this.filename}`); + } + return fs.readFileSync(this.path); + } + + /** + * Get file as a string (only works for text files) + */ + asString(): string { + if (!this.exists) { + throw new Error(`File not found: ${this.filename}`); + } + + // Check if it's likely a text file + const textTypes = ['text/', 'application/json', 'application/xml']; + const isTextFile = textTypes.some((type) => + this.contentType.startsWith(type) + ); + + if (!isTextFile && this.size > MAX_SMALL_FILE_SIZE_LIMIT) { + // > 1MB + throw new Error( + `File ${this.filename} is too large or not a text file to read as string` + ); + } + + return fs.readFileSync(this.path, 'utf8'); + } +} + +/** + * File manager utility to handle all test files + */ +export class TestFileManager { + private files: Map = new Map(); + private baseDir: string; + + constructor(baseDir?: string, files?: string[]) { + // Default to attachments subdirectory relative to the messages folder + this.baseDir = baseDir || path.resolve(__dirname, '../attachments'); + + // Initialize all test files + files?.forEach((fileName) => { + this.files.set(fileName, new TestFileHandler(fileName, this.baseDir)); + }); + } + + /** + * Get a file handler by filename + */ + getFile(fileName: string): TestFileHandler { + const handler = this.files.get(fileName); + if (!handler) { + throw new Error(`Unknown test file: ${fileName}`); + } + return handler; + } + + /** + * Get all available files + */ + getAllFiles(): TestFileHandler[] { + return Array.from(this.files.values()); + } + + /** + * Get only files that exist + */ + getExistingFiles(): TestFileHandler[] { + return this.getAllFiles().filter((file) => file.exists); + } + + /** + * Get small files (< 1MB) + */ + getSmallFiles(): TestFileHandler[] { + return this.getExistingFiles().filter( + (file) => file.size < MAX_SMALL_FILE_SIZE_LIMIT + ); + } + + /** + * Get large files (>= 1MB) + */ + getLargeFiles(): TestFileHandler[] { + return this.getExistingFiles().filter( + (file) => file.size >= MAX_SMALL_FILE_SIZE_LIMIT + ); + } + + /** + * Check status of all test files + */ + checkFileStatus(): void { + console.log('\nChecking test file status:'); + this.getAllFiles().forEach((file) => { + const status = file.exists + ? `βœ“ Found (${file.size} bytes)` + : 'βœ— Not found'; + const sizeLabel = + file.size >= MAX_SMALL_FILE_SIZE_LIMIT ? 'LARGE' : 'SMALL'; + console.log(` ${file.filename}: ${status} [${sizeLabel}]`); + }); + } + + /** + * Create attachment request for a file in the specified format + */ + createAttachmentRequest( + fileName: string, + format: FileFormat + ): CreateAttachmentRequest { + const file = this.getFile(fileName); + + switch (format) { + case 'file': + return file.asFileRequest(); + + case 'stream': + return { + filename: file.filename, + contentType: file.contentType, + content: file.asStream(), + size: file.size, + }; + + case 'buffer': + return { + filename: file.filename, + contentType: file.contentType, + content: file.asBuffer(), + size: file.size, + }; + + case 'string': + const stringContent = file.asString(); + return { + filename: file.filename, + contentType: file.contentType, + content: stringContent, + size: Buffer.byteLength(stringContent, 'utf8'), + }; + + default: + throw new Error(`Unsupported format: ${format}`); + } + } +} + +/** + * Helper function to create a file request builder for any file path + * This maintains backward compatibility with the original function + */ +export function createFileRequestBuilder( + filePath: string +): CreateAttachmentRequest { + // If it's not an absolute path, assume it's in the attachments subdirectory + const fullPath = path.resolve(__dirname, filePath); + + const stats = fs.statSync(fullPath); + const filename = path.basename(fullPath); + const contentType = mime.lookup(fullPath) || 'application/octet-stream'; + const content = fs.createReadStream(fullPath); + + return { + filename, + contentType, + content, + size: stats.size, + }; +} diff --git a/examples/notetakers/README.md b/examples/notetakers/README.md new file mode 100644 index 00000000..c7af5cc6 --- /dev/null +++ b/examples/notetakers/README.md @@ -0,0 +1,54 @@ +# Nylas Notetakers API Examples + +This directory contains examples of how to use the Nylas Notetakers API with the Nylas Node.js SDK. + +## What is Notetakers? + +The Nylas Notetakers API allows you to invite a Notetaker bot to your meetings. The bot can record audio, video, and generate transcripts of your meetings. + +## Examples + +- [notetaker.ts](./notetaker.ts) - A complete example showing how to invite a Notetaker to a meeting, list all Notetakers, get media from a Notetaker, and leave a meeting. + +## Running the Examples + +To run these examples, you'll need to: + +1. Install dependencies from the examples directory: + ```bash + cd examples + npm install + ``` + +2. Copy the `.env.example` file to `.env` and fill in your API key: + ```bash + cp .env.example .env + # Edit .env with your editor + ``` + +3. Edit the `.env` file to include: + - `NYLAS_API_KEY` - Your Nylas API key + - `NYLAS_API_URI` (optional) - The Nylas API server URI (defaults to "https://api.us.nylas.com") + - `MEETING_LINK` - The URL of the meeting to join (e.g., a Zoom, Google Meet, or Microsoft Teams meeting link) + +4. Run the example: + ```bash + # From the examples directory + npm run notetakers + + # Or directly with ts-node + npx ts-node notetakers/notetaker.ts + ``` + +## Understanding the Example + +This example demonstrates: + +1. **Inviting a Notetaker**: Adding a Notetaker bot to a meeting by providing a meeting link and settings. +2. **Listing Notetakers**: Getting a list of all Notetakers in your account. +3. **Retrieving Media**: Accessing recordings and transcripts after the meeting (if the state is `media_available`). +4. **Leaving a Meeting**: Having the Notetaker bot leave the meeting. + +## Documentation + +For more information, see the [Nylas API Documentation](https://developer.nylas.com/). \ No newline at end of file diff --git a/examples/notetakers/notetaker.ts b/examples/notetakers/notetaker.ts new file mode 100644 index 00000000..cc3166fc --- /dev/null +++ b/examples/notetakers/notetaker.ts @@ -0,0 +1,275 @@ +import dotenv from 'dotenv'; +import path from 'path'; +import * as process from 'process'; +import Nylas from 'nylas'; +import { + CreateNotetakerRequest, + NotetakerMedia, + NotetakerLeaveResponse, + Notetaker, + NylasResponse, + NylasListResponse, + NylasApiError, + ListNotetakersQueryParams, +} from 'nylas'; + +// Load environment variables from .env file +dotenv.config({ path: path.resolve(__dirname, '../.env') }); + +// Check for required environment variables +const apiKey: string = process.env.NYLAS_API_KEY || ''; +if (!apiKey) { + throw new Error('NYLAS_API_KEY environment variable is not set'); +} + +// Initialize the Nylas client +const nylas = new Nylas({ + apiKey, + apiUri: process.env.NYLAS_API_URI || 'https://api.us.nylas.com', +}); + +/** + * Invites a Notetaker to a meeting + * @returns The created Notetaker + */ +async function inviteNotetaker(): Promise> { + console.log('\n=== Inviting Notetaker to Meeting ==='); + + try { + const meetingLink: string = process.env.MEETING_LINK || ''; + if (!meetingLink) { + throw new Error( + 'MEETING_LINK environment variable is not set. Please set it with your meeting URL.' + ); + } + + const requestBody: CreateNotetakerRequest = { + meetingLink, + name: 'Nylas Notetaker', + meetingSettings: { + videoRecording: true, + audioRecording: true, + transcription: true, + }, + }; + + console.log(`Request body: ${JSON.stringify(requestBody, null, 2)}`); + + const notetaker = await nylas.notetakers.create({ requestBody }); + + console.log(`Invited Notetaker with ID: ${notetaker.data.id}`); + console.log(`Name: ${notetaker.data.name}`); + console.log(`State: ${notetaker.data.state}`); + return notetaker; + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`Error inviting notetaker: ${error.message}`); + console.error(`Error details: ${JSON.stringify(error, null, 2)}`); + } else if (error instanceof Error) { + console.error(`Unexpected error in invite_notetaker: ${error.message}`); + console.error(`Error type: ${error.constructor.name}`); + } + throw error; + } +} + +/** + * Lists all Notetakers + * @returns A list of Notetakers + */ +async function listNotetakers(): Promise> { + console.log('\n=== Listing All Notetakers ==='); + + try { + // List notetakers ordered by name in ascending order + const notetakers = await nylas.notetakers.list({ + queryParams: { + orderBy: 'name', + orderDirection: 'asc', + }, + }); + + console.log( + `Found ${notetakers.data.length} notetakers (ordered by name):` + ); + for (const notetaker of notetakers.data) { + console.log( + `- ${notetaker.name} (ID: ${notetaker.id}, State: ${notetaker.state})` + ); + } + + return notetakers; + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`Error listing notetakers: ${error.message}`); + } else if (error instanceof Error) { + console.error(`Unexpected error in list_notetakers: ${error.message}`); + } + throw error; + } +} + +/** + * Gets media from a Notetaker + * @param notetakerId The ID of the Notetaker to get media from + * @returns The media (recording and transcript) from the Notetaker + */ +async function getNotetakerMedia( + notetakerId: string +): Promise> { + console.log('\n=== Getting Notetaker Media ==='); + + try { + const media = await nylas.notetakers.downloadMedia({ notetakerId }); + + if (media.data.recording) { + const recording = media.data.recording; + console.log(`Recording URL: ${recording.url}`); + console.log(`Recording Name: ${recording.name}`); + console.log(`Recording Type: ${recording.type}`); + console.log(`Recording Size: ${recording.size} bytes`); + + // Handle both snake_case (API) and camelCase (SDK model) property naming + const createdAt = + 'createdAt' in recording + ? recording.createdAt + : 'created_at' in recording + ? (recording as any).created_at + : undefined; + const expiresAt = + 'expiresAt' in recording + ? recording.expiresAt + : 'expires_at' in recording + ? (recording as any).expires_at + : undefined; + + if (createdAt) { + console.log( + `Recording Created: ${new Date(createdAt * 1000).toISOString()}` + ); + } + if (expiresAt) { + console.log( + `Recording Expires: ${new Date(expiresAt * 1000).toISOString()}` + ); + } + console.log(`Recording TTL: ${recording.ttl} seconds`); + } + + if (media.data.transcript) { + const transcript = media.data.transcript; + console.log(`Transcript URL: ${transcript.url}`); + console.log(`Transcript Name: ${transcript.name}`); + console.log(`Transcript Type: ${transcript.type}`); + console.log(`Transcript Size: ${transcript.size} bytes`); + + // Handle both snake_case (API) and camelCase (SDK model) property naming + const createdAt = + 'createdAt' in transcript + ? transcript.createdAt + : 'created_at' in transcript + ? (transcript as any).created_at + : undefined; + const expiresAt = + 'expiresAt' in transcript + ? transcript.expiresAt + : 'expires_at' in transcript + ? (transcript as any).expires_at + : undefined; + + if (createdAt) { + console.log( + `Transcript Created: ${new Date(createdAt * 1000).toISOString()}` + ); + } + if (expiresAt) { + console.log( + `Transcript Expires: ${new Date(expiresAt * 1000).toISOString()}` + ); + } + console.log(`Transcript TTL: ${transcript.ttl} seconds`); + } + + return media; + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`Error getting notetaker media: ${error.message}`); + } else if (error instanceof Error) { + console.error( + `Unexpected error in get_notetaker_media: ${error.message}` + ); + } + throw error; + } +} + +/** + * Leaves a Notetaker meeting + * @param notetakerId The ID of the Notetaker to leave + * @returns A response containing the Notetaker ID and a message + */ +async function leaveNotetaker( + notetakerId: string +): Promise> { + console.log('\n=== Leaving Notetaker ==='); + + try { + const response = await nylas.notetakers.leave({ notetakerId }); + console.log(`Left Notetaker with ID: ${response.data.id}`); + console.log(`Message: ${response.data.message}`); + return response; + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`Error leaving notetaker: ${error.message}`); + } else if (error instanceof Error) { + console.error(`Unexpected error in leave_notetaker: ${error.message}`); + } + throw error; + } +} + +/** + * Main function to run all demo examples + */ +async function main(): Promise { + try { + // Log API key (first few characters only) + console.log(`Using API key: ${apiKey.substring(0, 5)}...`); + + // Invite a Notetaker to a meeting + const notetaker = await inviteNotetaker(); + + // List all Notetakers + await listNotetakers(); + + // Get media from the Notetaker (if available) + if (notetaker.data.state === 'media_available') { + await getNotetakerMedia(notetaker.data.id); + } else { + console.log( + `\nNotetaker state is ${notetaker.data.state}, media not available yet.` + ); + console.log( + `You can check back later when the state is 'media_available'.` + ); + } + + // Leave the Notetaker meeting + await leaveNotetaker(notetaker.data.id); + } catch (error) { + if (error instanceof NylasApiError) { + console.error(`\nNylas API Error: ${error.message}`); + console.error(`Error details: ${JSON.stringify(error, null, 2)}`); + process.exit(1); + } else if (error instanceof Error) { + console.error(`\nUnexpected Error: ${error.message}`); + console.error(`Error type: ${error.constructor.name}`); + process.exit(1); + } + } +} + +// Run the main function +if (require.main === module) { + main().catch(console.error); +} diff --git a/examples/package-lock.json b/examples/package-lock.json new file mode 100644 index 00000000..1684f867 --- /dev/null +++ b/examples/package-lock.json @@ -0,0 +1,933 @@ +{ + "name": "nylas-examples", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "nylas-examples", + "version": "1.0.0", + "dependencies": { + "chalk": "^5.6.2", + "commander": "^14.0.0", + "dotenv": "^17.2.2", + "inquirer": "^12.9.4", + "mime-types": "^3.0.1", + "nylas": "file:.." + }, + "devDependencies": { + "@types/inquirer": "^9.0.9", + "@types/mime-types": "^2.1.4", + "@types/node": "^18.11.9", + "ts-node": "^10.9.2", + "typescript": "^5.8.3" + } + }, + "..": { + "name": "nylas", + "version": "7.13.0", + "license": "MIT", + "dependencies": { + "change-case": "^4.1.2", + "form-data-encoder": "^4.1.0", + "formdata-node": "^6.0.3", + "mime-types": "^2.1.35", + "node-fetch": "^3.3.2", + "uuid": "^8.3.2" + }, + "devDependencies": { + "@babel/core": "^7.3.3", + "@types/jest": "^29.5.2", + "@types/mime-types": "^2.1.2", + "@types/node": "^22.15.21", + "@types/uuid": "^8.3.4", + "@typescript-eslint/eslint-plugin": "^2.25.0", + "@typescript-eslint/parser": "^2.25.0", + "eslint": "^5.14.0", + "eslint-config-prettier": "^4.0.0", + "eslint-plugin-custom-rules": "^0.0.0", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-prettier": "^3.0.1", + "jest": "^29.6.1", + "jest-fetch-mock": "^3.0.3", + "prettier": "^3.5.3", + "ts-jest": "^29.1.1", + "typedoc": "^0.28.4", + "typedoc-plugin-rename-defaults": "^0.7.3", + "typescript": "^5.8.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.2.2.tgz", + "integrity": "sha512-E+KExNurKcUJJdxmjglTl141EwxWyAHplvsYJQgSwXf8qiNWkTxTuCCqmhFEmbIXd4zLaGMfQFJ6WrZ7fSeV3g==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.2.0", + "@inquirer/figures": "^1.0.13", + "@inquirer/type": "^3.0.8", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.1.16", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.16.tgz", + "integrity": "sha512-j1a5VstaK5KQy8Mu8cHmuQvN1Zc62TbLhjJxwHvKPPKEoowSF6h/0UdOpA9DNdWZ+9Inq73+puRq1df6OJ8Sag==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.2.0", + "@inquirer/type": "^3.0.8" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.2.0.tgz", + "integrity": "sha512-NyDSjPqhSvpZEMZrLCYUquWNl+XC/moEcVFqS55IEYIYsY0a1cUCevSqk7ctOlnm/RaSBU5psFryNlxcmGrjaA==", + "license": "MIT", + "dependencies": { + "@inquirer/figures": "^1.0.13", + "@inquirer/type": "^3.0.8", + "ansi-escapes": "^4.3.2", + "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/editor": { + "version": "4.2.18", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.18.tgz", + "integrity": "sha512-yeQN3AXjCm7+Hmq5L6Dm2wEDeBRdAZuyZ4I7tWSSanbxDzqM0KqzoDbKM7p4ebllAYdoQuPJS6N71/3L281i6w==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.2.0", + "@inquirer/external-editor": "^1.0.1", + "@inquirer/type": "^3.0.8" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.18.tgz", + "integrity": "sha512-xUjteYtavH7HwDMzq4Cn2X4Qsh5NozoDHCJTdoXg9HfZ4w3R6mxV1B9tL7DGJX2eq/zqtsFjhm0/RJIMGlh3ag==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.2.0", + "@inquirer/type": "^3.0.8", + "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.1", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.1.tgz", + "integrity": "sha512-Oau4yL24d2B5IL4ma4UpbQigkVhzPDXLoqy1ggK4gnHg/stmkffJE4oOXHXF3uz0UEpywG68KcyXsyYpA1Re/Q==", + "license": "MIT", + "dependencies": { + "chardet": "^2.1.0", + "iconv-lite": "^0.6.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.13.tgz", + "integrity": "sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.2.2.tgz", + "integrity": "sha512-hqOvBZj/MhQCpHUuD3MVq18SSoDNHy7wEnQ8mtvs71K8OPZVXJinOzcvQna33dNYLYE4LkA9BlhAhK6MJcsVbw==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.2.0", + "@inquirer/type": "^3.0.8" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.18.tgz", + "integrity": "sha512-7exgBm52WXZRczsydCVftozFTrrwbG5ySE0GqUd2zLNSBXyIucs2Wnm7ZKLe/aUu6NUg9dg7Q80QIHCdZJiY4A==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.2.0", + "@inquirer/type": "^3.0.8" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.18.tgz", + "integrity": "sha512-zXvzAGxPQTNk/SbT3carAD4Iqi6A2JS2qtcqQjsL22uvD+JfQzUrDEtPjLL7PLn8zlSNyPdY02IiQjzoL9TStA==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.2.0", + "@inquirer/type": "^3.0.8", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.8.4.tgz", + "integrity": "sha512-MuxVZ1en1g5oGamXV3DWP89GEkdD54alcfhHd7InUW5BifAdKQEK9SLFa/5hlWbvuhMPlobF0WAx7Okq988Jxg==", + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.2.2", + "@inquirer/confirm": "^5.1.16", + "@inquirer/editor": "^4.2.18", + "@inquirer/expand": "^4.0.18", + "@inquirer/input": "^4.2.2", + "@inquirer/number": "^3.0.18", + "@inquirer/password": "^4.0.18", + "@inquirer/rawlist": "^4.1.6", + "@inquirer/search": "^3.1.1", + "@inquirer/select": "^4.3.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.6.tgz", + "integrity": "sha512-KOZqa3QNr3f0pMnufzL7K+nweFFCCBs6LCXZzXDrVGTyssjLeudn5ySktZYv1XiSqobyHRYYK0c6QsOxJEhXKA==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.2.0", + "@inquirer/type": "^3.0.8", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.1.1.tgz", + "integrity": "sha512-TkMUY+A2p2EYVY3GCTItYGvqT6LiLzHBnqsU1rJbrpXUijFfM6zvUx0R4civofVwFCmJZcKqOVwwWAjplKkhxA==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.2.0", + "@inquirer/figures": "^1.0.13", + "@inquirer/type": "^3.0.8", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.3.2.tgz", + "integrity": "sha512-nwous24r31M+WyDEHV+qckXkepvihxhnyIaod2MG7eCE6G0Zm/HUF6jgN8GXgf4U7AU6SLseKdanY195cwvU6w==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.2.0", + "@inquirer/figures": "^1.0.13", + "@inquirer/type": "^3.0.8", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.8.tgz", + "integrity": "sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/inquirer": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.9.tgz", + "integrity": "sha512-/mWx5136gts2Z2e5izdoRCo46lPp5TMs9R15GTSsgg/XnZyxDWVqoVU3R9lWnccKpqwsJLvRoxbCjoJtZB7DSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/through": "*", + "rxjs": "^7.2.0" + } + }, + "node_modules/@types/mime-types": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.4.tgz", + "integrity": "sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "18.19.86", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.86.tgz", + "integrity": "sha512-fifKayi175wLyKyc5qUfyENhQ1dCNI1UNjp653d8kuYcPQN5JhX3dGuP/XmvPTg/xRBn1VTLpbmi+H/Mr7tLfQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/through": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.33.tgz", + "integrity": "sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/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/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, + "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==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.0.tgz", + "integrity": "sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==", + "license": "MIT" + }, + "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==", + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "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/commander": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.0.tgz", + "integrity": "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "17.2.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.2.tgz", + "integrity": "sha512-Sf2LSQP+bOlhKWWyhFsn0UsfdK/kCWRv1iuA2gXAwt3dyNabr6QSj00I2V10pidqz69soatm9ZwZvpQMTIOd5Q==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "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/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inquirer": { + "version": "12.9.4", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-12.9.4.tgz", + "integrity": "sha512-5bV3LOgLtMAiJq1QpaUddfRrvaX59wiMYppS7z2jNRSQ64acI0yqx7WMxWhgymenSXOyD657g9tlsTjqGYM8sg==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.2.0", + "@inquirer/prompts": "^7.8.4", + "@inquirer/type": "^3.0.8", + "ansi-escapes": "^4.3.2", + "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/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/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/nylas": { + "resolved": "..", + "link": true + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "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==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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/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/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "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-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==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "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==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/examples/package.json b/examples/package.json new file mode 100644 index 00000000..055c7a6b --- /dev/null +++ b/examples/package.json @@ -0,0 +1,31 @@ +{ + "name": "nylas-examples", + "version": "1.0.0", + "description": "Examples for the Nylas Node.js SDK", + "private": true, + "scripts": { + "start": "ts-node", + "build": "tsc", + "grants": "ts-node grants/grants.ts", + "notetakers": "ts-node notetakers/notetaker.ts", + "calendars": "ts-node calendars/event_with_notetaker.ts", + "messages": "ts-node messages/messages.ts", + "send-attachments": "ts-node messages/send-attachments-cli.ts", + "folders": "ts-node folders/folders.ts" + }, + "dependencies": { + "chalk": "^5.6.2", + "commander": "^14.0.0", + "dotenv": "^17.2.2", + "inquirer": "^12.9.4", + "mime-types": "^3.0.1", + "nylas": "file:.." + }, + "devDependencies": { + "ts-node": "^10.9.2", + "typescript": "^5.8.3", + "@types/node": "^18.11.9", + "@types/inquirer": "^9.0.9", + "@types/mime-types": "^2.1.4" + } +} \ No newline at end of file diff --git a/examples/tsconfig.json b/examples/tsconfig.json new file mode 100644 index 00000000..ab56d392 --- /dev/null +++ b/examples/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "es2019", + "module": "commonjs", + "lib": ["es2019", "dom"], + "declaration": false, + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "outDir": "dist" + }, + "include": [ + "**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/examples/utils/logger.mjs b/examples/utils/logger.mjs new file mode 100644 index 00000000..758eb4c2 --- /dev/null +++ b/examples/utils/logger.mjs @@ -0,0 +1,44 @@ +// Pretty logger +const COLORS = { + reset: '\x1b[0m', + dim: '\x1b[2m', + gray: '\x1b[90m', + bold: '\x1b[1m', + info: '\x1b[36m', + success: '\x1b[32m', + warn: '\x1b[33m', + error: '\x1b[31m', + debug: '\x1b[35m', +}; + +export function ts() { + return new Date().toISOString(); +} + +export function maskSecret(value, visibleStart = 8, visibleEnd = 0) { + if (!value) return ''; + const start = value.slice(0, visibleStart); + const end = visibleEnd ? value.slice(-visibleEnd) : ''; + const hidden = Math.max(0, value.length - start.length - end.length); + return `${start}${'β€’'.repeat(hidden)}${end}`; +} + +export function print(level, symbol, message, meta) { + const color = COLORS[level] || COLORS.info; + const time = `${COLORS.dim}${ts()}${COLORS.reset}`; + const label = `${color}${symbol} ${level.toUpperCase()}${COLORS.reset}`; + const line = + typeof message === 'string' ? message : JSON.stringify(message, null, 2); + console.log(`${time} ${label} ${line}`); + if (meta !== undefined) { + console.dir(meta, { depth: null, colors: true, maxArrayLength: 100 }); + } +} + +export const logger = { + info: (msg, meta) => print('info', 'β„Ή', msg, meta), + success: (msg, meta) => print('success', 'βœ”', msg, meta), + warn: (msg, meta) => print('warn', '⚠', msg, meta), + error: (msg, meta) => print('error', 'βœ–', msg, meta), + debug: (msg, meta) => print('debug', 'πŸ›', msg, meta), +}; diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000..b3785f22 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,37 @@ +const config = { + preset: 'ts-jest/presets/js-with-ts', + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + tsconfig: 'tsconfig.test.json', + }, + ], + }, + moduleNameMapper: { + '^[../]+src/([^/]+)$': '/src/$1.ts', + '^[../]+src/resources/([^/]+)$': '/src/resources/$1.ts', + '^[../]+src/models/([^/]+)$': '/src/models/$1.ts', + // Handle .js imports in TypeScript files for Jest + '^(.+)\\.js$': '$1', + }, + // Handle ESM modules like node-fetch v3 + extensionsToTreatAsEsm: ['.ts'], + transformIgnorePatterns: [ + 'node_modules/(?!(node-fetch|data-uri-to-buffer|fetch-blob|formdata-polyfill)/)', + ], + // Set up jest-fetch-mock + setupFilesAfterEnv: ['/tests/setupTests.ts'], + coverageThreshold: { + global: { + functions: 80, + lines: 80, + statements: 80, + }, + }, + clearMocks: true, + collectCoverage: true, + coverageReporters: ['text', 'cobertura'], +}; + +module.exports = config; diff --git a/package-lock.json b/package-lock.json index c3e43ba2..921191bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5414 +1,13211 @@ { "name": "nylas", - "version": "4.1.0", - "lockfileVersion": 1, + "version": "8.0.1", + "lockfileVersion": 2, "requires": true, - "dependencies": { - "abab": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", - "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=", - "dev": true - }, - "acorn": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", - "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", - "dev": true - }, - "acorn-globals": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", - "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", - "dev": true, - "requires": { - "acorn": "4.0.13" - }, + "packages": { + "": { + "name": "nylas", + "version": "8.0.1", + "license": "MIT", "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - } + "change-case": "^4.1.2", + "form-data-encoder": "^4.1.0", + "formdata-node": "^6.0.3", + "mime-types": "^2.1.35", + "uuid": "^8.3.2" + }, + "devDependencies": { + "@babel/core": "^7.3.3", + "@types/jest": "^29.5.2", + "@types/mime-types": "^2.1.2", + "@types/node": "^22.15.21", + "@types/uuid": "^8.3.4", + "@typescript-eslint/eslint-plugin": "^2.25.0", + "@typescript-eslint/parser": "^2.25.0", + "eslint": "^5.14.0", + "eslint-config-prettier": "^4.0.0", + "eslint-plugin-custom-rules": "^0.0.0", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-prettier": "^3.0.1", + "jest": "^29.6.1", + "jest-fetch-mock": "^3.0.3", + "prettier": "^3.5.3", + "ts-jest": "^29.1.1", + "typedoc": "^0.28.4", + "typedoc-plugin-rename-defaults": "^0.7.3", + "typescript": "^5.8.3" + }, + "engines": { + "node": ">=18" } }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, - "requires": { - "acorn": "3.3.0" - }, "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" } }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "node_modules/@babel/code-frame": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", - "dev": true - }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "node_modules/@babel/compat-data": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz", + "integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==", "dev": true, - "requires": { - "kind-of": "3.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" + "engines": { + "node": ">=6.9.0" } }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true - }, - "ansi-escapes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", - "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "node_modules/@babel/core": { + "version": "7.22.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.8.tgz", + "integrity": "sha512-75+KxFB4CZqYRXjx4NlR4J7yGvKumBuZTmV4NV6v09dVXXkuYVYLT68N6HCzLvfJ+fWCxQsntNzKwwIXL4bHnw==", "dev": true, - "requires": { - "micromatch": "2.3.11", - "normalize-path": "2.1.1" + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.7", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helpers": "^7.22.6", + "@babel/parser": "^7.22.7", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.8", + "@babel/types": "^7.22.5", + "@nicolo-ribaudo/semver-v6": "^6.3.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "append-transform": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", - "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", + "node_modules/@babel/generator": { + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.7.tgz", + "integrity": "sha512-p+jPjMG+SI8yvIaxGgeW24u7q9+5+TGpZh8/CuB7RhBKd7RCy8FayNEFNNKrNK/eUcY/4ExQqLmyrvBXKsIcwQ==", "dev": true, - "requires": { - "default-require-extensions": "1.0.0" + "dependencies": { + "@babel/types": "^7.22.5", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz", + "integrity": "sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA==", "dev": true, - "requires": { - "sprintf-js": "1.0.3" + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-validator-option": "^7.22.5", + "@nicolo-ribaudo/semver-v6": "^6.3.3", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", + "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", "dev": true, - "requires": { - "arr-flatten": "1.1.0" + "engines": { + "node": ">=6.9.0" } }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "array-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", - "dev": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "node_modules/@babel/helper-function-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", + "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", "dev": true, - "requires": { - "array-uniq": "1.0.3" + "dependencies": { + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, - "async": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz", - "integrity": "sha1-rDYTsdqb7RtHUQu0ZRuJMeRxRsc=" - }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, - "optional": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" - }, - "babel-cli": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", - "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", - "dev": true, - "requires": { - "babel-core": "6.26.0", - "babel-polyfill": "6.26.0", - "babel-register": "6.26.0", - "babel-runtime": "6.26.0", - "chokidar": "1.7.0", - "commander": "2.12.2", - "convert-source-map": "1.5.1", - "fs-readdir-recursive": "1.1.0", - "glob": "7.1.2", - "lodash": "4.17.4", - "output-file-sync": "1.1.2", - "path-is-absolute": "1.0.1", - "slash": "1.0.0", - "source-map": "0.5.7", - "v8flags": "2.1.1" + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "node_modules/@babel/helper-module-imports": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", "dev": true, - "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "babel-core": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", - "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", + "node_modules/@babel/helper-module-transforms": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz", + "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==", "dev": true, - "requires": { - "babel-code-frame": "6.26.0", - "babel-generator": "6.26.0", - "babel-helpers": "6.24.1", - "babel-messages": "6.23.0", - "babel-register": "6.26.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "convert-source-map": "1.5.1", - "debug": "2.6.9", - "json5": "0.5.1", - "lodash": "4.17.4", - "minimatch": "3.0.4", - "path-is-absolute": "1.0.1", - "private": "0.1.8", - "slash": "1.0.0", - "source-map": "0.5.7" + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "babel-generator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz", - "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=", + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "dev": true, - "requires": { - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "detect-indent": "4.0.0", - "jsesc": "1.3.0", - "lodash": "4.17.4", - "source-map": "0.5.7", - "trim-right": "1.0.1" + "engines": { + "node": ">=6.9.0" } }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, - "requires": { - "babel-helper-explode-assignable-expression": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, - "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "babel-helper-define-map": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "dev": true, - "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.4" + "engines": { + "node": ">=6.9.0" } }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", "dev": true, - "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "engines": { + "node": ">=6.9.0" } }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "node_modules/@babel/helper-validator-option": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", + "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", "dev": true, - "requires": { - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "engines": { + "node": ">=6.9.0" } }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "node_modules/@babel/helpers": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz", + "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==", "dev": true, - "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.6", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "node_modules/@babel/highlight": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", "dev": true, - "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "node_modules/@babel/parser": { + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", + "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==", "dev": true, - "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" } }, - "babel-helper-regex": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", - "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, - "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, - "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, - "requires": { - "babel-helper-optimise-call-expression": "6.24.1", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, - "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-jest": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-21.2.0.tgz", - "integrity": "sha512-O0W2qLoWu1QOoOGgxiR2JID4O6WSpxPiQanrkyi9SSlM0PJ60Ptzlck47lhtnr9YZO3zYOsxHwnyeWJ6AffoBQ==", + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, - "requires": { - "babel-plugin-istanbul": "4.1.5", - "babel-preset-jest": "21.2.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", "dev": true, - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-plugin-istanbul": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.5.tgz", - "integrity": "sha1-Z2DN2Xf0EdPhdbsGTyvDJ9mbK24=", + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "requires": { - "find-up": "2.1.0", - "istanbul-lib-instrument": "1.9.1", - "test-exclude": "4.1.1" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-plugin-jest-hoist": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-21.2.0.tgz", - "integrity": "sha512-yi5QuiVyyvhBUDLP4ButAnhYzkdrUwWDtvUJv71hjH3fclhnZg4HkDeqaitcR2dZZx/E67kGkRcPVjtVu+SJfQ==", - "dev": true - }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", - "dev": true - }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", - "dev": true - }, - "babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", - "dev": true - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", - "dev": true - }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, - "requires": { - "babel-helper-remap-async-to-generator": "6.24.1", - "babel-plugin-syntax-async-functions": "6.13.0", - "babel-runtime": "6.26.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, - "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, - "requires": { - "babel-helper-define-map": "6.26.0", - "babel-helper-function-name": "6.24.1", - "babel-helper-optimise-call-expression": "6.24.1", - "babel-helper-replace-supers": "6.24.1", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", + "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", "dev": true, - "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "node_modules/@babel/template": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", + "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", "dev": true, - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "@babel/code-frame": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "node_modules/@babel/traverse": { + "version": "7.22.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.8.tgz", + "integrity": "sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==", "dev": true, - "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.7", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.22.7", + "@babel/types": "^7.22.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "node_modules/@babel/types": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", + "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", "dev": true, - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@gerrit0/mini-shiki": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.4.2.tgz", + "integrity": "sha512-3jXo5bNjvvimvdbIhKGfFxSnKCX+MA8wzHv55ptzk/cx8wOzT+BRcYgj8aFN3yTiTs+zvQQiaZFr7Jce1ZG3fw==", "dev": true, - "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "license": "MIT", + "dependencies": { + "@shikijs/engine-oniguruma": "^3.4.2", + "@shikijs/langs": "^3.4.2", + "@shikijs/themes": "^3.4.2", + "@shikijs/types": "^3.4.2", + "@shikijs/vscode-textmate": "^10.0.2" } }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "engines": { + "node": ">=8" } }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz", - "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, - "requires": { - "babel-plugin-transform-strict-mode": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-types": "6.26.0" + "engines": { + "node": ">=8" } }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "node_modules/@jest/console": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.1.tgz", + "integrity": "sha512-Aj772AYgwTSr5w8qnyoJ0eDYvN6bMsH3ORH1ivMotrInHLKdUz6BDlaEXHdM6kODaBIkNIyQGzsMvRdOv7VG7Q==", "dev": true, - "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "dependencies": { + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "node_modules/@jest/console/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, - "requires": { - "babel-helper-replace-supers": "6.24.1", - "babel-runtime": "6.26.0" + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "node_modules/@jest/console/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { - "babel-helper-call-delegate": "6.24.1", - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "node_modules/@jest/console/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/console/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, - "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "engines": { + "node": ">=8" } }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "node_modules/@jest/console/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, - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "node_modules/@jest/core": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.1.tgz", + "integrity": "sha512-CcowHypRSm5oYQ1obz1wfvkjZZ2qoQlrKKvlfPwh5jUXVU12TWr2qMeH8chLMuTFzHh5a1g2yaqlqDICbr+ukQ==", "dev": true, - "requires": { - "babel-helper-regex": "6.26.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "@jest/console": "^29.6.1", + "@jest/reporters": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.6.1", + "jest-haste-map": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.6.1", + "jest-resolve-dependencies": "^29.6.1", + "jest-runner": "^29.6.1", + "jest-runtime": "^29.6.1", + "jest-snapshot": "^29.6.1", + "jest-util": "^29.6.1", + "jest-validate": "^29.6.1", + "jest-watcher": "^29.6.1", + "micromatch": "^4.0.4", + "pretty-format": "^29.6.1", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "node_modules/@jest/core/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, - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "node_modules/@jest/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, - "requires": { - "babel-runtime": "6.26.0" + "engines": { + "node": ">=8" } }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { - "babel-helper-regex": "6.26.0", - "babel-runtime": "6.26.0", - "regexpu-core": "2.0.0" + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "node_modules/@jest/core/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, - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", - "babel-plugin-syntax-exponentiation-operator": "6.13.0", - "babel-runtime": "6.26.0" + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "node_modules/@jest/core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { - "regenerator-transform": "0.10.1" + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "node_modules/@jest/core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/core/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, - "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "engines": { + "node": ">=8" } }, - "babel-polyfill": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", - "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "node_modules/@jest/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, - "requires": { - "babel-runtime": "6.26.0", - "core-js": "2.5.3", - "regenerator-runtime": "0.10.5" - }, "dependencies": { - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", - "dev": true - } + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "babel-preset-env": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz", - "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "6.22.0", - "babel-plugin-syntax-trailing-function-commas": "6.22.0", - "babel-plugin-transform-async-to-generator": "6.24.1", - "babel-plugin-transform-es2015-arrow-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoping": "6.26.0", - "babel-plugin-transform-es2015-classes": "6.24.1", - "babel-plugin-transform-es2015-computed-properties": "6.24.1", - "babel-plugin-transform-es2015-destructuring": "6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", - "babel-plugin-transform-es2015-for-of": "6.23.0", - "babel-plugin-transform-es2015-function-name": "6.24.1", - "babel-plugin-transform-es2015-literals": "6.22.0", - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", - "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", - "babel-plugin-transform-es2015-modules-umd": "6.24.1", - "babel-plugin-transform-es2015-object-super": "6.24.1", - "babel-plugin-transform-es2015-parameters": "6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", - "babel-plugin-transform-es2015-spread": "6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "6.24.1", - "babel-plugin-transform-es2015-template-literals": "6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "6.24.1", - "babel-plugin-transform-exponentiation-operator": "6.24.1", - "babel-plugin-transform-regenerator": "6.26.0", - "browserslist": "2.10.0", - "invariant": "2.2.2", - "semver": "5.4.1" + "node_modules/@jest/core/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "babel-preset-jest": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-21.2.0.tgz", - "integrity": "sha512-hm9cBnr2h3J7yXoTtAVV0zg+3vg0Q/gT2GYuzlreTU0EPkJRtlNgKJJ3tBKEn0+VjAi3JykV6xCJkuUYttEEfA==", + "node_modules/@jest/environment": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.1.tgz", + "integrity": "sha512-RMMXx4ws+Gbvw3DfLSuo2cfQlK7IwGbpuEWXCqyYDcqYTI+9Ju3a5hDnXaxjNsa6uKh9PQF2v+qg+RLe63tz5A==", "dev": true, - "requires": { - "babel-plugin-jest-hoist": "21.2.0", - "babel-plugin-syntax-object-rest-spread": "6.13.0" + "dependencies": { + "@jest/fake-timers": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "jest-mock": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "node_modules/@jest/expect": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.6.1.tgz", + "integrity": "sha512-N5xlPrAYaRNyFgVf2s9Uyyvr795jnB6rObuPx4QFvNJz8aAjpZUDfO4bh5G/xuplMID8PrnuF1+SfSyDxhsgYg==", "dev": true, - "requires": { - "babel-core": "6.26.0", - "babel-runtime": "6.26.0", - "core-js": "2.5.3", - "home-or-tmp": "2.0.0", - "lodash": "4.17.4", - "mkdirp": "0.5.1", - "source-map-support": "0.4.18" + "dependencies": { + "expect": "^29.6.1", + "jest-snapshot": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "node_modules/@jest/expect-utils": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.1.tgz", + "integrity": "sha512-o319vIf5pEMx0LmzSxxkYYxo4wrRLKHq9dP1yJU7FoPTB0LfAKSz8SWD6D/6U3v/O52t9cF5t+MeJiRsfk7zMw==", "dev": true, - "requires": { - "core-js": "2.5.3", - "regenerator-runtime": "0.11.1" + "dependencies": { + "jest-get-type": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "node_modules/@jest/fake-timers": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.1.tgz", + "integrity": "sha512-RdgHgbXyosCDMVYmj7lLpUwXA4c69vcNzhrt69dJJdf8azUrpRh3ckFCaTPNjsEeRi27Cig0oKDGxy5j7hOgHg==", "dev": true, - "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "lodash": "4.17.4" + "dependencies": { + "@jest/types": "^29.6.1", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.6.1", + "jest-mock": "^29.6.1", + "jest-util": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "node_modules/@jest/globals": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.6.1.tgz", + "integrity": "sha512-2VjpaGy78JY9n9370H8zGRCFbYVWwjY6RdDMhoJHa1sYfwe6XM/azGN0SjY8kk7BOZApIejQ1BFPyH7FPG0w3A==", "dev": true, - "requires": { - "babel-code-frame": "6.26.0", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "debug": "2.6.9", - "globals": "9.18.0", - "invariant": "2.2.2", - "lodash": "4.17.4" + "dependencies": { + "@jest/environment": "^29.6.1", + "@jest/expect": "^29.6.1", + "@jest/types": "^29.6.1", + "jest-mock": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "node_modules/@jest/reporters": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.1.tgz", + "integrity": "sha512-9zuaI9QKr9JnoZtFQlw4GREQbxgmNYXU6QuWtmuODvk5nvPUeBYapVR/VYMyi2WSx3jXTLJTJji8rN6+Cm4+FA==", "dev": true, - "requires": { - "babel-runtime": "6.26.0", - "esutils": "2.0.2", - "lodash": "4.17.4", - "to-fast-properties": "1.0.3" + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1", + "jest-worker": "^29.6.1", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, - "backoff": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.4.1.tgz", - "integrity": "sha1-L2jFDg3Xidvv4kIApi77BNJFbWg=", - "requires": { - "precond": "0.2.3" + "node_modules/@jest/reporters/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, + "engines": { + "node": ">=8" } }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", - "optional": true, - "requires": { - "tweetnacl": "0.14.5" + "node_modules/@jest/reporters/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, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "binary-extensions": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", - "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "node_modules/@jest/reporters/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "optional": true + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } }, - "bluebird": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", - "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=" + "node_modules/@jest/reporters/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "boom": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", - "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", - "requires": { - "hoek": "4.2.0" + "node_modules/@jest/reporters/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, + "engines": { + "node": ">=8" } }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "node_modules/@jest/reporters/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, - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "node_modules/@jest/reporters/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, - "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "browser-resolve": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", - "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", + "node_modules/@jest/schemas": { + "version": "29.6.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz", + "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==", "dev": true, - "requires": { - "resolve": "1.1.7" + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "browserslist": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.10.0.tgz", - "integrity": "sha512-WyvzSLsuAVPOjbljXnyeWl14Ae+ukAT8MUuagKVzIDvwBxl4UAwD1xqtyQs2eWYPGUKMeC3Ol62goqYuKqTTcw==", + "node_modules/@jest/source-map": { + "version": "29.6.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.0.tgz", + "integrity": "sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA==", "dev": true, - "requires": { - "caniuse-lite": "1.0.30000784", - "electron-to-chromium": "1.3.30" + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "bser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", - "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "node_modules/@jest/test-result": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.1.tgz", + "integrity": "sha512-Ynr13ZRcpX6INak0TPUukU8GWRfm/vAytE3JbJNGAvINySWYdfE7dGZMbk36oVuK4CigpbhMn8eg1dixZ7ZJOw==", "dev": true, - "requires": { - "node-int64": "0.4.0" + "dependencies": { + "@jest/console": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "node_modules/@jest/test-sequencer": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.1.tgz", + "integrity": "sha512-oBkC36PCDf/wb6dWeQIhaviU0l5u6VCsXa119yqdUosYAt7/FbQU2M2UoziO3igj/HBDEgp57ONQ3fm0v9uyyg==", "dev": true, - "requires": { - "callsites": "0.2.0" + "dependencies": { + "@jest/test-result": "^29.6.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "node_modules/@jest/transform": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.1.tgz", + "integrity": "sha512-URnTneIU3ZjRSaf906cvf6Hpox3hIeJXRnz3VDSw5/X93gR8ycdfSIEy19FlVx8NFmpN7fe3Gb1xF+NjXaQLWg==", "dev": true, - "optional": true - }, - "caniuse-lite": { - "version": "1.0.30000784", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000784.tgz", - "integrity": "sha1-EpztdOmhKApEGIC2zSvOMO9Z5sA=", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.1", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.1", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.6.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "optional": true, - "requires": { - "align-text": "0.1.4", - "lazy-cache": "1.0.4" + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "node_modules/@jest/transform/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, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "node_modules/@jest/transform/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "optional": true, - "requires": { - "anymatch": "1.3.2", - "async-each": "1.0.1", - "fsevents": "1.1.3", - "glob-parent": "2.0.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "2.0.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0" + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "ci-info": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.2.tgz", - "integrity": "sha512-uTGIPNx/nSpBdsF6xnseRXLLtfr9VLqkz8ZqHXr3Y7b6SftyRxBGjwMtJj1OhNbmlc1wZzLNAlAcvyIiE8a6ZA==", + "node_modules/@jest/transform/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "node_modules/@jest/transform/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, - "requires": { - "restore-cursor": "2.0.0" + "engines": { + "node": ">=8" } }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true + "node_modules/@jest/transform/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "node_modules/@jest/types": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.1.tgz", + "integrity": "sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==", "dev": true, - "optional": true, - "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", - "wordwrap": "0.0.2" + "dependencies": { + "@jest/schemas": "^29.6.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true, - "optional": true - } + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "clone": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.1.tgz", - "integrity": "sha1-CwimMbxqSkG4nOKj1D+KhNZrTUs=" + "node_modules/@jest/types/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, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "node_modules/@jest/types/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, - "requires": { - "color-name": "1.1.3" + "engines": { + "node": ">=8" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", - "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", - "requires": { - "delayed-stream": "1.0.0" + "node_modules/@jest/types/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "commander": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", - "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", - "dev": true + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } }, - "concat-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "typedarray": "0.0.6" + "engines": { + "node": ">=6.0.0" } }, - "content-type-parser": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz", - "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, - "convert-source-map": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", - "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", - "dev": true + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } }, - "core-js": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz", - "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=", + "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "node_modules/@nicolo-ribaudo/semver-v6": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz", + "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==", "dev": true, - "requires": { - "lru-cache": "4.1.1", - "shebang-command": "1.2.0", - "which": "1.3.0" + "bin": { + "semver": "bin/semver.js" } }, - "cryptiles": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", - "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", - "requires": { - "boom": "5.2.0" - }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.4.2.tgz", + "integrity": "sha512-zcZKMnNndgRa3ORja6Iemsr3DrLtkX3cAF7lTJkdMB6v9alhlBsX9uNiCpqofNrXOvpA3h6lHcLJxgCIhVOU5Q==", + "dev": true, + "license": "MIT", "dependencies": { - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "requires": { - "hoek": "4.2.0" - } - } + "@shikijs/types": "3.4.2", + "@shikijs/vscode-textmate": "^10.0.2" } }, - "cssom": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", - "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=", - "dev": true - }, - "cssstyle": { - "version": "0.2.37", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", - "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", + "node_modules/@shikijs/langs": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.4.2.tgz", + "integrity": "sha512-H6azIAM+OXD98yztIfs/KH5H4PU39t+SREhmM8LaNXyUrqj2mx+zVkr8MWYqjceSjDw9I1jawm1WdFqU806rMA==", "dev": true, - "requires": { - "cssom": "0.3.2" + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.4.2" } }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "1.0.0" + "node_modules/@shikijs/themes": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.4.2.tgz", + "integrity": "sha512-qAEuAQh+brd8Jyej2UDDf+b4V2g1Rm8aBIdvt32XhDPrHvDkEnpb7Kzc9hSuHUxz0Iuflmq7elaDuQAP9bHIhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.4.2" } }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/@shikijs/types": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.4.2.tgz", + "integrity": "sha512-zHC1l7L+eQlDXLnxvM9R91Efh2V4+rN3oMVS2swCBssbj2U/FBwybD1eeLaq8yl/iwT+zih8iUbTBCgGZOYlVg==", "dev": true, - "requires": { - "ms": "2.0.0" + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "dev": true, + "license": "MIT" }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, - "default-require-extensions": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", - "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", + "node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", "dev": true, - "requires": { - "strip-bom": "2.0.0" + "dependencies": { + "type-detect": "4.0.8" } }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, - "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.2" + "dependencies": { + "@sinonjs/commons": "^3.0.0" } }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "node_modules/@types/babel__core": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", + "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", "dev": true, - "requires": { - "repeating": "2.0.1" + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" } }, - "diff": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", - "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==", - "dev": true + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } }, - "doctrine": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", - "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==", + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, - "requires": { - "esutils": "2.0.2" + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "optional": true, - "requires": { - "jsbn": "0.1.1" + "node_modules/@types/babel__traverse": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz", + "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" } }, - "electron-releases": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/electron-releases/-/electron-releases-2.1.0.tgz", - "integrity": "sha512-cyKFD1bTE/UgULXfaueIN1k5EPFzs+FRc/rvCY5tIynefAPqopQEgjr0EzY+U3Dqrk/G4m9tXSPuZ77v6dL/Rw==", + "node_modules/@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", "dev": true }, - "electron-to-chromium": { - "version": "1.3.30", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.30.tgz", - "integrity": "sha512-zx1Prv7kYLfc4OA60FhxGbSo4qrEjgSzpo1/37i7l9ltXPYOoQBtjQxY9KmsgfHnBxHlBGXwLlsbt/gub1w5lw==", - "dev": true, - "requires": { - "electron-releases": "2.1.0" - } - }, - "errno": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.6.tgz", - "integrity": "sha512-IsORQDpaaSwcDP4ZZnHxgE85werpo34VYn1Ud3mq+eUsF593faR8oCZNXrROVkpFu2TsbrNhHin0aUrTsQ9vNw==", + "node_modules/@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", "dev": true, - "requires": { - "prr": "1.0.1" + "dependencies": { + "@types/node": "*" } }, - "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", "dev": true, - "requires": { - "is-arrayish": "0.2.1" + "license": "MIT", + "dependencies": { + "@types/unist": "*" } }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, - "escodegen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz", - "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==", + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", "dev": true, - "requires": { - "esprima": "3.1.3", - "estraverse": "4.2.0", - "esutils": "2.0.2", - "optionator": "0.8.2", - "source-map": "0.5.7" - }, "dependencies": { - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true - } + "@types/istanbul-lib-coverage": "*" } }, - "eslint": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.14.0.tgz", - "integrity": "sha512-Ul6CSGRjKscEyg0X/EeNs7o2XdnbTEOD1OM8cTjmx85RPcBJQrEhZLevhuJZNAE/vS2iVl5Uhgiqf3h5uLMCJQ==", - "dev": true, - "requires": { - "ajv": "5.5.2", - "babel-code-frame": "6.26.0", - "chalk": "2.3.0", - "concat-stream": "1.6.0", - "cross-spawn": "5.1.0", - "debug": "3.1.0", - "doctrine": "2.0.2", - "eslint-scope": "3.7.1", - "eslint-visitor-keys": "1.0.0", - "espree": "3.5.2", - "esquery": "1.0.0", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "functional-red-black-tree": "1.0.1", - "glob": "7.1.2", - "globals": "11.1.0", - "ignore": "3.3.7", - "imurmurhash": "0.1.4", - "inquirer": "3.3.0", - "is-resolvable": "1.0.1", - "js-yaml": "3.10.0", - "json-stable-stringify-without-jsonify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.4", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "7.0.0", - "progress": "2.0.0", - "require-uncached": "1.0.3", - "semver": "5.4.1", - "strip-ansi": "4.0.0", - "strip-json-comments": "2.0.1", - "table": "4.0.2", - "text-table": "0.2.0" - }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.1" - } - }, - "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "globals": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.1.0.tgz", - "integrity": "sha512-uEuWt9mqTlPDwSqi+sHjD4nWU/1N+q0fiWI9T1mZpD2UENqX20CFD5T/ziLZvztPaBKl7ZylUi1q6Qfm7E2CiQ==", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "3.0.0" - } - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "2.0.0" - } - } + "@types/istanbul-lib-report": "*" } }, - "eslint-config-prettier": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-2.9.0.tgz", - "integrity": "sha512-ag8YEyBXsm3nmOv1Hz991VtNNDMRa+MNy8cY47Pl4bw6iuzqKbJajXdqUpiw13STdLLrznxgm1hj9NhxeOYq0A==", + "node_modules/@types/jest": { + "version": "29.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.2.tgz", + "integrity": "sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg==", "dev": true, - "requires": { - "get-stdin": "5.0.1" + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" } }, - "eslint-plugin-prettier": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.4.0.tgz", - "integrity": "sha512-P0EohHM1MwL36GX5l1TOEYyt/5d7hcxrX3CqCjibTN3dH7VCAy2kjsC/WB6dUHnpB4mFkZq1Ndfh2DYQ2QMEGQ==", + "node_modules/@types/json-schema": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/mime-types": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.2.tgz", + "integrity": "sha512-q9QGHMGCiBJCHEvd4ZLdasdqXv570agPsUW0CeIm/B8DzhxsYMerD0l3IlI+EQ1A2RWHY2mmM9x1YIuuWxisCg==", + "dev": true + }, + "node_modules/@types/node": { + "version": "22.15.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz", + "integrity": "sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==", "dev": true, - "requires": { - "fast-diff": "1.1.2", - "jest-docblock": "21.2.0" + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" } }, - "eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "dev": true + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", "dev": true, - "requires": { - "esrecurse": "4.2.0", - "estraverse": "4.2.0" - } + "license": "MIT" }, - "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", "dev": true }, - "espree": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", - "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", + "node_modules/@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", "dev": true, - "requires": { - "acorn": "5.3.0", - "acorn-jsx": "3.0.1" + "dependencies": { + "@types/yargs-parser": "*" } }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, - "esquery": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", - "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz", + "integrity": "sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==", "dev": true, - "requires": { - "estraverse": "4.2.0" + "dependencies": { + "@typescript-eslint/experimental-utils": "2.34.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^2.0.0", + "eslint": "^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "esrecurse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", - "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "node_modules/@typescript-eslint/experimental-utils": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", + "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", "dev": true, - "requires": { - "estraverse": "4.2.0", - "object-assign": "4.1.1" + "dependencies": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" } }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "exec-sh": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.1.tgz", - "integrity": "sha512-aLt95pexaugVtQerpmE51+4QfWrNc304uez7jvj6fWnN8GeEHpttB8F36n8N7uVhUMbH/1enbxQ9HImZ4w/9qg==", + "node_modules/@typescript-eslint/parser": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.34.0.tgz", + "integrity": "sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==", "dev": true, - "requires": { - "merge": "1.2.0" + "dependencies": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "2.34.0", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", "dev": true, - "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "dependencies": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", "dev": true, - "requires": { - "is-posix-bracket": "0.1.1" + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" } }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "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, - "requires": { - "fill-range": "2.2.3" + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "expect": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-21.2.1.tgz", - "integrity": "sha512-orfQQqFRTX0jH7znRIGi8ZMR8kTNpXklTTz8+HGTpmTKZo3Occ6JNB5FXMb8cRuiiC/GyDqsr30zUa66ACYlYw==", + "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, - "requires": { - "ansi-styles": "3.2.0", - "jest-diff": "21.2.1", - "jest-get-type": "21.2.0", - "jest-matcher-utils": "21.2.1", - "jest-message-util": "21.2.1", - "jest-regex-util": "21.2.0" - }, "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.1" - } - } + "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" } }, - "extend": { + "node_modules/ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-regex": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "external-editor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", - "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "requires": { - "chardet": "0.4.2", - "iconv-lite": "0.4.19", - "tmp": "0.0.33" + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, - "requires": { - "is-extglob": "1.0.0" + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } }, - "fast-deep-equal": { + "node_modules/array-buffer-byte-length": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", - "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "fast-diff": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz", - "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==", - "dev": true + "node_modules/array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + "node_modules/array.prototype.findlastindex": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.2.tgz", + "integrity": "sha512-tb5thFFlUcp7NdNF6/MpDk/1r/4awWG1FIz3YqDf+/zJSTezBb+/5WViH41obXULHVpDzoiCLpJ/ZO9YbJMsdw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "node_modules/array.prototype.flat": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "fb-watchman": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", - "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", + "node_modules/array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", "dev": true, - "requires": { - "bser": "2.0.0" + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz", + "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==", "dev": true, - "requires": { - "escape-string-regexp": "1.0.5" + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "node_modules/astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true, - "requires": { - "flat-cache": "1.3.0", - "object-assign": "4.1.1" + "engines": { + "node": ">=4" } }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "fileset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", - "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "node_modules/babel-jest": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.1.tgz", + "integrity": "sha512-qu+3bdPEQC6KZSPz+4Fyjbga5OODNcp49j6GKzG1EKbkfyJBxEYGVUmVGpwCSeGouG52R4EgYMLb6p9YeEEQ4A==", "dev": true, - "requires": { - "glob": "7.1.2", - "minimatch": "3.0.4" + "dependencies": { + "@jest/transform": "^29.6.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.5.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" } }, - "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "node_modules/babel-jest/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, - "requires": { - "locate-path": "2.0.0" + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "node_modules/babel-jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { - "circular-json": "0.3.3", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "node_modules/babel-jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "node_modules/babel-jest/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, - "requires": { - "for-in": "1.0.2" + "engines": { + "node": ">=8" } }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", - "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" + "node_modules/babel-jest/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", + "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", + "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.5.0", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "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 + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "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, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", + "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001503", + "electron-to-chromium": "^1.4.431", + "node-releases": "^2.0.12", + "update-browserslist-db": "^1.0.11" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "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==", + "dev": true, + "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==", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001512", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001512.tgz", + "integrity": "sha512-2S9nK0G/mE+jasCUsMPlARhRCts1ebcp2Ji8Y8PWi4NDE1iRdLCnEPHkEfeBrGC45L4isBx5ur3IQ6yTE2mRZw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "dependencies": { + "camel-case": "^4.1.2", + "capital-case": "^1.0.4", + "constant-case": "^3.0.4", + "dot-case": "^3.0.4", + "header-case": "^2.0.4", + "no-case": "^3.0.4", + "param-case": "^3.0.4", + "pascal-case": "^3.1.2", + "path-case": "^3.0.4", + "sentence-case": "^3.0.4", + "snake-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true + }, + "node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "dev": true, + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "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==", + "dev": 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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "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==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/cross-fetch": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", + "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "node-fetch": "^2.7.0" + } + }, + "node_modules/cross-fetch/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": 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 + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "dev": true, + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.451", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.451.tgz", + "integrity": "sha512-YYbXHIBxAHe3KWvGOJOuWa6f3tgow44rBW+QAuwVp2DvGqNZeE//K2MowNdWS7XE8li5cgQDrX1LdBr41LufkA==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "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==", + "dev": true + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", + "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.1", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.2.1", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.0", + "safe-array-concat": "^1.0.0", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^6.14.0 || ^8.10.0 || >=9.10.0" + } + }, + "node_modules/eslint-config-prettier": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-4.3.0.tgz", + "integrity": "sha512-sZwhSTHVVz78+kYD3t5pCWSYEdVSBR0PXnwjDRsUs8ytIrK8PLXw+6FKp8r3Z7rx4ZszdetWlXYKOHoUrrwPlA==", + "dev": true, + "dependencies": { + "get-stdin": "^6.0.0" + }, + "bin": { + "eslint-config-prettier-check": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=3.14.1" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-custom-rules": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-custom-rules/-/eslint-plugin-custom-rules-0.0.0.tgz", + "integrity": "sha512-AWzQCMQK36n/Jv0ClVdVIBo8PZ2CtxQ8zejuVC6eh0vwVeZ3F9SY5ZoNULpu/E06nYN+bZ1EfEudGQPSR3AxZA==", + "dev": true, + "dependencies": { + "jsx-ast-utils": "^1.3.5", + "lodash": "^4.17.4", + "object-assign": "^4.1.0", + "requireindex": "~1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.28.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", + "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.findlastindex": "^1.2.2", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.8.0", + "has": "^1.0.3", + "is-core-module": "^2.13.0", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.6", + "object.groupby": "^1.0.0", + "object.values": "^1.1.6", + "semver": "^6.3.1", + "tsconfig-paths": "^3.14.2" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "eslint": ">=5.0.0", + "prettier": ">=1.13.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/eslint/node_modules/eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint/node_modules/regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true, + "engines": { + "node": ">=6.5.0" + } + }, + "node_modules/eslint/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "dependencies": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/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, + "engines": { + "node": ">=4.0" + } + }, + "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, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/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, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/execa/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/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, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/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, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.1.tgz", + "integrity": "sha512-XEdDLonERCU1n9uR56/Stx9OqojaLAQtZf9PrCHH9Hl8YXiEIka3H4NXJ3NOIBmQJTg7+j7buh34PMHfJujc8g==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.6.1", + "@types/node": "*", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "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 + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "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 + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "dependencies": { + "flat-cache": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "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, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "dependencies": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/form-data-encoder": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-4.1.0.tgz", + "integrity": "sha512-G6NsmEW15s0Uw9XnCg+33H3ViYRyiM0hMrMhhqQOR8NFc5GhYrI+6I3u7OTw7b91J2g8rtvMBZJDbcGb2YUniw==", + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/formdata-node": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-6.0.3.tgz", + "integrity": "sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg==", + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "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 + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "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, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "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/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "dependencies": { + "capital-case": "^1.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "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, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/inquirer/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/inquirer/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "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, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.6.1.tgz", + "integrity": "sha512-Nirw5B4nn69rVUZtemCQhwxOBhm0nsp3hmtF4rzCeWD7BkjAXRIji7xWQfnTNbz9g0aVsBX6aZK3n+23LM6uDw==", + "dev": true, + "dependencies": { + "@jest/core": "^29.6.1", + "@jest/types": "^29.6.1", + "import-local": "^3.0.2", + "jest-cli": "^29.6.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", + "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.1.tgz", + "integrity": "sha512-tPbYLEiBU4MYAL2XoZme/bgfUeotpDBd81lgHLCbDZZFaGmECk0b+/xejPFtmiBP87GgP/y4jplcRpbH+fgCzQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.1", + "@jest/expect": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.6.1", + "jest-matcher-utils": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-runtime": "^29.6.1", + "jest-snapshot": "^29.6.1", + "jest-util": "^29.6.1", + "p-limit": "^3.1.0", + "pretty-format": "^29.6.1", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/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, + "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/jest-circus/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-circus/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-circus/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.1.tgz", + "integrity": "sha512-607dSgTA4ODIN6go9w6xY3EYkyPFGicx51a69H7yfvt7lN53xNswEVLovq+E77VsTRi5fWprLH0yl4DJgE8Ing==", + "dev": true, + "dependencies": { + "@jest/core": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/types": "^29.6.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.6.1", + "jest-util": "^29.6.1", + "jest-validate": "^29.6.1", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-cli/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, + "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/jest-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-cli/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.1.tgz", + "integrity": "sha512-XdjYV2fy2xYixUiV2Wc54t3Z4oxYPAELUzWnV6+mcbq0rh742X2p52pii5A3oeRzYjLnQxCsZmp0qpI6klE2cQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.6.1", + "@jest/types": "^29.6.1", + "babel-jest": "^29.6.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.6.1", + "jest-environment-node": "^29.6.1", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.6.1", + "jest-runner": "^29.6.1", + "jest-util": "^29.6.1", + "jest-validate": "^29.6.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.6.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/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, + "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/jest-config/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-config/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-config/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/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, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-config/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.1.tgz", + "integrity": "sha512-FsNCvinvl8oVxpNLttNQX7FAq7vR+gMDGj90tiP7siWw1UdakWUGqrylpsYrpvj908IYckm5Y0Q7azNAozU1Kg==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/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, + "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/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-diff/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-docblock": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", + "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.6.1.tgz", + "integrity": "sha512-n5eoj5eiTHpKQCAVcNTT7DRqeUmJ01hsAL0Q1SMiBHcBcvTKDELixQOGMCpqhbIuTcfC4kMfSnpmDqRgRJcLNQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "jest-util": "^29.6.1", + "pretty-format": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/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, + "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/jest-each/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-each/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-each/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-node": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.1.tgz", + "integrity": "sha512-ZNIfAiE+foBog24W+2caIldl4Irh8Lx1PUhg/GZ0odM1d/h2qORAsejiFc7zb+SEmYPn1yDZzEDSU5PmDkmVLQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.1", + "@jest/fake-timers": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "jest-mock": "^29.6.1", + "jest-util": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-fetch-mock": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/jest-fetch-mock/-/jest-fetch-mock-3.0.3.tgz", + "integrity": "sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-fetch": "^3.0.4", + "promise-polyfill": "^8.1.3" + } + }, + "node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.1.tgz", + "integrity": "sha512-0m7f9PZXxOCk1gRACiVgX85knUKPKLPg4oRCjLoqIm9brTHXaorMA0JpmtmVkQiT8nmXyIVoZd/nnH1cfC33ig==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.6.1", + "jest-worker": "^29.6.1", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.1.tgz", + "integrity": "sha512-OrxMNyZirpOEwkF3UHnIkAiZbtkBWiye+hhBweCHkVbCgyEy71Mwbb5zgeTNYWJBi1qgDVfPC1IwO9dVEeTLwQ==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.1.tgz", + "integrity": "sha512-SLaztw9d2mfQQKHmJXKM0HCbl2PPVld/t9Xa6P9sgiExijviSp7TnZZpw2Fpt+OI3nwUO/slJbOfzfUMKKC5QA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.6.1", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/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, + "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/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-matcher-utils/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.1.tgz", + "integrity": "sha512-KoAW2zAmNSd3Gk88uJ56qXUWbFk787QKmjjJVOjtGFmmGSZgDBrlIL4AfQw1xyMYPNVD7dNInfIbur9B2rd/wQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.6.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/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, + "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/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-message-util/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-mock": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.6.1.tgz", + "integrity": "sha512-brovyV9HBkjXAEdRooaTQK42n8usKoSRR3gihzUpYeV/vwqgSoNfrksO7UfSACnPmxasO/8TmHM3w9Hp3G1dgw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "@types/node": "*", + "jest-util": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.1.tgz", + "integrity": "sha512-AeRkyS8g37UyJiP9w3mmI/VXU/q8l/IH52vj/cDAyScDcemRbSBhfX/NMYIGilQgSVwsjxrCHf3XJu4f+lxCMg==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.6.1", + "jest-validate": "^29.6.1", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.1.tgz", + "integrity": "sha512-BbFvxLXtcldaFOhNMXmHRWx1nXQO5LoXiKSGQcA1LxxirYceZT6ch8KTE1bK3X31TNG/JbkI7OkS/ABexVahiw==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-resolve/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, + "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/jest-resolve/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-resolve/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-resolve/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.1.tgz", + "integrity": "sha512-tw0wb2Q9yhjAQ2w8rHRDxteryyIck7gIzQE4Reu3JuOBpGp96xWgF0nY8MDdejzrLCZKDcp8JlZrBN/EtkQvPQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.6.1", + "@jest/environment": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.6.1", + "jest-haste-map": "^29.6.1", + "jest-leak-detector": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-resolve": "^29.6.1", + "jest-runtime": "^29.6.1", + "jest-util": "^29.6.1", + "jest-watcher": "^29.6.1", + "jest-worker": "^29.6.1", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runner/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, + "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/jest-runner/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runner/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runner/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.1.tgz", + "integrity": "sha512-D6/AYOA+Lhs5e5il8+5pSLemjtJezUr+8zx+Sn8xlmOux3XOqx4d8l/2udBea8CRPqqrzhsKUsN/gBDE/IcaPQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.1", + "@jest/fake-timers": "^29.6.1", + "@jest/globals": "^29.6.1", + "@jest/source-map": "^29.6.0", + "@jest/test-result": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-mock": "^29.6.1", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.6.1", + "jest-snapshot": "^29.6.1", + "jest-util": "^29.6.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runtime/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, + "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/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runtime/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.6.1.tgz", + "integrity": "sha512-G4UQE1QQ6OaCgfY+A0uR1W2AY0tGXUPQpoUClhWHq1Xdnx1H6JOrC2nH5lqnOEqaDgbHFgIwZ7bNq24HpB180A==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.6.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.6.1", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1", + "natural-compare": "^1.4.0", + "pretty-format": "^29.6.1", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/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, + "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/jest-snapshot/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-snapshot/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.1.tgz", + "integrity": "sha512-NRFCcjc+/uO3ijUVyNOQJluf8PtGCe/W6cix36+M3cTFgiYqFOOW5MgN4JOOcvbUhcKTYVd1CvHz/LWi8d16Mg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/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, + "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/jest-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-util/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.1.tgz", + "integrity": "sha512-r3Ds69/0KCN4vx4sYAbGL1EVpZ7MSS0vLmd3gV78O+NAx3PDQQukRU5hNHPXlyqCgFY8XUk7EuTMLugh0KzahA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "leven": "^3.1.0", + "pretty-format": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-validate/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, + "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/jest-validate/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-validate/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.1.tgz", + "integrity": "sha512-d4wpjWTS7HEZPaaj8m36QiaP856JthRZkrgcIY/7ISoUWPIillrXM23WPboZVLbiwZBt4/qn2Jke84Sla6JhFA==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.6.1", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-watcher/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, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watcher/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, + "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/jest-watcher/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-watcher/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.1.tgz", + "integrity": "sha512-U+Wrbca7S8ZAxAe9L6nb6g8kPdia5hj32Puu5iOqBCMTMWFHXuK6dOV2IFrpedbTV8fjMFLdWNttQTBL6u2MRA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.6.1", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "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 + }, + "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 + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsx-ast-utils": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", + "integrity": "sha512-0LwSmMlQjjUdXsdlyYhEfBJCn2Chm0zgUBmfmf1++KUULh+JOdlzrZfiwe2zmlVJx44UF+KX/B/odBoeK9hxmw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "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, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "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==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it/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/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" + }, + "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 + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "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==", + "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==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "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==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", + "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-run-path/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.0.tgz", + "integrity": "sha512-70MWG6NfRH9GnbZOikuhPPYzpUpof9iW2J9E4dW7FXTqPNb6rllE6u39SKwwiNh8lCwX3DDb5OgcKGiEBrTTyw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.21.2", + "get-intrinsic": "^1.2.1" + } + }, + "node_modules/object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "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, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "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, + "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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", + "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-polyfill": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.3.0.tgz", + "integrity": "sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg==", + "dev": true, + "license": "MIT" + }, + "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, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-rand": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz", + "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", + "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requireindex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.1.0.tgz", + "integrity": "sha512-LBnkqsDE7BZKvqylbmn7lTIVdpx4K/QCduRATpO5R+wtPmky/a8pN1bO2D6wXppn1497AJF9mNjqAXr6bdl9jg==", + "dev": true, + "engines": { + "node": ">=0.10.5" + } + }, + "node_modules/resolve": { + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", + "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", + "dev": true, + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/rxjs/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/safe-array-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", + "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.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 + }, + "node_modules/semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "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==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length/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, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", + "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "dependencies": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/table/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/table/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ts-jest": { + "version": "29.1.1", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", + "integrity": "sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", + "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedoc": { + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.4.tgz", + "integrity": "sha512-xKvKpIywE1rnqqLgjkoq0F3wOqYaKO9nV6YkkSat6IxOWacUCc/7Es0hR3OPmkIqkPoEn7U3x+sYdG72rstZQA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@gerrit0/mini-shiki": "^3.2.2", + "lunr": "^2.3.9", + "markdown-it": "^14.1.0", + "minimatch": "^9.0.5", + "yaml": "^2.7.1" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 18", + "pnpm": ">= 10" + }, + "peerDependencies": { + "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x" + } + }, + "node_modules/typedoc-plugin-rename-defaults": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/typedoc-plugin-rename-defaults/-/typedoc-plugin-rename-defaults-0.7.3.tgz", + "integrity": "sha512-fDtrWZ9NcDfdGdlL865GW7uIGQXlthPscURPOhDkKUe4DBQSRRFUf33fhWw41FLlsz8ZTeSxzvvuNmh54MynFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^8.0.0" + }, + "peerDependencies": { + "typedoc": ">=0.22.x <0.29.x" + } + }, + "node_modules/typedoc-plugin-rename-defaults/node_modules/camelcase": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedoc/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/typedoc/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/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "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==", + "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, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "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/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "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==", + "dev": true, + "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 + }, + "node_modules/write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.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==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yaml": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": 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==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" } }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "dev": true, + "requires": { + "@babel/highlight": "^7.22.5" + } + }, + "@babel/compat-data": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz", + "integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==", "dev": true }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "@babel/core": { + "version": "7.22.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.8.tgz", + "integrity": "sha512-75+KxFB4CZqYRXjx4NlR4J7yGvKumBuZTmV4NV6v09dVXXkuYVYLT68N6HCzLvfJ+fWCxQsntNzKwwIXL4bHnw==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.7", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helpers": "^7.22.6", + "@babel/parser": "^7.22.7", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.8", + "@babel/types": "^7.22.5", + "@nicolo-ribaudo/semver-v6": "^6.3.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2" + } + }, + "@babel/generator": { + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.7.tgz", + "integrity": "sha512-p+jPjMG+SI8yvIaxGgeW24u7q9+5+TGpZh8/CuB7RhBKd7RCy8FayNEFNNKrNK/eUcY/4ExQqLmyrvBXKsIcwQ==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz", + "integrity": "sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-validator-option": "^7.22.5", + "@nicolo-ribaudo/semver-v6": "^6.3.3", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", + "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", "dev": true }, - "fsevents": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", - "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", + "@babel/helper-function-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", + "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "dev": true, + "requires": { + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-module-imports": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-module-transforms": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz", + "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true + }, + "@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", + "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz", + "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==", + "dev": true, + "requires": { + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.6", + "@babel/types": "^7.22.5" + } + }, + "@babel/highlight": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", + "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==", + "dev": true + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, - "optional": true, "requires": { - "nan": "2.8.0", - "node-pre-gyp": "0.6.39" + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", + "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/template": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", + "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/types": "^7.22.5" + } + }, + "@babel/traverse": { + "version": "7.22.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.8.tgz", + "integrity": "sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.7", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.22.7", + "@babel/types": "^7.22.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", + "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@gerrit0/mini-shiki": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.4.2.tgz", + "integrity": "sha512-3jXo5bNjvvimvdbIhKGfFxSnKCX+MA8wzHv55ptzk/cx8wOzT+BRcYgj8aFN3yTiTs+zvQQiaZFr7Jce1ZG3fw==", + "dev": true, + "requires": { + "@shikijs/engine-oniguruma": "^3.4.2", + "@shikijs/langs": "^3.4.2", + "@shikijs/themes": "^3.4.2", + "@shikijs/types": "^3.4.2", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jest/console": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.1.tgz", + "integrity": "sha512-Aj772AYgwTSr5w8qnyoJ0eDYvN6bMsH3ORH1ivMotrInHLKdUz6BDlaEXHdM6kODaBIkNIyQGzsMvRdOv7VG7Q==", + "dev": true, + "requires": { + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1", + "slash": "^3.0.0" }, "dependencies": { - "abbrev": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", - "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "optional": true + "requires": { + "color-convert": "^2.0.1" + } }, - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "optional": true, "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "aproba": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.1.tgz", - "integrity": "sha1-ldNgDwdxCqDpKYxyatXs8urLq6s=", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "optional": true + "requires": { + "color-name": "~1.1.4" + } }, - "are-we-there-yet": { + "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", - "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 + }, + "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, - "optional": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.2.9" + "has-flag": "^4.0.0" } - }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", + } + } + }, + "@jest/core": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.1.tgz", + "integrity": "sha512-CcowHypRSm5oYQ1obz1wfvkjZZ2qoQlrKKvlfPwh5jUXVU12TWr2qMeH8chLMuTFzHh5a1g2yaqlqDICbr+ukQ==", + "dev": true, + "requires": { + "@jest/console": "^29.6.1", + "@jest/reporters": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.6.1", + "jest-haste-map": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.6.1", + "jest-resolve-dependencies": "^29.6.1", + "jest-runner": "^29.6.1", + "jest-runtime": "^29.6.1", + "jest-snapshot": "^29.6.1", + "jest-util": "^29.6.1", + "jest-validate": "^29.6.1", + "jest-watcher": "^29.6.1", + "micromatch": "^4.0.4", + "pretty-format": "^29.6.1", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "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, - "optional": true + "requires": { + "type-fest": "^0.21.3" + } + }, + "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 }, - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "optional": true + "requires": { + "color-convert": "^2.0.1" + } }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "optional": true + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "optional": true + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 }, - "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", + "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, - "optional": true + "requires": { + "ansi-regex": "^5.0.1" + } }, - "balanced-match": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "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, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/environment": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.1.tgz", + "integrity": "sha512-RMMXx4ws+Gbvw3DfLSuo2cfQlK7IwGbpuEWXCqyYDcqYTI+9Ju3a5hDnXaxjNsa6uKh9PQF2v+qg+RLe63tz5A==", + "dev": true, + "requires": { + "@jest/fake-timers": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "jest-mock": "^29.6.1" + } + }, + "@jest/expect": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.6.1.tgz", + "integrity": "sha512-N5xlPrAYaRNyFgVf2s9Uyyvr795jnB6rObuPx4QFvNJz8aAjpZUDfO4bh5G/xuplMID8PrnuF1+SfSyDxhsgYg==", + "dev": true, + "requires": { + "expect": "^29.6.1", + "jest-snapshot": "^29.6.1" + } + }, + "@jest/expect-utils": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.1.tgz", + "integrity": "sha512-o319vIf5pEMx0LmzSxxkYYxo4wrRLKHq9dP1yJU7FoPTB0LfAKSz8SWD6D/6U3v/O52t9cF5t+MeJiRsfk7zMw==", + "dev": true, + "requires": { + "jest-get-type": "^29.4.3" + } + }, + "@jest/fake-timers": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.1.tgz", + "integrity": "sha512-RdgHgbXyosCDMVYmj7lLpUwXA4c69vcNzhrt69dJJdf8azUrpRh3ckFCaTPNjsEeRi27Cig0oKDGxy5j7hOgHg==", + "dev": true, + "requires": { + "@jest/types": "^29.6.1", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.6.1", + "jest-mock": "^29.6.1", + "jest-util": "^29.6.1" + } + }, + "@jest/globals": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.6.1.tgz", + "integrity": "sha512-2VjpaGy78JY9n9370H8zGRCFbYVWwjY6RdDMhoJHa1sYfwe6XM/azGN0SjY8kk7BOZApIejQ1BFPyH7FPG0w3A==", + "dev": true, + "requires": { + "@jest/environment": "^29.6.1", + "@jest/expect": "^29.6.1", + "@jest/types": "^29.6.1", + "jest-mock": "^29.6.1" + } + }, + "@jest/reporters": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.1.tgz", + "integrity": "sha512-9zuaI9QKr9JnoZtFQlw4GREQbxgmNYXU6QuWtmuODvk5nvPUeBYapVR/VYMyi2WSx3jXTLJTJji8rN6+Cm4+FA==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1", + "jest-worker": "^29.6.1", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "dependencies": { + "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 }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "inherits": "2.0.3" + "color-convert": "^2.0.1" } }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { - "hoek": "2.16.3" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "brace-expansion": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", - "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "balanced-match": "0.4.2", - "concat-map": "0.0.1" + "color-name": "~1.1.4" } }, - "buffer-shims": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true, - "optional": true - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "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 }, - "combined-stream": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", - "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "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, "requires": { - "delayed-stream": "1.0.0" + "ansi-regex": "^5.0.1" } }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "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, "requires": { - "boom": "2.10.1" + "has-flag": "^4.0.0" } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + } + } + }, + "@jest/schemas": { + "version": "29.6.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz", + "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/source-map": { + "version": "29.6.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.0.tgz", + "integrity": "sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + } + }, + "@jest/test-result": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.1.tgz", + "integrity": "sha512-Ynr13ZRcpX6INak0TPUukU8GWRfm/vAytE3JbJNGAvINySWYdfE7dGZMbk36oVuK4CigpbhMn8eg1dixZ7ZJOw==", + "dev": true, + "requires": { + "@jest/console": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.1.tgz", + "integrity": "sha512-oBkC36PCDf/wb6dWeQIhaviU0l5u6VCsXa119yqdUosYAt7/FbQU2M2UoziO3igj/HBDEgp57ONQ3fm0v9uyyg==", + "dev": true, + "requires": { + "@jest/test-result": "^29.6.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.1", + "slash": "^3.0.0" + } + }, + "@jest/transform": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.1.tgz", + "integrity": "sha512-URnTneIU3ZjRSaf906cvf6Hpox3hIeJXRnz3VDSw5/X93gR8ycdfSIEy19FlVx8NFmpN7fe3Gb1xF+NjXaQLWg==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.1", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.1", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.6.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "optional": true, "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true, - "optional": true - } + "color-convert": "^2.0.1" } }, - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "optional": true, "requires": { - "ms": "2.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "deep-extend": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", - "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", - "dev": true, - "optional": true - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.2.tgz", - "integrity": "sha1-ca1dIEvxempsqPRQxhRUBm70YeE=", - "dev": true, - "optional": true - }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "optional": true, "requires": { - "jsbn": "0.1.1" + "color-name": "~1.1.4" } }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", - "dev": true, - "optional": true + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "extsprintf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", - "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true, - "optional": true + "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 }, - "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "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, - "optional": true, "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.15" + "has-flag": "^4.0.0" } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + } + } + }, + "@jest/types": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.1.tgz", + "integrity": "sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.1" + "color-convert": "^2.0.1" } }, - "fstream-ignore": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", - "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "optional": true, "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "optional": true, "requires": { - "aproba": "1.1.1", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" + "color-name": "~1.1.4" } }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 + }, + "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, - "optional": true, "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true, - "optional": true - } + "has-flag": "^4.0.0" } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + } + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + }, + "dependencies": { + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + } + } + }, + "@nicolo-ribaudo/semver-v6": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz", + "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==", + "dev": true + }, + "@shikijs/engine-oniguruma": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.4.2.tgz", + "integrity": "sha512-zcZKMnNndgRa3ORja6Iemsr3DrLtkX3cAF7lTJkdMB6v9alhlBsX9uNiCpqofNrXOvpA3h6lHcLJxgCIhVOU5Q==", + "dev": true, + "requires": { + "@shikijs/types": "3.4.2", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "@shikijs/langs": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.4.2.tgz", + "integrity": "sha512-H6azIAM+OXD98yztIfs/KH5H4PU39t+SREhmM8LaNXyUrqj2mx+zVkr8MWYqjceSjDw9I1jawm1WdFqU806rMA==", + "dev": true, + "requires": { + "@shikijs/types": "3.4.2" + } + }, + "@shikijs/themes": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.4.2.tgz", + "integrity": "sha512-qAEuAQh+brd8Jyej2UDDf+b4V2g1Rm8aBIdvt32XhDPrHvDkEnpb7Kzc9hSuHUxz0Iuflmq7elaDuQAP9bHIhg==", + "dev": true, + "requires": { + "@shikijs/types": "3.4.2" + } + }, + "@shikijs/types": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.4.2.tgz", + "integrity": "sha512-zHC1l7L+eQlDXLnxvM9R91Efh2V4+rN3oMVS2swCBssbj2U/FBwybD1eeLaq8yl/iwT+zih8iUbTBCgGZOYlVg==", + "dev": true, + "requires": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "dev": true + }, + "@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.0" + } + }, + "@types/babel__core": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", + "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", + "dev": true, + "requires": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz", + "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==", + "dev": true, + "requires": { + "@babel/types": "^7.20.7" + } + }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, + "@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "requires": { + "@types/unist": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "29.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.2.tgz", + "integrity": "sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg==", + "dev": true, + "requires": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "@types/json-schema": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "@types/mime-types": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.2.tgz", + "integrity": "sha512-q9QGHMGCiBJCHEvd4ZLdasdqXv570agPsUW0CeIm/B8DzhxsYMerD0l3IlI+EQ1A2RWHY2mmM9x1YIuuWxisCg==", + "dev": true + }, + "@types/node": { + "version": "22.15.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz", + "integrity": "sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==", + "dev": true, + "requires": { + "undici-types": "~6.21.0" + } + }, + "@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true + }, + "@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "dev": true + }, + "@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz", + "integrity": "sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "2.34.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "tsutils": "^3.17.1" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", + "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.34.0.tgz", + "integrity": "sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "2.34.0", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-visitor-keys": "^1.1.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + }, + "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, + "requires": {} + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + } + }, + "array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" + } + }, + "array.prototype.findlastindex": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.2.tgz", + "integrity": "sha512-tb5thFFlUcp7NdNF6/MpDk/1r/4awWG1FIz3YqDf+/zJSTezBb+/5WViH41obXULHVpDzoiCLpJ/ZO9YbJMsdw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.1.3" + } + }, + "array.prototype.flat": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + } + }, + "arraybuffer.prototype.slice": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz", + "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true + }, + "babel-jest": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.1.tgz", + "integrity": "sha512-qu+3bdPEQC6KZSPz+4Fyjbga5OODNcp49j6GKzG1EKbkfyJBxEYGVUmVGpwCSeGouG52R4EgYMLb6p9YeEEQ4A==", + "dev": true, + "requires": { + "@jest/transform": "^29.6.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.5.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "color-convert": "^2.0.1" } }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "har-schema": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", - "dev": true, - "optional": true - }, - "har-validator": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "optional": true, "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "has-unicode": { + "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true - }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true, - "optional": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", - "sshpk": "1.13.0" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "ini": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", - "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "color-name": "~1.1.4" } }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true, - "optional": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true, - "optional": true - }, - "jodid25519": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", - "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=", - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true, - "optional": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "optional": true, - "requires": { - "jsonify": "0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true, - "optional": true - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true, - "optional": true - }, - "jsprim": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", - "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.0.2", - "json-schema": "0.2.3", - "verror": "1.3.6" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true, - "optional": true - } - } - }, - "mime-db": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz", - "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=", + "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 }, - "mime-types": { - "version": "2.1.15", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz", - "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=", - "dev": true, - "requires": { - "mime-db": "1.27.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "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, "requires": { - "brace-expansion": "1.1.7" + "has-flag": "^4.0.0" } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + } + } + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", + "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", + "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^29.5.0", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "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 + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "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, + "requires": { + "fill-range": "^7.1.1" + } + }, + "browserslist": { + "version": "4.21.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", + "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001503", + "electron-to-chromium": "^1.4.431", + "node-releases": "^2.0.12", + "update-browserslist-db": "^1.0.11" + } + }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001512", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001512.tgz", + "integrity": "sha512-2S9nK0G/mE+jasCUsMPlARhRCts1ebcp2Ji8Y8PWi4NDE1iRdLCnEPHkEfeBrGC45L4isBx5ur3IQ6yTE2mRZw==", + "dev": true + }, + "capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "requires": { + "camel-case": "^4.1.2", + "capital-case": "^1.0.4", + "constant-case": "^3.0.4", + "dot-case": "^3.0.4", + "header-case": "^2.0.4", + "no-case": "^3.0.4", + "param-case": "^3.0.4", + "pascal-case": "^3.1.2", + "path-case": "^3.0.4", + "sentence-case": "^3.0.4", + "snake-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true + }, + "cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "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 }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "optional": true - }, - "node-pre-gyp": { - "version": "0.6.39", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz", - "integrity": "sha512-OsJV74qxnvz/AMGgcfZoDaeDXKD3oY3QVIbBmwszTFkRisTSXbMQyn4UWzUMOtA5SVhrBZOTp0wcoSBgfMfMmQ==", - "dev": true, - "optional": true, - "requires": { - "detect-libc": "1.0.2", - "hawk": "3.1.3", - "mkdirp": "0.5.1", - "nopt": "4.0.1", - "npmlog": "4.1.0", - "rc": "1.2.1", - "request": "2.81.0", - "rimraf": "2.6.1", - "semver": "5.3.0", - "tar": "2.2.1", - "tar-pack": "3.4.0" - } - }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "optional": true, - "requires": { - "abbrev": "1.1.0", - "osenv": "0.1.4" - } - }, - "npmlog": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.0.tgz", - "integrity": "sha512-ocolIkZYZt8UveuiDS0yAkkIjid1o7lPG8cYm05yNYzBn8ykQtaiPMEGp8fY9tKdDgm8okpdKzkvu1y9hUYugA==", - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "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==", "dev": true }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", - "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", + "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, - "optional": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true, - "optional": true - }, - "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", - "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", + "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, - "optional": true, "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true, - "optional": true - } + "ansi-regex": "^5.0.1" } - }, - "readable-stream": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", - "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + } + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } + }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "cross-fetch": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", + "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", + "dev": true, + "requires": { + "node-fetch": "^2.7.0" + }, + "dependencies": { + "node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, "requires": { - "buffer-shims": "1.0.0", - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "1.0.1", - "util-deprecate": "1.0.2" + "whatwg-url": "^5.0.0" } - }, - "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + } + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "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 + }, + "deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true + }, + "define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "dev": true, + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, + "diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "electron-to-chromium": { + "version": "1.4.451", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.451.tgz", + "integrity": "sha512-YYbXHIBxAHe3KWvGOJOuWa6f3tgow44rBW+QAuwVp2DvGqNZeE//K2MowNdWS7XE8li5cgQDrX1LdBr41LufkA==", + "dev": true + }, + "emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true + }, + "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==", + "dev": true + }, + "entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", + "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.1", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.2.1", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.0", + "safe-array-concat": "^1.0.0", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.10" + } + }, + "es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + } + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", "dev": true, - "optional": true, "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.0.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.6.0", - "uuid": "3.0.1" + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, - "rimraf": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", "dev": true, "requires": { - "glob": "7.1.2" + "eslint-visitor-keys": "^1.1.0" } }, - "safe-buffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", - "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=", + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", "dev": true }, "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true, - "optional": true - }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "sshpk": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.0.tgz", - "integrity": "sha1-/yo+T9BEl1Vf7Zezmg/YL6+zozw=", - "dev": true, - "optional": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jodid25519": "1.0.2", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true, - "optional": true - } - } - }, - "string_decoder": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", - "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", - "dev": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", - "dev": true, - "optional": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "eslint-config-prettier": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-4.3.0.tgz", + "integrity": "sha512-sZwhSTHVVz78+kYD3t5pCWSYEdVSBR0PXnwjDRsUs8ytIrK8PLXw+6FKp8r3Z7rx4ZszdetWlXYKOHoUrrwPlA==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ms": "^2.1.1" } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "optional": true - }, - "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + } + } + }, + "eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "dev": true, + "requires": { + "debug": "^3.2.7" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" + "ms": "^2.1.1" } - }, - "tar-pack": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.0.tgz", - "integrity": "sha1-I74tf2cagzk3bL2wuP4/3r8xeYQ=", + } + } + }, + "eslint-plugin-custom-rules": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-custom-rules/-/eslint-plugin-custom-rules-0.0.0.tgz", + "integrity": "sha512-AWzQCMQK36n/Jv0ClVdVIBo8PZ2CtxQ8zejuVC6eh0vwVeZ3F9SY5ZoNULpu/E06nYN+bZ1EfEudGQPSR3AxZA==", + "dev": true, + "requires": { + "jsx-ast-utils": "^1.3.5", + "lodash": "^4.17.4", + "object-assign": "^4.1.0", + "requireindex": "~1.1.0" + } + }, + "eslint-plugin-import": { + "version": "2.28.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", + "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", + "dev": true, + "requires": { + "array-includes": "^3.1.6", + "array.prototype.findlastindex": "^1.2.2", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.8.0", + "has": "^1.0.3", + "is-core-module": "^2.13.0", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.6", + "object.groupby": "^1.0.0", + "object.values": "^1.1.6", + "semver": "^6.3.1", + "tsconfig-paths": "^3.14.2" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "optional": true, "requires": { - "debug": "2.6.8", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.2.9", - "rimraf": "2.6.1", - "tar": "2.2.1", - "uid-number": "0.0.6" + "ms": "^2.1.1" } }, - "tough-cookie": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", - "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, - "optional": true, "requires": { - "punycode": "1.4.1" + "esutils": "^2.0.2" } }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + } + } + }, + "eslint-plugin-prettier": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "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, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "optional": true, "requires": { - "safe-buffer": "5.0.1" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true - }, - "uid-number": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", - "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=", - "dev": true, - "optional": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "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 }, - "uuid": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz", - "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=", - "dev": true, - "optional": true - }, - "verror": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", - "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", + "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, - "optional": true, "requires": { - "extsprintf": "1.0.2" + "shebang-regex": "^3.0.0" } }, - "wide-align": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", - "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "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 + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "optional": true, "requires": { - "string-width": "1.0.2" + "isexe": "^2.0.0" } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true } } }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true }, - "get-caller-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", - "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "expect": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.1.tgz", + "integrity": "sha512-XEdDLonERCU1n9uR56/Stx9OqojaLAQtZf9PrCHH9Hl8YXiEIka3H4NXJ3NOIBmQJTg7+j7buh34PMHfJujc8g==", + "dev": true, + "requires": { + "@jest/expect-utils": "^29.6.1", + "@types/node": "*", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1" + } + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "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 }, - "get-stdin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", - "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", + "fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "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 + }, + "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 }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, "requires": { - "assert-plus": "1.0.0" + "bser": "2.1.1" } }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", "dev": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "escape-string-regexp": "^1.0.5" } }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", "dev": true, "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" + "flat-cache": "^2.0.1" } }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "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, "requires": { - "is-glob": "2.0.1" + "to-regex-range": "^5.0.1" } }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "is-callable": "^1.1.3" } }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "form-data-encoder": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-4.1.0.tgz", + "integrity": "sha512-G6NsmEW15s0Uw9XnCg+33H3ViYRyiM0hMrMhhqQOR8NFc5GhYrI+6I3u7OTw7b91J2g8rtvMBZJDbcGb2YUniw==" + }, + "formdata-node": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-6.0.3.tgz", + "integrity": "sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg==" + }, + "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 }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "handlebars": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", - "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", "dev": true, "requires": { - "async": "1.5.2", - "optimist": "0.6.1", - "source-map": "0.4.4", - "uglify-js": "2.8.29" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": "1.0.1" - } - } + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" } }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true }, - "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "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==", + "dev": true + }, + "get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dev": true, "requires": { - "ajv": "5.5.2", - "har-schema": "2.0.0" + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "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 + }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" } }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "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" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, - "hawk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", - "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, "requires": { - "boom": "4.3.1", - "cryptiles": "3.1.2", - "hoek": "4.2.0", - "sntp": "2.1.0" + "define-properties": "^1.1.3" } }, - "hoek": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", - "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "get-intrinsic": "^1.1.3" } }, - "hosted-git-info": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", - "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "html-encoding-sniffer": { + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", "dev": true, "requires": { - "whatwg-encoding": "1.0.3" + "get-intrinsic": "^1.1.1" } }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" + "has-symbols": "^1.0.2" } }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "requires": { + "capital-case": "^1.0.4", + "tslib": "^2.0.3" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, "ignore": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", - "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true - }, - "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "requires": { - "ansi-escapes": "3.0.0", - "chalk": "2.3.0", - "cli-cursor": "2.1.0", - "cli-width": "2.2.0", - "external-editor": "2.1.0", - "figures": "2.0.0", - "lodash": "4.17.4", + }, + "inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", "mute-stream": "0.0.7", - "run-async": "2.3.0", - "rx-lite": "4.0.8", - "rx-lite-aggregates": "4.0.8", - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "through": "2.3.8" + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", "dev": true }, - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.1" - } - }, - "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" - } - }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "3.0.0" - } - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "has-flag": "2.0.0" + "ansi-regex": "^4.1.0" } } } }, - "invariant": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", - "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", "dev": true, "requires": { - "loose-envify": "1.3.1" + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" } }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true + "is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + } }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, - "optional": true, "requires": { - "binary-extensions": "1.11.0" + "has-bigints": "^1.0.1" } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, "requires": { - "builtin-modules": "1.1.1" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" } }, - "is-ci": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", - "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "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==", + "dev": true + }, + "is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", "dev": true, "requires": { - "ci-info": "1.1.2" + "has": "^1.0.3" } }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, "requires": { - "is-primitive": "2.0.0" + "has-tostringtag": "^1.0.0" } }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true }, "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^2.1.1" } }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, "requires": { - "kind-of": "3.2.2" + "has-tostringtag": "^1.0.0" } }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "requires": { - "is-path-inside": "1.0.1" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" } }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dev": true, "requires": { - "path-is-inside": "1.0.2" + "call-bind": "^1.0.2" } }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, - "is-resolvable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz", - "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==", - "dev": true + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dev": true, + "requires": { + "which-typed-array": "^1.1.11" + } }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } }, "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "requires": { - "isarray": "1.0.0" + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "istanbul-api": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.2.1.tgz", - "integrity": "sha512-oFCwXvd65amgaPCzqrR+a2XjanS1MvpXN6l/MlMUTv6uiA1NOgGX+I0uyq8Lg3GDxsxPsaP1049krz3hIJ5+KA==", - "dev": true, - "requires": { - "async": "2.6.0", - "fileset": "2.0.3", - "istanbul-lib-coverage": "1.1.1", - "istanbul-lib-hook": "1.1.0", - "istanbul-lib-instrument": "1.9.1", - "istanbul-lib-report": "1.1.2", - "istanbul-lib-source-maps": "1.2.2", - "istanbul-reports": "1.1.3", - "js-yaml": "3.10.0", - "mkdirp": "0.5.1", - "once": "1.4.0" - }, - "dependencies": { - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "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 + }, + "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, "requires": { - "lodash": "4.17.4" + "has-flag": "^4.0.0" } } } }, - "istanbul-lib-coverage": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz", - "integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q==", - "dev": true - }, - "istanbul-lib-hook": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz", - "integrity": "sha512-U3qEgwVDUerZ0bt8cfl3dSP3S6opBoOtk3ROO5f2EfBr/SRiD9FQqzwaZBqFORu8W7O0EXpai+k7kxHK13beRg==", + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "requires": { - "append-transform": "0.4.0" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" } }, - "istanbul-lib-instrument": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz", - "integrity": "sha512-RQmXeQ7sphar7k7O1wTNzVczF9igKpaeGQAG9qR2L+BS4DCJNTI9nytRmIVYevwO0bbq+2CXvJmYDuz0gMrywA==", + "istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "dev": true, "requires": { - "babel-generator": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "istanbul-lib-coverage": "1.1.1", - "semver": "5.4.1" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" } }, - "istanbul-lib-report": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz", - "integrity": "sha512-UTv4VGx+HZivJQwAo1wnRwe1KTvFpfi/NYwN7DcsrdzMXwpRT/Yb6r4SBPoHWj4VuQPakR32g4PUUeyKkdDkBA==", + "jest": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.6.1.tgz", + "integrity": "sha512-Nirw5B4nn69rVUZtemCQhwxOBhm0nsp3hmtF4rzCeWD7BkjAXRIji7xWQfnTNbz9g0aVsBX6aZK3n+23LM6uDw==", "dev": true, "requires": { - "istanbul-lib-coverage": "1.1.1", - "mkdirp": "0.5.1", - "path-parse": "1.0.5", - "supports-color": "3.2.3" + "@jest/core": "^29.6.1", + "@jest/types": "^29.6.1", + "import-local": "^3.0.2", + "jest-cli": "^29.6.1" + } + }, + "jest-changed-files": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", + "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", + "dev": true, + "requires": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + } + }, + "jest-circus": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.1.tgz", + "integrity": "sha512-tPbYLEiBU4MYAL2XoZme/bgfUeotpDBd81lgHLCbDZZFaGmECk0b+/xejPFtmiBP87GgP/y4jplcRpbH+fgCzQ==", + "dev": true, + "requires": { + "@jest/environment": "^29.6.1", + "@jest/expect": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.6.1", + "jest-matcher-utils": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-runtime": "^29.6.1", + "jest-snapshot": "^29.6.1", + "jest-util": "^29.6.1", + "p-limit": "^3.1.0", + "pretty-format": "^29.6.1", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "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, "requires": { - "has-flag": "1.0.0" + "has-flag": "^4.0.0" } } } }, - "istanbul-lib-source-maps": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz", - "integrity": "sha512-8BfdqSfEdtip7/wo1RnrvLpHVEd8zMZEDmOFEnpC6dg0vXflHt9nvoAyQUzig2uMSXfF2OBEYBV3CVjIL9JvaQ==", + "jest-cli": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.1.tgz", + "integrity": "sha512-607dSgTA4ODIN6go9w6xY3EYkyPFGicx51a69H7yfvt7lN53xNswEVLovq+E77VsTRi5fWprLH0yl4DJgE8Ing==", + "dev": true, + "requires": { + "@jest/core": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/types": "^29.6.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.6.1", + "jest-util": "^29.6.1", + "jest-validate": "^29.6.1", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 + }, + "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, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-config": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.1.tgz", + "integrity": "sha512-XdjYV2fy2xYixUiV2Wc54t3Z4oxYPAELUzWnV6+mcbq0rh742X2p52pii5A3oeRzYjLnQxCsZmp0qpI6klE2cQ==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.6.1", + "@jest/types": "^29.6.1", + "babel-jest": "^29.6.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.6.1", + "jest-environment-node": "^29.6.1", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.6.1", + "jest-runner": "^29.6.1", + "jest-util": "^29.6.1", + "jest-validate": "^29.6.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.6.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 + }, + "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 + }, + "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, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-diff": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.1.tgz", + "integrity": "sha512-FsNCvinvl8oVxpNLttNQX7FAq7vR+gMDGj90tiP7siWw1UdakWUGqrylpsYrpvj908IYckm5Y0Q7azNAozU1Kg==", "dev": true, "requires": { - "debug": "3.1.0", - "istanbul-lib-coverage": "1.1.1", - "mkdirp": "0.5.1", - "rimraf": "2.6.2", - "source-map": "0.5.7" + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.1" }, "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 + }, + "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, "requires": { - "ms": "2.0.0" + "has-flag": "^4.0.0" } } } }, - "istanbul-reports": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.3.tgz", - "integrity": "sha512-ZEelkHh8hrZNI5xDaKwPMFwDsUf5wIEI2bXAFGp1e6deR2mnEKBPhLJEgr4ZBt8Gi6Mj38E/C8kcy9XLggVO2Q==", + "jest-docblock": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", + "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", "dev": true, "requires": { - "handlebars": "4.0.11" + "detect-newline": "^3.0.0" } }, - "jest": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-21.2.1.tgz", - "integrity": "sha512-mXN0ppPvWYoIcC+R+ctKxAJ28xkt/Z5Js875padm4GbgUn6baeR5N4Ng6LjatIRpUQDZVJABT7Y4gucFjPryfw==", + "jest-each": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.6.1.tgz", + "integrity": "sha512-n5eoj5eiTHpKQCAVcNTT7DRqeUmJ01hsAL0Q1SMiBHcBcvTKDELixQOGMCpqhbIuTcfC4kMfSnpmDqRgRJcLNQ==", "dev": true, "requires": { - "jest-cli": "21.2.1" + "@jest/types": "^29.6.1", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "jest-util": "^29.6.1", + "pretty-format": "^29.6.1" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^2.0.1" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "jest-cli": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-21.2.1.tgz", - "integrity": "sha512-T1BzrbFxDIW/LLYQqVfo94y/hhaj1NzVQkZgBumAC+sxbjMROI7VkihOdxNR758iYbQykL2ZOWUBurFgkQrzdg==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "ansi-escapes": "3.0.0", - "chalk": "2.3.0", - "glob": "7.1.2", - "graceful-fs": "4.1.11", - "is-ci": "1.0.10", - "istanbul-api": "1.2.1", - "istanbul-lib-coverage": "1.1.1", - "istanbul-lib-instrument": "1.9.1", - "istanbul-lib-source-maps": "1.2.2", - "jest-changed-files": "21.2.0", - "jest-config": "21.2.1", - "jest-environment-jsdom": "21.2.1", - "jest-haste-map": "21.2.0", - "jest-message-util": "21.2.1", - "jest-regex-util": "21.2.0", - "jest-resolve-dependencies": "21.2.0", - "jest-runner": "21.2.1", - "jest-runtime": "21.2.1", - "jest-snapshot": "21.2.1", - "jest-util": "21.2.1", - "micromatch": "2.3.11", - "node-notifier": "5.1.2", - "pify": "3.0.0", - "slash": "1.0.0", - "string-length": "2.0.0", - "strip-ansi": "4.0.0", - "which": "1.3.0", - "worker-farm": "1.5.2", - "yargs": "9.0.1" + "color-name": "~1.1.4" } }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "strip-ansi": { + "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "3.0.0" - } + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "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, "requires": { - "has-flag": "2.0.0" + "has-flag": "^4.0.0" } } } }, - "jest-changed-files": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-21.2.0.tgz", - "integrity": "sha512-+lCNP1IZLwN1NOIvBcV5zEL6GENK6TXrDj4UxWIeLvIsIDa+gf6J7hkqsW2qVVt/wvH65rVvcPwqXdps5eclTQ==", + "jest-environment-node": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.1.tgz", + "integrity": "sha512-ZNIfAiE+foBog24W+2caIldl4Irh8Lx1PUhg/GZ0odM1d/h2qORAsejiFc7zb+SEmYPn1yDZzEDSU5PmDkmVLQ==", "dev": true, "requires": { - "throat": "4.1.0" + "@jest/environment": "^29.6.1", + "@jest/fake-timers": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "jest-mock": "^29.6.1", + "jest-util": "^29.6.1" } }, - "jest-config": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-21.2.1.tgz", - "integrity": "sha512-fJru5HtlD/5l2o25eY9xT0doK3t2dlglrqoGpbktduyoI0T5CwuB++2YfoNZCrgZipTwPuAGonYv0q7+8yDc/A==", + "jest-fetch-mock": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/jest-fetch-mock/-/jest-fetch-mock-3.0.3.tgz", + "integrity": "sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==", + "dev": true, + "requires": { + "cross-fetch": "^3.0.4", + "promise-polyfill": "^8.1.3" + } + }, + "jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true + }, + "jest-haste-map": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.1.tgz", + "integrity": "sha512-0m7f9PZXxOCk1gRACiVgX85knUKPKLPg4oRCjLoqIm9brTHXaorMA0JpmtmVkQiT8nmXyIVoZd/nnH1cfC33ig==", + "dev": true, + "requires": { + "@jest/types": "^29.6.1", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.6.1", + "jest-worker": "^29.6.1", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-leak-detector": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.1.tgz", + "integrity": "sha512-OrxMNyZirpOEwkF3UHnIkAiZbtkBWiye+hhBweCHkVbCgyEy71Mwbb5zgeTNYWJBi1qgDVfPC1IwO9dVEeTLwQ==", + "dev": true, + "requires": { + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.1" + } + }, + "jest-matcher-utils": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.1.tgz", + "integrity": "sha512-SLaztw9d2mfQQKHmJXKM0HCbl2PPVld/t9Xa6P9sgiExijviSp7TnZZpw2Fpt+OI3nwUO/slJbOfzfUMKKC5QA==", "dev": true, "requires": { - "chalk": "2.3.0", - "glob": "7.1.2", - "jest-environment-jsdom": "21.2.1", - "jest-environment-node": "21.2.1", - "jest-get-type": "21.2.0", - "jest-jasmine2": "21.2.1", - "jest-regex-util": "21.2.0", - "jest-resolve": "21.2.0", - "jest-util": "21.2.1", - "jest-validate": "21.2.1", - "pretty-format": "21.2.1" + "chalk": "^4.0.0", + "jest-diff": "^29.6.1", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.1" }, "dependencies": { "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^2.0.1" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "color-name": "~1.1.4" } }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 + }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "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, "requires": { - "has-flag": "2.0.0" + "has-flag": "^4.0.0" } } } }, - "jest-diff": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-21.2.1.tgz", - "integrity": "sha512-E5fu6r7PvvPr5qAWE1RaUwIh/k6Zx/3OOkZ4rk5dBJkEWRrUuSgbMt2EO8IUTPTd6DOqU3LW6uTIwX5FRvXoFA==", - "dev": true, - "requires": { - "chalk": "2.3.0", - "diff": "3.4.0", - "jest-get-type": "21.2.0", - "pretty-format": "21.2.1" + "jest-message-util": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.1.tgz", + "integrity": "sha512-KoAW2zAmNSd3Gk88uJ56qXUWbFk787QKmjjJVOjtGFmmGSZgDBrlIL4AfQw1xyMYPNVD7dNInfIbur9B2rd/wQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.6.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "dependencies": { "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^2.0.1" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 + }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "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, "requires": { - "has-flag": "2.0.0" + "has-flag": "^4.0.0" } } } }, - "jest-docblock": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz", - "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==", - "dev": true - }, - "jest-environment-jsdom": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-21.2.1.tgz", - "integrity": "sha512-mecaeNh0eWmzNrUNMWARysc0E9R96UPBamNiOCYL28k7mksb1d0q6DD38WKP7ABffjnXyUWJPVaWRgUOivwXwg==", + "jest-mock": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.6.1.tgz", + "integrity": "sha512-brovyV9HBkjXAEdRooaTQK42n8usKoSRR3gihzUpYeV/vwqgSoNfrksO7UfSACnPmxasO/8TmHM3w9Hp3G1dgw==", "dev": true, "requires": { - "jest-mock": "21.2.0", - "jest-util": "21.2.1", - "jsdom": "9.12.0" + "@jest/types": "^29.6.1", + "@types/node": "*", + "jest-util": "^29.6.1" } }, - "jest-environment-node": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-21.2.1.tgz", - "integrity": "sha512-R211867wx9mVBVHzrjGRGTy5cd05K7eqzQl/WyZixR/VkJ4FayS8qkKXZyYnwZi6Rxo6WEV81cDbiUx/GfuLNw==", + "jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, - "requires": { - "jest-mock": "21.2.0", - "jest-util": "21.2.1" - } + "requires": {} }, - "jest-get-type": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-21.2.0.tgz", - "integrity": "sha512-y2fFw3C+D0yjNSDp7ab1kcd6NUYfy3waPTlD8yWkAtiocJdBRQqNoRqVfMNxgj+IjT0V5cBIHJO0z9vuSSZ43Q==", + "jest-regex-util": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", "dev": true }, - "jest-haste-map": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-21.2.0.tgz", - "integrity": "sha512-5LhsY/loPH7wwOFRMs+PT4aIAORJ2qwgbpMFlbWbxfN0bk3ZCwxJ530vrbSiTstMkYLao6JwBkLhCJ5XbY7ZHw==", - "dev": true, - "requires": { - "fb-watchman": "2.0.0", - "graceful-fs": "4.1.11", - "jest-docblock": "21.2.0", - "micromatch": "2.3.11", - "sane": "2.2.0", - "worker-farm": "1.5.2" - } - }, - "jest-jasmine2": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-21.2.1.tgz", - "integrity": "sha512-lw8FXXIEekD+jYNlStfgNsUHpfMWhWWCgHV7n0B7mA/vendH7vBFs8xybjQsDzJSduptBZJHqQX9SMssya9+3A==", - "dev": true, - "requires": { - "chalk": "2.3.0", - "expect": "21.2.1", - "graceful-fs": "4.1.11", - "jest-diff": "21.2.1", - "jest-matcher-utils": "21.2.1", - "jest-message-util": "21.2.1", - "jest-snapshot": "21.2.1", - "p-cancelable": "0.3.0" + "jest-resolve": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.1.tgz", + "integrity": "sha512-AeRkyS8g37UyJiP9w3mmI/VXU/q8l/IH52vj/cDAyScDcemRbSBhfX/NMYIGilQgSVwsjxrCHf3XJu4f+lxCMg==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.6.1", + "jest-validate": "^29.6.1", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" }, "dependencies": { "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^2.0.1" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "color-name": "~1.1.4" } }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 + }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "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, "requires": { - "has-flag": "2.0.0" + "has-flag": "^4.0.0" } } } }, - "jest-matcher-utils": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-21.2.1.tgz", - "integrity": "sha512-kn56My+sekD43dwQPrXBl9Zn9tAqwoy25xxe7/iY4u+mG8P3ALj5IK7MLHZ4Mi3xW7uWVCjGY8cm4PqgbsqMCg==", + "jest-resolve-dependencies": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.1.tgz", + "integrity": "sha512-BbFvxLXtcldaFOhNMXmHRWx1nXQO5LoXiKSGQcA1LxxirYceZT6ch8KTE1bK3X31TNG/JbkI7OkS/ABexVahiw==", "dev": true, "requires": { - "chalk": "2.3.0", - "jest-get-type": "21.2.0", - "pretty-format": "21.2.1" + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.6.1" + } + }, + "jest-runner": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.1.tgz", + "integrity": "sha512-tw0wb2Q9yhjAQ2w8rHRDxteryyIck7gIzQE4Reu3JuOBpGp96xWgF0nY8MDdejzrLCZKDcp8JlZrBN/EtkQvPQ==", + "dev": true, + "requires": { + "@jest/console": "^29.6.1", + "@jest/environment": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.6.1", + "jest-haste-map": "^29.6.1", + "jest-leak-detector": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-resolve": "^29.6.1", + "jest-runtime": "^29.6.1", + "jest-util": "^29.6.1", + "jest-watcher": "^29.6.1", + "jest-worker": "^29.6.1", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" }, "dependencies": { "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^2.0.1" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 + }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "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, "requires": { - "has-flag": "2.0.0" + "has-flag": "^4.0.0" } } } }, - "jest-message-util": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-21.2.1.tgz", - "integrity": "sha512-EbC1X2n0t9IdeMECJn2BOg7buOGivCvVNjqKMXTzQOu7uIfLml+keUfCALDh8o4rbtndIeyGU8/BKfoTr/LVDQ==", - "dev": true, - "requires": { - "chalk": "2.3.0", - "micromatch": "2.3.11", - "slash": "1.0.0" + "jest-runtime": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.1.tgz", + "integrity": "sha512-D6/AYOA+Lhs5e5il8+5pSLemjtJezUr+8zx+Sn8xlmOux3XOqx4d8l/2udBea8CRPqqrzhsKUsN/gBDE/IcaPQ==", + "dev": true, + "requires": { + "@jest/environment": "^29.6.1", + "@jest/fake-timers": "^29.6.1", + "@jest/globals": "^29.6.1", + "@jest/source-map": "^29.6.0", + "@jest/test-result": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-mock": "^29.6.1", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.6.1", + "jest-snapshot": "^29.6.1", + "jest-util": "^29.6.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" }, "dependencies": { "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^2.0.1" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "color-name": "~1.1.4" } }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 + }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "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, "requires": { - "has-flag": "2.0.0" + "has-flag": "^4.0.0" } } } }, - "jest-mock": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-21.2.0.tgz", - "integrity": "sha512-aZDfyVf0LEoABWiY6N0d+O963dUQSyUa4qgzurHR3TBDPen0YxKCJ6l2i7lQGh1tVdsuvdrCZ4qPj+A7PievCw==", - "dev": true - }, - "jest-regex-util": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-21.2.0.tgz", - "integrity": "sha512-BKQ1F83EQy0d9Jen/mcVX7D+lUt2tthhK/2gDWRgLDJRNOdRgSp1iVqFxP8EN1ARuypvDflRfPzYT8fQnoBQFQ==", - "dev": true - }, - "jest-resolve": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-21.2.0.tgz", - "integrity": "sha512-vefQ/Lr+VdNvHUZFQXWtOqHX3HEdOc2MtSahBO89qXywEbUxGPB9ZLP9+BHinkxb60UT2Q/tTDOS6rYc6Mwigw==", - "dev": true, - "requires": { - "browser-resolve": "1.11.2", - "chalk": "2.3.0", - "is-builtin-module": "1.0.0" + "jest-snapshot": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.6.1.tgz", + "integrity": "sha512-G4UQE1QQ6OaCgfY+A0uR1W2AY0tGXUPQpoUClhWHq1Xdnx1H6JOrC2nH5lqnOEqaDgbHFgIwZ7bNq24HpB180A==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.6.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.6.1", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1", + "natural-compare": "^1.4.0", + "pretty-format": "^29.6.1", + "semver": "^7.5.3" }, "dependencies": { "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^2.0.1" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 + }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "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, "requires": { - "has-flag": "2.0.0" + "has-flag": "^4.0.0" } } } }, - "jest-resolve-dependencies": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-21.2.0.tgz", - "integrity": "sha512-ok8ybRFU5ScaAcfufIQrCbdNJSRZ85mkxJ1EhUp8Bhav1W1/jv/rl1Q6QoVQHObNxmKnbHVKrfLZbCbOsXQ+bQ==", - "dev": true, - "requires": { - "jest-regex-util": "21.2.0" - } - }, - "jest-runner": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-21.2.1.tgz", - "integrity": "sha512-Anb72BOQlHqF/zETqZ2K20dbYsnqW/nZO7jV8BYENl+3c44JhMrA8zd1lt52+N7ErnsQMd2HHKiVwN9GYSXmrg==", + "jest-util": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.1.tgz", + "integrity": "sha512-NRFCcjc+/uO3ijUVyNOQJluf8PtGCe/W6cix36+M3cTFgiYqFOOW5MgN4JOOcvbUhcKTYVd1CvHz/LWi8d16Mg==", "dev": true, "requires": { - "jest-config": "21.2.1", - "jest-docblock": "21.2.0", - "jest-haste-map": "21.2.0", - "jest-jasmine2": "21.2.1", - "jest-message-util": "21.2.1", - "jest-runtime": "21.2.1", - "jest-util": "21.2.1", - "pify": "3.0.0", - "throat": "4.1.0", - "worker-farm": "1.5.2" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "jest-runtime": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-21.2.1.tgz", - "integrity": "sha512-6omlpA3+NSE+rHwD0PQjNEjZeb2z+oRmuehMfM1tWQVum+E0WV3pFt26Am0DUfQkkPyTABvxITRjCUclYgSOsA==", - "dev": true, - "requires": { - "babel-core": "6.26.0", - "babel-jest": "21.2.0", - "babel-plugin-istanbul": "4.1.5", - "chalk": "2.3.0", - "convert-source-map": "1.5.1", - "graceful-fs": "4.1.11", - "jest-config": "21.2.1", - "jest-haste-map": "21.2.0", - "jest-regex-util": "21.2.0", - "jest-resolve": "21.2.0", - "jest-util": "21.2.1", - "json-stable-stringify": "1.0.1", - "micromatch": "2.3.11", - "slash": "1.0.0", - "strip-bom": "3.0.0", - "write-file-atomic": "2.3.0", - "yargs": "9.0.1" + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "dependencies": { "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^2.0.1" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "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, "requires": { - "has-flag": "2.0.0" + "has-flag": "^4.0.0" } } } }, - "jest-snapshot": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-21.2.1.tgz", - "integrity": "sha512-bpaeBnDpdqaRTzN8tWg0DqOTo2DvD3StOemxn67CUd1p1Po+BUpvePAp44jdJ7Pxcjfg+42o4NHw1SxdCA2rvg==", + "jest-validate": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.1.tgz", + "integrity": "sha512-r3Ds69/0KCN4vx4sYAbGL1EVpZ7MSS0vLmd3gV78O+NAx3PDQQukRU5hNHPXlyqCgFY8XUk7EuTMLugh0KzahA==", "dev": true, "requires": { - "chalk": "2.3.0", - "jest-diff": "21.2.1", - "jest-matcher-utils": "21.2.1", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "pretty-format": "21.2.1" + "@jest/types": "^29.6.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "leven": "^3.1.0", + "pretty-format": "^29.6.1" }, "dependencies": { "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^2.0.1" } }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "color-name": "~1.1.4" } }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 + }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "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, "requires": { - "has-flag": "2.0.0" + "has-flag": "^4.0.0" } } } }, - "jest-util": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-21.2.1.tgz", - "integrity": "sha512-r20W91rmHY3fnCoO7aOAlyfC51x2yeV3xF+prGsJAUsYhKeV670ZB8NO88Lwm7ASu8SdH0S+U+eFf498kjhA4g==", + "jest-watcher": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.1.tgz", + "integrity": "sha512-d4wpjWTS7HEZPaaj8m36QiaP856JthRZkrgcIY/7ISoUWPIillrXM23WPboZVLbiwZBt4/qn2Jke84Sla6JhFA==", "dev": true, "requires": { - "callsites": "2.0.0", - "chalk": "2.3.0", - "graceful-fs": "4.1.11", - "jest-message-util": "21.2.1", - "jest-mock": "21.2.0", - "jest-validate": "21.2.1", - "mkdirp": "0.5.1" + "@jest/test-result": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.6.1", + "string-length": "^4.0.1" }, "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "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, "requires": { - "color-convert": "1.9.1" + "type-fest": "^0.21.3" } }, - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "color-name": "~1.1.4" } }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 + }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "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, "requires": { - "has-flag": "2.0.0" + "has-flag": "^4.0.0" } } } }, - "jest-validate": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-21.2.1.tgz", - "integrity": "sha512-k4HLI1rZQjlU+EC682RlQ6oZvLrE5SCh3brseQc24vbZTxzT/k/3urar5QMCVgjadmSO7lECeGdc6YxnM3yEGg==", + "jest-worker": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.1.tgz", + "integrity": "sha512-U+Wrbca7S8ZAxAe9L6nb6g8kPdia5hj32Puu5iOqBCMTMWFHXuK6dOV2IFrpedbTV8fjMFLdWNttQTBL6u2MRA==", "dev": true, "requires": { - "chalk": "2.3.0", - "jest-get-type": "21.2.0", - "leven": "2.1.0", - "pretty-format": "21.2.1" + "@types/node": "*", + "jest-util": "^29.6.1", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.1" - } - }, - "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" - } + "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 }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { - "has-flag": "2.0.0" + "has-flag": "^4.0.0" } } } }, "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, "js-yaml": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", - "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "requires": { - "argparse": "1.0.9", - "esprima": "4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "optional": true - }, - "jsdom": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz", - "integrity": "sha1-6MVG//ywbADUgzyoRBD+1/igl9Q=", - "dev": true, - "requires": { - "abab": "1.0.4", - "acorn": "4.0.13", - "acorn-globals": "3.1.0", - "array-equal": "1.0.0", - "content-type-parser": "1.0.2", - "cssom": "0.3.2", - "cssstyle": "0.2.37", - "escodegen": "1.9.0", - "html-encoding-sniffer": "1.0.2", - "nwmatcher": "1.4.3", - "parse5": "1.5.1", - "request": "2.83.0", - "sax": "1.2.4", - "symbol-tree": "3.2.2", - "tough-cookie": "2.3.3", - "webidl-conversions": "4.0.2", - "whatwg-encoding": "1.0.3", - "whatwg-url": "4.8.0", - "xml-name-validator": "2.0.1" - }, - "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - } + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true }, "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "0.0.0" - } + "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 }, "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": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, - "jsonparse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.0.0.tgz", - "integrity": "sha1-JiL05mwI4arH7b63YFPJt+EhH3Y=" - }, - "JSONStream": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.0.4.tgz", - "integrity": "sha1-qobWqJyOd/IGzVQlgbVj5+7jJFk=", - "requires": { - "jsonparse": "1.0.0", - "through": "2.3.8" - } - }, - "jsprim": { + "jsx-ast-utils": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true, - "optional": true + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", + "integrity": "sha512-0LwSmMlQjjUdXsdlyYhEfBJCn2Chm0zgUBmfmf1++KUULh+JOdlzrZfiwe2zmlVJx44UF+KX/B/odBoeK9hxmw==", + "dev": true }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "1.0.0" - } + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true }, "leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dev": true, "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" } }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" + "uc.micro": "^2.0.0" } }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "p-locate": "2.0.0", - "path-exists": "3.0.0" + "p-locate": "^4.1.0" } }, "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true }, - "loose-envify": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", - "dev": true, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", "requires": { - "js-tokens": "3.0.2" + "tslib": "^2.0.3" } }, "lru-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, "requires": { - "tmpl": "1.0.4" + "tmpl": "1.0.5" } }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, "requires": { - "mimic-fn": "1.1.0" + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "dependencies": { + "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 + } } }, - "merge": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz", - "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=", + "mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true + }, + "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 }, "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" } }, "mime-db": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", - "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { - "version": "2.1.17", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", - "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "requires": { - "mime-db": "1.30.0" + "mime-db": "1.52.0" } }, "mimic-fn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", - "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "^1.1.7" } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.6" } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", "dev": true }, - "nan": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", - "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", - "dev": true, - "optional": true - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, - "node-notifier": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.1.2.tgz", - "integrity": "sha1-L6nhJgX6EACdRFSdb82KY93g5P8=", - "dev": true, - "requires": { - "growly": "1.3.0", - "semver": "5.4.1", - "shellwords": "0.1.1", - "which": "1.3.0" - } - }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "dev": true, - "requires": { - "hosted-git-info": "2.5.0", - "is-builtin-module": "1.0.0", - "semver": "5.4.1", - "validate-npm-package-license": "3.0.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "1.1.0" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", "requires": { - "path-key": "2.0.1" + "lower-case": "^2.0.2", + "tslib": "^2.0.3" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, - "nwmatcher": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz", - "integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw==", + "node-releases": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", + "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", "dev": true }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.3" + "path-key": "^3.0.0" }, "dependencies": { - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "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 } } }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "0.7.0", - "lcid": "1.0.0", - "mem": "1.1.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "output-file-sync": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", - "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "mkdirp": "0.5.1", - "object-assign": "4.1.1" - } - }, - "p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "dev": true }, - "p-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", - "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, "requires": { - "p-limit": "1.1.0" + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" } }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "object.fromentries": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", "dev": true, "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "object.groupby": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.0.tgz", + "integrity": "sha512-70MWG6NfRH9GnbZOikuhPPYzpUpof9iW2J9E4dW7FXTqPNb6rllE6u39SKwwiNh8lCwX3DDb5OgcKGiEBrTTyw==", "dev": true, "requires": { - "error-ex": "1.3.1" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.21.2", + "get-intrinsic": "^1.2.1" } }, - "parse5": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", - "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "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, "requires": { - "pinkie": "2.0.4" + "wrappy": "1" } }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, - "precond": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", - "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=" - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.9.2.tgz", - "integrity": "sha512-piXx9N2WT8hWb7PBbX1glAuJVIkEyUV9F5fMXFINpZ0x3otVOFKKeGmeuiclFJlP/UrgTckyV606VjH2rNK4bw==", - "dev": true - }, - "pretty-format": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-21.2.1.tgz", - "integrity": "sha512-ZdWPGYAnYfcVP8yKA3zFjCn8s4/17TeYH28MXuC8vTp0o21eXjbFGcOAXZEaDaOFJjc3h2qa7HQNHNshhvoh2A==", + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { - "ansi-regex": "3.0.0", - "ansi-styles": "3.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.1" - } - } + "mimic-fn": "^2.1.0" } }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "progress": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", - "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "pseudomap": { + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + "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, + "requires": { + "yocto-queue": "^0.1.0" + } }, - "randomatic": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "p-limit": "^2.2.0" }, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { - "is-buffer": "1.1.6" + "p-try": "^2.0.0" } } } }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" + "dot-case": "^3.0.4", + "tslib": "^2.0.3" } }, - "read-pkg-up": { + "parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "2.0.1" - } - } + "callsites": "^3.0.0" } }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" } }, - "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", - "dev": true, - "optional": true, + "pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", "requires": { - "graceful-fs": "4.1.11", - "minimatch": "3.0.4", - "readable-stream": "2.3.3", - "set-immediate-shim": "1.0.1" + "dot-case": "^3.0.4", + "tslib": "^2.0.3" } }, - "regenerate": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", - "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==", + "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 + }, + "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 + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true }, - "regenerator-transform": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", - "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "private": "0.1.8" + "find-up": "^4.0.0" } }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true + }, + "prettier": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", + "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, "requires": { - "is-equal-shallow": "0.1.3" + "fast-diff": "^1.1.2" } }, - "regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", "dev": true, "requires": { - "regenerate": "1.3.3", - "regjsgen": "0.2.0", - "regjsparser": "0.1.5" + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } } }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "promise-polyfill": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.3.0.tgz", + "integrity": "sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg==", "dev": true }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "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, "requires": { - "jsesc": "0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" } }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, - "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", "dev": true }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "pure-rand": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz", + "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==", "dev": true }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "1.0.2" - } - }, - "request": { - "version": "2.83.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", - "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", - "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.3.1", - "har-validator": "5.0.3", - "hawk": "6.0.2", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.1", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.3", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "regexp.prototype.flags": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", + "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" } }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "requireindex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.1.0.tgz", + "integrity": "sha512-LBnkqsDE7BZKvqylbmn7lTIVdpx4K/QCduRATpO5R+wtPmky/a8pN1bO2D6wXppn1497AJF9mNjqAXr6bdl9jg==", "dev": true }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "resolve": { + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", + "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", "dev": true, "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } }, "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "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 + }, + "resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", "dev": true }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", "dev": true, "requires": { - "onetime": "2.0.1", - "signal-exit": "3.0.2" + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "dependencies": { + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + } } }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, - "optional": true, "requires": { - "align-text": "0.1.4" + "glob": "^7.1.3" } }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, "requires": { - "glob": "7.1.2" + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } } }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "safe-array-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", + "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", "dev": true, "requires": { - "is-promise": "2.1.0" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" } }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", "dev": true, "requires": { - "rx-lite": "4.0.8" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" } }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true }, - "sane": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-2.2.0.tgz", - "integrity": "sha512-OSJxhHO0CgPUw3lUm3GhfREAfza45smvEI9ozuFrxKG10GHVo0ryW9FK5VYlLvxj0SV7HVKHW0voYJIRu27GWg==", + "semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, "requires": { - "anymatch": "1.3.2", - "exec-sh": "0.2.1", - "fb-watchman": "2.0.0", - "fsevents": "1.1.3", - "minimatch": "3.0.4", - "minimist": "1.2.0", - "walker": "1.0.7", - "watch": "0.18.0" + "lru-cache": "^6.0.0" }, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true, - "optional": true + "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==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, "requires": { - "shebang-regex": "1.0.0" + "shebang-regex": "^1.0.0" } }, "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "dev": true }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } }, "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true }, "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", "dev": true, "requires": { - "is-fullwidth-code-point": "2.0.0" + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" } }, - "sntp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", - "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", "requires": { - "hoek": "4.2.0" + "dot-case": "^3.0.4", + "tslib": "^2.0.3" } }, "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "0.5.7" - } - }, - "spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, "requires": { - "spdx-license-ids": "1.2.2" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "spdx-expression-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", - "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", - "dev": true - }, - "spdx-license-ids": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", - "dev": true - }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "sshpk": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", - "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } } }, "string-length": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", - "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "requires": { - "astral-regex": "1.0.0", - "strip-ansi": "4.0.0" + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^5.0.1" } } } @@ -5419,148 +13216,153 @@ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "3.0.0" - } - } + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string.prototype.trim": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", + "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, - "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dev": true, "requires": { - "is-utf8": "0.2.1" + "ansi-regex": "^3.0.0" } }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true }, "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } }, - "symbol-tree": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", - "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, "table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", "dev": true, "requires": { - "ajv": "5.5.2", - "ajv-keywords": "2.1.1", - "chalk": "2.3.0", - "lodash": "4.17.4", - "slice-ansi": "1.0.0", - "string-width": "2.1.1" + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.1" - } + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true }, - "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" } }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "has-flag": "2.0.0" + "ansi-regex": "^4.1.0" } } } }, "test-exclude": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.1.1.tgz", - "integrity": "sha512-35+Asrsk3XHJDBgf/VRFexPgh3UyETv8IAn/LRTiZjVy6rjPVqdEk8dJcJYBzl1w0XCJM48lvTy8SfEsCWS4nA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, "requires": { - "arrify": "1.0.1", - "micromatch": "2.3.11", - "object-assign": "4.1.1", - "read-pkg-up": "1.0.1", - "require-main-filename": "1.0.1" + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" } }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "throat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", - "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true }, "tmp": { "version": "0.0.33", @@ -5568,281 +13370,433 @@ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { - "os-tmpdir": "1.0.2" + "os-tmpdir": "~1.0.2" } }, "tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true }, - "tough-cookie": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", - "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "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, "requires": { - "punycode": "1.4.1" + "is-number": "^7.0.0" } }, "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true + "ts-jest": { + "version": "29.1.1", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", + "integrity": "sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + } }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "dev": true, "requires": { - "safe-buffer": "5.1.1" + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + } } }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "optional": true + "tslib": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", + "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", "dev": true, "requires": { - "prelude-ls": "1.1.2" + "prelude-ls": "~1.1.2" } }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "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 }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + } + }, + "typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + } + }, + "typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + } + }, + "typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "dev": true, - "optional": true, "requires": { - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + } + }, + "typedoc": { + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.4.tgz", + "integrity": "sha512-xKvKpIywE1rnqqLgjkoq0F3wOqYaKO9nV6YkkSat6IxOWacUCc/7Es0hR3OPmkIqkPoEn7U3x+sYdG72rstZQA==", + "dev": true, + "requires": { + "@gerrit0/mini-shiki": "^3.2.2", + "lunr": "^2.3.9", + "markdown-it": "^14.1.0", + "minimatch": "^9.0.5", + "yaml": "^2.7.1" }, "dependencies": { - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, - "optional": true, "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", - "window-size": "0.1.0" + "brace-expansion": "^2.0.1" } } } }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "typedoc-plugin-rename-defaults": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/typedoc-plugin-rename-defaults/-/typedoc-plugin-rename-defaults-0.7.3.tgz", + "integrity": "sha512-fDtrWZ9NcDfdGdlL865GW7uIGQXlthPscURPOhDkKUe4DBQSRRFUf33fhWw41FLlsz8ZTeSxzvvuNmh54MynFA==", "dev": true, - "optional": true + "requires": { + "camelcase": "^8.0.0" + }, + "dependencies": { + "camelcase": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", + "dev": true + } + } }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + "typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", + "uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", "dev": true }, - "util-deprecate": { + "unbox-primitive": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } }, - "uuid": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", - "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + "undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true }, - "v8flags": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", - "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", + "update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", "dev": true, "requires": { - "user-home": "1.1.1" + "escalade": "^3.1.1", + "picocolors": "^1.0.0" } }, - "validate-npm-package-license": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", - "dev": true, + "upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" + "tslib": "^2.0.3" } }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "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==", "requires": { - "assert-plus": "1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "1.3.0" + "tslib": "^2.0.3" } }, - "walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "requires": { - "makeerror": "1.0.11" + "punycode": "^2.1.0" } }, - "watch": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/watch/-/watch-0.18.0.tgz", - "integrity": "sha1-KAlUdsbffJDJYxOJkMClQj60uYY=", + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, + "v8-to-istanbul": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", "dev": true, "requires": { - "exec-sh": "0.2.1", - "minimist": "1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" } }, - "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", - "dev": true - }, - "whatwg-encoding": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz", - "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==", + "walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, "requires": { - "iconv-lite": "0.4.19" + "makeerror": "1.0.12" } }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, "whatwg-url": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz", - "integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, "requires": { - "tr46": "0.0.3", - "webidl-conversions": "3.0.1" - }, - "dependencies": { - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - } + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" } }, "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { - "isexe": "2.0.0" + "isexe": "^2.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, - "optional": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } }, - "worker-farm": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.5.2.tgz", - "integrity": "sha512-XxiQ9kZN5n6mmnW+mFJ+wXjNNI/Nx4DIdaAKLX1Bn6LYBWlN/zaBhu34DQYPZ1AJobQuu67S2OfDdNSVULvXkQ==", + "which-typed-array": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", "dev": true, "requires": { - "errno": "0.1.6", - "xtend": "4.0.1" + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" } }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "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, "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "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 + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "color-name": "~1.1.4" } }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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==", + "dev": true + }, "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "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, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "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, + "requires": { + "ansi-regex": "^5.0.1" } } } @@ -5850,179 +13804,106 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", "dev": true, "requires": { - "mkdirp": "0.5.1" + "mkdirp": "^0.5.1" } }, "write-file-atomic": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", - "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "imurmurhash": "0.1.4", - "signal-exit": "3.0.2" + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" } }, - "xml-name-validator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", - "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=", - "dev": true - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - }, "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yaml": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", "dev": true }, "yargs": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", - "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", - "dev": true, - "requires": { - "camelcase": "4.1.0", - "cliui": "3.2.0", - "decamelize": "1.2.0", - "get-caller-file": "1.0.2", - "os-locale": "2.1.0", - "read-pkg-up": "2.0.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "3.2.1", - "yargs-parser": "7.0.0" + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "requires": { + "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" }, "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "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 }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - } - } - }, "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "strip-bom": "3.0.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "2.3.0" - } + "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==", + "dev": true }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "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, "requires": { - "load-json-file": "2.0.0", - "normalize-package-data": "2.4.0", - "path-type": "2.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "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, "requires": { - "find-up": "2.1.0", - "read-pkg": "2.0.0" + "ansi-regex": "^5.0.1" } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true } } }, "yargs-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", - "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", - "dev": true, - "requires": { - "camelcase": "4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - } - } + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + }, + "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 } } } diff --git a/package.json b/package.json index 1a4dfbfc..b04d0d7a 100644 --- a/package.json +++ b/package.json @@ -1,43 +1,85 @@ { "name": "nylas", - "version": "4.2.2", - "description": - "A NodeJS wrapper for the Nylas REST API for email, contacts, and calendar.", - "main": "lib/nylas.js", + "version": "8.0.1", + "description": "A NodeJS wrapper for the Nylas REST API for email, contacts, and calendar.", + "main": "lib/cjs/nylas.js", + "types": "lib/types/nylas.d.ts", + "module": "lib/esm/nylas.js", + "files": [ + "lib", + "cjs-wrapper.js", + "cjs-wrapper.d.ts" + ], + "engines": { + "node": ">=18" + }, "scripts": { "test": "jest", - "lint": "eslint \"./src/**/*.js\"", - "prettier": - "prettier --single-quote --trailing-comma es5 --write \"./src/**/*.js\"", - "build": "babel src --presets babel-preset-env --out-dir lib", - "prepublish": "yarn build", - "prepare": "yarn build", - "watch": "nodemon -w src --exec npm run build" + "test:coverage": "npm run test -- --coverage", + "lint": "eslint --ext .js,.ts -f visualstudio .", + "lint:fix": "npm run lint -- --fix", + "lint:ci": "npm run lint:fix -- --quiet", + "lint:prettier": "prettier --write '**/*.{ts,js}'", + "lint:prettier:check": "prettier --check '**/*.{ts,js}'", + "export-version": "node scripts/exportVersion.js", + "generate-lib-package-json": "node scripts/generateLibPackageJson.js", + "generate-model-index": "node scripts/generateModelIndex.js", + "prebuild": "npm run export-version && npm run generate-model-index", + "build": "rm -rf lib && npm run build-esm && npm run build-cjs && npm run generate-lib-package-json", + "build-esm": "tsc -p tsconfig.esm.json", + "build-cjs": "tsc -p tsconfig.cjs.json", + "prepare": "npm run build", + "build:docs": "typedoc --out docs", + "version": "npm run export-version && git add src/version.ts" }, - "keywords": ["email", "contacts", "calendar", "nylas"], + "keywords": [ + "email", + "contacts", + "calendar", + "nylas" + ], "author": "Nylas, Inc.", "license": "MIT", "dependencies": { - "JSONStream": "1.0.4", - "async": "0.9.0", - "backoff": "2.4.1", - "bluebird": "^2.9.13", - "clone": "1.0.1", - "express-session": "^1.15.6", - "request": "^2.63.0", - "underscore": "^1.7.0" + "change-case": "^4.1.2", + "form-data-encoder": "^4.1.0", + "formdata-node": "^6.0.3", + "mime-types": "^2.1.35", + "uuid": "^8.3.2" }, "devDependencies": { - "babel-cli": "6", - "babel-preset-env": "^1.6.0", - "eslint": "^4.8.0", - "eslint-config-prettier": "^2.6.0", - "eslint-plugin-prettier": "^2.3.1", - "jest": "^21.2.1", - "prettier": "^1.7.4" + "@babel/core": "^7.3.3", + "@types/jest": "^29.5.2", + "@types/mime-types": "^2.1.2", + "@types/node": "^22.15.21", + "@types/uuid": "^8.3.4", + "@typescript-eslint/eslint-plugin": "^2.25.0", + "@typescript-eslint/parser": "^2.25.0", + "eslint": "^5.14.0", + "eslint-config-prettier": "^4.0.0", + "eslint-plugin-custom-rules": "^0.0.0", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-prettier": "^3.0.1", + "jest": "^29.6.1", + "jest-fetch-mock": "^3.0.3", + "prettier": "^3.5.3", + "ts-jest": "^29.1.1", + "typedoc": "^0.28.4", + "typedoc-plugin-rename-defaults": "^0.7.3", + "typescript": "^5.8.3" }, "repository": { "type": "git", "url": "https://github.com/nylas/nylas-nodejs.git" + }, + "exports": { + "import": { + "types": "./lib/types/nylas.d.ts", + "default": "./lib/esm/nylas.js" + }, + "require": { + "types": "./cjs-wrapper.d.ts", + "default": "./cjs-wrapper.js" + } } } diff --git a/pull_request_template.md b/pull_request_template.md new file mode 100644 index 00000000..6dd0e824 --- /dev/null +++ b/pull_request_template.md @@ -0,0 +1,4 @@ + + +# License +I confirm that this contribution is made under the terms of the MIT license and that I have the authority necessary to make this contribution on behalf of its copyright owner. \ No newline at end of file diff --git a/scripts/exportVersion.js b/scripts/exportVersion.js new file mode 100644 index 00000000..27f13aca --- /dev/null +++ b/scripts/exportVersion.js @@ -0,0 +1,20 @@ +/** + * This script exports the version of the SDK from the package.json to src/version.ts + */ + +const fs = require('fs'); +const path = require('path'); + +// Read the version from package.json +const packageJsonPath = path.join(__dirname, '..', 'package.json'); +const packageJson = require(packageJsonPath); +const version = packageJson.version; + +// Create the output string +const comment = '// This file is generated by scripts/exportVersion.js\n'; +const varStr = `export const SDK_VERSION = '${version}';\n`; +const output = comment + varStr; + +// Write the output to src/version.ts +const outputPath = path.join(__dirname, '..', 'src', 'version.ts'); +fs.writeFileSync(outputPath, output); diff --git a/scripts/generateLibPackageJson.js b/scripts/generateLibPackageJson.js new file mode 100644 index 00000000..73ce73ef --- /dev/null +++ b/scripts/generateLibPackageJson.js @@ -0,0 +1,28 @@ +/** + * This script generates the package.json files for the CJS and ESM builds. + */ + +const fs = require('fs'); +const path = require('path'); + +// Create the "lib/cjs/package.json" file +const cjsFolderPath = path.join(__dirname, '..', 'lib', 'cjs'); +const cjsPackageJsonPath = path.join(cjsFolderPath, 'package.json'); +const cjsContent = JSON.stringify({ type: 'commonjs' }, null, 2); + +// Ensure the directory exists before writing the file +if (!fs.existsSync(cjsFolderPath)) { + fs.mkdirSync(cjsFolderPath, { recursive: true }); +} +fs.writeFileSync(cjsPackageJsonPath, cjsContent); + +// Create the "lib/esm/package.json" file +const esmFolderPath = path.join(__dirname, '..', 'lib', 'esm'); +const esmPackageJsonPath = path.join(esmFolderPath, 'package.json'); +const esmContent = JSON.stringify({ type: 'module' }, null, 2); + +// Ensure the directory exists before writing the file +if (!fs.existsSync(esmFolderPath)) { + fs.mkdirSync(esmFolderPath, { recursive: true }); +} +fs.writeFileSync(esmPackageJsonPath, esmContent); diff --git a/scripts/generateModelIndex.js b/scripts/generateModelIndex.js new file mode 100644 index 00000000..d4ae818d --- /dev/null +++ b/scripts/generateModelIndex.js @@ -0,0 +1,15 @@ +const fs = require('fs'); +const path = require('path'); + +const comment = '// This file is generated by scripts/generateModelIndex.js\n'; +const modelsDir = path.join(__dirname, '..', 'src', 'models'); +let indexContent = ''; + +fs.readdirSync(modelsDir).forEach((file) => { + if (file.endsWith('.ts') && file !== 'index.ts') { + const modelName = file.replace('.ts', '.js'); + indexContent += `export * from './${modelName}';\n`; + } +}); + +fs.writeFileSync(path.join(modelsDir, 'index.ts'), comment + indexContent); diff --git a/src/apiClient.ts b/src/apiClient.ts new file mode 100644 index 00000000..6b7013ea --- /dev/null +++ b/src/apiClient.ts @@ -0,0 +1,352 @@ +import { NylasConfig, OverridableNylasConfig } from './config.js'; +import { + NylasApiError, + NylasOAuthError, + NylasSdkTimeoutError, +} from './models/error.js'; +import { objKeysToCamelCase, objKeysToSnakeCase } from './utils.js'; +import { SDK_VERSION } from './version.js'; +import { FormData } from 'formdata-node'; +import { FormDataEncoder } from 'form-data-encoder'; +import { Readable } from 'stream'; +import { snakeCase } from 'change-case'; + +/** + * The header key for the debugging flow ID + */ +export const FLOW_ID_HEADER = 'x-fastly-id'; +/** + * The header key for the request ID + */ +export const REQUEST_ID_HEADER = 'x-request-id'; + +/** + * Options for a request to the Nylas API + * @property path The path to the API endpoint + * @property method The HTTP method to use + * @property headers Additional headers to send with the request + * @property queryParams Query parameters to send with the request + * @property body The body of the request + * @property overrides Overrides to the default Nylas API client configuration + * @ignore Not for public use + */ +export interface RequestOptionsParams { + path: string; + method: string; + headers?: Record; + queryParams?: Record; + body?: any; + form?: FormData; + overrides?: OverridableNylasConfig; +} + +/** + * Options for building a request for fetch to understand + * @property path The path to the API endpoint + * @property method The HTTP method to use + * @property headers Additional headers to send with the request + * @property url The URL of the request + * @property body The body of the request + * @property overrides Overrides to the default Nylas API client configuration + * @ignore Not for public use + */ +interface RequestOptions { + path: string; + method: string; + headers: Record; + url: URL; + body?: any; + overrides?: Partial; + duplex?: 'half'; +} + +/** + * The API client for communicating with the Nylas API + * @ignore Not for public use + */ +export default class APIClient { + /** + * The API key to use for authentication + */ + apiKey: string; + /** + * The URL to use for communicating with the Nylas API + */ + serverUrl: string; + /** + * The timeout for requests to the Nylas API, in seconds + */ + timeout: number; + /** + * Additional headers to send with outgoing requests + */ + headers: Record; + + constructor({ apiKey, apiUri, timeout, headers }: Required) { + this.apiKey = apiKey; + this.serverUrl = apiUri; + this.timeout = timeout * 1000; // fetch timeout uses milliseconds + this.headers = headers; + } + + private setRequestUrl({ + overrides, + path, + queryParams, + }: RequestOptionsParams): URL { + const url = new URL(`${overrides?.apiUri || this.serverUrl}${path}`); + + return this.setQueryStrings(url, queryParams); + } + + private setQueryStrings( + url: URL, + queryParams?: Record + ): URL { + if (queryParams) { + for (const [key, value] of Object.entries(queryParams)) { + const snakeCaseKey = snakeCase(key); + if (key == 'metadataPair') { + // The API understands a metadata_pair filter in the form of: + // : + const metadataPair: string[] = []; + for (const item in value as Record) { + metadataPair.push( + `${item}:${(value as Record)[item]}` + ); + } + url.searchParams.set('metadata_pair', metadataPair.join(',')); + } else if (Array.isArray(value)) { + for (const item of value) { + url.searchParams.append(snakeCaseKey, item as string); + } + } else if (typeof value === 'object') { + for (const item in value) { + url.searchParams.append( + snakeCaseKey, + `${item}:${(value as Record)[item]}` + ); + } + } else { + url.searchParams.set(snakeCaseKey, value as string); + } + } + } + + return url; + } + + private setRequestHeaders({ + headers, + overrides, + }: RequestOptionsParams): Record { + const mergedHeaders: Record = { + ...headers, + ...this.headers, + ...overrides?.headers, + }; + + return { + Accept: 'application/json', + 'User-Agent': `Nylas Node SDK v${SDK_VERSION}`, + Authorization: `Bearer ${overrides?.apiKey || this.apiKey}`, + ...mergedHeaders, + }; + } + + private async sendRequest(options: RequestOptionsParams): Promise { + const req = await this.newRequest(options); + const controller: AbortController = new AbortController(); + + // Handle timeout + let timeoutDuration: number; + if (options.overrides?.timeout) { + // Determine if the override timeout is likely in milliseconds (β‰₯ 1000) + if (options.overrides.timeout >= 1000) { + timeoutDuration = options.overrides.timeout; // Keep as milliseconds for backward compatibility + } else { + // Treat as seconds and convert to milliseconds + timeoutDuration = options.overrides.timeout * 1000; + } + } else { + timeoutDuration = this.timeout; // Already in milliseconds from constructor + } + + const timeout = setTimeout(() => { + controller.abort(); + }, timeoutDuration); + + try { + const response = await fetch(req, { + signal: controller.signal as AbortSignal, + }); + clearTimeout(timeout); + + if (typeof response === 'undefined') { + throw new Error('Failed to fetch response'); + } + + const headers = response?.headers?.entries + ? Object.fromEntries(response.headers.entries()) + : {}; + const flowId = headers[FLOW_ID_HEADER]; + const requestId = headers[REQUEST_ID_HEADER]; + + if (response.status > 299) { + const text = await response.text(); + let error: Error; + try { + const parsedError = JSON.parse(text); + const camelCaseError = objKeysToCamelCase(parsedError); + + // Check if the request is an authentication request + const isAuthRequest = + options.path.includes('connect/token') || + options.path.includes('connect/revoke'); + + if (isAuthRequest) { + error = new NylasOAuthError( + camelCaseError, + response.status, + requestId, + flowId, + headers + ); + } else { + error = new NylasApiError( + camelCaseError, + response.status, + requestId, + flowId, + headers + ); + } + } catch (e) { + throw new Error( + `Received an error but could not parse response from the server${ + flowId ? ` with flow ID ${flowId}` : '' + }: ${text}` + ); + } + + throw error; + } + + return response; + } catch (error) { + if (error instanceof Error && error.name === 'AbortError') { + // Calculate the timeout in seconds for the error message + // If we determined it was milliseconds (β‰₯ 1000), convert to seconds for the error + const timeoutInSeconds = options.overrides?.timeout + ? options.overrides.timeout >= 1000 + ? options.overrides.timeout / 1000 // Convert ms to s for error message + : options.overrides.timeout // Already in seconds + : this.timeout / 1000; // Convert ms to s + throw new NylasSdkTimeoutError(req.url, timeoutInSeconds); + } + + clearTimeout(timeout); + throw error; + } + } + + requestOptions(optionParams: RequestOptionsParams): RequestOptions { + const requestOptions = {} as RequestOptions; + + requestOptions.url = this.setRequestUrl(optionParams); + requestOptions.headers = this.setRequestHeaders(optionParams); + requestOptions.method = optionParams.method; + + if (optionParams.body) { + requestOptions.body = JSON.stringify( + objKeysToSnakeCase(optionParams.body, ['metadata']) // metadata should remain as is + ); + requestOptions.headers['Content-Type'] = 'application/json'; + } + + if (optionParams.form) { + // Use FormDataEncoder to properly encode the form data with the correct + // Content-Type header including the multipart boundary. + // This is required for Node.js environments where formdata-node's FormData + // doesn't automatically set the Content-Type header on fetch requests. + const encoder = new FormDataEncoder(optionParams.form); + + // Set the Content-Type header with the boundary from the encoder + requestOptions.headers['Content-Type'] = encoder.contentType; + + // Convert the encoded form data to a readable stream for the request body + requestOptions.body = Readable.from(encoder); + + // Node.js native fetch requires duplex: 'half' when sending a streaming body + requestOptions.duplex = 'half'; + } + + return requestOptions; + } + + async newRequest(options: RequestOptionsParams): Promise { + const newOptions = this.requestOptions(options); + const requestInit: RequestInit = { + method: newOptions.method, + headers: newOptions.headers, + body: newOptions.body, + }; + + // Add duplex option for streaming bodies (required by Node.js native fetch) + if (newOptions.duplex) { + (requestInit as any).duplex = newOptions.duplex; + } + + return new Request(newOptions.url, requestInit); + } + + async requestWithResponse(response: Response): Promise { + const headers = response?.headers?.entries + ? Object.fromEntries(response.headers.entries()) + : {}; + const flowId = headers[FLOW_ID_HEADER]; + const text = await response.text(); + + try { + const parsed = JSON.parse(text); + const payload = objKeysToCamelCase( + { + ...parsed, + flowId, + // deprecated: headers will be removed in a future release. This is for backwards compatibility. + headers, + }, + ['metadata'] + ); + // Attach rawHeaders as a non-enumerable property to avoid breaking deep equality + Object.defineProperty(payload, 'rawHeaders', { + value: headers, + enumerable: false, + }); + return payload; + } catch (e) { + throw new Error(`Could not parse response from the server: ${text}`); + } + } + + async request(options: RequestOptionsParams): Promise { + const response = await this.sendRequest(options); + return this.requestWithResponse(response); + } + + async requestRaw(options: RequestOptionsParams): Promise { + const response = await this.sendRequest(options); + const arrayBuffer = await response.arrayBuffer(); + return Buffer.from(arrayBuffer); + } + + async requestStream( + options: RequestOptionsParams + ): Promise> { + const response = await this.sendRequest(options); + if (!response.body) { + throw new Error('No response body'); + } + return response.body; + } +} diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 00000000..a9c183b6 --- /dev/null +++ b/src/config.ts @@ -0,0 +1,73 @@ +/** + * Configuration options for initializing the Nylas SDK. + * @property apiKey The Nylas API key to use for authentication + * @property apiUri The URL to use for communicating with the Nylas API + * @property timeout The timeout for requests to the Nylas API, in seconds + * @property headers Additional headers to send with outgoing requests + */ +export type NylasConfig = { + apiKey: string; + apiUri?: string; + timeout?: number; + headers?: Record; +}; + +/** + * The options that can override the default Nylas API client configuration. + */ +export type OverridableNylasConfig = { + apiKey?: string; + apiUri?: string; + /** + * @deprecated Providing timeout in milliseconds is deprecated and will be removed in the next major release. Please use seconds instead. + */ + timeout?: number; + headers?: Record; +}; + +/** + * An object that can be used to override the default Nylas API client configuration on a per-request basis. + * @property overrides Overrides to the default Nylas API client configuration + */ +export interface Overrides { + overrides?: OverridableNylasConfig; +} + +/** + * Enum representing the available Nylas API regions. + */ +export enum Region { + Us = 'us', + Eu = 'eu', +} + +/** + * The default Nylas API region. + * @default Region.Us + */ +export const DEFAULT_REGION = Region.Us; + +/** + * The configuration options for each Nylas API region. + */ +type RegionConfig = { + nylasAPIUrl: string; +}; + +/** + * The available preset configuration values for each Nylas API region. + */ +export const REGION_CONFIG: Record = { + [Region.Us]: { + nylasAPIUrl: 'https://api.us.nylas.com', + }, + [Region.Eu]: { + nylasAPIUrl: 'https://api.eu.nylas.com', + }, +}; + +/** + * The default Nylas API URL. + * @default https://api.us.nylas.com + */ +export const DEFAULT_SERVER_URL = REGION_CONFIG[DEFAULT_REGION].nylasAPIUrl; diff --git a/src/models/account.js b/src/models/account.js deleted file mode 100644 index 99e7d2af..00000000 --- a/src/models/account.js +++ /dev/null @@ -1,36 +0,0 @@ -import _ from 'underscore'; - -import RestfulModel from './restful-model'; -import Attributes from './attributes'; - -export default class Account extends RestfulModel {} -Account.collectionName = 'accounts'; -Account.endpointName = 'account'; -Account.attributes = _.extend({}, RestfulModel.attributes, { - name: Attributes.String({ - modelKey: 'name', - }), - - emailAddress: Attributes.String({ - modelKey: 'emailAddress', - jsonKey: 'email_address', - }), - - provider: Attributes.String({ - modelKey: 'provider', - }), - - organizationUnit: Attributes.String({ - modelKey: 'organizationUnit', - jsonKey: 'organization_unit', - }), - - syncState: Attributes.String({ - modelKey: 'syncState', - jsonKey: 'sync_state', - }), - linkedAt: Attributes.DateTime({ - modelKey: 'linkedAt', - jsonKey: 'linked_at', - }), -}); diff --git a/src/models/applicationDetails.ts b/src/models/applicationDetails.ts new file mode 100644 index 00000000..9d6456af --- /dev/null +++ b/src/models/applicationDetails.ts @@ -0,0 +1,95 @@ +import { RedirectUri } from './redirectUri.js'; + +/** + * Interface for a Nylas application details object + */ +export interface ApplicationDetails { + /** + * Public Application ID + */ + applicationId: string; + /** + * ID of organization + */ + organizationId: string; + /** + * Region identifier + */ + region: 'us' | 'eu'; + /** + * Environment identifier + */ + environment: 'production' | 'staging'; + /** + * Branding details for the application + */ + branding: Branding; + /** + * Hosted authentication branding details + */ + hostedAuthentication?: HostedAuthentication; + /** + * List of redirect URIs + */ + redirectUris?: RedirectUri[]; +} + +/** + * Interface for branding details for the application + */ +interface Branding { + /** + * Name of the application + */ + name: string; + /** + * URL points to application icon + */ + iconUrl?: string; + /** + * Application / publisher website URL + */ + websiteUrl?: string; + /** + * Description of the appli∏cati∏on + */ + description?: string; +} + +/** + * Interface for hosted authentication branding details + */ +interface HostedAuthentication { + /** + * URL of the background image + */ + backgroundImageUrl?: string; + /** + * Alignment of background image + */ + alignment?: string; + /** + * Primary color + */ + colorPrimary?: string; + /** + * Secondary color + */ + colorSecondary?: string; + /** + * Title + */ + title?: string; + /** + * Subtitle + */ + subtitle?: string; + /** + * Background color + */ + backgroundColor?: string; + /** + * CSS spacing attribute in px + */ + spacing?: number; +} diff --git a/src/models/attachments.ts b/src/models/attachments.ts new file mode 100644 index 00000000..de577d19 --- /dev/null +++ b/src/models/attachments.ts @@ -0,0 +1,77 @@ +/** + * Interface of an attachment object from Nylas. + */ +interface BaseAttachment { + /** + * Attachment's name. + */ + filename: string; + + /** + * Attachment's content type. + */ + contentType: string; + + /** + * If it's an inline attachment. + */ + isInline?: boolean; + + /** + * Attachment's size in bytes. + */ + size?: number; + + /** + * Content ID of the attachment. + */ + contentId?: string; + + /** + * Content disposition of the attachment. + */ + contentDisposition?: string; +} + +/** + * Interface of a create attachment request. + */ +export interface CreateAttachmentRequest extends BaseAttachment { + /** + * Content of the attachment. + * It can either be a readable stream, a base64 encoded string, or a buffer. + * For attachments less than 3MB, the content can be a readable stream, or a base64 encoded string. + * For attachments greater than 3MB, the content must be either a readable stream or a buffer. + */ + content: NodeJS.ReadableStream | string | Buffer; +} + +/** + * Interface of an attachment object from Nylas. + */ +export interface Attachment extends BaseAttachment { + /** + * Attachment's ID. + */ + id: string; + + /** + * Grant ID of the Nylas account. + */ + grantId: string; +} + +/** + * Interface representing of the query parameters for finding an attachment's metadata. + */ +export interface FindAttachmentQueryParams { + /** + * ID of the message the attachment belongs to. + */ + messageId: string; +} + +/** + * Interface representing of the query parameters for downloading an attachment. + */ +export type DownloadAttachmentQueryParams = FindAttachmentQueryParams; diff --git a/src/models/attributes.js b/src/models/attributes.js deleted file mode 100644 index fd66f977..00000000 --- a/src/models/attributes.js +++ /dev/null @@ -1,173 +0,0 @@ -// The Attribute class represents a single model attribute, like 'namespace_id' -// Subclasses of Attribute like AttributeDateTime know how to covert between -// the JSON representation of that type and the javascript representation. -// The Attribute class also exposes convenience methods for generating Matchers. - -class Attribute { - constructor({ modelKey, jsonKey }) { - this.modelKey = modelKey; - this.jsonKey = jsonKey || modelKey; - } - - toJSON(val) { - return val; - } - fromJSON(val, parent) { - return val || null; - } -} - -class AttributeNumber extends Attribute { - toJSON(val) { - return val; - } - fromJSON(val, parent) { - if (!isNaN(val)) { - return Number(val); - } else { - return null; - } - } -} - -class AttributeBoolean extends Attribute { - toJSON(val) { - return val; - } - fromJSON(val, parent) { - return val === 'true' || val === true || false; - } -} - -class AttributeString extends Attribute { - toJSON(val) { - return val; - } - fromJSON(val, parent) { - return val || ''; - } -} - -class AttributeStringList extends Attribute { - toJSON(val) { - return val; - } - fromJSON(val, parent) { - return val || []; - } -} - -class AttributeDate extends Attribute { - toJSON(val) { - if (!val) { - return val; - } - if (!(val instanceof Date)) { - throw new Error( - `Attempting to toJSON AttributeDate which is not a date: ${ - this.modelKey - } = ${val}` - ); - } - return val.toISOString(); - } - - fromJSON(val, parent) { - if (!val) { - return null; - } - return new Date(val); - } -} - -class AttributeDateTime extends Attribute { - toJSON(val) { - if (!val) { - return null; - } - if (!(val instanceof Date)) { - throw new Error( - `Attempting to toJSON AttributeDateTime which is not a date: ${ - this.modelKey - } = ${val}` - ); - } - return val.getTime() / 1000.0; - } - - fromJSON(val, parent) { - if (!val) { - return null; - } - return new Date(val * 1000); - } -} - -class AttributeCollection extends Attribute { - constructor({ modelKey, jsonKey, itemClass }) { - super(...arguments); - this.itemClass = itemClass; - } - - toJSON(vals) { - if (!vals) { - return []; - } - const json = []; - for (const val of vals) { - if (val.toJSON != null) { - json.push(val.toJSON()); - } else { - json.push(val); - } - } - return json; - } - - fromJSON(json, parent) { - if (!json || !(json instanceof Array)) { - return []; - } - const objs = []; - for (const objJSON of json) { - const obj = new this.itemClass(parent.connection, objJSON); - objs.push(obj); - } - return objs; - } -} - -module.exports = { - Number() { - return new AttributeNumber(...arguments); - }, - String() { - return new AttributeString(...arguments); - }, - StringList() { - return new AttributeStringList(...arguments); - }, - DateTime() { - return new AttributeDateTime(...arguments); - }, - Date() { - return new AttributeDate(...arguments); - }, - Collection() { - return new AttributeCollection(...arguments); - }, - Boolean() { - return new AttributeBoolean(...arguments); - }, - Object() { - return new Attribute(...arguments); - }, - - AttributeNumber, - AttributeString, - AttributeStringList, - AttributeDateTime, - AttributeCollection, - AttributeBoolean, - AttributeDate, -}; diff --git a/src/models/auth.ts b/src/models/auth.ts new file mode 100644 index 00000000..737dac10 --- /dev/null +++ b/src/models/auth.ts @@ -0,0 +1,245 @@ +/** + * Type for the access type of the authentication URL. + */ +type AccessType = 'online' | 'offline'; + +/** + * Type for the different OAuth providers Nylas supports. + */ +export type Provider = + | 'google' + | 'imap' + | 'microsoft' + | 'icloud' + | 'virtual-calendar' + | 'ews' + | 'zoom'; + +/** + * Configuration for generating a URL for OAuth 2.0 authentication. + */ +export interface URLForAuthenticationConfig { + /** + * The client ID of your application. + */ + clientId: string; + /** + * Redirect URI of the integration. + */ + redirectUri: string; + /** + * The integration provider type that you already had set up with Nylas for this application. + * If not set, the user is directed to the Hosted Login screen and prompted to select a provider. + */ + provider?: Provider; + /** + * If the exchange token should return a refresh token too. Not suitable for client side or JavaScript apps. + */ + accessType?: AccessType; + /** + * The prompt parameter is used to force the consent screen to be displayed even if the user has already given consent to your application. + */ + prompt?: string; + /** + * A space-delimited list of scopes that identify the resources that your application could access on the user's behalf. + * If no scope is given, all of the default integration's scopes are used. + */ + scope?: string[]; + /** + * If set to true, the scopes granted to the application will be included in the response. + */ + includeGrantScopes?: boolean; + /** + * Optional state to be returned after authentication + */ + state?: string; + /** + * Prefill the login name (usually email) during authorization flow. + * If a Grant for the provided email already exists, a Grant's re-auth will automatically be initiated. + */ + loginHint?: string; +} + +/** + * Configuration for generating a URL for admin consent authentication for Microsoft. + */ +export interface URLForAdminConsentConfig extends URLForAuthenticationConfig { + /** + * The credential ID for the Microsoft account + */ + credentialId: string; +} + +/** + * Interface of a Nylas code exchange request + */ +export interface CodeExchangeRequest { + /** + * Should match the same redirect URI that was used for getting the code during the initial authorization request. + */ + redirectUri: string; + /** + * OAuth 2.0 code fetched from the previous step. + */ + code: string; + /** + * Client ID of the application. + */ + clientId: string; + /** + * Client secret of the application. If not provided, the API Key will be used instead. + */ + clientSecret?: string; + /** + * The original plain text code verifier (code_challenge) used in the initial authorization request (PKCE). + */ + codeVerifier?: string; +} + +/** + * Interface of a Nylas token exchange request + */ +export interface TokenExchangeRequest { + /** + * Should match the same redirect URI that was used for getting the code during the initial authorization request. + */ + redirectUri: string; + /** + * Token to refresh/request your short-lived access token + */ + refreshToken: string; + /** + * Client ID of the application. + */ + clientId: string; + /** + * Client secret of the application. If not provided, the API Key will be used instead. + */ + clientSecret?: string; +} + +/** + * Interface of the object containing the OAuth 2.0 URL as well as the hashed secret. + */ +export interface PKCEAuthURL { + /** + * The URL for hosted authentication + */ + url: string; + /** + * Server-side challenge used in the OAuth 2.0 flow + */ + secret: string; + /** + * SHA-256 hash of the secret + */ + secretHash: string; +} + +/** + * Interface of a Nylas code exchange response + */ +export interface CodeExchangeResponse { + /** + * Supports exchanging the code for tokens, or refreshing an access token using [Auth.refreshAccessToken][com.nylas.resources.Auth.refreshAccessToken]. + */ + accessToken: string; + /** + * Nylas grant ID that is now successfully created. + */ + grantId: string; + /** + * Email address of the grant that is created. + */ + email: string; + /** + * The remaining lifetime of the access token in seconds. + */ + expiresIn: number; + /** + * List of scopes associated with this token. + */ + scope: string; + /** + * Only returned if the code was requested using [AccessType.OFFLINE][com.nylas.models.AccessType.OFFLINE]. + */ + refreshToken?: string; + /** + * A JWT that contains identity information about the user that is digitally signed by Nylas. + */ + idToken?: string; + /** + * Currently always Bearer. + */ + tokenType?: string; + /** + * The provider that the code was exchanged with. + */ + provider?: Provider; +} + +/** + * Interface representing the object used to set parameters for detecting a provider. + */ +export interface ProviderDetectParams { + /** + * Email address to detect the provider for. + */ + email: string; + /** + * Search by all providers regardless of created integrations. If unset, defaults to false. + */ + allProviderTypes?: boolean; +} + +/** + * Interface representing the Nylas provider detect response. + */ +export interface ProviderDetectResponse { + /** + * Email provided for autodetection + */ + emailAddress: string; + /** + * Whether the provider was detected + */ + detected: boolean; + /** + * Detected provider + */ + provider?: string; + /** + * Provider type (if IMAP provider detected displays the IMAP provider) + */ + type?: string; +} + +/** + * Interface representing a Nylas token information response. + */ +export interface TokenInfoResponse { + /** + * The issuer of the token. + */ + iss: string; + /** + * The token's audience. + */ + aud: string; + /** + * The time that the token was issued. + */ + iat: number; + /** + * The time that the token expires. + */ + exp: number; + /** + * The token's subject. + */ + sub?: string; + /** + * The email address of the Grant belonging to the user's token. + */ + email?: string; +} diff --git a/src/models/availability.ts b/src/models/availability.ts new file mode 100644 index 00000000..572c1647 --- /dev/null +++ b/src/models/availability.ts @@ -0,0 +1,182 @@ +/** + * Interface for a Nylas get availability response + */ +export interface GetAvailabilityResponse { + /** + * This property is only populated for round-robin events. + * It will contain the order in which the accounts would be next in line to attend the proposed meeting. + */ + order: string[]; + /** + * The available time slots where a new meeting can be created for the requested preferences. + */ + timeSlots: TimeSlot[]; +} + +/** + * Interface for a Nylas get availability request + */ +export interface GetAvailabilityRequest { + /** + * Unix timestamp for the start time to check availability for. + */ + startTime: number; + /** + * Unix timestamp for the end time to check availability for. + */ + endTime: number; + /** + * Participant details to check availability for. + */ + participants: AvailabilityParticipant[]; + /** + * The total number of minutes the event should last. + */ + durationMinutes: number; + /** + * Nylas checks from the nearest interval of the passed [startTime]. + * For example, to schedule 30-minute meetings ([durationMinutes]) with 15 minutes between them ([intervalMinutes]). + * If you have a meeting starting at 9:59, the API returns times starting at 10:00. 10:00-10:30, 10:15-10:45. + */ + intervalMinutes?: number; + + /** + * The number of minutes to round the time slots to. + * This allows for rounding to any multiple of 5 minutes, up to a maximum of 60 minutes. + * The default value is set to 15 minutes. + * When this variable is assigned a value, it overrides the behavior of the {@link roundTo30Minutes} flag, if it was set. + */ + roundTo?: number; + /** + * The rules to apply when checking availability. + */ + availabilityRules?: AvailabilityRules; + /** + * When set to true, the availability time slots will start at 30 minutes past or on the hour. + * For example, a free slot starting at 16:10 is considered available only from 16:30. + * @deprecated Use {@link roundTo} instead. + */ + roundTo30Minutes?: boolean; +} + +/** + * Interface for a Nylas availability time slot + */ +export interface TimeSlot { + /** + * The emails of the participants who are available for the time slot. + */ + emails: string[]; + /** + * Unix timestamp for the start of the slot. + */ + startTime: string; + /** + * Unix timestamp for the end of the slot. + */ + endTime: string; +} + +/** + * Interface for the availability rules for a Nylas calendar. + */ +export interface AvailabilityRules { + /** + * The method used to determine availability for a meeting. + */ + availabilityMethod?: AvailabilityMethod; + /** + * The buffer to add to the start and end of a meeting. + */ + buffer?: MeetingBuffer; + /** + * A default set of open hours to apply to all participants. + * You can overwrite these open hours for individual participants by specifying [AvailabilityParticipant.openHours] + * on the participant object. + */ + defaultOpenHours?: OpenHours[]; + /** + * The ID on events that Nylas considers when calculating the order of round-robin participants. + * This is used for both max-fairness and max-availability methods. + */ + roundRobinEventId?: string; + /** + * tentative_as_busy: Controls whether tentative calendar events should be treated as busy time. + * When set to false, tentative events will be considered as free in availability calculations. + * Defaults to true. Only applicable for Microsoft and EWS calendar providers. + */ + tentativeAsBusy?: boolean; +} + +/** + * Interface for the meeting buffer object within an availability request. + */ +export interface MeetingBuffer { + /** + * The amount of buffer time in increments of 5 minutes to add before existing meetings. + * Defaults to 0. + */ + before: number; + /** + * The amount of buffer time in increments of 5 minutes to add after existing meetings. + * Defaults to 0. + */ + after: number; +} + +/** + * Interface of a participant's open hours. + */ +export interface OpenHours { + /** + * The days of the week that the open hour settings will be applied to. + * Sunday corresponds to 0 and Saturday corresponds to 6. + */ + days: number[]; + /** + * IANA time zone database formatted string (e.g. America/New_York). + * @see List of tz database time zones + */ + timezone: string; + /** + * Start time in 24-hour time format. Leading 0's are left off. + */ + start: string; + /** + * End time in 24-hour time format. Leading 0's are left off. + */ + end: string; + /** + * A list of dates that will be excluded from the open hours. + * Dates should be formatted as YYYY-MM-DD. + */ + exdates: string[]; +} + +/** + * Interface of participant details to check availability for. + */ +export interface AvailabilityParticipant { + /** + * The email address of the participant. + */ + email: string; + /** + * An optional list of the calendar IDs associated with each participant's email address. + * If not provided, Nylas uses the primary calendar ID. + */ + calendarIds?: string[]; + /** + * Open hours for this participant. The endpoint searches for free time slots during these open hours. + */ + openHours?: OpenHours[]; +} + +/** + * Enum representing the method used to determine availability for a meeting. + */ +export enum AvailabilityMethod { + MaxFairness = 'max-fairness', + MaxAvailability = 'max-availability', + Collective = 'collective', +} diff --git a/src/models/calendar.js b/src/models/calendar.js deleted file mode 100644 index 94312ba3..00000000 --- a/src/models/calendar.js +++ /dev/null @@ -1,19 +0,0 @@ -import _ from 'underscore'; - -import RestfulModel from './restful-model'; -import Attributes from './attributes'; - -export default class Calendar extends RestfulModel {} -Calendar.collectionName = 'calendars'; -Calendar.attributes = _.extend({}, RestfulModel.attributes, { - name: Attributes.String({ - modelKey: 'name', - }), - description: Attributes.String({ - modelKey: 'description', - }), - readOnly: Attributes.Boolean({ - modelKey: 'readOnly', - jsonKey: 'read_only', - }), -}); diff --git a/src/models/calendars.ts b/src/models/calendars.ts new file mode 100644 index 00000000..2fe92a0a --- /dev/null +++ b/src/models/calendars.ts @@ -0,0 +1,189 @@ +import { ListQueryParams } from './listQueryParams.js'; +import { NotetakerMeetingSettings } from './notetakers.js'; + +/** + * Interface for Calendar Notetaker participant filter + */ +export interface CalendarNotetakerParticipantFilter { + /** + * Only have meeting bot join meetings with greater than or equal to this number of participants + */ + participantsGte?: number; + /** + * Only have meeting bot join meetings with less than or equal to this number of participants + */ + participantsLte?: number; +} + +/** + * Interface for Calendar Notetaker rules + */ +export interface CalendarNotetakerRules { + /** + * Types of events to include for notetaking. This is a union of events that should have a Notetaker sent to them. + * "internal": Events where the host domain matches all participants' domain names + * "external": Events where the host domain differs from any participant's domain name + * "own_events": Events where the host is the same as the user's grant + * "participant_only": Events where the user's grant is a participant but not the host + * "all": When all options are included, all events with meeting links will have Notetakers + */ + eventSelection?: Array< + 'internal' | 'external' | 'all' | 'ownEvents' | 'participantOnly' + >; + /** + * Filters to apply based on the number of participants. This is an intersection with the event_selection. + * When null, there are no restrictions on the number of participants for notetaker events. + */ + participantFilter?: CalendarNotetakerParticipantFilter; +} + +/** + * Interface for Calendar Notetaker settings + */ +export interface CalendarNotetaker { + /** + * The display name for the Notetaker bot. + * @default "Nylas Notetaker" + */ + name?: string; + /** + * Notetaker Meeting Settings + */ + meetingSettings?: NotetakerMeetingSettings; + /** + * Rules for when the Notetaker should join a meeting. + */ + rules?: CalendarNotetakerRules; +} + +/** + * Interface of the query parameters for listing calendars. + */ +export interface ListCalendersQueryParams extends ListQueryParams { + /** + * The maximum number of objects to return. + * This field defaults to 50. The maximum allowed value is 200. + */ + limit?: number; + /** + * An identifier that specifies which page of data to return. + * This value should be taken from the [ListResponse.nextCursor] response field. + */ + pageToken?: string; + /** + * Pass in your metadata key and value pair to search for metadata. + */ + metadataPair?: Record; +} + +/** + * Interface of a Nylas create calendar request + */ +export interface CreateCalenderRequest { + /** + * Name of the Calendar. + */ + name: string; + /** + * Description of the calendar. + */ + description?: string; + /** + * Geographic location of the calendar as free-form text. + */ + location?: string; + /** + * IANA time zone database formatted string (e.g. America/New_York). + * @see List of tz database time zones + */ + timezone?: string; + /** + * A list of key-value pairs storing additional data. + */ + metadata?: Record; + /** + * Notetaker meeting bot settings + */ + notetaker?: CalendarNotetaker; +} + +/** + * Interface of a Nylas update calendar request + */ +export interface UpdateCalenderRequest extends Partial { + /** + * The background color of the calendar in the hexadecimal format (e.g. #0099EE). + * Empty indicates default color. + */ + hexColor?: string; + /** + * The background color of the calendar in the hexadecimal format (e.g. #0099EE). + * Empty indicates default color. (Google only) + */ + hexForegroundColor?: string; +} + +/** + * Interface of a Nylas calendar object + */ +export interface Calendar { + /** + * Globally unique object identifier. + */ + id: string; + /** + * Grant ID of the Nylas account. + */ + grantId: string; + /** + * Name of the Calendar. + */ + name: string; + /** + * The type of object. + */ + object: string; + /** + * IANA time zone database formatted string (e.g. America/New_York). + * @see List of tz database time zones + */ + timezone: string; + /** + * If the event participants are able to edit the event. + */ + readOnly: boolean; + /** + * If the calendar is owned by the user account. + */ + isOwnedByUser: boolean; + /** + * Description of the calendar. + */ + description?: string; + /** + * Geographic location of the calendar as free-form text. + */ + location?: string; + /** + * The background color of the calendar in the hexadecimal format (e.g. #0099EE). + * Empty indicates default color. + */ + hexColor?: string; + /** + * The background color of the calendar in the hexadecimal format (e.g. #0099EE). + * Empty indicates default color. (Google only) + */ + hexForegroundColor?: string; + /** + * If the calendar is the primary calendar. + */ + isPrimary?: boolean; + /** + * A list of key-value pairs storing additional data. + */ + metadata?: Record; + /** + * Notetaker meeting bot settings + */ + notetaker?: CalendarNotetaker; +} diff --git a/src/models/connectors.ts b/src/models/connectors.ts new file mode 100644 index 00000000..7f68a29e --- /dev/null +++ b/src/models/connectors.ts @@ -0,0 +1,140 @@ +import { Provider } from './auth.js'; +import { ListQueryParams } from './listQueryParams.js'; + +/** + * Interface representing the Nylas connector response. + */ +export interface Connector { + /** + * The provider type + */ + provider: Provider; + /** + * Optional settings from provider + */ + settings?: Record; + /** + * Default scopes for the connector + */ + scope?: string[]; +} + +/** + * Interface representing a Google connector creation request. + */ +export interface GoogleCreateConnectorSettings { + /** + * The Google Client ID + */ + clientId: string; + /** + * The Google Client Secret + */ + clientSecret: string; + /** + * The Google Pub/Sub topic name + */ + topicName?: string; +} + +/** + * Interface representing a Microsoft connector creation request. + */ +export interface MicrosoftCreateConnectorSettings { + /** + * The Microsoft Client ID + */ + clientId: string; + /** + * The Microsoft Client Secret + */ + clientSecret: string; + /** + * The Microsoft tenant ID + */ + tenant?: string; +} + +/** + * Interface representing the base Nylas connector creation request. + */ +interface BaseCreateConnectionRequest { + /** + * Custom name of the connector + */ + name: string; + /** + * The provider type + */ + provider: Provider; +} + +/** + * Interface representing the base Nylas connector creation request. + */ +export interface GoogleCreateConnectorRequest + extends BaseCreateConnectionRequest { + /** + * The Google OAuth provider credentials and settings + */ + settings: GoogleCreateConnectorSettings; + /** + * The Google OAuth scopes + */ + scope?: string[]; +} + +export interface MicrosoftCreateConnectorRequest + extends BaseCreateConnectionRequest { + /** + * The Microsoft OAuth provider credentials and settings + */ + settings: MicrosoftCreateConnectorSettings; + /** + * The Microsoft OAuth scopes + */ + scope?: string[]; +} + +/** + * Interface representing the base Nylas connector creation request. + */ +export type ImapCreateConnectorRequest = BaseCreateConnectionRequest; + +/** + * Interface representing the base Nylas connector creation request. + */ +export type VirtualCalendarsCreateConnectorRequest = + BaseCreateConnectionRequest; + +/** + * The type of the Nylas connector creation request. + */ +export type CreateConnectorRequest = + | GoogleCreateConnectorRequest + | MicrosoftCreateConnectorRequest + | ImapCreateConnectorRequest + | VirtualCalendarsCreateConnectorRequest; + +/** + * Interface representing the base Nylas connector creation request. + */ +export interface UpdateConnectorRequest { + /** + * Custom name of the connector + */ + name?: string; + /** + * The OAuth provider credentials and settings + */ + settings?: Record; + /** + * The OAuth scopes + */ + scope?: string[]; +} + +/** + * Interface of the query parameters for listing connectors. + */ +export type ListConnectorsQueryParams = ListQueryParams; diff --git a/src/models/contact.js b/src/models/contact.js deleted file mode 100644 index 08350970..00000000 --- a/src/models/contact.js +++ /dev/null @@ -1,211 +0,0 @@ -import _ from 'underscore'; - -import RestfulModel from './restful-model'; -import Attributes from './attributes'; - -class EmailAddress extends RestfulModel { - toJSON() { - const json = { - type: this.type, - email: this.email, - }; - return json; - } -} -EmailAddress.collectionName = 'email_addresses'; -EmailAddress.attributes = _.extend({}, RestfulModel.attributes, { - type: Attributes.String({ - modelKey: 'type', - }), - email: Attributes.String({ - modelKey: 'email', - }), -}); - -class IMAddress extends RestfulModel { - toJSON() { - const json = { - type: this.type, - im_address: this.im_address, - }; - return json; - } -} -IMAddress.collectionName = 'im_addresses'; -IMAddress.attributes = _.extend({}, RestfulModel.attributes, { - type: Attributes.String({ - modelKey: 'type', - }), - imAddress: Attributes.String({ - modelKey: 'imAddress', - jsonKey: 'im_address', - }), -}); - -class PhysicalAddress extends RestfulModel { - toJSON() { - const json = { - type: this.type, - format: this.format, - }; - if (this.format == 'unstructured') { - json.address = this.address; - } else { - json.street_address = this.streetAddress; - json.postal_code = this.postalCode; - json.state = this.state; - json.city = this.city; - json.country = this.country; - } - return json; - } -} -PhysicalAddress.collectionName = 'physical_addresses'; -PhysicalAddress.attributes = _.extend({}, RestfulModel.attributes, { - type: Attributes.String({ - modelKey: 'type', - }), - format: Attributes.String({ - modelKey: 'format', - }), - address: Attributes.String({ - modelKey: 'address', - }), - streetAddress: Attributes.String({ - modelKey: 'streetAddress', - jsonKey: 'street_address', - }), - city: Attributes.String({ - modelKey: 'city', - }), - postalCode: Attributes.String({ - modelKey: 'postalCode', - jsonKey: 'postal_code', - }), - state: Attributes.String({ - modelKey: 'state', - }), - country: Attributes.String({ - modelKey: 'country', - }), -}); - -class PhoneNumber extends RestfulModel { - toJSON() { - const json = { - type: this.type, - number: this.number, - }; - return json; - } -} - -PhoneNumber.collectionName = 'phone_numbers'; -PhoneNumber.attributes = _.extend({}, RestfulModel.attributes, { - type: Attributes.String({ - modelKey: 'type', - }), - number: Attributes.String({ - modelKey: 'number', - }), -}); - -class WebPage extends RestfulModel { - toJSON() { - const json = { - type: this.type, - url: this.url, - }; - return json; - } -} -WebPage.collectionName = 'web_pages'; -WebPage.attributes = _.extend({}, RestfulModel.attributes, { - type: Attributes.String({ - modelKey: 'type', - }), - url: Attributes.String({ - modelKey: 'url', - }), -}); - -export default class Contact extends RestfulModel { - save(params = {}, callback = null) { - return this._save(params, callback); - } - - getPicture(params = {}, callback = null) { - return this._get(params, callback, '/picture'); - } -} -Contact.collectionName = 'contacts'; -Contact.attributes = _.extend({}, RestfulModel.attributes, { - givenName: Attributes.String({ - modelKey: 'givenName', - jsonKey: 'given_name', - }), - middleName: Attributes.String({ - modelKey: 'middleName', - jsonKey: 'middle_name', - }), - surname: Attributes.String({ - modelKey: 'surname', - }), - suffix: Attributes.String({ - modelKey: 'suffix', - }), - nickname: Attributes.String({ - modelKey: 'nickname', - }), - birthday: Attributes.Date({ - modelKey: 'birthday', - }), - companyName: Attributes.String({ - modelKey: 'companyName', - jsonKey: 'company_name', - }), - jobTitle: Attributes.String({ - modelKey: 'jobTitle', - jsonKey: 'job_title', - }), - managerName: Attributes.String({ - modelKey: 'managerName', - jsonKey: 'manager_name', - }), - officeLocation: Attributes.String({ - modelKey: 'officeLocation', - jsonKey: 'office_location', - }), - notes: Attributes.String({ - modelKey: 'notes', - }), - pictureUrl: Attributes.String({ - modelKey: 'pictureUrl', - jsonKey: 'picture_url', - }), - emailAddresses: Attributes.Collection({ - modelKey: 'emailAddresses', - jsonKey: 'email_addresses', - itemClass: EmailAddress, - }), - imAddresses: Attributes.Collection({ - modelKey: 'imAddresses', - jsonKey: 'im_addresses', - itemClass: IMAddress, - }), - physicalAddresses: Attributes.Collection({ - modelKey: 'physicalAddresses', - jsonKey: 'physical_addresses', - itemClass: PhysicalAddress, - }), - phoneNumbers: Attributes.Collection({ - modelKey: 'phoneNumbers', - jsonKey: 'phone_numbers', - itemClass: PhoneNumber, - }), - webPages: Attributes.Collection({ - modelKey: 'webPages', - jsonKey: 'web_pages', - itemClass: WebPage, - }), -}); diff --git a/src/models/contacts.ts b/src/models/contacts.ts new file mode 100644 index 00000000..fc2dc0cc --- /dev/null +++ b/src/models/contacts.ts @@ -0,0 +1,159 @@ +import { ListQueryParams } from './listQueryParams.js'; + +/** + * Interface representing a Nylas Contact object. + */ +export interface Contact { + id: string; + grantId: string; + object: 'contact'; + birthday?: string; + companyName?: string; + displayName: string; + emails: Email[]; + imAddresses: InstantMessagingAddress[]; + givenName?: string; + jobTitle?: string; + managerName?: string; + middleName?: string; + nickname?: string; + notes?: string; + officeLocation?: string; + pictureUrl?: string; + picture?: string; + suffix?: string; + surname?: string; + source?: SourceType; + phoneNumbers: PhoneNumber[]; + physicalAddresses: PhysicalAddress[]; + webPages: WebPage[]; + groups: ContactGroup[]; +} + +/** + * Custom Types. + */ +export type SourceType = 'address_book' | 'inbox' | 'domain'; +export type GroupType = 'user' | 'system' | 'other'; + +/** + * Interface for email addresses in a contact. + */ +export interface Email { + email?: string; + type?: string; +} + +/** + * Interface for IM addresses in a contact. + */ +export interface InstantMessagingAddress { + type?: string; + imAddress?: string; +} + +/** + * Interface for phone numbers in a contact. + */ +export interface PhoneNumber { + number?: string; + type?: string; +} + +/** + * Interface for physical addresses in a contact. + */ +export interface PhysicalAddress { + format?: string; + streetAddress?: string; + city?: string; + postalCode?: string; + state?: string; + country?: string; + type?: string; +} + +/** + * Interface for web pages in a contact. + */ +export interface WebPage { + url?: string; + type?: string; +} + +/** + * Interface representing a contact group. + */ +export interface ContactGroup { + id: string; + object: 'contact_group'; + grantId?: string; + groupType?: GroupType; + name?: string; + path?: string; +} + +/** + * Interface representing the query parameters for listing contacts. + */ +export interface ListContactQueryParams extends ListQueryParams { + /** + * Returns the contacts matching the exact contact's email. + */ + email?: string; + /** + * Returns the contacts matching the contact's exact phone number + */ + phoneNumber?: string; + /** + * Returns the contacts matching from the address book or auto-generated contacts from emails. + * For example of contacts only from the address book: /contacts?source=address_bookor for only autogenerated contacts:/contacts?source=inbox` + */ + source?: string; + /** + * Returns the contacts belonging to the Contact Group matching this ID + */ + group?: string; + /** + * When set to true, returns the contacts also within the specified Contact Group subgroups, if the group parameter is set. + */ + recurse?: boolean; +} + +/** + * Interface representing the query parameters for retrieving a single contact. + */ +export interface FindContactQueryParams { + profilePicture?: boolean; +} + +/** + * Interface for creating a contact. + */ +export type CreateContactRequest = { + displayName?: string; + birthday?: string; + companyName?: string; + emails?: Email[]; + givenName?: string; + imAddresses?: InstantMessagingAddress[]; + jobTitle?: string; + managerName?: string; + middleName?: string; + nickname?: string; + notes?: string; + officeLocation?: string; + phoneNumbers?: PhoneNumber[]; + physicalAddresses?: PhysicalAddress[]; + suffix?: string; + surname?: string; + webPages?: WebPage[]; + picture?: string; + source?: SourceType; + groups?: ContactGroup[]; +}; + +/** + * Interface for updating a contact. + */ +export type UpdateContactRequest = CreateContactRequest; diff --git a/src/models/credentials.ts b/src/models/credentials.ts new file mode 100644 index 00000000..ce2e60e3 --- /dev/null +++ b/src/models/credentials.ts @@ -0,0 +1,168 @@ +/** + * Interface representing a Nylas Credential object. + */ +export interface Credential { + /** + * Globally unique object identifier + */ + id: string; + /** + * Name of the credential + */ + name: string; + /** + * The type of credential + */ + credentialType?: CredentialType; + /** + * Hashed value of the credential that you created + */ + hashedData?: string; + /** + * Timestamp of when the credential was created + */ + createdAt?: number; + /** + * Timestamp of when the credential was updated + */ + updatedAt?: number; +} + +/** + * Interface representing additional data needed to create a credential for Microsoft Admin Consent + */ +export interface MicrosoftAdminConsentSettings { + clientId: string; + clientSecret: string; + [key: string]: string; +} + +/** + * Interface representing additional data needed to create a credential for Google Service Account + */ +export interface GoogleServiceAccountCredential { + privateKeyId: string; + privateKey: string; + clientEmail: string; + [key: string]: string; +} + +/** + * Interface representing additional data needed to create a credential for a Connector Override + */ +export type ConnectorOverrideCredential = Record; + +/** + * Type representing the data needed to create a credential + */ +export type CredentialData = + | MicrosoftAdminConsentSettings + | GoogleServiceAccountCredential + | ConnectorOverrideCredential; + +/** + * Interface representing a request to create a Microsoft Admin Consent credential + */ +export interface CreateMicrosoftCredentialRequest { + /** + * Unique name of this credential + */ + name: string; + /** + * Type of credential for the admin consent flow + */ + credentialType: CredentialType.ADMINCONSENT; + /** + * Data that specifies some special data required for this credential + */ + credentialData: MicrosoftAdminConsentSettings; +} + +/** + * Interface representing a request to create a Google Service Account credential + */ +export interface CreateGoogleCredentialRequest { + /** + * Unique name of this credential + */ + name: string; + /** + * Type of credential for the app permission flow + */ + credentialType: CredentialType.SERVICEACCOUNT; + /** + * Data that specifies some special data required for this credential + */ + credentialData: GoogleServiceAccountCredential; +} + +/** + * Interface representing a request to create a Connector Override credential + */ +export interface CreateOverrideCredentialRequest { + /** + * Unique name of this credential + */ + name: string; + /** + * Type of credential to force the override of a connector's client values + */ + credentialType: CredentialType.CONNECTOR; + /** + * Data that specifies some special data required for this credential + */ + credentialData: ConnectorOverrideCredential; +} + +/** + * Interface representing a request to create a credential + */ +export type CreateCredentialRequest = + | CreateMicrosoftCredentialRequest + | CreateGoogleCredentialRequest + | CreateOverrideCredentialRequest; + +/** + * Interface representing a request to update a credential + */ +export interface UpdateCredentialRequest { + /** + * Unique name of this credential + */ + name?: string; + /** + * Data that specifies some special data required for this credential + */ + credentialData?: CredentialData; +} + +/** + * Enum representing the type of credential + */ +export enum CredentialType { + ADMINCONSENT = 'adminconsent', + SERVICEACCOUNT = 'serviceaccount', + CONNECTOR = 'connector', +} + +/** + * Interface representing the query parameters for listing credentials. + */ +export interface ListCredentialsQueryParams { + /** + * Limit the number of results + */ + limit?: number; + /** + * Offset the results by this number + */ + offset?: number; + /** + * Sort the results by field name + */ + sortBy?: 'createdAt' | 'updatedAt'; + /** + * Order the results by ascending or descending + */ + orderBy?: 'desc' | 'asc'; +} diff --git a/src/models/delta.js b/src/models/delta.js deleted file mode 100644 index 2ca3fbda..00000000 --- a/src/models/delta.js +++ /dev/null @@ -1,202 +0,0 @@ -import _ from 'underscore'; -import backoff from 'backoff'; -import JSONStream from 'JSONStream'; -import Promise from 'bluebird'; -import request from 'request'; -import { EventEmitter } from 'events'; - -export default class Delta { - constructor(connection) { - this.connection = connection; - if (!(this.connection instanceof require('../nylas-connection'))) { - throw new Error('Connection object not provided'); - } - } - - latestCursor(callback) { - const reqOpts = { - method: 'POST', - path: '/delta/latest_cursor', - }; - - return this.connection - .request(reqOpts) - .then(response => { - const { cursor } = response; - if (callback) { - callback(null, cursor); - } - return Promise.resolve(cursor); - }) - .catch(err => { - if (callback) { - callback(err, null); - } - return Promise.reject(err); - }); - } - - startStream(cursor, params = {}) { - return this._startStream(request, cursor, params); - } - - _startStream(createRequest, cursor, params) { - const stream = new DeltaStream( - createRequest, - this.connection, - cursor, - params - ); - stream.open(); - return stream; - } -} -Delta.streamingTimeoutMs = 15000; - -/* -A connection to the Nylas delta streaming API. - -Emits the following events: -- `response` when the connection is established, with one argument, a `http.IncomingMessage` -- `delta` for each delta received -- `error` when an error occurs in the connection -- `info` when the connection status changes -*/ -class DeltaStream extends EventEmitter { - // @param {function} createRequest function to create a request; only present for testability - // @param {string} cursor Nylas delta API cursor - // @param {Object} params object contianing query string params to be passed to the request - // @param {Array} params.excludeTypes object types to not return deltas for (e.g., {excludeTypes: ['thread']}) - // @param {Array} params.includeTypes object types to exclusively return deltas for (e.g., {includeTypes: ['thread']}) - // @param {boolean} params.expanded boolean to specify wether to request the expanded view - constructor(createRequest, connection, cursor, params = {}) { - super(createRequest, connection, cursor, params); - this.createRequest = createRequest; - this.connection = connection; - this.cursor = cursor; - this.params = params; - if (!(this.connection instanceof require('../nylas-connection'))) { - throw new Error('Connection object not provided'); - } - this.restartBackoff = backoff.exponential({ - randomisationFactor: 0.5, - initialDelay: 250, - maxDelay: 30000, - factor: 4, - }); - this.restartBackoff.failAfter(DeltaStream.MAX_RESTART_RETRIES); - this.restartBackoff - .on('backoff', this._restartConnection.bind(this)) - .on('fail', () => { - return this.emit( - 'error', - `Nylas DeltaStream failed to reconnect after ${ - DeltaStream.MAX_RESTART_RETRIES - } retries.` - ); - }); - } - - close() { - clearTimeout(this.timeoutId); - delete this.timeoutId; - this.restartBackoff.reset(); - if (this.request) { - this.request.abort(); - } - delete this.request; - } - - open() { - this.close(); - const path = '/delta/streaming'; - const excludeTypes = - this.params.excludeTypes != null ? this.params.excludeTypes : []; - const includeTypes = - this.params.includeTypes != null ? this.params.includeTypes : []; - - const queryObj = _.extend( - {}, - _.omit(this.params, 'excludeTypes', 'includeTypes'), - { - cursor: this.cursor, - } - ); - if (excludeTypes.length > 0) { - queryObj.exclude_types = excludeTypes.join(','); - } - if (includeTypes.length > 0) { - queryObj.include_types = includeTypes.join(','); - } - - const reqOpts = this.connection.requestOptions({ - method: 'GET', - path, - qs: queryObj, - }); - - return (this.request = this.createRequest(reqOpts) - .on('response', response => { - if (response.statusCode !== 200) { - response.on('data', data => { - let err = data; - try { - err = JSON.parse(err); - } catch (e) {} - // Do nothing, keep err as string. - return this._onError(err); - }); - return; - } - // Successfully established connection - this.emit('response', response); - this._onDataReceived(); - return ( - response - .on('data', this._onDataReceived.bind(this)) - // Each data block received may not be a complete JSON object. Pipe through - // JSONStream.parse(), which handles converting data blocks to JSON objects. - .pipe(JSONStream.parse()) - .on('data', obj => { - if (obj.cursor) { - this.cursor = obj.cursor; - } - return this.emit('delta', obj); - }) - ); - }) - .on('error', this._onError.bind(this))); - } - - _onDataReceived(data) { - // Nylas sends a newline heartbeat in the raw data stream once every 5 seconds. - // Automatically restart the connection if we haven't gotten any data in - // Delta.streamingTimeoutMs. The connection will restart with the last - // received cursor. - clearTimeout(this.timeoutId); - this.restartBackoff.reset(); - return (this.timeoutId = setTimeout( - this.restartBackoff.backoff.bind(this.restartBackoff), - Delta.streamingTimeoutMs - )); - } - - _onError(err) { - this.emit('error', err); - return this.restartBackoff.reset(); - } - - _restartConnection(n) { - this.emit( - 'info', - `Restarting Nylas DeltaStream connection (attempt ${n + 1}): ${ - this.request != null ? this.request.href : undefined - }` - ); - this.close(); - return this.open(); - } -} -// Max number of times to retry a connection if we receive no data heartbeats -// from the Nylas server. -DeltaStream.MAX_RESTART_RETRIES = 5; diff --git a/src/models/draft.js b/src/models/draft.js deleted file mode 100644 index d471c617..00000000 --- a/src/models/draft.js +++ /dev/null @@ -1,107 +0,0 @@ -import _ from 'underscore'; -import Promise from 'bluebird'; - -import File from './file'; -import Message from './message'; -import Contact from './contact'; -import Attributes from './attributes'; - -export default class Draft extends Message { - constructor(...args) { - super(...args); - } - - toJSON() { - if (this.rawMime) { - throw Error('toJSON() cannot be called for raw MIME drafts'); - } - const json = super.toJSON(...arguments); - json.file_ids = this.fileIds(); - if (this.draft) { - json.object = 'draft'; - } - return json; - } - - save(params = {}, callback = null) { - if (this.rawMime) { - const err = new Error('save() cannot be called for raw MIME drafts'); - if (callback) { - callback(err); - } - return Promise.reject(err); - } - return this._save(params, callback); - } - - saveRequestBody() { - if (this.rawMime) { - throw Error('saveRequestBody() cannot be called for raw MIME drafts'); - } - return super.saveRequestBody(...arguments); - } - - toString() { - if (this.rawMime) { - throw Error('toString() cannot be called for raw MIME drafts'); - } - super.toString(); - } - - send(callback = null) { - let body = this.rawMime, - headers = { 'Content-Type': 'message/rfc822' }, - json = false; - - if (!this.rawMime) { - headers = {}; - json = true; - if (this.id) { - body = { - draft_id: this.id, - version: this.version, - }; - } else { - body = this.saveRequestBody(); - } - } - - return this.connection - .request({ - method: 'POST', - path: '/send', - headers, - body, - json, - }) - .then(json => { - const message = new Message(this.connection, json); - - // We may get failures for a partial send - if (json.failures) { - message.failures = json.failures; - } - - if (callback) { - callback(null, message); - } - return Promise.resolve(message); - }) - .catch(err => { - if (callback) { - callback(err); - } - return Promise.reject(err); - }); - } -} -Draft.collectionName = 'drafts'; -Draft.attributes = _.extend({}, Message.attributes, { - version: Attributes.Number({ - modelKey: 'version', - }), - replyToMessageId: Attributes.String({ - modelKey: 'replyToMessageId', - jsonKey: 'reply_to_message_id', - }), -}); diff --git a/src/models/drafts.ts b/src/models/drafts.ts new file mode 100644 index 00000000..02060557 --- /dev/null +++ b/src/models/drafts.ts @@ -0,0 +1,171 @@ +import { BaseMessage } from './messages.js'; +import { ListQueryParams } from './listQueryParams.js'; +import { EmailName } from './events.js'; +import { CreateAttachmentRequest } from './attachments.js'; + +export interface CustomHeader { + /** + * The name of the custom header. + */ + name: string; + /** + * The value of the custom header. + */ + value: string; +} + +/** + * Interface representing a request to create a draft. + */ +export interface CreateDraftRequest { + /** + * An array of name/email address pairs that the message was sent from. This is usually one pair only, but can be many. + */ + from?: EmailName[]; + /** + * An array of message recipients. + */ + to: EmailName[]; + /** + * An array of bcc recipients. + */ + bcc?: EmailName[]; + /** + * An array of cc recipients. + */ + cc?: EmailName[]; + /** + * An array of name and email pairs that override the sent reply-to headers. + */ + replyTo?: EmailName[]; + /** + * An array of files to attach to the message. + */ + attachments?: CreateAttachmentRequest[]; + /** + * The message subject. + */ + subject?: string; + /** + * The full HTML message body. + * Messages with only plain-text representations are up-converted to HTML. + */ + body?: string; + /** + * Whether or not the message has been starred by the user. + */ + starred?: boolean; + /** + * Unix timestamp to send the message at. + */ + sendAt?: number; + /** + * The ID of the message that you are replying to. + */ + replyToMessageId?: string; + /** + * Options for tracking opens, links, and thread replies. + */ + trackingOptions?: TrackingOptions; + /** + * An array of custom headers to add to the message. + */ + customHeaders?: CustomHeader[]; + /** + * When true, the message body is sent as plain text and the MIME data doesn't include the HTML version of the message. + * When false, the message body is sent as HTML. Defaults to false. + */ + isPlaintext?: boolean; +} + +/** + * Interface representing a request to send a message. + */ +export interface SendMessageRequest extends CreateDraftRequest { + /** + * An array of message senders. + */ + from?: EmailName[]; + /** + * Whether or not to use draft support. + * This is primarily used when dealing with large attachments. + */ + useDraft?: boolean; +} + +/** + * Interface representing a Nylas Draft object. + */ +export interface Draft + extends BaseMessage, + Omit { + /** + * The type of object. + */ + object: 'draft'; +} + +/** + * Interface representing a request to update a draft. + */ +export type UpdateDraftRequest = Omit< + Partial, + 'isPlaintext' +> & { + /** + * Return drafts that are unread. + */ + unread?: boolean; +}; + +/** + * Interface representing the different tracking options for when a message is sent. + */ +export interface TrackingOptions { + label?: string; + links?: boolean; + opens?: boolean; + threadReplies?: boolean; +} + +/** + * Interface representing the query parameters for listing drafts. + */ +export interface ListDraftsQueryParams extends ListQueryParams { + /** + * Return items with a matching literal subject. + */ + subject?: string; + /** + * Return emails that have been sent or received from this list of email addresses. + */ + anyEmail?: string[]; + /** + * Return items containing drafts to be sent these email address. + */ + to?: string[]; + /** + * Return items containing drafts cc'ing these email address. + */ + cc?: string[]; + /** + * Return items containing drafts bcc'ing these email address. + */ + bcc?: string[]; + /** + * Return drafts that are unread. + */ + unread?: boolean; + /** + * Return drafts that are starred. + */ + starred?: boolean; + /** + * Return drafts that belong to this thread. + */ + threadId?: string; + /** + * Return drafts that contain attachments. + */ + hasAttachment?: boolean; +} diff --git a/src/models/email-participant.js b/src/models/email-participant.js deleted file mode 100644 index 7280dd5d..00000000 --- a/src/models/email-participant.js +++ /dev/null @@ -1,24 +0,0 @@ -import _ from 'underscore'; - -import RestfulModel from './restful-model'; -import Attributes from './attributes'; - -export default class EmailParticipant extends RestfulModel { - toJSON() { - const json = super.toJSON(...arguments); - if (!json['name']) { - json['name'] = json['email']; - } - delete json['object']; - return json; - } -} -EmailParticipant.collectionName = 'email-participants'; -EmailParticipant.attributes = { - name: Attributes.String({ - modelKey: 'name', - }), - email: Attributes.String({ - modelKey: 'email', - }), -}; diff --git a/src/models/error.ts b/src/models/error.ts new file mode 100644 index 00000000..d14a5979 --- /dev/null +++ b/src/models/error.ts @@ -0,0 +1,187 @@ +/** + * Base class for all Nylas API errors. + */ +export abstract class AbstractNylasApiError extends Error { + /** + * The unique identifier of the request. + */ + requestId?: string; + /** + * The HTTP status code of the error response. + */ + statusCode?: number; + /** + * The flow ID + * Provide this to Nylas support to help trace requests and responses + */ + flowId?: string | null; + /** + * The response headers + */ + headers?: Record; +} + +/** + * Base class for all Nylas SDK errors. + */ +export abstract class AbstractNylasSdkError extends Error {} + +/** + * Class representation of a general Nylas API error. + */ +export class NylasApiError + extends AbstractNylasApiError + implements NylasApiErrorResponseData +{ + /** + * Error type. + */ + type: string; + /** + * Provider Error. + */ + providerError: any; + + constructor( + apiError: NylasApiErrorResponse, + statusCode?: number, + requestId?: string, + flowId?: string, + headers?: Record + ) { + super(apiError.error.message); + this.type = apiError.error.type; + this.requestId = requestId; + this.flowId = flowId; + this.headers = headers; + this.providerError = apiError.error.providerError; + this.statusCode = statusCode; + } +} + +/** + * Class representing an OAuth error returned by the Nylas API. + */ +export class NylasOAuthError + extends AbstractNylasApiError + implements NylasOAuthErrorResponse +{ + /** + * Error type. + */ + error: string; + /** + * Error code used for referencing the docs, logs, and data stream. + */ + errorCode: number; + /** + * Human readable error description. + */ + errorDescription: string; + /** + * URL to the related documentation and troubleshooting regarding this error. + */ + errorUri: string; + + constructor( + apiError: NylasOAuthErrorResponse, + statusCode?: number, + requestId?: string, + flowId?: string, + headers?: Record + ) { + super(apiError.errorDescription); + this.error = apiError.error; + this.errorCode = apiError.errorCode; + this.errorDescription = apiError.errorDescription; + this.errorUri = apiError.errorUri; + this.statusCode = statusCode; + this.requestId = requestId; + this.flowId = flowId; + this.headers = headers; + } +} + +/** + * Error thrown when the Nylas SDK times out before receiving a response from the server + */ +export class NylasSdkTimeoutError extends AbstractNylasSdkError { + /** + * The URL that timed out + */ + url: string; + /** + * The timeout value set in the Nylas SDK, in seconds + */ + timeout: number; + /** + * The request ID + */ + requestId?: string; + /** + * The flow ID + * Provide this to Nylas support to help trace requests and responses + */ + flowId?: string; + /** + * The response headers + */ + headers?: Record; + + constructor( + url: string, + timeout: number, + requestId?: string, + flowId?: string, + headers?: Record + ) { + super('Nylas SDK timed out before receiving a response from the server.'); + this.url = url; + this.timeout = timeout; + this.requestId = requestId; + this.flowId = flowId; + this.headers = headers; + } +} + +/** + * Interface representing the error response from the Nylas API. + */ + +export interface NylasApiErrorResponse { + requestId: string; + error: NylasApiErrorResponseData; + flowId?: string; + headers?: Record; +} + +/** + * Interface representing the error data within the response object. + */ +export interface NylasApiErrorResponseData { + type: string; + message: string; + providerError?: any; +} + +/** + * Interface representing an OAuth error returned by the Nylas API. + */ +export interface NylasOAuthErrorResponse { + /** + * Error type. + */ + error: string; + /** + * Error code used for referencing the docs, logs, and data stream. + */ + errorCode: number; + /** + * Human readable error description. + */ + errorDescription: string; + /** + * URL to the related documentation and troubleshooting regarding this error. + */ + errorUri: string; +} diff --git a/src/models/event-participant.js b/src/models/event-participant.js deleted file mode 100644 index 9cbd84c7..00000000 --- a/src/models/event-participant.js +++ /dev/null @@ -1,27 +0,0 @@ -import _ from 'underscore'; - -import RestfulModel from './restful-model'; -import Attributes from './attributes'; - -export default class EventParticipant extends RestfulModel { - toJSON() { - const json = super.toJSON(...arguments); - if (!json['name']) { - json['name'] = json['email']; - } - delete json['object']; - return json; - } -} -EventParticipant.collectionName = 'event-participants'; -EventParticipant.attributes = { - name: Attributes.String({ - modelKey: 'name', - }), - email: Attributes.String({ - modelKey: 'email', - }), - status: Attributes.String({ - modelKey: 'status', - }), -}; diff --git a/src/models/event.js b/src/models/event.js deleted file mode 100644 index d89f158c..00000000 --- a/src/models/event.js +++ /dev/null @@ -1,115 +0,0 @@ -import Promise from 'bluebird'; -import _ from 'underscore'; - -import RestfulModel from './restful-model'; -import Attributes from './attributes'; -import EventParticipant from './event-participant'; - -export default class Event extends RestfulModel { - saveRequestBody() { - const dct = this.toJSON(); - if (this.start && this.end) { - dct['when'] = { - start_time: this.start.toString(), - end_time: this.end.toString(), - }; - } - delete dct['_start']; - delete dct['_end']; - return dct; - } - - save(params = {}, callback = null) { - return this._save(params, callback); - } - - fromJSON(json) { - super.fromJSON(json); - - if (this.when) { - // For indexing and querying purposes, we flatten the start and end of the different - // "when" formats into two timestamps we can use for range querying. Note that for - // all-day events, we use first second of start date and last second of end date. - this.start = - this.when.start_time || - new Date(this.when.start_date).getTime() / 1000.0 || - this.when.time; - this.end = - this.when.end_time || - new Date(this.when.end_date).getTime() / 1000.0 + (60 * 60 * 24 - 1) || - this.when.time; - delete this.when.object; - } - return this; - } - - rsvp(status, comment, callback) { - return this.connection - .request({ - method: 'POST', - body: { event_id: this.id, status: status, comment: comment }, - path: '/send-rsvp', - }) - .then(json => { - this.fromJSON(json); - if (callback) { - callback(null, this); - } - return Promise.resolve(this); - }) - .catch(err => { - if (callback) { - callback(err); - } - return Promise.reject(err); - }); - } -} -Event.collectionName = 'events'; -Event.attributes = _.extend({}, RestfulModel.attributes, { - calendarId: Attributes.String({ - modelKey: 'calendarId', - jsonKey: 'calendar_id', - }), - messageId: Attributes.String({ - modelKey: 'messageId', - jsonKey: 'message_id', - }), - title: Attributes.String({ - modelKey: 'title', - }), - description: Attributes.String({ - modelKey: 'description', - }), - owner: Attributes.String({ - modelKey: 'owner', - }), - participants: Attributes.Collection({ - modelKey: 'participants', - itemClass: EventParticipant, - }), - readOnly: Attributes.Boolean({ - modelKey: 'readOnly', - jsonKey: 'read_only', - }), - location: Attributes.String({ - modelKey: 'location', - }), - when: Attributes.Object({ - modelKey: 'when', - }), - start: Attributes.Number({ - modelKey: 'start', - jsonKey: '_start', - }), - end: Attributes.Number({ - modelKey: 'end', - jsonKey: '_end', - }), - busy: Attributes.Boolean({ - modelKey: 'busy', - }), - status: Attributes.String({ - modelKey: 'status', - }), -}); diff --git a/src/models/events.ts b/src/models/events.ts new file mode 100644 index 00000000..865cead4 --- /dev/null +++ b/src/models/events.ts @@ -0,0 +1,687 @@ +import { Subset } from '../utils.js'; +import { NylasApiErrorResponseData } from './error.js'; +import { ListQueryParams } from './listQueryParams.js'; +import { NylasBaseResponse } from './response.js'; +import { NotetakerMeetingSettings } from './notetakers.js'; + +/** + * Interface representing Notetaker settings + */ +export interface NotetakerSettings { + /** + * The display name for the Notetaker bot. + * Default: Nylas Notetaker + */ + name?: string; + /** + * Notetaker Meeting Settings + */ + meetingSettings?: NotetakerMeetingSettings; +} + +/** + * Interface representing a Nylas Event object. + */ +export interface Event { + /** + * Globally unique object identifier. + */ + id: string; + /** + * Grant ID of the Nylas account. + */ + grantId: string; + /** + * The type of object. + */ + object: 'event'; + /** + * Calendar ID of the event. + */ + calendarId: string; + /** + * This value determines whether to show this event's time block as available on shared or public calendars. + */ + busy: boolean; + /** + * If the event participants are able to edit the event. + */ + readOnly: boolean; + /** + * List of participants invited to the event. Participants may also be rooms or resources. + */ + participants: Participant[]; + /** + * Representation of time and duration for events. When object can be in one of four formats (sub-objects): + * - {@link Date} + * - {@link Datespan} + * - {@link Time} + * - {@link Timespan} + */ + when: When; + /** + * Representation of conferencing details for events. Conferencing object can be in one of two formats (sub-objects): + * - {@link Autocreate} + * - {@link Details} + */ + conferencing?: Conferencing; + /** + * Visibility of the event, if the event is private or public. + */ + visibility: Visibility; + /** + * Description of the event. + */ + description?: string; + /** + * Location of the event, such as a physical address or meeting room name. + */ + location?: string; + /** + * Unique id for iCalendar standard, for identifying events across calendaring systems. + * Recurring events may share the same value. Can be null for events synced before the year 2020. + */ + icalUid?: string; + /** + * Title of the event. + */ + title?: string; + /** + * A link to this event in the provider's UI + */ + htmlLink?: string; + /** + * Whether participants of the event should be hidden. + */ + hideParticipants?: boolean; + /** + * List of key-value pairs storing additional data. + */ + metadata?: Record; + /** + * User who created the event. + * Not supported for all providers. + */ + creator?: EmailName; + /** + * Organizer of the event. + */ + organizer?: EmailName; + /** + * An list of RRULE and EXDATE strings. + * @see RFC-5545 + */ + recurrence?: string[]; + /** + * A list of reminders to send for the event. If left empty or omitted, the event uses the provider defaults. + */ + reminders?: Reminders; + /** + * Status of the event. + */ + status?: Status; + /** + * Unix timestamp when the event was created. + */ + createdAt?: number; + /** + * Unix timestamp when the event was last updated. + */ + updatedAt?: number; + /** + * Master event id if recurring events. + */ + masterEventId?: string; + /** + * The original start time of the event, in Unix timestamp format. + * This field is present only if the event is an instance of a recurring event. + */ + originalStartTime?: number; + /** + * Notetaker meeting bot settings + */ + notetaker?: NotetakerSettings; +} + +/** + * Interface representing a request to create an event. + */ +export interface CreateEventRequest { + /** + * Representation of time and duration for events. When object can be in one of four formats (sub-objects): + * - {@link Date} + * - {@link Datespan} + * - {@link Time} + * - {@link Timespan} + */ + when: CreateWhen; + /** + * Title of the event. + */ + title?: string; + /** + * This value determines whether to show this event's time block as available on shared or public calendars. + */ + busy?: boolean; + /** + * Description of the event. + */ + description?: string; + /** + * Location of the event, such as a physical address or meeting room name. + */ + location?: string; + /** + * Representation of conferencing details for events. Conferencing object can be in one of two formats (sub-objects): + * - {@link Autocreate} + * - {@link Details} + */ + conferencing?: Conferencing; + /** + * A list of reminders to send for the event. If left empty or omitted, the event uses the provider defaults. + */ + reminders?: Reminders; + /** + * A list of key-value pairs storing additional data. + */ + metadata?: Record; + /** + * List of participants invited to the event. Participants may also be rooms or resources. + */ + participants?: Participant[]; + /** + * An list of RRULE and EXDATE strings. + * @see RFC-5545 + */ + recurrence?: string[]; + /** + * Calendar ID of the event. + */ + calendarId?: string; + /** + * If the event participants are able to edit the event. + */ + readOnly?: boolean; + /** + * Visibility of the event, if the event is private or public. + */ + visibility?: 'public' | 'private'; + /** + * The maximum number of participants that may attend the event. + */ + capacity?: number; + /** + * Whether participants of the event should be hidden. + */ + hideParticipants?: boolean; + /** + * Notetaker meeting bot settings + */ + notetaker?: NotetakerSettings; +} + +/** + * Interface representing a request to update an event. + */ +export type UpdateEventRequest = Subset; + +/** + * Interface representing a request to send RSVP to an event. + */ +export type SendRsvpRequest = { + status: RsvpStatus; +}; + +/** + * Interface representing the response from sending RSVP to an event. + * @property sendIcsError If the send-rsvp request succeeded but the ICS email could not be sent, this will contain the error. + */ +export interface SendRsvpResponse extends NylasBaseResponse { + sendIcsError?: NylasApiErrorResponseData; +} + +/** + * Interface representing the query parameters for listing events. + */ +export interface ListEventQueryParams extends ListQueryParams { + /** + * Return events that have a status of cancelled. + * If an event is recurring, then it returns no matter the value set. + * Different providers have different semantics for cancelled events. + */ + showCancelled?: boolean; + /** + * Specify calendar ID of the event. "primary" is a supported value indicating the user's primary calendar. + */ + calendarId: string; + /** + * Return events matching the specified title. + */ + title?: string; + /** + * Return events matching the specified description. + * Graph: NOT supported + */ + description?: string; + /** + * Return events matching the specified location. + */ + location?: string; + /** + * Return events ending before the specified unix timestamp. + * Defaults to a month from now. Not respected by metadata filtering. + */ + end?: string; + /** + * Return events starting after the specified unix timestamp. + * Defaults to the current timestamp. Not respected by metadata filtering. + */ + start?: string; + /** + * Pass in your metadata key and value pair to search for metadata. + */ + metadataPair?: Record; + /** + * If true, the response will include an event for each occurrence of a recurring event within the requested time range. + * If false, only a single primary event will be returned for each recurring event. + * Cannot be used when filtering on metadata. + * Defaults to false. + */ + expandRecurring?: boolean; + /** + * Returns events with a busy status of true. + */ + busy?: boolean; + /** + * Order results by the specified field. + * Currently only start is supported. + */ + orderBy?: string; + /** + * The maximum number of objects to return. + * This field defaults to 50. The maximum allowed value is 200. + */ + limit?: number; + /** + * An identifier that specifies which page of data to return. + * This value should be taken from the {@link NylasListResponse.nextCursor} response field. + */ + pageToken?: string; + /** + * (Google only) Filter events by event type. + * You can pass the query parameter multiple times to select or exclude multiple event types. + */ + eventType?: EventType[]; + /** + * Filter for events that include the specified attendees. + * Not supported for virtual calendars. + */ + attendees?: string[]; + /** + * Master event id if recurring events. + */ + masterEventId?: string; + /** + * When set to false, treats tentative calendar events as busy:false. + * Only applicable for Microsoft and EWS calendar providers. Defaults to true. + */ + tentativeAsBusy?: boolean; +} + +/** + * Interface representing of the query parameters for creating an event. + */ +export interface CreateEventQueryParams { + /** + * The ID of the calendar to create the event in. + */ + calendarId: string; + /** + * Email notifications containing the calendar event is sent to all event participants. + */ + notifyParticipants?: boolean; + /** + * When set to false, treats tentative calendar events as busy:false. + * Only applicable for Microsoft and EWS calendar providers. Defaults to true. + */ + tentativeAsBusy?: boolean; +} + +/** + * Interface representing of the query parameters for finding an event. + */ +export interface FindEventQueryParams { + /** + * Calendar ID to find the event in. "primary" is a supported value indicating the user's primary calendar. + */ + calendarId: string; + /** + * When set to false, treats tentative calendar events as busy:false. + * Only applicable for Microsoft and EWS calendar providers. Defaults to true. + */ + tentativeAsBusy?: boolean; +} + +/** + * Interface representing of the query parameters for updating events. + */ +export type UpdateEventQueryParams = CreateEventQueryParams; + +/** + * Interface representing of the query parameters for destroying events. + */ +export type DestroyEventQueryParams = CreateEventQueryParams; + +/** + * Interface representing of the query parameters for sending RSVP to an event. + */ +export type SendRsvpQueryParams = FindEventQueryParams; + +/** + * Interface representing the query parameters for importing events. + */ +export interface ListImportEventQueryParams extends ListQueryParams { + /** + * (Required) Calendar ID to import events from. "primary" is a supported value indicating the user's primary calendar. + * Note: "primary" is not supported for iCloud. + */ + calendarId: string; + /** + * Filter for events that start at or after the specified time, in Unix timestamp format. + * Defaults to the time of the request. + */ + start?: number; + /** + * Filter for events that end at or before the specified time, in Unix timestamp format. + * Defaults to one month from the time of the request. + */ + end?: number; +} + +/** + * Enum representing the status of an event. + */ +type Status = 'confirmed' | 'maybe' | 'cancelled'; + +/** + * Enum representing the status of an RSVP response. + */ +type RsvpStatus = 'yes' | 'no' | 'maybe'; + +/** + * Enum representing the visibility of an event. + */ +type Visibility = 'default' | 'public' | 'private'; + +/** + * Enum representing the supported conferencing providers. + */ +type ConferencingProvider = + | 'Google Meet' + | 'Zoom Meeting' + | 'Microsoft Teams' + | 'GoToMeeting' + | 'WebEx'; + +/** + * Enum representing the status of an event participant. + */ +type ParticipantStatus = 'noreply' | 'yes' | 'no' | 'maybe'; + +/** + * Enum representing the different types of reminders. + */ +type ReminderMethod = 'email' | 'popup' | 'sound' | 'display'; + +/** + * Type representing the different conferencing objects. + */ +export type Conferencing = Details | Autocreate; + +/** + * Type representing the different objects representing time and duration for events. + */ +type When = Time | Timespan | Date | Datespan; + +/** + * Type representing the different objects representing time and duration when creating events. + */ +type CreateWhen = + | Omit + | Omit + | Omit + | Omit; + +/** + * Enum representing the different types of when objects. + */ +export enum WhenType { + Time = 'time', + Timespan = 'timespan', + Date = 'date', + Datespan = 'datespan', +} + +/** + * Interface of a conferencing details object + */ +export interface Details { + /** + * The conferencing provider + */ + provider: ConferencingProvider; + + /** + * The conferencing details + */ + details: DetailsConfig; +} + +/** + * Interface of a the configuration for a conferencing object + */ +export interface DetailsConfig { + /** + * The conferencing meeting code. Used for Zoom. + */ + meetingCode?: string; + /** + * The conferencing meeting password. Used for Zoom. + */ + password?: string; + /** + * The conferencing meeting url. + */ + url?: string; + /** + * The conferencing meeting pin. Used for Google Meet. + */ + pin?: string; + /** + * The conferencing meeting phone numbers. Used for Google Meet. + */ + phone?: string[]; +} + +/** + * Class representation of a conferencing autocreate object + */ +export interface Autocreate { + /** + * The conferencing provider + */ + provider: ConferencingProvider; + /** + * Empty dict to indicate an intention to autocreate a video link. + * Additional provider settings may be included in autocreate.settings, but Nylas does not validate these. + */ + autocreate: Record; +} + +/** + * Class representation of a specific point in time. + * A meeting at 2pm would be represented as a time subobject. + */ +export interface Time { + /** + * A UNIX timestamp representing the time of occurrence. + */ + time: number; + /** + * If timezone is present, then the value for time will be read with timezone. + * Timezone using IANA formatted string. (e.g. "America/New_York") + * @see List of tz database time zones + */ + timezone: string; + /** + * The type of 'when' object. + */ + object: WhenType.Time; +} + +/** + * Class representation of a time span with start and end times. + * An hour lunch meeting would be represented as timespan subobjects. + */ +export interface Timespan { + /** + * The start time of the event. + */ + startTime: number; + /** + * The end time of the event. + */ + endTime: number; + /** + * The timezone of the start time. + * Timezone using IANA formatted string. (e.g. "America/New_York") + * @see List of tz database time zones + */ + startTimezone?: string; + /** + * The timezone of the end time. + * Timezone using IANA formatted string. (e.g. "America/New_York") + * @see List of tz database time zones + */ + endTimezone?: string; + /** + * The type of 'when' object. + */ + object: WhenType.Timespan; +} + +/** + * Class representation of an entire day spans without specific times. + * Your birthday and holidays would be represented as date subobjects. + */ +export interface Date { + /** + * Date of occurrence in ISO 8601 format. + * @see ISO 8601 + */ + date: string; + /** + * The type of 'when' object. + */ + object: WhenType.Date; +} + +/** + * Class representation of a specific dates without clock-based start or end times. + * A business quarter or academic semester would be represented as datespan subobjects. + */ +export interface Datespan { + /** + * The start date in ISO 8601 format. + * @see ISO 8601 + */ + startDate: string; + /** + * The end date in ISO 8601 format. + * @see ISO 8601 + */ + endDate: string; + /** + * The type of 'when' object. + */ + object: WhenType.Datespan; +} + +/** + * Interface representing an Event participant. + */ +export interface Participant { + /** + * Participant's email address. + */ + email?: string; + /** + * Participant's name. + */ + name?: string; + /** + * Participant's status. + */ + status: ParticipantStatus; + /** + * Comment by the participant. + */ + comment?: string; + /** + * Participant's phone number. + */ + phoneNumber?: string; +} + +/** + * Interface representing the reminders field of an event. + */ +export interface Reminders { + /** + * Whether to use the default reminders for the calendar. + * When true, uses the default reminder settings for the calendar + */ + useDefault: boolean; + /** + * A list of reminders for the event if useDefault is set to false. + */ + overrides: ReminderOverride[]; +} + +/** + * Interface representing the reminder details for an event. + */ +export interface ReminderOverride { + /** + * The number of minutes before the event start time when a user wants a reminder for this event. + * Reminder minutes are in the following format: "[20]". + */ + reminderMinutes: number; + /** + * Method to remind the user about the event. (Google only). + */ + reminderMethod: ReminderMethod; +} + +/** + * Interface representing an email address and optional name. + */ +export interface EmailName { + /** + * Email address. + */ + email: string; + /** + * Full name. + */ + name?: string; +} + +/** + * Type representing the event type to filter by. + */ +export type EventType = + | 'default' + | 'outOfOffice' + | 'focusTime' + | 'workingLocation'; diff --git a/src/models/file.js b/src/models/file.js deleted file mode 100644 index 942aa4da..00000000 --- a/src/models/file.js +++ /dev/null @@ -1,137 +0,0 @@ -import _ from 'underscore'; - -import RestfulModel from './restful-model'; -import Attributes from './attributes'; - -export default class File extends RestfulModel { - constructor(...args) { - super(...args); - this.upload = this.upload.bind(this); - this.download = this.download.bind(this); - } - - upload(callback = null) { - if (!this.filename) { - throw new Error('Please define a filename'); - } - if (!this.data) { - throw new Error('Please add some data to the file'); - } - if (!this.contentType) { - throw new Error('Please define a content-type'); - } - - return this.connection - .request({ - method: 'POST', - json: false, - path: `/${this.constructor.collectionName}`, - formData: { - file: { - value: this.data, - options: { - filename: this.filename, - contentType: this.contentType, - }, - }, - }, - }) - .then(json => { - // The API returns a list of files. It should - // always have a length of 1 since we only - // upload file-by-file. - if (json.length > 0) { - this.fromJSON(json[0]); - if (callback) { - callback(null, this); - } - return Promise.resolve(this); - } else { - return Promise.reject(null); - } - }) - .catch(err => { - if (callback) { - callback(err); - } - return Promise.reject(err); - }); - } - - download(callback = null) { - if (!this.id) { - throw new Error('Please provide a File id'); - } - - return this.connection - .request({ - path: `/files/${this.id}/download`, - encoding: null, - downloadRequest: true, - }) - .then(response => { - let filename; - const file = _.extend(response.headers, { body: response.body }); - if ('content-disposition' in file) { - filename = - /filename=([^;]*)/.exec(file['content-disposition'])[1] || - 'filename'; - } else { - filename = 'filename'; - } - if (callback) { - callback(null, file); - } - return Promise.resolve(file); - }) - .catch(err => { - if (callback) { - callback(err); - } - return Promise.reject(err); - }); - } - - metadata(callback = null) { - return this.connection - .request({ - path: `/files/${this.id}`, - }) - .then(response => { - if (callback) { - callback(null, response); - } - return Promise.resolve(response); - }) - .catch(err => { - if (callback) { - callback(err); - } - return Promise.reject(err); - }); - } -} -File.collectionName = 'files'; -File.attributes = _.extend({}, RestfulModel.attributes, { - contentType: Attributes.String({ - modelKey: 'contentType', - jsonKey: 'content_type', - }), - size: Attributes.Number({ - modelKey: 'size', - jsonKey: 'size', - }), - filename: Attributes.String({ - modelKey: 'filename', - jsonKey: 'filename', - }), - messageIds: Attributes.Collection({ - modelKey: 'messageIds', - jsonKey: 'message_ids', - itemClass: String, - }), - contentId: Attributes.String({ - modelKey: 'contentId', - jsonKey: 'content_id', - }), -}); diff --git a/src/models/folder.js b/src/models/folder.js deleted file mode 100644 index 9c827c19..00000000 --- a/src/models/folder.js +++ /dev/null @@ -1,32 +0,0 @@ -import Promise from 'bluebird'; -import _ from 'underscore'; - -import RestfulModel from './restful-model'; -import Attributes from './attributes'; - -export class Label extends RestfulModel { - saveRequestBody() { - const json = {}; - json['display_name'] = this.displayName; - json['name'] = this.name; - return json; - } - - save(params = {}, callback = null) { - return this._save(params, callback); - } -} -Label.collectionName = 'labels'; -Label.attributes = _.extend({}, RestfulModel.attributes, { - name: Attributes.String({ - modelKey: 'name', - jsonKey: 'name', - }), - displayName: Attributes.String({ - modelKey: 'displayName', - jsonKey: 'display_name', - }), -}); - -export class Folder extends Label {} -Folder.collectionName = 'folders'; diff --git a/src/models/folders.ts b/src/models/folders.ts new file mode 100644 index 00000000..974f65b5 --- /dev/null +++ b/src/models/folders.ts @@ -0,0 +1,136 @@ +import { ListQueryParams } from './listQueryParams.js'; + +/** + * Interface of a folder object from Nylas. + */ +export interface Folder { + /** + * A globally unique object identifier. + */ + id: string; + + /** + * Folder name. + */ + name: string; + + /** + * The type of object. + */ + object: string; + + /** + * Grant ID of the Nylas account + */ + grantId: string; + + /** + * (Google only) Folder background color. + */ + backgroundColor?: string; + + /** + * (Google only) Indicates if the folder is user created or system created. + */ + systemFolder?: boolean; + + /** + * (Google only) Folder text color. + */ + textColor?: string; + + /** + * (Microsoft only) The number of immediate child folders in the current folder. + */ + childCount?: number; + + /** + * (Microsoft only) ID of the parent folder. + */ + parentId?: string; + + /** + * The number of items inside of a folder. + */ + totalCount?: number; + + /** + * The number of unread items inside of a folder. + */ + unreadCount?: number; + + /** + * Common attribute descriptors shared by system folders across providers. + * For example, Sent email folders have the `["\\Sent"]` attribute. + * For IMAP grants, IMAP providers provide the attributes. + * For Google and Microsoft Graph, Nylas matches system folders to a set of common attributes. + */ + attributes?: string[]; +} + +/** + * Interface for creating a new folder. + */ +export interface CreateFolderRequest { + /** + * Creates a folder with the specified display name. (Constraints: 1 to 1024 chars) + */ + name: string; + + /** + * (Microsoft only) ID of the parent folder. + */ + parentId?: string; + + /** + * (Google only) The text color of the folder in the hexadecimal format "#0099EE". See Google Defined Values for more information. + */ + textColor?: string; + + /** + * (Google only) The background color of the folder in the hexadecimal format "#0099EE". See Google Defined Values for more information. + */ + backgroundColor?: string; +} +/** + * Interface representing the query parameters for listing folders. + */ + +export interface ListFolderQueryParams extends ListQueryParams { + /** + * (Microsoft and EWS only.) Use the ID of a folder to find all child folders it contains. + */ + parentId?: string; + + /** + * (Microsoft only) When true, Nylas includes hidden folders in its response. + */ + includeHiddenFolders?: boolean; + + /** + * (Microsoft only) If true, retrieves folders from a single-level hierarchy only. + * If false, retrieves folders across a multi-level hierarchy. + * @default false + */ + singleLevel?: boolean; +} + +/** + * Interface representing the query parameters for finding a folder. + */ +export interface FindFolderQueryParams { + /** + * (Microsoft only) When true, Nylas includes hidden folders in its response. + * @default false + */ + includeHiddenFolders?: boolean; + + /** + * Specify fields that you want Nylas to return, as a comma-separated list (for example, select=id,updated_at). + * This allows you to receive only the portion of object data that you're interested in. + * You can use select to optimize response size and reduce latency by limiting queries to only the information that you need. + */ + select?: string; +} + +export type UpdateFolderRequest = Partial; diff --git a/src/models/freeBusy.ts b/src/models/freeBusy.ts new file mode 100644 index 00000000..c94229d5 --- /dev/null +++ b/src/models/freeBusy.ts @@ -0,0 +1,89 @@ +/** + * Interface representation of a Nylas free-busy time slot object. + */ +export interface FreeBusyTimeSlot { + /** + * Unix timestamp for the start of the slot. + */ + startTime: number; + /** + * Unix timestamp for the end of the slot. + */ + endTime: number; + /** + * The status of the time slot. + */ + status: string; +} + +/** + * Class representation of a Nylas get free-busy request + */ +export interface GetFreeBusyRequest { + /** + * Unix timestamp representing the start of the time block for assessing the account's free/busy schedule. + */ + startTime: number; + /** + * Unix timestamp representing the end of the time block for assessing the account's free/busy schedule. + */ + endTime: number; + /** + * A list of email addresses to check the free/busy schedules for. + */ + emails: string[]; + /** + * When true, Nylas treats tentative events as busy. + * @default true + */ + tentativeAsBusy?: boolean; +} + +/** + * Enum representing the type of free/busy information returned for a calendar. + */ +export enum FreeBusyType { + FREE_BUSY = 'free_busy', + ERROR = 'error', +} + +/** + * Union type of the possible Nylas get free busy response. + */ +export type GetFreeBusyResponse = FreeBusy | FreeBusyError; + +/** + * This interface represents a successful free-busy response. + */ +export interface FreeBusy { + /** + * The participant's email address. + */ + email: string; + /** + * A list of busy time slots. + */ + timeSlots: FreeBusyTimeSlot[]; + /** + * The type of the response. + */ + object: FreeBusyType.FREE_BUSY; +} + +/** + * This interface represents a failed free-busy response. + */ +export interface FreeBusyError { + /** + * The participant's email address. + */ + email: string; + /** + * Description of the error fetching data for this participant. + */ + error: string; + /** + * The type of the response. + */ + object: FreeBusyType.ERROR; +} diff --git a/src/models/grants.ts b/src/models/grants.ts new file mode 100644 index 00000000..2fddebb2 --- /dev/null +++ b/src/models/grants.ts @@ -0,0 +1,142 @@ +import { Provider } from './auth.js'; + +/** + * Interface representing a Nylas Grant object. + */ +export interface Grant { + /** + * Globally unique object identifier. + */ + id: string; + /** + * OAuth provider that the user authenticated with. + */ + provider: string; + /** + * Scopes specified for the grant. + */ + scope: string[]; + /** + * Unix timestamp when the grant was created. + */ + createdAt: number; + /** + * Status of the grant, if it is still valid or if the user needs to re-authenticate. + */ + grantStatus?: string; + /** + * Email address associated with the grant. + */ + email?: string; + /** + * Name associated with the grant. + */ + name?: string; + /** + * End user's client user agent. + */ + userAgent?: string; + /** + * End user's client IP address. + */ + ip?: string; + /** + * Initial state that was sent as part of the OAuth request. + */ + state?: string; + /** + * Unix timestamp when the grant was updated. + */ + updatedAt?: number; + /** + * Provider's ID for the user this grant is associated with. + */ + providerUserId?: string; + /** + * Settings required by the provider that were sent as part of the OAuth request. + */ + settings?: Record; +} + +/** + * Interface representing a request to create a grant. + */ +export interface CreateGrantRequest { + /** + * OAuth provider + */ + provider: Provider; + /** + * Settings required by provider. + */ + settings: Record; + /** + * Optional state value to return to developer's website after authentication flow is completed. + */ + state?: string; + /** + * Optional list of scopes to request. If not specified it will use the integration default scopes. + */ + scope?: string[]; +} + +/** + * Interface representing a request to update a grant. + */ +export interface UpdateGrantRequest { + /** + * Settings required by provider. + */ + settings?: Record; + /** + * List of integration scopes for the grant. + */ + scope?: string[]; +} + +/** + * Interface representing the query parameters for listing grants. + */ +export interface ListGrantsQueryParams { + /** + * The maximum number of objects to return. + * This field defaults to 10. The maximum allowed value is 200. + */ + limit?: number; + /** + * Offset grant results by this number. + */ + offset?: number; + /** + * Sort entries by field name + */ + sortBy?: 'created_at' | 'updated_at'; + /** + * Specify ascending or descending order. + */ + orderBy?: 'asc' | 'desc'; + /** + * Scope grants from a specific point in time by Unix timestamp. + */ + since?: number; + /** + * Scope grants to a specific point in time by Unix timestamp. + */ + before?: number; + /** + * Filtering your query based on grant email address (if applicable) + */ + email?: string; + /** + * Filtering your query based on grant email status (if applicable) + */ + grantStatus?: string; + /** + * Filtering your query based on grant IP address + */ + ip?: string; + /** + * Filtering your query based on OAuth provider + */ + provider?: Provider; +} diff --git a/src/models/index.ts b/src/models/index.ts new file mode 100644 index 00000000..c4627ad8 --- /dev/null +++ b/src/models/index.ts @@ -0,0 +1,24 @@ +// This file is generated by scripts/generateModelIndex.js +export * from './applicationDetails.js'; +export * from './attachments.js'; +export * from './auth.js'; +export * from './availability.js'; +export * from './calendars.js'; +export * from './connectors.js'; +export * from './contacts.js'; +export * from './credentials.js'; +export * from './drafts.js'; +export * from './error.js'; +export * from './events.js'; +export * from './folders.js'; +export * from './freeBusy.js'; +export * from './grants.js'; +export * from './listQueryParams.js'; +export * from './messages.js'; +export * from './notetakers.js'; +export * from './redirectUri.js'; +export * from './response.js'; +export * from './scheduler.js'; +export * from './smartCompose.js'; +export * from './threads.js'; +export * from './webhooks.js'; diff --git a/src/models/listQueryParams.ts b/src/models/listQueryParams.ts new file mode 100644 index 00000000..f0c8f2d3 --- /dev/null +++ b/src/models/listQueryParams.ts @@ -0,0 +1,18 @@ +export interface ListQueryParams { + /** + * The maximum number of objects to return. + * This field defaults to 50. The maximum allowed value is 200. + */ + limit?: number; + /** + * An identifier that specifies which page of data to return. + * This value should be taken from the [ListResponse.nextCursor] response field. + */ + pageToken?: string; + /** + * Specify fields that you want Nylas to return + * as a comma-separated list (for example, select=id,updated_at). + * This allows you to receive only the portion of object data that you're interested in. + */ + select?: string; +} diff --git a/src/models/management-account.js b/src/models/management-account.js deleted file mode 100644 index b74144ab..00000000 --- a/src/models/management-account.js +++ /dev/null @@ -1,46 +0,0 @@ -import _ from 'underscore'; - -import ManagementModel from './management-model'; -import Attributes from './attributes'; - -export default class ManagementAccount extends ManagementModel { - upgrade() { - return this.connection - .request({ - method: 'POST', - path: `/a/${this.appId}/${this.constructor.collectionName}/${ - this.id - }/upgrade`, - }) - .catch(err => Promise.reject(err)); - } - - downgrade() { - return this.connection - .request({ - method: 'POST', - path: `/a/${this.appId}/${this.constructor.collectionName}/${ - this.id - }/downgrade`, - }) - .catch(err => Promise.reject(err)); - } -} -ManagementAccount.collectionName = 'accounts'; -ManagementAccount.attributes = _.extend({}, ManagementModel.attributes, { - billingState: Attributes.String({ - modelKey: 'billingState', - jsonKey: 'billing_state', - }), - namespaceId: Attributes.String({ - modelKey: 'namespaceId', - jsonKey: 'namespace_id', - }), - syncState: Attributes.String({ - modelKey: 'syncState', - jsonKey: 'sync_state', - }), - trial: Attributes.Boolean({ - modelKey: 'trial', - }), -}); diff --git a/src/models/management-model-collection.js b/src/models/management-model-collection.js deleted file mode 100644 index f606d7d0..00000000 --- a/src/models/management-model-collection.js +++ /dev/null @@ -1,16 +0,0 @@ -import RestfulModelCollection from './restful-model-collection'; - -export default class ManagementModelCollection extends RestfulModelCollection { - constructor(modelClass, connection, appId) { - super(modelClass, connection); - this.appId = appId; - } - - path() { - return `/a/${this.appId}/${this.modelClass.collectionName}`; - } - - _createModel(json) { - return new this.modelClass(this.connection, this.appId, json); - } -} diff --git a/src/models/management-model.js b/src/models/management-model.js deleted file mode 100644 index 2003b814..00000000 --- a/src/models/management-model.js +++ /dev/null @@ -1,8 +0,0 @@ -import RestfulModel from './restful-model'; - -export default class ManagementModel extends RestfulModel { - constructor(connection, appId, json = null) { - super(connection, json); - this.appId = appId; - } -} diff --git a/src/models/message.js b/src/models/message.js deleted file mode 100644 index aa3bf619..00000000 --- a/src/models/message.js +++ /dev/null @@ -1,165 +0,0 @@ -import _ from 'underscore'; - -import RestfulModel from './restful-model'; -import Attributes from './attributes'; -import File from './file'; -import Event from './event'; -import EmailParticipant from './email-participant'; -import { Label, Folder } from './folder'; - -export default class Message extends RestfulModel { - constructor() { - super(...arguments); - if (!this.body) { - this.body = ''; - } - if (!this.subject) { - this.subject = ''; - } - if (!this.to) { - this.to = []; - } - if (!this.cc) { - this.cc = []; - } - if (!this.bcc) { - this.bcc = []; - } - } - - // We calculate the list of participants instead of grabbing it from - // a parent because it is a better source of ground truth, and saves us - // from more dependencies. - participants() { - const participants = {}; - const contacts = _.union( - this.to != null ? this.to : [], - this.cc != null ? this.cc : [], - this.from != null ? this.from : [] - ); - for (const contact of contacts) { - if (contact && (contact.email ? contact.email.length : undefined) > 0) { - if (contact) { - participants[ - `${((contact ? contact.email : undefined) != null - ? contact ? contact.email : undefined - : '' - ) - .toLowerCase() - .trim()} ${((contact ? contact.name : undefined) != null - ? contact ? contact.name : undefined - : '' - ) - .toLowerCase() - .trim()}` - ] = contact; - } - } - } - return _.values(participants); - } - - fileIds() { - return _.map(this.files, file => file.id); - } - - getRaw() { - return this.connection - .request({ - method: 'GET', - headers: { - Accept: 'message/rfc822', - }, - path: `/${this.constructor.collectionName}/${this.id}`, - }) - .catch(err => Promise.reject(err)); - } - - saveRequestBody() { - // It's possible to update most of the fields of a draft. - if (this.constructor.name === 'Draft') { - return super.saveRequestBody(...arguments); - } - - // Messages are more limited, though. - const json = {}; - if (this.labels) { - json['label_ids'] = Array.from(this.labels).map(label => label.id); - } else if (this.folder) { - json['folder_id'] = this.folder.id; - } - - json['starred'] = this.starred; - json['unread'] = this.unread; - return json; - } - - save(params = {}, callback = null) { - return this._save(params, callback); - } -} -Message.collectionName = 'messages'; -Message.attributes = _.extend({}, RestfulModel.attributes, { - subject: Attributes.String({ - modelKey: 'subject', - }), - from: Attributes.Collection({ - modelKey: 'from', - itemClass: EmailParticipant, - }), - replyTo: Attributes.Collection({ - modelKey: 'replyTo', - jsonKey: 'reply_to', - itemClass: EmailParticipant, - }), - to: Attributes.Collection({ - modelKey: 'to', - itemClass: EmailParticipant, - }), - cc: Attributes.Collection({ - modelKey: 'cc', - itemClass: EmailParticipant, - }), - bcc: Attributes.Collection({ - modelKey: 'bcc', - itemClass: EmailParticipant, - }), - date: Attributes.DateTime({ - modelKey: 'date', - }), - threadId: Attributes.String({ - modelKey: 'threadId', - jsonKey: 'thread_id', - }), - snippet: Attributes.String({ - modelKey: 'snippet', - }), - body: Attributes.String({ - modelKey: 'body', - }), - unread: Attributes.Boolean({ - modelKey: 'unread', - }), - starred: Attributes.Boolean({ - modelKey: 'starred', - }), - files: Attributes.Collection({ - modelKey: 'files', - itemClass: File, - }), - events: Attributes.Collection({ - modelKey: 'events', - itemClass: Event, - }), - folder: Attributes.Object({ - modelKey: 'folder', - itemClass: Folder, - }), - labels: Attributes.Collection({ - modelKey: 'labels', - itemClass: Label, - }), - headers: Attributes.Object({ - modelKey: 'headers', - }), -}); diff --git a/src/models/messages.ts b/src/models/messages.ts new file mode 100644 index 00000000..f09fe7d4 --- /dev/null +++ b/src/models/messages.ts @@ -0,0 +1,358 @@ +import { Attachment } from './attachments.js'; +import { EmailName } from './events.js'; +import { ListQueryParams } from './listQueryParams.js'; + +/** + * @internal Internal interface for a message. + */ +export interface BaseMessage { + /** + * The unique identifier for the message. + */ + id: string; + /** + * Grant ID of the Nylas account. + */ + grantId: string; + /** + * Unix timestamp of when the message was received by the mail server. + * This may be different from the unverified Date header in raw message object. + */ + date: number; + /** + * The ID of the folder(s) the message appears in. + */ + folders: string[]; + /** + * An array of message recipients. + */ + to: EmailName[]; + /** + * An array of bcc recipients. + */ + bcc?: EmailName[]; + /** + * An array of cc recipients. + */ + cc?: EmailName[]; + /** + * An array of name and email pairs that override the sent reply-to headers. + */ + replyTo?: EmailName[]; + /** + * The message subject. + */ + subject?: string; + /** + * The full HTML message body. + * Messages with only plain-text representations are up-converted to HTML. + */ + body?: string; + /** + * Whether or not the message has been starred by the user. + */ + starred?: boolean; + /** + * An array of message senders. + */ + from?: EmailName[]; + /** + * An array of files attached to the message. + */ + attachments?: Attachment[]; + /** + * A short snippet of the message body. + * This is the first 100 characters of the message body, with any HTML tags removed. + */ + snippet?: string; + /** + * A reference to the parent thread object. + * If this is a new draft, the thread will be empty. + */ + threadId?: string; + /** + * Whether or not the message has been read by the user. + */ + unread?: boolean; +} + +/** + * Interface representing message tracking options. + */ +export interface MessageTrackingOptions { + /** + * When true, shows that message open tracking is enabled. + */ + opens: boolean; + /** + * When true, shows that thread replied tracking is enabled. + */ + threadReplies: boolean; + /** + * When true, shows that link clicked tracking is enabled. + */ + links: boolean; + /** + * A label describing the message tracking purpose. + * Maximum length: 2048 characters. + */ + label: string; +} + +/** + * Interface representing a Nylas Message object. + */ +export interface Message extends BaseMessage { + /** + * The type of object. + */ + object: 'message'; + /** + * The message headers. + * Only present if the 'fields' query parameter is set to includeHeaders. + */ + headers?: MessageHeaders[]; + /** + * The message tracking options. + * Only present if the 'fields' query parameter is set to include_tracking_options. + */ + trackingOptions?: MessageTrackingOptions; + /** + * A Base64url-encoded string containing the message data (including the body content). + * Only present if the 'fields' query parameter is set to raw_mime. + * When this field is requested, only grant_id, object, id, and raw_mime fields are returned. + */ + rawMime?: string; + /** + * A list of key-value pairs storing additional data. + */ + metadata?: Record; + /** + * The unique identifier for the scheduled message. + */ + scheduleId?: string; + /** + * Unix timestamp to send the message at. + */ + sendAt?: number; + /** + * Whether or not to use draft support. + * This is primarily used when dealing with large attachments. + */ + useDraft?: boolean; +} + +/** + * Interface representing a request to update a message. + */ +export interface UpdateMessageRequest { + /** + * Sets the message as starred or unstarred. + */ + starred?: boolean; + /** + * Sets the message as read or unread. + */ + unread?: boolean; + /** + * The IDs of the folders the message should appear in. + */ + folders?: string[]; + /** + * A list of key-value pairs storing additional data. + */ + metadata?: Record; +} + +/** + * Interface representing a message header. + */ +export interface MessageHeaders { + /** + * The header name. + */ + name: string; + /** + * The header value. + */ + value: string; +} + +/** + * Enum representing the message fields that can be included in a response. + */ +export enum MessageFields { + STANDARD = 'standard', + INCLUDE_HEADERS = 'include_headers', + INCLUDE_TRACKING_OPTIONS = 'include_tracking_options', + RAW_MIME = 'raw_mime', +} + +/** + * Interface representing information about a scheduled message. + */ +export interface ScheduledMessage { + /** + * The unique identifier for the scheduled message. + */ + scheduleId: number; + /** + * The status of the scheduled message. + */ + status: ScheduledMessageStatus; + /** + * The time the message was sent or failed to send, in epoch time. + */ + closeTime?: number; +} + +/** + * Interface representing a list of scheduled messages. + */ +export interface ScheduledMessagesList { + /** + * The list of scheduled messages. + */ + schedules: ScheduledMessage[]; +} + +/** + * Interface representing a scheduled message status. + */ +export interface ScheduledMessageStatus { + /** + * The status code the describes the state of the scheduled message + */ + code: string; + /** + * A description of the status of the scheduled message + */ + description: string; +} + +/** + * Interface representing a response after stopping a scheduled message. + */ +export interface StopScheduledMessageResponse { + /** + * A message describing the result of the request. + */ + message: string; +} + +/** + * Interface representing the query parameters for listing messages. + */ +export interface ListMessagesQueryParams extends ListQueryParams { + /** + * Return items with a matching literal subject. + */ + subject?: string; + /** + * Return emails that have been sent or received from this list of email addresses. + */ + anyEmail?: string[]; + /** + * Return items containing messages sent to these email address. + */ + to?: string[]; + /** + * Return items containing messages sent from these email address. + */ + from?: string[]; + /** + * Return items containing messages cc'd on these email address. + */ + cc?: string[]; + /** + * Return items containing messages bcc'd on these email address. + */ + bcc?: string[]; + /** + * Return emails that are in these folder IDs. + */ + in?: string[]; + /** + * Return emails that are unread. + */ + unread?: boolean; + /** + * Return emails that are starred. + */ + starred?: boolean; + /** + * Return emails that belong to this thread. + */ + threadId?: string; + /** + * Return emails that have been received before this timestamp. + */ + receivedBefore?: number; + /** + * Return emails that have been received after this timestamp. + */ + receivedAfter?: number; + /** + * Return emails that contain attachments. + */ + hasAttachment?: boolean; + /** + * Allows you to specify to return messages with headers included. + */ + fields?: MessageFields; + /** + * The provider-specific query string used to search messages. + * Available for Google and Microsoft Graph only. + */ + searchQueryNative?: string; +} + +/** + * Interface representing the query parameters for finding a message. + */ +export interface FindMessageQueryParams { + /** + * Allows you to specify to the message with headers included. + */ + fields?: MessageFields; +} + +/** + * Interface representing the request to clean a message. + */ +export interface CleanMessagesRequest { + /** + * IDs of the email messages to clean. + */ + messageId: string[]; + /** + * If true, removes link-related tags () from the email message while keeping the text. + */ + ignoreLinks?: boolean; + /** + * If true, removes images from the email message. + */ + ignoreImages?: boolean; + /** + * If true, converts images in the email message to Markdown. + */ + imagesAsMarkdown?: boolean; + /** + * If true, removes table-related tags (, ) from the email message while keeping rows. + */ + ignoreTables?: boolean; + /** + * If true, removes phrases such as "Best" and "Regards" in the email message signature. + */ + removeConclusionPhrases?: boolean; +} + +/** + * Interface representing the response after cleaning a message. + */ +export interface CleanMessagesResponse extends Message { + /** + * The cleaned HTML message body. + */ + conversation: string; +} diff --git a/src/models/notetakers.ts b/src/models/notetakers.ts new file mode 100644 index 00000000..24abb6af --- /dev/null +++ b/src/models/notetakers.ts @@ -0,0 +1,287 @@ +import { NylasListResponse } from './response.js'; +import { ListQueryParams } from './listQueryParams.js'; + +/** + * Enum representing the supported meeting providers. + */ +export type NotetakerMeetingProvider = + | 'Google Meet' + | 'Microsoft Teams' + | 'Zoom Meeting'; + +/** + * Enum representing the current state of the Notetaker bot. + */ +export type NotetakerState = + | 'scheduled' + | 'connecting' + | 'waiting_for_entry' + | 'failed_entry' + | 'attending' + | 'media_processing' + | 'media_available' + | 'media_error' + | 'media_deleted'; + +/** + * Interface representing Notetaker Meeting Settings + */ +export interface NotetakerMeetingSettings { + /** + * When true, Notetaker records the meeting's video. + */ + videoRecording: boolean; + /** + * When true, Notetaker records the meeting's audio. + */ + audioRecording: boolean; + /** + * When true, Notetaker transcribes the meeting's audio. + * If transcription is true, audioRecording must also be true. + */ + transcription: boolean; +} + +/** + * Interface representing a Nylas Notetaker object. + */ +export interface Notetaker { + /** + * The Notetaker ID. + */ + id: string; + /** + * The display name for the Notetaker bot. + */ + name: string; + /** + * When Notetaker joined the meeting, in Unix timestamp format. + */ + joinTime: number; + /** + * The meeting link. + */ + meetingLink: string; + /** + * The meeting provider. + */ + meetingProvider: NotetakerMeetingProvider; + /** + * The current state of the Notetaker bot. + */ + state: NotetakerState; + /** + * Notetaker Meeting Settings + */ + meetingSettings: NotetakerMeetingSettings; +} + +/** + * Interface representing Notetaker media recording information + */ +export interface NotetakerRecording { + /** + * A link to the meeting recording. + */ + url: string; + /** + * The size of the file, in bytes. + */ + size: number; + /** + * The name of the recording file. + */ + name: string; + /** + * The MIME type of the recording file. + */ + type: string; + /** + * When the recording file was uploaded to the storage server, in Unix timestamp format. + */ + createdAt: number; + /** + * When the recording file will be deleted from the storage server, in Unix timestamp format. + */ + expiresAt: number; + /** + * Time-to-live in seconds until the recording file will be deleted from Nylas' storage server. + */ + ttl: number; +} + +/** + * Interface representing Notetaker media transcript information + */ +export interface NotetakerTranscript { + /** + * A link to the meeting transcript. + */ + url: string; + /** + * The size of the file, in bytes. + */ + size: number; + /** + * The name of the transcript file. + */ + name: string; + /** + * The MIME type of the transcript file. + */ + type: string; + /** + * When the transcript file was uploaded to the storage server, in Unix timestamp format. + */ + createdAt: number; + /** + * When the transcript file will be deleted from the storage server, in Unix timestamp format. + */ + expiresAt: number; + /** + * Time-to-live in seconds until the transcript file will be deleted from Nylas' storage server. + */ + ttl: number; +} + +/** + * Interface representing Notetaker media data + */ +export interface NotetakerMedia { + /** + * The meeting recording. + */ + recording: NotetakerRecording; + /** + * The meeting transcript. + */ + transcript: NotetakerTranscript; +} + +/** + * Interface representing the request body for creating a Notetaker. + */ +export interface CreateNotetakerRequest { + /** + * A meeting invitation link that Notetaker uses to join the meeting. + */ + meetingLink: string; + + /** + * When Notetaker should join the meeting, in Unix timestamp format. + * If empty, Notetaker joins the meeting immediately. + * If you provide a time that's in the past, Nylas returns an error. + */ + joinTime?: number; + + /** + * The display name for the Notetaker bot. + * Default: Nylas Notetaker + */ + name?: string; + + /** + * Notetaker Meeting Settings + */ + meetingSettings?: Partial; +} + +/** + * Interface representing the request body for updating a Notetaker. + */ +export interface UpdateNotetakerRequest { + /** + * When Notetaker should join the meeting, in Unix timestamp format. + * If empty, Notetaker joins the meeting immediately. + * If you provide a time that's in the past, Nylas returns an error. + */ + joinTime?: number; + + /** + * The display name for the Notetaker bot. + * Default: Nylas Notetaker + */ + name?: string; + + /** + * Notetaker Meeting Settings + */ + meetingSettings?: Partial; +} + +export interface ListNotetakersResponse extends NylasListResponse { + /** + * A cursor pointing to the previous page of results for the request. + */ + prevCursor?: string; + + /** + * A cursor pointing to the next page of results for the request. + */ + nextCursor?: string; +} + +/** + * Interface representing the query parameters for listing notetakers. + */ +export interface ListNotetakersQueryParams extends ListQueryParams { + /** + * Filter for Notetaker bots with the specified meeting state. + */ + state?: NotetakerState; + + /** + * Filter for Notetaker bots that have join times that start at or after a specific time, in Unix timestamp format. + */ + joinTimeStart?: number; + + /** + * Filter for Notetaker bots that have join times that end at or are before a specific time, in Unix timestamp format. + */ + joinTimeEnd?: number; + + /** + * The maximum number of objects to return. + * This field defaults to 50. The maximum allowed value is 200. + */ + limit?: number; + + /** + * An identifier that specifies which page of data to return. + * This value should be taken from the next_cursor response field. + */ + pageToken?: string; + + /** + * An identifier that specifies which page of data to return. + * This value should be taken from the prev_cursor response field. + */ + prevPageToken?: string; + + /** + * The field to order the Notetaker bots by. + * @default created_at + */ + orderBy?: 'name' | 'join_time' | 'created_at'; + + /** + * The direction to order the Notetaker bots by. + * @default asc + */ + orderDirection?: 'asc' | 'desc'; +} + +/** + * Interface representing the response from leaving a Notetaker session + */ +export interface NotetakerLeaveResponse { + /** + * The Notetaker ID. + */ + id: string; + + /** + * A message describing the API response. + */ + message: string; +} diff --git a/src/models/redirectUri.ts b/src/models/redirectUri.ts new file mode 100644 index 00000000..b6f207f4 --- /dev/null +++ b/src/models/redirectUri.ts @@ -0,0 +1,74 @@ +/** + * Interface representation of a Redirect URI object + */ +export type RedirectUri = { + /** + * Globally unique object identifier + */ + id: string; + /** + * Redirect URL + */ + url: string; + /** + * Platform identifier + */ + platform: string; + /** + * Configuration settings + */ + settings?: RedirectUriSettings; +}; + +/** + * Configuration settings for a Redirect URI object + */ +export type RedirectUriSettings = { + /** + * Related to JS platform + */ + origin?: string; + /** + * Related to iOS platform + */ + bundleId?: string; + /** + * Related to iOS platform + */ + appStoreId?: string; + /** + * Related to iOS platform + */ + teamId?: string; + /** + * Related to Android platform + */ + packageName?: string; + /** + * Related to Android platform + */ + sha1CertificateFingerprint?: string; +}; + +/** + * Class representing a request to create a redirect uri. + */ +export type CreateRedirectUriRequest = { + /** + * Redirect URL. + */ + url: string; + /** + * Platform identifier. + */ + platform: string; + /** + * Optional settings for the redirect uri. + */ + settings?: RedirectUriSettings; +}; + +/** + * Interface representation of a Nylas update redirect uri request + */ +export type UpdateRedirectUriRequest = Partial; diff --git a/src/models/response.ts b/src/models/response.ts new file mode 100644 index 00000000..f72261e9 --- /dev/null +++ b/src/models/response.ts @@ -0,0 +1,86 @@ +/** + * Interface representing a base response to a request. + */ +export interface NylasBaseResponse { + requestId: string; + /** + * The flow ID + * Provide this to Nylas support to help trace requests and responses + */ + flowId?: string; + /** + * The response headers with camelCased keys (backwards compatible) + * @deprecated Use rawHeaders instead + */ + headers?: Record; + /** + * The raw response headers with original dashed lowercase keys + */ + rawHeaders?: Record; +} + +/** + * Interface representation of a Nylas response object + */ +export interface NylasResponse { + /** + * The requested data object + */ + data: T; + /** + * The request ID + */ + requestId: string; + /** + * The flow ID + * Provide this t + */ + flowId?: string; + /** + * The response headers + * @deprecated Use rawHeaders instead + */ + headers?: Record; + /** + * The raw response headers with original dashed lowercase keys + */ + rawHeaders?: Record; +} + +/** + * Interface representation of a Nylas response object that contains a list of objects. + */ +export interface NylasListResponse { + /** + * The list of requested data objects. + */ + data: T[]; + /** + * The request ID. + */ + requestId: string; + /** + * The cursor to use to get the next page of data. + */ + nextCursor?: string; + /** + * The flow ID + * Provide this to Nylas support to help trace requests and responses + */ + flowId?: string; + /** + * The response headers with camelCased keys (backwards compatible) + * @deprecated Use rawHeaders instead + */ + headers?: Record; + /** + * The raw response headers with original dashed lowercase keys + */ + rawHeaders?: Record; +} + +/** + * Helper type for pagination + */ +export type ListResponseInnerType = + T extends NylasListResponse ? R : never; diff --git a/src/models/restful-model-collection.js b/src/models/restful-model-collection.js deleted file mode 100644 index 54a17ba5..00000000 --- a/src/models/restful-model-collection.js +++ /dev/null @@ -1,319 +0,0 @@ -import async from 'async'; -import _ from 'underscore'; -import Promise from 'bluebird'; - -import Message from './message'; -import Thread from './thread'; - -const REQUEST_CHUNK_SIZE = 100; - -export default class RestfulModelCollection { - constructor(modelClass, connection) { - this.modelClass = modelClass; - this.connection = connection; - if (!(this.connection instanceof require('../nylas-connection'))) { - throw new Error('Connection object not provided'); - } - if (!this.modelClass) { - throw new Error('Model class not provided'); - } - } - - forEach(params = {}, eachCallback, completeCallback = null) { - if (params.view == 'count') { - const err = new Error('forEach() cannot be called with the count view'); - if (callback) { - callback(err); - } - return Promise.reject(err); - } - - let offset = 0; - let finished = false; - - return async.until( - () => finished, - callback => { - return this._getItems(params, offset, REQUEST_CHUNK_SIZE).then( - items => { - for (const item of items) { - eachCallback(item); - } - offset += items.length; - finished = items.length < REQUEST_CHUNK_SIZE; - return callback(); - } - ); - }, - err => { - if (completeCallback) { - return completeCallback(err); - } - } - ); - } - - count(params = {}, callback = null) { - return this.connection - .request({ - method: 'GET', - path: this.path(), - qs: _.extend({ view: 'count' }, params), - }) - .then(json => { - if (callback) { - callback(null, json.count); - } - return Promise.resolve(json.count); - }) - .catch(err => { - if (callback) { - callback(err); - } - return Promise.reject(err); - }); - } - - first(params = {}, callback = null) { - if (params.view == 'count') { - const err = new Error('first() cannot be called with the count view'); - if (callback) { - callback(err); - } - return Promise.reject(err); - } - - return this._getItems(params, 0, 1) - .then(items => { - if (callback) { - callback(null, items[0]); - } - return Promise.resolve(items[0]); - }) - .catch(err => { - if (callback) { - callback(err); - } - return Promise.reject(err); - }); - } - - list(params = {}, callback = null) { - if (params.view == 'count') { - const err = new Error('list() cannot be called with the count view'); - if (callback) { - callback(err); - } - return Promise.reject(err); - } - - const limit = params.limit || Infinity; - const offset = params.offset; - return this._range({ params, offset, limit, callback }); - } - - find(id, callback = null, params = {}) { - if (!id) { - const err = new Error('find() must be called with an item id'); - if (callback) { - callback(err); - } - return Promise.reject(err); - } - - if (params.view == 'count' || params.view == 'ids') { - const err = new Error( - 'find() cannot be called with the count or ids view' - ); - if (callback) { - callback(err); - } - return Promise.reject(err); - } - - return this._getModel(id, params) - .then(model => { - if (callback) { - callback(null, model); - } - return Promise.resolve(model); - }) - .catch(err => { - if (callback) { - callback(err); - } - return Promise.reject(err); - }); - } - - search(query, params = {}, callback = null) { - if (this.modelClass != Message && this.modelClass != Thread) { - const err = new Error( - 'search() can only be called for messages and threads' - ); - if (callback) { - callback(err); - } - return Promise.reject(err); - } - - if (!query) { - const err = new Error('search() requires a query string'); - if (callback) { - callback(err); - } - return Promise.reject(err); - } - - params.q = query; - const limit = params.limit || 40; - const offset = params.offset; - const path = `${this.path()}/search`; - - return this._range({ params, offset, limit, path }); - } - - delete(itemOrId, params = {}, callback = null) { - if (!itemOrId) { - const err = new Error('delete() requires an item or an id'); - if (callback) { - callback(err); - } - return Promise.reject(err); - } - - const id = itemOrId.id ? itemOrId.id : itemOrId; - - if (_.isFunction(params)) { - callback = params; - params = {}; - } - return this.connection - .request({ - method: 'DELETE', - qs: params, - path: `${this.path()}/${id}`, - }) - .then(() => { - if (callback) { - callback(null); - } - return Promise.resolve(); - }) - .catch(err => { - if (callback) { - callback(err); - } - return Promise.reject(err); - }); - } - - build(args) { - const model = new this.modelClass(this.connection); - for (const key in args) { - const val = args[key]; - model[key] = val; - } - return model; - } - - path() { - return `/${this.modelClass.collectionName}`; - } - - _range({ - params = {}, - offset = 0, - limit = 100, - callback = null, - path = null, - }) { - return new Promise((resolve, reject) => { - let accumulated = []; - let finished = false; - - return async.until( - () => finished, - chunkCallback => { - const chunkOffset = offset + accumulated.length; - const chunkLimit = Math.min( - REQUEST_CHUNK_SIZE, - limit - accumulated.length - ); - return this._getItems(params, chunkOffset, chunkLimit, path) - .then(items => { - accumulated = accumulated.concat(items); - finished = - items.length < REQUEST_CHUNK_SIZE || - accumulated.length >= limit; - return chunkCallback(); - }) - .catch(err => reject(err)); - }, - err => { - if (err) { - if (callback) { - callback(err); - } - return reject(err); - } else { - if (callback) { - callback(null, accumulated); - } - return resolve(accumulated); - } - } - ); - }); - } - - _getItems(params, offset, limit, path) { - // Items can be either models or ids - - if (!path) { - path = this.path(); - } - - if (params.view == 'ids') { - return this.connection.request({ - method: 'GET', - path, - qs: _.extend({}, params, { offset, limit }), - }); - } - - return this._getModelCollection(params, offset, limit, path); - } - - _createModel(json) { - return new this.modelClass(this.connection, json); - } - - _getModel(id, params = {}) { - return this.connection - .request({ - method: 'GET', - path: `${this.path()}/${id}`, - qs: params, - }) - .then(json => { - const model = this._createModel(json); - return Promise.resolve(model); - }); - } - - _getModelCollection(params, offset, limit, path) { - return this.connection - .request({ - method: 'GET', - path, - qs: _.extend({}, params, { offset, limit }), - }) - .then(jsonArray => { - const models = jsonArray.map(json => { - return this._createModel(json); - }); - return Promise.resolve(models); - }); - } -} diff --git a/src/models/restful-model-instance.js b/src/models/restful-model-instance.js deleted file mode 100644 index 217019de..00000000 --- a/src/models/restful-model-instance.js +++ /dev/null @@ -1,31 +0,0 @@ -import Promise from 'bluebird'; - -export default class RestfulModelInstance { - constructor(modelClass, connection) { - this.modelClass = modelClass; - this.connection = connection; - if (!(this.connection instanceof require('../nylas-connection'))) { - throw new Error('Connection object not provided'); - } - if (!this.modelClass) { - throw new Error('Model class not provided'); - } - } - - path() { - return `/${this.modelClass.endpointName}`; - } - - get(params = {}) { - return this.connection - .request({ - method: 'GET', - path: this.path(), - qs: params, - }) - .then(json => { - const model = new this.modelClass(this.connection, json); - return Promise.resolve(model); - }); - } -} diff --git a/src/models/restful-model.js b/src/models/restful-model.js deleted file mode 100644 index f31ef67e..00000000 --- a/src/models/restful-model.js +++ /dev/null @@ -1,115 +0,0 @@ -import Promise from 'bluebird'; -import _ from 'underscore'; - -import * as Attributes from './attributes'; - -export default class RestfulModel { - constructor(connection, json = null) { - this.connection = connection; - if (!(this.connection instanceof require('../nylas-connection'))) { - throw new Error('Connection object not provided'); - } - if (json) { - this.fromJSON(json); - } - } - - attributes() { - return this.constructor.attributes; - } - - isEqual(other) { - return ( - (other ? other.id : undefined) === this.id && - (other ? other.constructor : undefined) === this.constructor - ); - } - - fromJSON(json = {}) { - const attributes = this.attributes(); - for (const attrName in attributes) { - const attr = attributes[attrName]; - if (json[attr.jsonKey] !== undefined) { - this[attrName] = attr.fromJSON(json[attr.jsonKey], this); - } - } - return this; - } - - toJSON() { - const json = {}; - const attributes = this.attributes(); - for (const attrName in attributes) { - const attr = attributes[attrName]; - json[attr.jsonKey] = attr.toJSON(this[attrName]); - } - json['object'] = this.constructor.name.toLowerCase(); - return json; - } - - // saveRequestBody is used by save(). It returns a JSON dict containing only the - // fields the API allows updating. Subclasses should override this method. - saveRequestBody() { - return this.toJSON(); - } - - toString() { - return JSON.stringify(this.toJSON()); - } - - // Not every model needs to have a save function, but those who - // do shouldn't have to reimplement the same boilerplate. - // They should instead define a save() function which calls _save. - _save(params = {}, callback = null) { - if (_.isFunction(params)) { - callback = params; - params = {}; - } - return this.connection - .request({ - method: this.id ? 'PUT' : 'POST', - body: this.saveRequestBody(), - qs: params, - path: this.id - ? `/${this.constructor.collectionName}/${this.id}` - : `/${this.constructor.collectionName}`, - }) - .then(json => { - this.fromJSON(json); - if (callback) { - callback(null, this); - } - return Promise.resolve(this); - }) - .catch(err => { - if (callback) { - callback(err); - } - return Promise.reject(err); - }); - } - - _get(params = {}, callback = null, path_suffix = '') { - return this.connection - .request({ - method: 'GET', - path: `/${this.constructor.collectionName}/${this.id}${path_suffix}`, - qs: params, - }) - .then(response => { - return Promise.resolve(response); - }); - } -} -RestfulModel.attributes = { - id: Attributes.String({ - modelKey: 'id', - }), - object: Attributes.String({ - modelKey: 'object', - }), - accountId: Attributes.String({ - modelKey: 'accountId', - jsonKey: 'account_id', - }), -}; diff --git a/src/models/scheduler.ts b/src/models/scheduler.ts new file mode 100644 index 00000000..a51d1588 --- /dev/null +++ b/src/models/scheduler.ts @@ -0,0 +1,461 @@ +import { Subset } from '../utils.js'; +import { AvailabilityRules, OpenHours } from './availability.js'; +import { Conferencing } from './events.js'; + +export type BookingType = 'booking' | 'organizer-confirmation'; +export type BookingReminderType = 'email' | 'webhook'; +export type BookingRecipientType = 'host' | 'guest' | 'all'; + +export interface BookingConfirmedTemplate { + /** + * The title to replace the default 'Booking Confirmed' title. + * This doesn't change the email subject line. Only visible in emails sent to guests. + */ + title?: string; + /** + * The additional body to be appended after the default body. + * Only visible in emails sent to guests. + */ + body?: string; +} + +export interface EmailTemplate { + /** + * The URL to a custom logo that appears at the top of the booking email. + * Replaces the default Nylas logo. The URL must be publicly accessible. + */ + logo?: string; + /** + * Configurable settings specifically for booking confirmed emails. + */ + bookingConfirmed?: BookingConfirmedTemplate; +} + +export interface SchedulerSettings { + /** + * The definitions for additional fields to be displayed in the Scheduler UI. + * Guest will see the additional fields on the Scheduling Page when they book an event. + */ + additionalFields?: Record; + /** + * The number of days in the future that Scheduler is available for scheduling events. + */ + availableDaysInFuture?: number; + /** + * The minimum number of minutes in the future that a user can make a new booking. + */ + minBookingNotice?: number; + /** + * The minimum number of minutes before a booking can be cancelled. + */ + minCancellationNotice?: number; + /** + * A message about the cancellation policy to display to users when booking an event. + */ + cancellationPolicy?: string; + /** + * The URL used to reschedule bookings. This URL is included in confirmation email messages. + */ + reschedulingUrl?: string; + /** + * The URL used to cancel bookings. This URL is included in confirmation email messages. + */ + cancellationUrl?: string; + /** + * The URL used to confirm or cancel pending bookings. This URL is included in booking request email messages. + */ + organizerConfirmationUrl?: string; + /** + * The custom URL to redirect to once the booking is confirmed. + */ + confirmationRedirectUrl?: string; + /** + * If true, the option to reschedule an event is hidden in booking confirmations and email notifications. + */ + hideReschedulingOptions?: boolean; + /** + * If true, the option to cancel an event is hidden in booking confirmations and email notifications. + */ + hideCancellationOptions?: boolean; + /** + * Whether to hide the Additional guests field on the Scheduling Page. If true, guests cannot invite additional guests to the event. + */ + hideAdditionalGuests?: boolean; + /** + * Configurable settings for booking emails. + */ + emailTemplate?: EmailTemplate; +} + +export interface BookingReminder { + /** + * The reminder type. + */ + type: BookingReminderType; + /** + * The number of minutes before the event to send the reminder. + */ + minutesBeforeEvent: number; + /** + * The recipient of the reminder. + */ + recipient?: BookingRecipientType; + /** + * The subject of the email reminder. + */ + emailSubject?: string; +} + +export interface EventBooking { + /** + * The title of the event. + */ + title: string; + /** + * The description of the event. + */ + description?: string; + /** + * The location of the event. + */ + location?: string; + /** + * The timezone for displaying the times in confirmation email messages and reminders. + */ + timezone?: string; + /** + * The type of booking. If set to booking, Scheduler follows the standard booking flow and instantly creates the event. + * If set to organizer-confirmation, Scheduler creates an event marked "Pending" in the organizer's calendar and sends + * an confirmation request email to the organizer. + * The confirmation request email includes a link to a page where the organizer can confirm or cancel the booking. + */ + bookingType?: BookingType; + /** + * An object that allows you to automatically create a conference or enter conferencing details manually. + */ + conferencing?: Conferencing; + /** + * If true, Nylas doesn't send any email messages when an event is booked, cancelled, or rescheduled. + */ + disableEmails?: boolean; + /** + * The list of reminders to send to participants before the event starts. + */ + reminders?: BookingReminder[]; +} + +export interface Availability { + /** + * The total number of minutes the event should last. + */ + durationMinutes: number; + /** + * The interval between meetings in minutes. + */ + intervalMinutes?: number; + /** + * Nylas rounds each time slot to the nearest multiple of this number of minutes. + * Must be a multiple of 5. + */ + roundTo?: number; + /** + * Availability rules for the scheduling configuration. + * These rules define how Nylas calculates availability for all participants. + */ + availabilityRules?: Omit; +} + +export interface ParticipantBooking { + /** + * The calendar ID that the event is created in. + */ + calendarId: string; +} + +export interface ParticipantAvailability { + /** + * An optional list of the calendar IDs associated with each participant's email address. + * If not provided, Nylas uses the primary calendar ID. + */ + calendarIds: string[]; + /** + * Open hours for this participant. The endpoint searches for free time slots during these open hours. + */ + openHours?: OpenHours[]; +} + +/** + * Interface representing a booking participant. + */ +export interface ConfigParticipant { + /** + * Participant's email address. + */ + email: string; + /** + * The availability data for the participant. + * If omitted, the participant is considered to be available at all times. + * At least one participant must have availability data. + */ + availability: ParticipantAvailability; + /** + * The booking data for the participant. + * If omitted, the participant is not included in the booked event. + * At least one participant must have booking data. + */ + booking: ParticipantBooking; + /** + * Participant's name. + */ + name?: string; + /** + * Whether the participant is the organizer of the event. + * For non-round-robin meetings, one of the participants must be specified as an organizer. + */ + isOrganizer?: boolean; + /** + * The participant's timezone. + * This is used when calculating the participant's open hours and in email notifications. + */ + timezone?: string; +} + +export interface Configuration { + /** + * The list of participants that is included in the scheduled event. + * All participants must have a valid Nylas grant. + */ + participants: ConfigParticipant[]; + /** + * The rules that determine the available time slots for the event. + */ + availability: Availability; + /** + * The booking data for the event. + */ + eventBooking: EventBooking; + /** + * The slug of the Configuration object. This is an optional, unique identifier for the Configuration object. + */ + slug?: string; + /** + * If true, the scheduling Availability and Bookings endpoints require a valid session ID to authenticate requests when you use this configuration. + */ + requiresSessionAuth?: boolean; + /** + * The settings for the Scheduler UI. + */ + scheduler?: SchedulerSettings; + /** + * The appearance settings for the Scheduler UI. + */ + appearance?: Record; +} + +export type CreateConfigurationRequest = Configuration; +export type UpdateConfigurationRequest = Subset; + +export interface CreateSessionRequest { + /** + * The ID of the Scheduler Configuration object for the session. + * If you're using slug, you can omit this field. + */ + configurationId?: string; + /** + * The slug of the Scheduler Configuration object for the session. + * If you're using configurationId, you can omit this field. + */ + slug?: string; + /** + * The time to live for the session in minutes. + * The maximum value is 30 minutes. + */ + timeToLive?: number; +} + +export interface Session { + /** + * The ID of the session + */ + sessionId: string; +} + +/** + * The supported languages for email notifications. + */ +export type EmailLanguage = + | 'en' + | 'es' + | 'fr' + | 'de' + | 'nl' + | 'sv' + | 'ja' + | 'zh'; + +export interface BookingGuest { + /** + * The email address of the guest. + */ + email: string; + /** + * The name of the guest. + */ + name: string; +} + +export interface BookingParticipant { + /** + * The email address of the participant to include in the booking. + */ + email: string; +} + +/** + * Interface representing a create booking request. + */ +export interface CreateBookingRequest { + /** + * The event's start time, in Unix epoch format. + */ + startTime: number; + /** + * The event's end time, in Unix epoch format. + */ + endTime: number; + /** + * Details about the guest that is creating the booking. The guest name and email are required. + */ + guest: BookingGuest; + /** + * An array of objects that include a list of participant email addresses from the Configuration object to include in the booking. + * If not provided, Nylas includes all participants from the Configuration object. + */ + participants?: BookingParticipant[]; + /** + * The guest's timezone that is used in email notifications. + * If not provided, Nylas uses the timezone from the Configuration object. + */ + timezone?: string; + /** + * The language of the guest email notifications. + */ + emailLanguage?: EmailLanguage; + /** + * An array of objects that include a list of additional guest email addresses to include in the booking. + */ + additionalGuests?: BookingGuest[]; + /** + * A dictionary of additional field keys mapped to the values populated by the guest in the booking form. + */ + additionalFields?: Record; +} + +export interface BookingOrganizer { + /** + * The email address of the participant that is designated as the organizer of the event. + */ + email: string; + /** + * The name of the participant that is designated as the organizer of the event. + */ + name?: string; +} + +export type BookingStatus = 'pending' | 'booked' | 'cancelled'; +export type ConfirmBookingStatus = 'confirmed' | 'cancelled'; + +export interface Booking { + /** + * The unique ID of the booking + */ + bookingId: string; + /** + * The unique ID of the event associated with the booking + */ + eventId: string; + /** + * The title of the event + */ + title: string; + /** + * The participant that is designated as the organizer of the event + */ + organizer: BookingOrganizer; + /** + * The current status of the booking + */ + status: BookingStatus; + /** + * The description of the event + */ + description?: string; +} + +export interface ConfirmBookingRequest { + /** + * The salt extracted from the booking reference embedded in the organizer confirmation link, + * encoded as a URL-safe base64 string (without padding). + */ + salt: string; + /** + * The action to take on the pending booking + */ + status: ConfirmBookingStatus; + /** + * The reason that the booking is being cancelled + */ + cancellationReason?: string; +} + +export interface DeleteBookingRequest { + /** + * The reason that the booking is being cancelled + */ + cancellationReason?: string; +} + +export interface RescheduleBookingRequest { + /** + * The event's start time, in Unix epoch format. + */ + startTime: number; + /** + * The event's end time, in Unix epoch format. + */ + endTime: number; +} + +export interface CreateBookingQueryParams { + /** + * The ID of the Configuration object whose settings are used for calculating availability. + * If you're using session authentication (requires_session_auth is set to true), configuration_id is not required. + */ + configurationId?: string; + /** + * The slug of the Configuration object whose settings are used for calculating availability. + * If you're using session authentication (requires_session_auth is set to true) or using configurationId, slug is not required. + */ + slug?: string; + /** + * The timezone to use for the booking. If not provided, Nylas uses the timezone from the Configuration object. + */ + timezone?: string; +} + +export interface FindBookingQueryParams { + /** + * The ID of the Configuration object whose settings are used for calculating availability. + * If you're using session authentication (requires_session_auth is set to true), configuration_id is not required. + */ + configurationId?: string; + /** + * The slug of the Configuration object whose settings are used for calculating availability. + * If you're using session authentication (requires_session_auth is set to true) or using configurationId, slug is not required. + */ + slug?: string; +} + +export type ConfirmBookingQueryParams = FindBookingQueryParams; +export type RescheduleBookingQueryParams = FindBookingQueryParams; +export type DestroyBookingQueryParams = FindBookingQueryParams; diff --git a/src/models/smartCompose.ts b/src/models/smartCompose.ts new file mode 100644 index 00000000..3b17dd0a --- /dev/null +++ b/src/models/smartCompose.ts @@ -0,0 +1,19 @@ +/** + * Interface representing a request to compose a message. + */ +export interface ComposeMessageRequest { + /** + * The prompt that smart compose will use to generate a message suggestion. + */ + prompt: string; +} + +/** + * Interface representing a response to a message composition request. + */ +export interface ComposeMessageResponse { + /** + * The message suggestion generated by smart compose. + */ + suggestion: string; +} diff --git a/src/models/thread.js b/src/models/thread.js deleted file mode 100644 index ed9a1b54..00000000 --- a/src/models/thread.js +++ /dev/null @@ -1,104 +0,0 @@ -import _ from 'underscore'; - -import Message from './message'; -import RestfulModel from './restful-model'; -import Contact from './contact'; -import * as Attributes from './attributes'; -import { Label, Folder } from './folder'; - -export default class Thread extends RestfulModel { - constructor(...args) { - super(...args); - this.fromJSON = this.fromJSON.bind(this); - } - - fromJSON(json) { - super.fromJSON(json); - return this; - } - - saveRequestBody() { - const json = {}; - if (this.labels) { - json['label_ids'] = this.labels.map(label => label.id); - } else if (this.folder) { - json['folder_id'] = this.folder.id; - } - - json['starred'] = this.starred; - json['unread'] = this.unread; - return json; - } - - save(params = {}, callback = null) { - return this._save(params, callback); - } -} -Thread.collectionName = 'threads'; -Thread.attributes = _.extend({}, RestfulModel.attributes, { - subject: Attributes.String({ - modelKey: 'subject', - }), - participants: Attributes.Collection({ - modelKey: 'participants', - itemClass: Contact, - }), - lastMessageTimestamp: Attributes.DateTime({ - modelKey: 'lastMessageTimestamp', - jsonKey: 'last_message_timestamp', - }), - lastMessageReceivedTimestamp: Attributes.DateTime({ - modelKey: 'lastMessageReceivedTimestamp', - jsonKey: 'last_message_received_timestamp', - }), - lastMessageSentTimestamp: Attributes.DateTime({ - modelKey: 'lastMessageSentTimestamp', - jsonKey: 'last_message_sent_timestamp', - }), - firstMessageTimestamp: Attributes.DateTime({ - modelKey: 'firstMessageTimestamp', - jsonKey: 'first_message_timestamp', - }), - snippet: Attributes.String({ - modelKey: 'snippet', - }), - unread: Attributes.Boolean({ - modelKey: 'unread', - }), - starred: Attributes.Boolean({ - modelKey: 'starred', - }), - hasAttachments: Attributes.Boolean({ - modelKey: 'has_attachments', - }), - version: Attributes.String({ - modelKey: 'version', - jsonKey: 'version', - }), - folder: Attributes.Object({ - modelKey: 'folder', - itemClass: Folder, - jsonKey: 'folders', - }), - labels: Attributes.Collection({ - modelKey: 'labels', - itemClass: Label, - jsonKey: 'labels', - }), - messageIds: Attributes.StringList({ - modelKey: 'messageIds', - jsonKey: 'message_ids', - }), - draftIds: Attributes.StringList({ - modelKey: 'draftIds', - jsonKey: 'draft_ids', - }), - messages: Attributes.Collection({ - modelKey: 'messages', - itemClass: Message, - }), - drafts: Attributes.Collection({ - modelKey: 'drafts', - itemClass: Message, - }), -}); diff --git a/src/models/threads.ts b/src/models/threads.ts new file mode 100644 index 00000000..9869a41f --- /dev/null +++ b/src/models/threads.ts @@ -0,0 +1,156 @@ +import { Draft } from './drafts.js'; +import { EmailName } from './events.js'; +import { ListQueryParams } from './listQueryParams.js'; +import { Message } from './messages.js'; + +/** + * Interface representing a Nylas thread object. + */ +export interface Thread { + /** + * The unique identifier for the thread. + */ + id: string; + /** + * Grant ID of the Nylas account. + */ + grantId: string; + /** + * The latest message or draft in the thread. + */ + latestDraftOrMessage: Message | Draft; + /** + * Whether or not a message in a thread has attachments. + */ + hasAttachments: boolean; + /** + * Whether or not a message in a thread has drafts. + */ + hasDrafts: boolean; + /** + * A boolean indicating whether the thread is starred or not. + */ + starred: boolean; + /** + * A boolean indicating if all messages within the thread are read or not. + */ + unread: boolean; + /** + * Unix timestamp of the earliest or first message in the thread. + */ + earliestMessageDate: number; + /** + * Unix timestamp of the most recent message received in the thread. + */ + latestMessageReceivedDate?: number; + /** + * Unix timestamp of the most recent message sent in the thread. + */ + latestMessageSentDate?: number; + /** + * An array of participants in the thread. + */ + participants: EmailName[]; + /** + * An array of message IDs in the thread. + */ + messageIds: string[]; + /** + * An array of draft IDs in the thread. + */ + draftIds: string[]; + /** + * An array of folder IDs the thread appears in. + */ + folders: string[]; + /** + * The type of object. + */ + object: 'thread'; + /** + * A short snippet of the last received message/draft body. + * This is the first 100 characters of the message body, with any HTML tags removed. + */ + snippet?: string; + /** + * The subject line of the thread. + */ + subject?: string; +} + +/** + * Interface representing a request to update a thread. + */ +export interface UpdateThreadRequest { + /** + * Sets all messages in the thread as starred or unstarred. + */ + starred?: boolean; + /** + * Sets all messages in the thread as read or unread. + */ + unread?: boolean; + /** + * The IDs of the folders to apply, overwriting all previous folders for all messages in the thread. + */ + folders?: string[]; +} + +/** + * Interface representing the query parameters for listing drafts. + */ +export interface ListThreadsQueryParams extends ListQueryParams { + /** + * Return items with a matching literal subject. + */ + subject?: string; + /** + * Return threads that contain messages that have been sent or received from this list of email addresses. + */ + anyEmail?: string[]; + /** + * Return threads containing messages sent to these email address. + */ + to?: string[]; + /** + * Return threads containing messages sent from these email address. + */ + from?: string[]; + /** + * Return threads containing messages cc'd on these email address. + */ + cc?: string[]; + /** + * Return threads containing messages bcc'd on these email address. + */ + bcc?: string[]; + /** + * Return threads with messages that belong to these specified folder IDs. + */ + in?: string[]; + /** + * Return threads with unread messages. + */ + unread?: boolean; + /** + * Return threads with starred messages. + */ + starred?: boolean; + /** + * Return threads whose most recent message was received before this Unix timestamp. + */ + latestMessageBefore?: number; + /** + * Return threads whose most recent message was received after this Unix timestamp. + */ + latestMessageAfter?: number; + /** + * Return threads with messages that contain attachments. + */ + hasAttachment?: boolean; + /** + * The provider-specific query string used to search threads. + * Available for Google only. + */ + searchQueryNative?: string; +} diff --git a/src/models/webhooks.ts b/src/models/webhooks.ts new file mode 100644 index 00000000..8940b71e --- /dev/null +++ b/src/models/webhooks.ts @@ -0,0 +1,169 @@ +/** + * Interface representing a Nylas Webhook object. + */ +export interface Webhook { + /** + * Globally unique object identifier. + */ + id: string; + /** + * List of events that triggers the webhook. + */ + triggerTypes: WebhookTriggers[]; + /** + * The url to send webhooks to. + */ + webhookUrl: string; + /** + * The status of the new destination. + */ + status: WebhookStatus; + /** + * The time the status field was last updated, represented as a Unix timestamp in seconds. + */ + statusUpdatedAt: number; + /** + * The time the status field was created, represented as a Unix timestamp in seconds + */ + createdAt: number; + /** + * The time the status field was last updated, represented as a Unix timestamp in seconds. + */ + updatedAt: number; + /** + * A human-readable description of the webhook destination. + */ + description?: string; + /** + * The email addresses that Nylas notifies when a webhook is down for a while. + */ + notificationEmailAddresses?: string[]; +} + +/** + * Class representing a Nylas webhook with secret. + */ +export interface WebhookWithSecret extends Webhook { + /** + * A secret value used to encode the X-Nylas-Signature header on webhook requests. + */ + webhookSecret: string; +} + +/** + * Class representing a Nylas webhook delete response. + */ +export interface WebhookDeleteResponse { + /** + * ID of the request. + */ + requestId: string; + /** + * Object containing the webhook deletion status. + */ + data?: { + /** + * The status of the webhook deletion. + */ + status: 'success'; + }; +} + +/** + * Class representing the response for getting a list of webhook ip addresses. + */ +export interface WebhookIpAddressesResponse { + /** + * The IP addresses that Nylas send you webhook from. + */ + ipAddresses: string[]; + /** + * UNIX timestamp when Nylas updated the list of IP addresses. + */ + updatedAt: number; +} + +/** + * Class representation of a Nylas create webhook request. + */ +export interface CreateWebhookRequest { + /** + * List of events that triggers the webhook. + */ + triggerTypes: WebhookTriggers[]; + /** + * The url to send webhooks to. + */ + webhookUrl: string; + /** + * A human-readable description of the webhook destination. + */ + description?: string; + /** + * The email addresses that Nylas notifies when a webhook is down for a while. + */ + notificationEmailAddresses?: string[]; +} + +/** + * Class representation of a Nylas update webhook request. + */ +export type UpdateWebhookRequest = Partial; + +/** + * Enum representing the available webhook triggers. + */ +export enum WebhookTriggers { + // Calendar triggers + CalendarCreated = 'calendar.created', + CalendarUpdated = 'calendar.updated', + CalendarDeleted = 'calendar.deleted', + + // Event triggers + EventCreated = 'event.created', + EventUpdated = 'event.updated', + EventDeleted = 'event.deleted', + + // Grant triggers + GrantCreated = 'grant.created', + GrantUpdated = 'grant.updated', + GrantDeleted = 'grant.deleted', + GrantExpired = 'grant.expired', + + // Message triggers + MessageCreated = 'message.created', + MessageUpdated = 'message.updated', + MessageSendSuccess = 'message.send_success', + MessageSendFailed = 'message.send_failed', + MessageBounceDetected = 'message.bounce_detected', + + // Message tracking triggers + MessageOpened = 'message.opened', + MessageLinkClicked = 'message.link_clicked', + ThreadReplied = 'thread.replied', + + // ExtractAI triggers + MessageIntelligenceOrder = 'message.intelligence.order', + MessageIntelligenceTracking = 'message.intelligence.tracking', + + // Folder triggers + FolderCreated = 'folder.created', + FolderUpdated = 'folder.updated', + FolderDeleted = 'folder.deleted', + + // Contact triggers + ContactUpdated = 'contact.updated', + ContactDeleted = 'contact.deleted', + + // Scheduler triggers + BookingCreated = 'booking.created', + BookingPending = 'booking.pending', + BookingRescheduled = 'booking.rescheduled', + BookingCancelled = 'booking.cancelled', + BookingReminder = 'booking.reminder', +} + +/** + * Enum representing the available webhook statuses. + */ +export type WebhookStatus = 'active' | 'failing' | 'failed' | 'pause'; diff --git a/src/nylas-connection.js b/src/nylas-connection.js deleted file mode 100644 index beb4a7bb..00000000 --- a/src/nylas-connection.js +++ /dev/null @@ -1,167 +0,0 @@ -import _ from 'underscore'; -import clone from 'clone'; -import request from 'request'; -import Promise from 'bluebird'; - -import RestfulModel from './models/restful-model'; -import RestfulModelCollection from './models/restful-model-collection'; -import RestfulModelInstance from './models/restful-model-instance'; -import Account from './models/account'; -import ManagementAccount from './models/management-account'; -import ManagementModelCollection from './models/management-model-collection'; -import Thread from './models/thread'; -import Contact from './models/contact'; -import Message from './models/message'; -import Draft from './models/draft'; -import File from './models/file'; -import Calendar from './models/calendar'; -import Event from './models/event'; -import Delta from './models/delta'; -import { Label, Folder } from './models/folder'; - -const PACKAGE_JSON = require('../package.json'); -const SDK_VERSION = PACKAGE_JSON.version; -const SUPPORTED_API_VERSION = '2.0'; - -module.exports = class NylasConnection { - constructor(accessToken) { - this.accessToken = accessToken; - this.threads = new RestfulModelCollection(Thread, this); - this.contacts = new RestfulModelCollection(Contact, this); - this.messages = new RestfulModelCollection(Message, this); - this.drafts = new RestfulModelCollection(Draft, this); - this.files = new RestfulModelCollection(File, this); - this.calendars = new RestfulModelCollection(Calendar, this); - this.events = new RestfulModelCollection(Event, this); - this.deltas = new Delta(this); - this.labels = new RestfulModelCollection(Label, this); - this.folders = new RestfulModelCollection(Folder, this); - this.account = new RestfulModelInstance(Account, this); - } - - requestOptions(options) { - if (!options) { - options = {}; - } - options = clone(options); - const Nylas = require('./nylas'); - if (!options.method) { - options.method = 'GET'; - } - if (options.path) { - if (!options.url) { - options.url = `${Nylas.apiServer}${options.path}`; - } - } - if (!options.formData) { - if (!options.body) { - options.body = {}; - } - } - if (options.json == null) { - options.json = true; - } - if (!options.downloadRequest) { - options.downloadRequest = false; - } - - // For convenience, If `expanded` param is provided, convert to view: - // 'expanded' api option - if (options.qs && options.qs.expanded) { - if (options.qs.expanded === true) { - options.qs.view = 'expanded'; - } - delete options.qs.expanded; - } - - const user = - options.path.substr(0, 3) === '/a/' ? Nylas.appSecret : this.accessToken; - - if (user) { - options.auth = { - user: user, - pass: '', - sendImmediately: true, - }; - } - - if (options.headers == null) { - options.headers = {}; - } - if (options.headers['User-Agent'] == null) { - options.headers['User-Agent'] = `Nylas Node SDK v${SDK_VERSION}`; - } - - options.headers['Nylas-SDK-API-Version'] = SUPPORTED_API_VERSION; - - return options; - } - _getWarningForVersion(sdkApiVersion = null, apiVersion = null) { - let warning = ''; - - if (sdkApiVersion != apiVersion) { - if (sdkApiVersion && apiVersion) { - warning += - `WARNING: SDK version may not support your Nylas API version.` + - ` SDK supports version ${sdkApiVersion} of the API and your application` + - ` is currently running on version ${apiVersion} of the API.`; - - const apiNum = parseInt(apiVersion.split('-')[0]); - const sdkNum = parseInt(sdkApiVersion.split('-')[0]); - - if (sdkNum > apiNum) { - warning += ` Please update the version of the API that your application is using through the developer dashboard.`; - } else if (apiNum > sdkNum) { - warning += ` Please update the sdk to ensure it works properly.`; - } - } - } - return warning; - } - request(options) { - if (!options) { - options = {}; - } - options = this.requestOptions(options); - - return new Promise((resolve, reject) => { - return request(options, (error, response, body = {}) => { - // node headers are lowercase so this refers to `Nylas-Api-Version` - const apiVersion = response.headers['nylas-api-version']; - - const warning = this._getWarningForVersion( - SUPPORTED_API_VERSION, - apiVersion - ); - if (warning) { - console.warn(warning); - } - - // raw MIMI emails have json === false and the body is a string so - // we need to turn into JSON before we can access fields - if (options.json === false) { - body = JSON.parse(body); - } - - if (error || response.statusCode > 299) { - if (!error) { - error = new Error(body.message); - } - if (body.server_error) { - error = `${error.message} (Server Error: ${body.server_error})`; - } - if (response.statusCode) { - error.statusCode = response.statusCode; - } - return reject(error); - } else { - if (options.downloadRequest) { - return resolve(response); - } else { - return resolve(body); - } - } - }); - }); - } -}; diff --git a/src/nylas.js b/src/nylas.js deleted file mode 100644 index 85ee3f55..00000000 --- a/src/nylas.js +++ /dev/null @@ -1,130 +0,0 @@ -import _ from 'underscore'; -import request from 'request'; -import Promise from 'bluebird'; - -import NylasConnection from './nylas-connection'; -import ManagementAccount from './models/management-account'; -import Account from './models/account'; -import RestfulModelCollection from './models/restful-model-collection'; -import ManagementModelCollection from './models/management-model-collection'; - -class Nylas { - constructor() { - this.appId = null; - this.appSecret = null; - } - - static config({ appId, appSecret, apiServer }) { - if (apiServer && apiServer.indexOf('://') === -1) { - throw new Error( - 'Please specify a fully qualified URL for the API Server.' - ); - } - - if (appId) { - this.appId = appId; - } - if (appSecret) { - this.appSecret = appSecret; - } - if (apiServer) { - this.apiServer = apiServer; - } - - let conn; - if (this.hostedAPI()) { - conn = new NylasConnection(this.appSecret); - this.accounts = new ManagementModelCollection( - ManagementAccount, - conn, - this.appId - ); - } else { - conn = new NylasConnection(this.appSecret); - this.accounts = new RestfulModelCollection(Account, conn, this.appId); - } - - return this; - } - - static hostedAPI() { - return this.appId != null && this.appSecret != null; - } - - static with(accessToken) { - if (!accessToken) { - throw new Error('This function requires an access token'); - } - return new NylasConnection(accessToken); - } - - static exchangeCodeForToken(code, callback) { - if (!this.appId || !this.appSecret) { - throw new Error( - 'exchangeCodeForToken() cannot be called until you provide an appId and secret via config()' - ); - } - if (!code) { - throw new Error('exchangeCodeForToken() must be called with a code'); - } - - return new Promise((resolve, reject) => { - const options = { - method: 'GET', - json: true, - url: `${this.apiServer}/oauth/token`, - qs: { - client_id: this.appId, - client_secret: this.appSecret, - grant_type: 'authorization_code', - code: code, - }, - }; - - return request(options, (error, response, body) => { - if (error) { - reject(error); - if (callback) { - return callback(error); - } - } else { - resolve(body['access_token']); - if (callback) { - return callback(null, body['access_token']); - } - } - }); - }); - } - - static urlForAuthentication(options = {}) { - if (!this.appId) { - throw new Error( - 'urlForAuthentication() cannot be called until you provide an appId via config()' - ); - } - if (!options.redirectURI) { - throw new Error('urlForAuthentication() requires options.redirectURI'); - } - if (!options.loginHint) { - options.loginHint = ''; - } - let url = `${this.apiServer}/oauth/authorize?client_id=${ - this.appId - }&response_type=code&login_hint=${ - options.loginHint - }&redirect_uri=${options.redirectURI}`; - if (options.state != null) { - url += `&state=${options.state}`; - } - if (options.scopes != null) { - url += `&scopes=${options.scopes.join(',')}`; - } - return url; - } -} -Nylas.apiServer = 'https://api.nylas.com'; - -// We keep the old `module.exports` syntax for now to ensure that people using -// `require` don't have to use `.default` to use this package -module.exports = Nylas; diff --git a/src/nylas.ts b/src/nylas.ts new file mode 100644 index 00000000..ef1dac5e --- /dev/null +++ b/src/nylas.ts @@ -0,0 +1,126 @@ +export * from './models/index.js'; + +import APIClient from './apiClient.js'; +import { NylasConfig, DEFAULT_SERVER_URL } from './config.js'; +import { Calendars } from './resources/calendars.js'; +import { Events } from './resources/events.js'; +import { Auth } from './resources/auth.js'; +import { Webhooks } from './resources/webhooks.js'; +import { Applications } from './resources/applications.js'; +import { Messages } from './resources/messages.js'; +import { Drafts } from './resources/drafts.js'; +import { Threads } from './resources/threads.js'; +import { Connectors } from './resources/connectors.js'; +import { Folders } from './resources/folders.js'; +import { Grants } from './resources/grants.js'; +import { Contacts } from './resources/contacts.js'; +import { Attachments } from './resources/attachments.js'; +import { Scheduler } from './resources/scheduler.js'; +import { Notetakers } from './resources/notetakers.js'; + +/** + * The entry point to the Node SDK + * + * A Nylas instance holds a configured http client pointing to a base URL and is intended to be reused and shared + * across threads and time. + */ +class Nylas { + /** + * Access the Applications API + */ + public applications: Applications; + /** + * Access the Attachments API + */ + public attachments: Attachments; + /** + * Access the Auth API + */ + public auth: Auth; + /** + * Access the Calendars API + */ + public calendars: Calendars; + /** + * Access the Connectors API + */ + public connectors: Connectors; + /** + * Access the Contacts API + */ + public contacts: Contacts; + /** + * Access the Drafts API + */ + public drafts: Drafts; + /** + * Access the Events API + */ + public events: Events; + /** + * Access the Grants API + */ + public grants: Grants; + /** + * Access the Messages API + */ + public messages: Messages; + /** + * Access the Notetakers API + */ + public notetakers: Notetakers; + /** + * Access the Threads API + */ + public threads: Threads; + /** + * Access the Webhooks API + */ + public webhooks: Webhooks; + /** + * Access the Folders API + */ + public folders: Folders; + /** + * Access the scheduler API + */ + public scheduler: Scheduler; + + /** + * The configured API client + * @ignore Not for public use + */ + apiClient: APIClient; + + /** + * @param config Configuration options for the Nylas SDK + */ + constructor(config: NylasConfig) { + this.apiClient = new APIClient({ + apiKey: config.apiKey, + apiUri: config.apiUri || DEFAULT_SERVER_URL, + timeout: config.timeout || 90, + headers: config.headers || {}, + }); + + this.applications = new Applications(this.apiClient); + this.auth = new Auth(this.apiClient); + this.calendars = new Calendars(this.apiClient); + this.connectors = new Connectors(this.apiClient); + this.drafts = new Drafts(this.apiClient); + this.events = new Events(this.apiClient); + this.grants = new Grants(this.apiClient); + this.messages = new Messages(this.apiClient); + this.notetakers = new Notetakers(this.apiClient); + this.threads = new Threads(this.apiClient); + this.webhooks = new Webhooks(this.apiClient); + this.folders = new Folders(this.apiClient); + this.contacts = new Contacts(this.apiClient); + this.attachments = new Attachments(this.apiClient); + this.scheduler = new Scheduler(this.apiClient); + + return this; + } +} + +export default Nylas; diff --git a/src/resources/applications.ts b/src/resources/applications.ts new file mode 100644 index 00000000..c1136f5d --- /dev/null +++ b/src/resources/applications.ts @@ -0,0 +1,40 @@ +import { Resource } from './resource.js'; +import { RedirectUris } from './redirectUris.js'; +import APIClient from '../apiClient.js'; +import { ApplicationDetails } from '../models/applicationDetails.js'; +import { NylasResponse } from '../models/response.js'; +import { Overrides } from '../config.js'; +import { makePathParams } from '../utils.js'; + +/** + * Nylas Applications API + * + * This endpoint allows for getting application details as well as redirect URI operations. + */ +export class Applications extends Resource { + /** + * Access the collection of redirect URI related API endpoints. + */ + public redirectUris: RedirectUris; + + /** + * @param apiClient client The configured Nylas API client + */ + constructor(apiClient: APIClient) { + super(apiClient); + this.redirectUris = new RedirectUris(apiClient); + } + + /** + * Get application details + * @returns The application details + */ + public getDetails({ overrides }: Overrides = {}): Promise< + NylasResponse + > { + return super._find({ + path: makePathParams('/v3/applications', {}), + overrides, + }); + } +} diff --git a/src/resources/attachments.ts b/src/resources/attachments.ts new file mode 100644 index 00000000..7296e3c8 --- /dev/null +++ b/src/resources/attachments.ts @@ -0,0 +1,112 @@ +import { Overrides } from '../config.js'; +import { + Attachment, + FindAttachmentQueryParams, + DownloadAttachmentQueryParams, +} from '../models/attachments.js'; +import { NylasResponse } from '../models/response.js'; +import { makePathParams } from '../utils.js'; +import { Resource } from './resource.js'; + +/** + * @property identifier The ID of the grant to act upon. Use "me" to refer to the grant associated with an access token. + * @property attachmentId The ID of the attachment to act upon. + * @property queryParams The query parameters to include in the request + */ +interface FindAttachmentParams { + identifier: string; + attachmentId: string; + queryParams: FindAttachmentQueryParams; +} + +/** + * @property identifier The ID of the grant to act upon. Use "me" to refer to the grant associated with an access token. + * @property attachmentId The ID of the attachment to act upon. + * @property queryParams The query parameters to include in the request + */ +interface DownloadAttachmentParams { + identifier: string; + attachmentId: string; + queryParams: DownloadAttachmentQueryParams; +} + +/** + * Nylas Attachments API + * + * The Nylas Attachments API allows you to retrieve metadata and download attachments. + */ +export class Attachments extends Resource { + /** + * Returns an attachment by ID. + * @return The Attachment metadata + */ + public find({ + identifier, + attachmentId, + queryParams, + overrides, + }: FindAttachmentParams & Overrides): Promise> { + return super._find({ + path: makePathParams( + '/v3/grants/{identifier}/attachments/{attachmentId}', + { identifier, attachmentId } + ), + queryParams, + overrides, + }); + } + + /** + * Download the attachment data + * + * This method returns a NodeJS.ReadableStream which can be used to stream the attachment data. + * This is particularly useful for handling large attachments efficiently, as it avoids loading + * the entire file into memory. The stream can be piped to a file stream or used in any other way + * that Node.js streams are typically used. + * + * @param identifier Grant ID or email account to query + * @param attachmentId The id of the attachment to download. + * @param queryParams The query parameters to include in the request + * @returns {NodeJS.ReadableStream} The ReadableStream containing the file data. + */ + public download({ + identifier, + attachmentId, + queryParams, + overrides, + }: DownloadAttachmentParams & Overrides): Promise< + ReadableStream + > { + return this._getStream({ + path: makePathParams( + '/v3/grants/{identifier}/attachments/{attachmentId}/download', + { identifier, attachmentId } + ), + queryParams, + overrides, + }); + } + + /** + * Download the attachment as a byte array + * @param identifier Grant ID or email account to query + * @param attachmentId The id of the attachment to download. + * @param queryParams The query parameters to include in the request + * @return The raw file data + */ + public downloadBytes({ + identifier, + attachmentId, + queryParams, + overrides, + }: DownloadAttachmentParams & Overrides): Promise { + return super._getRaw({ + path: makePathParams( + '/v3/grants/{identifier}/attachments/{attachmentId}/download', + { identifier, attachmentId } + ), + queryParams, + overrides, + }); + } +} diff --git a/src/resources/auth.ts b/src/resources/auth.ts new file mode 100644 index 00000000..d46f1a80 --- /dev/null +++ b/src/resources/auth.ts @@ -0,0 +1,237 @@ +import { v4 as uuid } from 'uuid'; +import { createHash } from 'node:crypto'; +import { Resource } from './resource.js'; +import { + URLForAdminConsentConfig, + URLForAuthenticationConfig, + CodeExchangeRequest, + PKCEAuthURL, + TokenExchangeRequest, + CodeExchangeResponse, + ProviderDetectParams, + ProviderDetectResponse, + TokenInfoResponse, +} from '../models/auth.js'; +import { Overrides } from '../config.js'; +import { NylasResponse } from '../models/response.js'; +import { CreateGrantRequest, Grant } from '../models/grants.js'; +import { makePathParams } from '../utils.js'; + +/** + * @property requestBody The values to create the Grant with. + */ +interface CreateGrantParams { + requestBody: CreateGrantRequest; +} + +/** + * A collection of authentication related API endpoints + * + * These endpoints allow for various functionality related to authentication. + * Also contains the Grants API and collection of provider API endpoints. + */ +export class Auth extends Resource { + /** + * Build the URL for authenticating users to your application with OAuth 2.0 + * @param config The configuration for building the URL + * @return The URL for hosted authentication + */ + public urlForOAuth2(config: URLForAuthenticationConfig): string { + return this.urlAuthBuilder(config).toString(); + } + + /** + * Exchange an authorization code for an access token + * @param request The request parameters for the code exchange + * @return Information about the Nylas application + */ + public exchangeCodeForToken( + request: CodeExchangeRequest + ): Promise { + if (!request.clientSecret) { + request.clientSecret = this.apiClient.apiKey; + } + + return this.apiClient.request({ + method: 'POST', + path: makePathParams('/v3/connect/token', {}), + body: { + ...request, + grantType: 'authorization_code', + }, + }); + } + + /** + * Refresh an access token + * @param request The refresh token request + * @return The response containing the new access token + */ + public refreshAccessToken( + request: TokenExchangeRequest + ): Promise { + if (!request.clientSecret) { + request.clientSecret = this.apiClient.apiKey; + } + + return this.apiClient.request({ + method: 'POST', + path: makePathParams('/v3/connect/token', {}), + body: { + ...request, + grantType: 'refresh_token', + }, + }); + } + + /** + * Build the URL for authenticating users to your application with OAuth 2.0 and PKCE + * IMPORTANT: YOU WILL NEED TO STORE THE 'secret' returned to use it inside the CodeExchange flow + * @param config The configuration for building the URL + * @return The URL for hosted authentication + */ + public urlForOAuth2PKCE(config: URLForAuthenticationConfig): PKCEAuthURL { + const url = this.urlAuthBuilder(config); + + // Add code challenge to URL generation + url.searchParams.set('code_challenge_method', 's256'); + const secret = uuid(); + const secretHash = this.hashPKCESecret(secret); + url.searchParams.set('code_challenge', secretHash); + // Return the url with secret & hashed secret + return { secret, secretHash, url: url.toString() }; + } + + /** + * Build the URL for admin consent authentication for Microsoft + * @param config The configuration for building the URL + * @return The URL for admin consent authentication + */ + public urlForAdminConsent(config: URLForAdminConsentConfig): string { + const configWithProvider = { ...config, provider: 'microsoft' }; + const url = this.urlAuthBuilder(configWithProvider); + url.searchParams.set('response_type', 'adminconsent'); + url.searchParams.set('credential_id', config.credentialId); + return url.toString(); + } + + /** + * Create a grant via Custom Authentication + * @return The created grant + */ + public customAuthentication({ + requestBody, + overrides, + }: CreateGrantParams & Overrides): Promise> { + return this.apiClient.request>({ + method: 'POST', + path: makePathParams('/v3/connect/custom', {}), + body: requestBody, + overrides, + }); + } + + /** + * Revoke a token (and the grant attached to the token) + * @param token The token to revoke + * @return True if the token was revoked successfully + */ + public async revoke(token: string): Promise { + await this.apiClient.request({ + method: 'POST', + path: makePathParams('/v3/connect/revoke', {}), + queryParams: { + token, + }, + }); + + return true; + } + + /** + * Detect provider from email address + * @param params The parameters to include in the request + * @return The detected provider, if found + */ + public async detectProvider( + params: ProviderDetectParams + ): Promise> { + return this.apiClient.request>({ + method: 'POST', + path: makePathParams('/v3/providers/detect', {}), + queryParams: params, + }); + } + + /** + * Get info about an ID token + * @param idToken The ID token to query. + * @return The token information + */ + public idTokenInfo( + idToken: string + ): Promise> { + return this.getTokenInfo({ id_token: idToken }); + } + + /** + * Get info about an access token + * @param accessToken The access token to query. + * @return The token information + */ + public accessTokenInfo( + accessToken: string + ): Promise> { + return this.getTokenInfo({ access_token: accessToken }); + } + + private urlAuthBuilder(config: Record): URL { + const url = new URL(`${this.apiClient.serverUrl}/v3/connect/auth`); + url.searchParams.set('client_id', config.clientId); + url.searchParams.set('redirect_uri', config.redirectUri); + url.searchParams.set( + 'access_type', + config.accessType ? config.accessType : 'online' + ); + url.searchParams.set('response_type', 'code'); + if (config.provider) { + url.searchParams.set('provider', config.provider); + } + if (config.loginHint) { + url.searchParams.set('login_hint', config.loginHint); + } + if (config.includeGrantScopes !== undefined) { + url.searchParams.set( + 'include_grant_scopes', + config.includeGrantScopes.toString() + ); + } + if (config.scope) { + url.searchParams.set('scope', config.scope.join(' ')); + } + if (config.prompt) { + url.searchParams.set('prompt', config.prompt); + } + if (config.state) { + url.searchParams.set('state', config.state); + } + + return url; + } + + private hashPKCESecret(secret: string): string { + const hash = createHash('sha256').update(secret).digest('hex'); + + return Buffer.from(hash).toString('base64').replace(/=+$/, ''); + } + + private getTokenInfo( + params: Record + ): Promise> { + return this.apiClient.request>({ + method: 'GET', + path: makePathParams('/v3/connect/tokeninfo', {}), + queryParams: params, + }); + } +} diff --git a/src/resources/bookings.ts b/src/resources/bookings.ts new file mode 100644 index 00000000..cfe29315 --- /dev/null +++ b/src/resources/bookings.ts @@ -0,0 +1,173 @@ +import { Overrides } from '../config.js'; +import { NylasBaseResponse, NylasResponse } from '../models/response.js'; +import { + Booking, + ConfirmBookingQueryParams, + ConfirmBookingRequest, + CreateBookingQueryParams, + CreateBookingRequest, + DeleteBookingRequest, + DestroyBookingQueryParams, + FindBookingQueryParams, + RescheduleBookingQueryParams, + RescheduleBookingRequest, +} from '../models/scheduler.js'; +import { makePathParams } from '../utils.js'; +import { Resource } from './resource.js'; + +/** + * The parameters for the {@link Bookings.find} method + * @property bookingId The id of the Booking to retrieve. Use "primary" to refer to the primary booking associated with grant. + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ +export interface FindBookingParams { + bookingId: string; + queryParams?: FindBookingQueryParams; +} + +/** + * The parameters for the {@link Bookings.create} method + * @property identifier The identifier of the grant to act upon + * @property requestBody The request body to create a booking + * @property queryParams The query parameters to include in the request + */ +export interface CreateBookingParams { + requestBody: CreateBookingRequest; + queryParams?: CreateBookingQueryParams; +} + +/** + * The parameters for the {@link Bookings.confirm} method + * @property identifier The identifier of the grant to act upon + * @property bookingId The id of the Booking to retrieve. Use "primary" to refer to the primary booking associated with grant. + * @property requestBody The values to confirm the Booking with + * @property queryParams The query parameters to include in the request + */ +export interface ConfirmBookingParams { + bookingId: string; + requestBody: ConfirmBookingRequest; + queryParams?: ConfirmBookingQueryParams; +} + +/** + * The parameters for the {@link Bookings.reschedule} method + * @property identifier The identifier of the grant to act upon + * @property bookingId The id of the Booking to retrieve. Use "primary" to refer to the primary booking associated with grant. + * @property requestBody The values to reschedule the Booking with + * @property queryParams The query parameters to include in the request + */ +export interface RescheduleBookingParams { + bookingId: string; + requestBody: RescheduleBookingRequest; + queryParams?: RescheduleBookingQueryParams; +} + +/** + * The parameters for the {@link Bookings.destroy} method + * @property identifier The identifier of the grant to act upon + * @property bookingId The id of the Booking to retrieve. Use "primary" to refer to the primary booking associated with grant. + * @property queryParams The query parameters to include in the request + */ +export interface DestroyBookingParams { + bookingId: string; + requestBody?: DeleteBookingRequest; + queryParams?: DestroyBookingQueryParams; +} + +export class Bookings extends Resource { + /** + * Return a Booking + * @return The booking + */ + public find({ + bookingId, + queryParams, + overrides, + }: FindBookingParams & Overrides): Promise> { + return super._find({ + path: makePathParams('/v3/scheduling/bookings/{bookingId}', { + bookingId, + }), + queryParams, + overrides, + }); + } + + /** + * Create a Booking + * @return The created booking + */ + public create({ + requestBody, + queryParams, + overrides, + }: CreateBookingParams & Overrides): Promise> { + return super._create({ + path: makePathParams('/v3/scheduling/bookings', {}), + requestBody, + queryParams, + overrides, + }); + } + + /** + * Confirm a Booking + * @return The confirmed Booking + */ + public confirm({ + bookingId, + requestBody, + queryParams, + overrides, + }: ConfirmBookingParams & Overrides): Promise> { + return super._update({ + path: makePathParams('/v3/scheduling/bookings/{bookingId}', { + bookingId, + }), + requestBody, + queryParams, + overrides, + }); + } + + /** + * Reschedule a Booking + * @return The rescheduled Booking + */ + public reschedule({ + bookingId, + requestBody, + queryParams, + overrides, + }: RescheduleBookingParams & Overrides): Promise> { + return super._updatePatch({ + path: makePathParams('/v3/scheduling/bookings/{bookingId}', { + bookingId, + }), + requestBody, + queryParams, + overrides, + }); + } + + /** + * Delete a Booking + * @return The deleted Booking + */ + public destroy({ + bookingId, + requestBody, + queryParams, + overrides, + }: DestroyBookingParams & Overrides): Promise { + return super._destroy({ + path: makePathParams('/v3/scheduling/bookings/{bookingId}', { + bookingId, + }), + requestBody, + queryParams, + overrides, + }); + } +} diff --git a/src/resources/calendars.ts b/src/resources/calendars.ts new file mode 100644 index 00000000..ea330089 --- /dev/null +++ b/src/resources/calendars.ts @@ -0,0 +1,225 @@ +import { Overrides } from '../config.js'; +import { + Calendar, + CreateCalenderRequest, + ListCalendersQueryParams, + UpdateCalenderRequest, +} from '../models/calendars.js'; +import { + NylasBaseResponse, + NylasResponse, + NylasListResponse, +} from '../models/response.js'; +import { Resource, AsyncListResponse } from './resource.js'; +import { + GetAvailabilityRequest, + GetAvailabilityResponse, +} from '../models/availability.js'; +import { GetFreeBusyRequest, GetFreeBusyResponse } from '../models/freeBusy.js'; +import { makePathParams } from '../utils.js'; + +/** + * The parameters for the {@link Calendars.find} method + * @property calendarId The id of the Calendar to retrieve. Use "primary" to refer to the primary calendar associated with grant. + * @property identifier The identifier of the grant to act upon + */ +export interface FindCalendarParams { + identifier: string; + calendarId: string; +} + +/** + * The parameters for the {@link Calendars.list} method + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ +export interface ListCalendersParams { + identifier: string; + queryParams?: ListCalendersQueryParams; +} + +/** + * The parameters for the {@link Calendars.create} method + * @property identifier The identifier of the grant to act upon + * @property requestBody The request body to create a calendar + */ +export interface CreateCalendarParams { + identifier: string; + requestBody: CreateCalenderRequest; +} + +/** + * The parameters for the {@link Calendars.update} method + * @property identifier The identifier of the grant to act upon + * @property calendarId The id of the Calendar to retrieve. Use "primary" to refer to the primary calendar associated with grant. + */ +export interface UpdateCalendarParams { + identifier: string; + calendarId: string; + requestBody: UpdateCalenderRequest; +} + +/** + * The parameters for the {@link Calendars.destroy} method + * @property identifier The identifier of the grant to act upon + * @property calendarId The id of the Calendar to retrieve. Use "primary" to refer to the primary calendar associated with grant. + */ +export interface DestroyCalendarParams { + identifier: string; + calendarId: string; +} + +/** + * The parameters for the {@link Calendars.getAvailability} method + * @property requestBody The availability request + */ +export interface GetAvailabilityParams { + requestBody: GetAvailabilityRequest; +} + +/** + * The parameters for the {@link Calendars.getFreeBusy} method + * @property identifier The identifier of the grant to act upon + * @property requestBody The free busy request + */ +export interface GetFreeBusyParams { + identifier: string; + requestBody: GetFreeBusyRequest; +} + +/** + * Nylas Calendar API + * + * The Nylas calendar API allows you to create new calendars or manage existing ones. + * A calendar can be accessed by one, or several people, and can contain events. + */ +export class Calendars extends Resource { + /** + * Return all Calendars + * @return A list of calendars + */ + public list({ + identifier, + queryParams, + overrides, + }: ListCalendersParams & + ListCalendersQueryParams & + Overrides): AsyncListResponse> { + return super._list>({ + queryParams, + overrides, + path: makePathParams('/v3/grants/{identifier}/calendars', { identifier }), + }); + } + + /** + * Return a Calendar + * @return The calendar + */ + public find({ + identifier, + calendarId, + overrides, + }: FindCalendarParams & Overrides): Promise> { + return super._find({ + path: makePathParams('/v3/grants/{identifier}/calendars/{calendarId}', { + identifier, + calendarId, + }), + overrides, + }); + } + + /** + * Create a Calendar + * @return The created calendar + */ + public create({ + identifier, + requestBody, + overrides, + }: CreateCalendarParams & Overrides): Promise> { + return super._create({ + path: makePathParams('/v3/grants/{identifier}/calendars', { identifier }), + requestBody, + overrides, + }); + } + + /** + * Update a Calendar + * @return The updated Calendar + */ + public update({ + calendarId, + identifier, + requestBody, + overrides, + }: UpdateCalendarParams & Overrides): Promise> { + return super._update({ + path: makePathParams('/v3/grants/{identifier}/calendars/{calendarId}', { + identifier, + calendarId, + }), + requestBody, + overrides, + }); + } + + /** + * Delete a Calendar + * @return The deleted Calendar + */ + public destroy({ + identifier, + calendarId, + overrides, + }: DestroyCalendarParams & Overrides): Promise { + return super._destroy({ + path: makePathParams('/v3/grants/{identifier}/calendars/{calendarId}', { + identifier, + calendarId, + }), + overrides, + }); + } + + /** + * Get Availability for a given account / accounts + * @return The availability response + */ + public getAvailability({ + requestBody, + overrides, + }: GetAvailabilityParams & Overrides): Promise< + NylasResponse + > { + return this.apiClient.request>({ + method: 'POST', + path: makePathParams('/v3/calendars/availability', {}), + body: requestBody, + overrides, + }); + } + + /** + * Get the free/busy schedule for a list of email addresses + * @return The free/busy response + */ + public getFreeBusy({ + identifier, + requestBody, + overrides, + }: GetFreeBusyParams & Overrides): Promise< + NylasResponse + > { + return this.apiClient.request>({ + method: 'POST', + path: makePathParams('/v3/grants/{identifier}/calendars/free-busy', { + identifier, + }), + body: requestBody, + overrides, + }); + } +} diff --git a/src/resources/configurations.ts b/src/resources/configurations.ts new file mode 100644 index 00000000..6ba5ab9b --- /dev/null +++ b/src/resources/configurations.ts @@ -0,0 +1,178 @@ +import { AsyncListResponse, Resource } from './resource.js'; +import { + CreateConfigurationRequest, + UpdateConfigurationRequest, + Configuration, +} from '../models/scheduler.js'; +import { Overrides } from '../config.js'; +import { + NylasBaseResponse, + NylasListResponse, + NylasResponse, +} from '../models/response.js'; +import { makePathParams } from '../utils.js'; + +/** + * The parameters for the {@link Configurations.find} method + * @property configurationId The id of the Configuration to retrieve. Use "primary" to refer to the primary configuration associated with grant. + * @property identifier The identifier of the grant to act upon + */ +export interface FindConfigurationParams { + identifier: string; + configurationId: string; +} + +/** + * The parameters for the {@link Configurations.list} method + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ +export interface ListConfigurationsParams { + identifier: string; +} + +/** + * The parameters for the {@link Configurations.create} method + * @property identifier The identifier of the grant to act upon + * @property requestBody The request body to create a configuration + */ +export interface CreateConfigurationParams { + identifier: string; + requestBody: CreateConfigurationRequest; +} + +/** + * The parameters for the {@link Configurations.update} method + * @property identifier The identifier of the grant to act upon + * @property configurationId The id of the Configuration to retrieve. Use "primary" to refer to the primary configuration associated with grant. + */ +export interface UpdateConfigurationParams { + identifier: string; + configurationId: string; + requestBody: UpdateConfigurationRequest; +} + +/** + * The parameters for the {@link Configurations.destroy} method + * @property identifier The identifier of the grant to act upon + * @property configurationId The id of the Configuration to retrieve. Use "primary" to refer to the primary configuration associated with grant. + */ +export interface DestroyConfigurationParams { + identifier: string; + configurationId: string; +} + +export class Configurations extends Resource { + /** + * Return all Configurations + * @return A list of configurations + */ + public list({ + identifier, + overrides, + }: ListConfigurationsParams & Overrides): AsyncListResponse< + NylasListResponse + > { + return super._list>({ + overrides, + path: makePathParams( + '/v3/grants/{identifier}/scheduling/configurations', + { + identifier, + } + ), + }); + } + + /** + * Return a Configuration + * @return The configuration + */ + public find({ + identifier, + configurationId, + overrides, + }: FindConfigurationParams & Overrides): Promise< + NylasResponse + > { + return super._find({ + path: makePathParams( + '/v3/grants/{identifier}/scheduling/configurations/{configurationId}', + { + identifier, + configurationId, + } + ), + overrides, + }); + } + + /** + * Create a Configuration + * @return The created configuration + */ + public create({ + identifier, + requestBody, + overrides, + }: CreateConfigurationParams & Overrides): Promise< + NylasResponse + > { + return super._create({ + path: makePathParams( + '/v3/grants/{identifier}/scheduling/configurations', + { + identifier, + } + ), + requestBody, + overrides, + }); + } + + /** + * Update a Configuration + * @return The updated Configuration + */ + public update({ + configurationId, + identifier, + requestBody, + overrides, + }: UpdateConfigurationParams & Overrides): Promise< + NylasResponse + > { + return super._update({ + path: makePathParams( + '/v3/grants/{identifier}/scheduling/configurations/{configurationId}', + { + identifier, + configurationId, + } + ), + requestBody, + overrides, + }); + } + + /** + * Delete a Configuration + * @return The deleted Configuration + */ + public destroy({ + identifier, + configurationId, + overrides, + }: DestroyConfigurationParams & Overrides): Promise { + return super._destroy({ + path: makePathParams( + '/v3/grants/{identifier}/scheduling/configurations/{configurationId}', + { + identifier, + configurationId, + } + ), + overrides, + }); + } +} diff --git a/src/resources/connectors.ts b/src/resources/connectors.ts new file mode 100644 index 00000000..8652ed1d --- /dev/null +++ b/src/resources/connectors.ts @@ -0,0 +1,150 @@ +import { AsyncListResponse, Resource } from './resource.js'; +import { + Connector, + CreateConnectorRequest, + ListConnectorsQueryParams, + UpdateConnectorRequest, +} from '../models/connectors.js'; +import { Overrides } from '../config.js'; +import { + NylasBaseResponse, + NylasListResponse, + NylasResponse, +} from '../models/response.js'; +import { Provider } from '../models/auth.js'; +import { Credentials } from './credentials.js'; +import APIClient from '../apiClient.js'; +import { makePathParams } from '../utils.js'; + +/** + * The parameters for the {@link Connectors.find} method + * @property provider The provider associated to the connector to retrieve. + */ +interface FindConnectorParams { + provider: Provider; +} + +/** + * The parameters for the {@link Connectors.list} method + * @property queryParams The query parameters to include in the request + */ +interface ListConnectorsParams { + queryParams?: ListConnectorsQueryParams; +} + +/** + * The parameters for the {@link Connectors.create} method + * @property requestBody The request body to create a connector + */ +interface CreateConnectorParams { + requestBody: CreateConnectorRequest; +} + +/** + * The parameters for the {@link Connectors.update} method + * @property provider The provider associated to the connector to update. + * @property requestBody The request body to create a connector + */ +interface UpdateConnectorParams { + provider: Provider; + requestBody: UpdateConnectorRequest; +} + +/** + * The parameters for the {@link Connectors.destroy} method + * @property provider The provider associated to the connector to update. + */ +interface DestroyConnectorParams { + provider: string; +} + +export class Connectors extends Resource { + /** + * Access the Credentials API + */ + public credentials: Credentials; + + /** + * @param apiClient client The configured Nylas API client + */ + constructor(apiClient: APIClient) { + super(apiClient); + this.credentials = new Credentials(apiClient); + } + + /** + * Return all connectors + * @return A list of connectors + */ + public list({ + queryParams, + overrides, + }: ListConnectorsParams & + ListConnectorsQueryParams & + Overrides): AsyncListResponse> { + return super._list>({ + queryParams, + overrides, + path: makePathParams('/v3/connectors', {}), + }); + } + + /** + * Return a connector + * @return The connector + */ + public find({ + provider, + overrides, + }: FindConnectorParams & Overrides): Promise> { + return super._find({ + path: makePathParams('/v3/connectors/{provider}', { provider }), + overrides, + }); + } + + /** + * Create a connector + * @return The created connector + */ + public create({ + requestBody, + overrides, + }: CreateConnectorParams & Overrides): Promise> { + return super._create({ + path: makePathParams('/v3/connectors', {}), + requestBody, + overrides, + }); + } + + /** + * Update a connector + * @return The updated connector + */ + public update({ + provider, + requestBody, + overrides, + }: UpdateConnectorParams & Overrides): Promise> { + return super._update({ + path: makePathParams('/v3/connectors/{provider}', { provider }), + requestBody, + overrides, + }); + } + + /** + * Delete a connector + * @return The deleted connector + */ + public destroy({ + provider, + overrides, + }: DestroyConnectorParams & Overrides): Promise { + return super._destroy({ + path: makePathParams('/v3/connectors/{provider}', { provider }), + overrides, + }); + } +} diff --git a/src/resources/contacts.ts b/src/resources/contacts.ts new file mode 100644 index 00000000..5c5b1969 --- /dev/null +++ b/src/resources/contacts.ts @@ -0,0 +1,189 @@ +import { Overrides } from '../config.js'; +import { + CreateContactRequest, + Contact, + ListContactQueryParams, + FindContactQueryParams, + UpdateContactRequest, + ContactGroup, +} from '../models/contacts.js'; +import { + NylasResponse, + NylasListResponse, + NylasBaseResponse, +} from '../models/response.js'; +import { AsyncListResponse, Resource } from './resource.js'; +import { makePathParams } from '../utils.js'; + +/** + * @property contactId The id of the Contact to retrieve. + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ +interface FindContactParams { + identifier: string; + contactId: string; + queryParams: FindContactQueryParams; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ +interface ListContactParams { + identifier: string; + queryParams: ListContactQueryParams; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property requestBody The values to create the Contact with + */ +interface CreateContactParams { + identifier: string; + requestBody: CreateContactRequest; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property contactId The id of the Contact to retrieve. + * @property requestBody The values to update the Contact with + */ +interface UpdateContactParams { + identifier: string; + contactId: string; + requestBody: UpdateContactRequest; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property contactId The id of the Contact to retrieve. + */ +interface DestroyContactParams { + identifier: string; + contactId: string; +} + +/** + * @property identifier The identifier of the grant to act upon + */ +interface ListContactGroupParams { + identifier: string; +} + +/** + * Nylas Contacts API + * + * The Nylas Contacts API allows you to create, update, and delete contacts. + */ +export class Contacts extends Resource { + /** + * Return all Contacts + * @return The list of Contacts + */ + public list({ + identifier, + queryParams, + overrides, + }: ListContactParams & Overrides): AsyncListResponse< + NylasListResponse + > { + return super._list({ + queryParams, + path: makePathParams('/v3/grants/{identifier}/contacts', { identifier }), + overrides, + }); + } + + /** + * Return a Contact + * @return The Contact + */ + public find({ + identifier, + contactId, + queryParams, + overrides, + }: FindContactParams & Overrides): Promise> { + return super._find({ + path: makePathParams('/v3/grants/{identifier}/contacts/{contactId}', { + identifier, + contactId, + }), + queryParams, + overrides, + }); + } + + /** + * Create a Contact + * @return The created Contact + */ + public create({ + identifier, + requestBody, + overrides, + }: CreateContactParams & Overrides): Promise> { + return super._create({ + path: makePathParams('/v3/grants/{identifier}/contacts', { identifier }), + requestBody, + overrides, + }); + } + + /** + * Update a Contact + * @return The updated Contact + */ + public update({ + identifier, + contactId, + requestBody, + overrides, + }: UpdateContactParams & Overrides): Promise> { + return super._update({ + path: makePathParams('/v3/grants/{identifier}/contacts/{contactId}', { + identifier, + contactId, + }), + requestBody, + overrides, + }); + } + + /** + * Delete a Contact + * @return The deletion response + */ + public destroy({ + identifier, + contactId, + overrides, + }: DestroyContactParams & Overrides): Promise { + return super._destroy({ + path: makePathParams('/v3/grants/{identifier}/contacts/{contactId}', { + identifier, + contactId, + }), + overrides, + }); + } + + /** + * Return a Contact Group + * @return The list of Contact Groups + */ + public groups({ + identifier, + overrides, + }: ListContactGroupParams & Overrides): Promise< + NylasListResponse + > { + return super._list({ + path: makePathParams('/v3/grants/{identifier}/contacts/groups', { + identifier, + }), + overrides, + }); + } +} diff --git a/src/resources/credentials.ts b/src/resources/credentials.ts new file mode 100644 index 00000000..8beb6edf --- /dev/null +++ b/src/resources/credentials.ts @@ -0,0 +1,159 @@ +import { Overrides } from '../config.js'; +import { Provider } from '../models/auth.js'; +import { + CreateCredentialRequest, + Credential, + ListCredentialsQueryParams, + UpdateCredentialRequest, +} from '../models/credentials.js'; +import { + NylasBaseResponse, + NylasListResponse, + NylasResponse, +} from '../models/response.js'; +import { AsyncListResponse, Resource } from './resource.js'; +import { makePathParams } from '../utils.js'; + +/** + * The parameters for the {@link Credentials.find} method + * @property provider The provider associated to the credential to retrieve. + * @property credentialsId The id of the credentials to retrieve. + */ +interface FindCredentialParams { + provider: Provider; + credentialsId: string; +} + +/** + * The parameters for the {@link Credentials.list} method + * @property provider The provider associated to the credential to list from. + * @property queryParams The query parameters to include in the request + */ +interface ListCredentialsParams { + provider: Provider; + queryParams?: ListCredentialsQueryParams; +} + +/** + * The parameters for the {@link Credentials.create} method + * @property provider The provider associated to the credential being created. + * @property requestBody The request body to create a credential + */ +interface CreateCredentialParams { + provider: Provider; + requestBody: CreateCredentialRequest; +} + +/** + * The parameters for the {@link Credentials.update} method + * @property provider The provider associated to the credential to update from. + * @property requestBody The request body to create a credential + * @property credentialsId The id of the credentials to update. + */ +interface UpdateCredentialParams { + provider: Provider; + credentialsId: string; + requestBody: UpdateCredentialRequest; +} + +/** + * The parameters for the {@link Credentials.destroy} method + * @property provider The provider associated to the credential to delete from. + * @property credentialsId The id of the credentials to delete. + */ +interface DestroyCredentialParams { + provider: string; + credentialsId: string; +} + +export class Credentials extends Resource { + /** + * Return all credentials + * @return A list of credentials + */ + public list({ + provider, + queryParams, + overrides, + }: ListCredentialsParams & + ListCredentialsQueryParams & + Overrides): AsyncListResponse> { + return super._list>({ + queryParams, + overrides, + path: makePathParams('/v3/connectors/{provider}/creds', { provider }), + }); + } + + /** + * Return a credential + * @return The credential + */ + public find({ + provider, + credentialsId, + overrides, + }: FindCredentialParams & Overrides): Promise> { + return super._find({ + path: makePathParams('/v3/connectors/{provider}/creds/{credentialsId}', { + provider, + credentialsId, + }), + overrides, + }); + } + + /** + * Create a credential + * @return The created credential + */ + public create({ + provider, + requestBody, + overrides, + }: CreateCredentialParams & Overrides): Promise> { + return super._create({ + path: makePathParams('/v3/connectors/{provider}/creds', { provider }), + requestBody, + overrides, + }); + } + + /** + * Update a credential + * @return The updated credential + */ + public update({ + provider, + credentialsId, + requestBody, + overrides, + }: UpdateCredentialParams & Overrides): Promise> { + return super._update({ + path: makePathParams('/v3/connectors/{provider}/creds/{credentialsId}', { + provider, + credentialsId, + }), + requestBody, + overrides, + }); + } + + /** + * Delete a credential + * @return The deleted credential + */ + public destroy({ + provider, + credentialsId, + overrides, + }: DestroyCredentialParams & Overrides): Promise { + return super._destroy({ + path: makePathParams('/v3/connectors/{provider}/creds/{credentialsId}', { + provider, + credentialsId, + }), + overrides, + }); + } +} diff --git a/src/resources/drafts.ts b/src/resources/drafts.ts new file mode 100644 index 00000000..2a14d14d --- /dev/null +++ b/src/resources/drafts.ts @@ -0,0 +1,239 @@ +import { Overrides } from '../config.js'; +import { Messages } from './messages.js'; +import { AsyncListResponse, Resource } from './resource.js'; +import { + CreateDraftRequest, + Draft, + ListDraftsQueryParams, + UpdateDraftRequest, +} from '../models/drafts.js'; +import { Message } from '../models/messages.js'; +import { + NylasBaseResponse, + NylasListResponse, + NylasResponse, +} from '../models/response.js'; +import { + encodeAttachmentContent, + calculateTotalPayloadSize, +} from '../utils.js'; +import { makePathParams } from '../utils.js'; +/** + * The parameters for the {@link Drafts.list} method + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ +export interface ListDraftsParams { + identifier: string; + queryParams?: ListDraftsQueryParams; +} + +/** + * The parameters for the {@link Drafts.find} method + * @property identifier The identifier of the grant to act upon + * @property draftId The id of the draft to retrieve. + */ +export interface FindDraftParams { + identifier: string; + draftId: string; +} + +/** + * The parameters for the {@link Drafts.create} method + * @property identifier The identifier of the grant to act upon + * @property requestBody The values to create the message with + */ +export interface CreateDraftParams { + identifier: string; + requestBody: CreateDraftRequest; +} + +/** + * The parameters for the {@link Drafts.update} method + * @property identifier The identifier of the grant to act upon + * @property draftId The id of the draft to update. + * @property requestBody The values to update the draft with + */ +export interface UpdateDraftParams { + identifier: string; + draftId: string; + requestBody: UpdateDraftRequest; +} + +/** + * The parameters for the {@link Drafts.destroy} method + */ +export type DestroyDraftParams = FindDraftParams; + +/** + * The parameters for the {@link Drafts.send} method + */ +export type SendDraftParams = FindDraftParams; + +/** + * Nylas Drafts API + * + * The Nylas Drafts API allows you to list, find, update, delete, and send drafts on user accounts. + */ +export class Drafts extends Resource { + /** + * Return all Drafts + * @return A list of drafts + */ + public list({ + identifier, + queryParams, + overrides, + }: ListDraftsParams & Overrides): AsyncListResponse< + NylasListResponse + > { + return super._list>({ + queryParams, + overrides, + path: makePathParams('/v3/grants/{identifier}/drafts', { identifier }), + }); + } + + /** + * Return a Draft + * @return The draft + */ + public find({ + identifier, + draftId, + overrides, + }: FindDraftParams & Overrides): Promise> { + return super._find({ + path: makePathParams('/v3/grants/{identifier}/drafts/{draftId}', { + identifier, + draftId, + }), + overrides, + }); + } + + /** + * Return a Draft + * @return The draft + */ + public async create({ + identifier, + requestBody, + overrides, + }: CreateDraftParams & Overrides): Promise> { + const path = makePathParams('/v3/grants/{identifier}/drafts', { + identifier, + }); + + // Use form data if the total payload size (body + attachments) is greater than 3mb + const totalPayloadSize = calculateTotalPayloadSize(requestBody); + + if (totalPayloadSize >= Messages.MAXIMUM_JSON_ATTACHMENT_SIZE) { + const form = Messages._buildFormRequest(requestBody); + + return this.apiClient.request({ + method: 'POST', + path, + form, + overrides, + }); + } else if (requestBody.attachments) { + const processedAttachments = await encodeAttachmentContent( + requestBody.attachments + ); + + requestBody = { + ...requestBody, + attachments: processedAttachments, + }; + } + + return super._create({ + path, + requestBody, + overrides, + }); + } + + /** + * Update a Draft + * @return The updated draft + */ + public async update({ + identifier, + draftId, + requestBody, + overrides, + }: UpdateDraftParams & Overrides): Promise> { + const path = makePathParams('/v3/grants/{identifier}/drafts/{draftId}', { + identifier, + draftId, + }); + + // Use form data if the total payload size (body + attachments) is greater than 3mb + const totalPayloadSize = calculateTotalPayloadSize(requestBody); + + if (totalPayloadSize >= Messages.MAXIMUM_JSON_ATTACHMENT_SIZE) { + const form = Messages._buildFormRequest(requestBody); + + return this.apiClient.request({ + method: 'PUT', + path, + form, + overrides, + }); + } else if (requestBody.attachments) { + const processedAttachments = await encodeAttachmentContent( + requestBody.attachments + ); + + requestBody = { + ...requestBody, + attachments: processedAttachments, + }; + } + + return super._update({ + path, + requestBody, + overrides, + }); + } + + /** + * Delete a Draft + * @return The deleted draft + */ + public destroy({ + identifier, + draftId, + overrides, + }: DestroyDraftParams & Overrides): Promise { + return super._destroy({ + path: makePathParams('/v3/grants/{identifier}/drafts/{draftId}', { + identifier, + draftId, + }), + overrides, + }); + } + + /** + * Send a Draft + * @return The sent message + */ + public send({ + identifier, + draftId, + overrides, + }: SendDraftParams & Overrides): Promise> { + return super._create({ + path: makePathParams('/v3/grants/{identifier}/drafts/{draftId}', { + identifier, + draftId, + }), + requestBody: {}, + overrides, + }); + } +} diff --git a/src/resources/events.ts b/src/resources/events.ts new file mode 100644 index 00000000..4bc82a7d --- /dev/null +++ b/src/resources/events.ts @@ -0,0 +1,248 @@ +import { Overrides } from '../config.js'; +import { + CreateEventQueryParams, + CreateEventRequest, + DestroyEventQueryParams, + Event, + FindEventQueryParams, + ListImportEventQueryParams, + ListEventQueryParams, + SendRsvpQueryParams, + SendRsvpRequest, + SendRsvpResponse, + UpdateEventQueryParams, + UpdateEventRequest, +} from '../models/events.js'; +import { + NylasBaseResponse, + NylasResponse, + NylasListResponse, +} from '../models/response.js'; +import { AsyncListResponse, Resource } from './resource.js'; +import { makePathParams } from '../utils.js'; + +/** + * @property eventId The id of the Event to retrieve. + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ +export interface FindEventParams { + identifier: string; + eventId: string; + queryParams: FindEventQueryParams; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ +export interface ListEventParams { + identifier: string; + queryParams: ListEventQueryParams; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + * @property requestBody The values to create the Event with + */ +export interface CreateEventParams { + identifier: string; + requestBody: CreateEventRequest; + queryParams: CreateEventQueryParams; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property eventId The id of the Event to retrieve. + * @property requestBody The values to update the Event with + * @property queryParams The query parameters to include in the request + */ +export interface UpdateEventParams { + identifier: string; + eventId: string; + requestBody: UpdateEventRequest; + queryParams: UpdateEventQueryParams; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property eventId The id of the Event to retrieve. + * @property queryParams The query parameters to include in the request + */ +export interface DestroyEventParams { + identifier: string; + eventId: string; + queryParams: DestroyEventQueryParams; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ +export interface ListImportEventParams { + identifier: string; + queryParams: ListImportEventQueryParams; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property eventId The id of the Event to update. + * @property queryParams The query parameters to include in the request + * @property requestBody The values to send the RSVP with + */ +interface SendRsvpParams { + identifier: string; + eventId: string; + queryParams: SendRsvpQueryParams; + requestBody: SendRsvpRequest; +} + +/** + * Nylas Events API + * + * The Nylas Events API allows you to create, update, and delete events on user calendars. + */ +export class Events extends Resource { + /** + * Return all Events + * @return The list of Events + */ + public list({ + identifier, + queryParams, + overrides, + }: ListEventParams & Overrides): AsyncListResponse> { + return super._list({ + queryParams, + path: makePathParams('/v3/grants/{identifier}/events', { identifier }), + overrides, + }); + } + + /** + * (Beta) Import events from a calendar within a given time frame + * This is useful when you want to import, store, and synchronize events from the time frame to your application + * @return The list of imported Events + */ + public listImportEvents({ + identifier, + queryParams, + overrides, + }: ListImportEventParams & Overrides): AsyncListResponse< + NylasListResponse + > { + return super._list({ + queryParams, + path: makePathParams('/v3/grants/{identifier}/events/import', { + identifier, + }), + overrides, + }); + } + + /** + * Return an Event + * @return The Event + */ + public find({ + identifier, + eventId, + queryParams, + overrides, + }: FindEventParams & Overrides): Promise> { + return super._find({ + path: makePathParams('/v3/grants/{identifier}/events/{eventId}', { + identifier, + eventId, + }), + queryParams, + overrides, + }); + } + + /** + * Create an Event + * @return The created Event + */ + public create({ + identifier, + requestBody, + queryParams, + overrides, + }: CreateEventParams & Overrides): Promise> { + return super._create({ + path: makePathParams('/v3/grants/{identifier}/events', { identifier }), + queryParams, + requestBody, + overrides, + }); + } + + /** + * Update an Event + * @return The updated Event + */ + public update({ + identifier, + eventId, + requestBody, + queryParams, + overrides, + }: UpdateEventParams & Overrides): Promise> { + return super._update({ + path: makePathParams('/v3/grants/{identifier}/events/{eventId}', { + identifier, + eventId, + }), + queryParams, + requestBody, + overrides, + }); + } + + /** + * Delete an Event + * @return The deletion response + */ + public destroy({ + identifier, + eventId, + queryParams, + overrides, + }: DestroyEventParams & Overrides): Promise { + return super._destroy({ + path: makePathParams('/v3/grants/{identifier}/events/{eventId}', { + identifier, + eventId, + }), + queryParams, + overrides, + }); + } + + /** + * Send RSVP. Allows users to respond to events they have been added to as an attendee. + * You cannot send RSVP as an event owner/organizer. + * You cannot directly update events as an invitee, since you are not the owner/organizer. + * @return The send-rsvp response + */ + public sendRsvp({ + identifier, + eventId, + requestBody, + queryParams, + overrides, + }: SendRsvpParams & Overrides): Promise { + return this.apiClient.request({ + method: 'POST', + path: makePathParams( + '/v3/grants/{identifier}/events/{eventId}/send-rsvp', + { identifier, eventId } + ), + queryParams, + body: requestBody, + overrides, + }); + } +} diff --git a/src/resources/folders.ts b/src/resources/folders.ts new file mode 100644 index 00000000..5534548a --- /dev/null +++ b/src/resources/folders.ts @@ -0,0 +1,175 @@ +import { Overrides } from '../config.js'; +import { + Folder, + CreateFolderRequest, + UpdateFolderRequest, + ListFolderQueryParams, + FindFolderQueryParams, +} from '../models/folders.js'; +import { + NylasBaseResponse, + NylasResponse, + NylasListResponse, +} from '../models/response.js'; +import { Resource, AsyncListResponse } from './resource.js'; +import { makePathParams } from '../utils.js'; +/** + * The parameters for the {@link Folders.list} method + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ +interface ListFoldersParams { + identifier: string; + queryParams?: ListFolderQueryParams; +} + +/** + * The parameters for the {@link Folders.find} method + * @property identifier The identifier of the grant to act upon + * @property folderId The id of the Folder to retrieve + * @property queryParams The query parameters to include in the request + */ +interface FindFolderParams { + identifier: string; + folderId: string; + queryParams?: FindFolderQueryParams; +} + +/** + * The parameters for the {@link Folders.create} method + * @property identifier The identifier of the grant to act upon + * @property requestBody The request body to create a folder + */ +interface CreateFolderParams { + identifier: string; + requestBody: CreateFolderRequest; +} + +/** + * The parameters for the {@link Folders.update} method + * @property identifier The identifier of the grant to act upon + * @property folderId The id of the Folder to update + * @property requestBody The request body to update a folder + */ +interface UpdateFolderParams { + identifier: string; + folderId: string; + requestBody: UpdateFolderRequest; +} + +/** + * The parameters for the {@link Folders.destroy} method + * @property identifier The identifier of the grant to act upon + * @property folderId The id of the Folder to delete + */ +interface DestroyFolderParams { + identifier: string; + folderId: string; +} + +/** + * Nylas Folder API + * + * Email providers use folders to store and organize email messages. Examples of common system folders include Inbox, Sent, Drafts, etc. + * + * If your team is migrating from Nylas APIv2, there were previously two separate endpoints for interacting with Folders (Microsoft) and Labels (Google). + * In Nylas API v3, these endpoints are consolidated under Folders. + * + * To simplify the developer experience, Nylas uses the same folders commands to manage both folders and labels, using the folder_id key to refer to the folder's ID on the provider. + * The API also exposes provider-specific fields such as background_color (Google only). + * + * Depending on the provider (Google, some IMAP providers, etc.), a message can be contained in more than one folder. + */ +export class Folders extends Resource { + /** + * Return all Folders + * @return A list of folders + */ + public list({ + identifier, + queryParams, + overrides, + }: ListFoldersParams & Overrides): AsyncListResponse< + NylasListResponse + > { + return super._list>({ + overrides, + queryParams, + path: makePathParams('/v3/grants/{identifier}/folders', { identifier }), + }); + } + + /** + * Return a Folder + * @return The folder + */ + public find({ + identifier, + folderId, + queryParams, + overrides, + }: FindFolderParams & Overrides): Promise> { + return super._find({ + path: makePathParams('/v3/grants/{identifier}/folders/{folderId}', { + identifier, + folderId, + }), + queryParams, + overrides, + }); + } + + /** + * Create a Folder + * @return The created folder + */ + public create({ + identifier, + requestBody, + overrides, + }: CreateFolderParams & Overrides): Promise> { + return super._create({ + path: makePathParams('/v3/grants/{identifier}/folders', { identifier }), + requestBody, + overrides, + }); + } + + /** + * Update a Folder + * @return The updated Folder + */ + public update({ + identifier, + folderId, + requestBody, + overrides, + }: UpdateFolderParams & Overrides): Promise> { + return super._update({ + path: makePathParams('/v3/grants/{identifier}/folders/{folderId}', { + identifier, + folderId, + }), + requestBody, + overrides, + }); + } + + /** + * Delete a Folder + * @return The deleted Folder + */ + public destroy({ + identifier, + folderId, + overrides, + }: DestroyFolderParams & Overrides): Promise { + return super._destroy({ + path: makePathParams('/v3/grants/{identifier}/folders/{folderId}', { + identifier, + folderId, + }), + overrides, + }); + } +} diff --git a/src/resources/grants.ts b/src/resources/grants.ts new file mode 100644 index 00000000..601f3ff6 --- /dev/null +++ b/src/resources/grants.ts @@ -0,0 +1,112 @@ +import { Resource } from './resource.js'; +import { Overrides } from '../config.js'; +import { + NylasBaseResponse, + NylasResponse, + NylasListResponse, +} from '../models/response.js'; +import { + Grant, + ListGrantsQueryParams, + UpdateGrantRequest, +} from '../models/grants.js'; +import { ListQueryParams } from '../models/listQueryParams.js'; +import { makePathParams } from '../utils.js'; +/** + * @property queryParams The query parameters to include in the request + */ +export interface ListGrantsParams { + queryParams?: ListGrantsQueryParams; +} + +/** + * @property grantId The id of the Grant to retrieve. + */ +export interface FindGrantParams { + grantId: string; +} + +/** + * @property grantId The id of the Grant to update. + * @property requestBody The values to update the Grant with. + */ +export interface UpdateGrantParams { + grantId: string; + requestBody: UpdateGrantRequest; +} + +/** + * @property grantId The id of the Grant to delete. + */ +export interface DestroyGrantParams { + grantId: string; +} + +/** + * Nylas Grants API + * + * The Nylas Grants API allows for the management of grants. + */ +export class Grants extends Resource { + /** + * Return all Grants + * @return The list of Grants + */ + public async list( + { overrides, queryParams }: Overrides & ListGrantsParams = {}, + /** + * @deprecated Use `queryParams` instead. + */ + _queryParams?: ListQueryParams + ): Promise> { + return super._list>({ + queryParams: queryParams ?? _queryParams ?? undefined, + path: makePathParams('/v3/grants', {}), + overrides: overrides ?? {}, + }); + } + + /** + * Return a Grant + * @return The Grant + */ + public find({ + grantId, + overrides, + }: FindGrantParams & Overrides): Promise> { + return super._find({ + path: makePathParams('/v3/grants/{grantId}', { grantId }), + overrides, + }); + } + + /** + * Update a Grant + * @return The updated Grant + */ + public update({ + grantId, + requestBody, + overrides, + }: UpdateGrantParams & Overrides): Promise> { + return super._updatePatch({ + path: makePathParams('/v3/grants/{grantId}', { grantId }), + requestBody, + overrides, + }); + } + + /** + * Delete a Grant + * @return The deletion response + */ + public destroy({ + grantId, + overrides, + }: DestroyGrantParams & Overrides): Promise { + return super._destroy({ + path: makePathParams('/v3/grants/{grantId}', { grantId }), + overrides, + }); + } +} diff --git a/src/resources/messages.ts b/src/resources/messages.ts new file mode 100644 index 00000000..8fe4ed46 --- /dev/null +++ b/src/resources/messages.ts @@ -0,0 +1,385 @@ +import { Blob, FormData } from 'formdata-node'; +import APIClient, { RequestOptionsParams } from '../apiClient.js'; +import { Overrides } from '../config.js'; +import { + CreateDraftRequest, + SendMessageRequest, + UpdateDraftRequest, +} from '../models/drafts.js'; +import { + CleanMessagesRequest, + CleanMessagesResponse, + FindMessageQueryParams, + ListMessagesQueryParams, + Message, + ScheduledMessage, + ScheduledMessagesList, + StopScheduledMessageResponse, + UpdateMessageRequest, +} from '../models/messages.js'; +import { + NylasBaseResponse, + NylasListResponse, + NylasResponse, +} from '../models/response.js'; +import { + attachmentStreamToFile, + calculateTotalPayloadSize, + encodeAttachmentContent, + makePathParams, + objKeysToSnakeCase, +} from '../utils.js'; +import { AsyncListResponse, Resource } from './resource.js'; +import { SmartCompose } from './smartCompose.js'; + +/** + * The parameters for the {@link Messages.list} method + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ +export interface ListMessagesParams { + identifier: string; + queryParams?: ListMessagesQueryParams; +} + +/** + * The parameters for the {@link Messages.find} method + * @property identifier The identifier of the grant to act upon + * @property messageId The id of the message to retrieve. + * @property queryParams The query parameters to include in the request + */ +export interface FindMessageParams { + identifier: string; + messageId: string; + queryParams?: FindMessageQueryParams; +} + +/** + * The parameters for the {@link Messages.update} method + * @property identifier The identifier of the grant to act upon + * @property messageId The id of the message to update + * @property requestBody The values to update the message with + */ +export interface UpdateMessageParams { + identifier: string; + messageId: string; + requestBody: UpdateMessageRequest; +} + +/** + * The parameters for the {@link Messages.destroy} method + * @property identifier The identifier of the grant to act upon + * @property messageId The id of the message to delete + */ +export interface DestroyMessageParams { + identifier: string; + messageId: string; +} + +/** + * The parameters for the {@link Messages.send} method + * @property identifier The identifier of the grant to act upon + * @property requestBody The message to send + */ +export interface SendMessageParams { + identifier: string; + requestBody: SendMessageRequest; +} + +/** + * The parameters for the {@link Messages.listScheduledMessages} method + * @property identifier The identifier of the grant to act upon + */ +export interface ListScheduledMessagesParams { + identifier: string; +} + +/** + * The parameters for the {@link Messages.findScheduledMessage} method + * @property identifier The identifier of the grant to act upon + * @property scheduleId The id of the scheduled message to retrieve. + */ +export interface FindScheduledMessageParams { + identifier: string; + scheduleId: string; +} + +/** + * The parameters for the {@link Messages.stopScheduledMessage} method + * @property identifier The identifier of the grant to act upon + * @property scheduleId The id of the scheduled message to destroy. + */ +export type StopScheduledMessageParams = FindScheduledMessageParams; + +/** + * The parameters for the {@link Messages.cleanMessages} method + * @property identifier The identifier of the grant to act upon + * @property requestBody The values to clean the message with + */ +export interface CleanMessagesParams { + identifier: string; + requestBody: CleanMessagesRequest; +} + +/** + * Nylas Messages API + * + * The Nylas Messages API allows you to list, find, update, delete, schedule, and send messages on user accounts. + */ +export class Messages extends Resource { + public smartCompose: SmartCompose; + // The maximum size of an attachment that can be sent using json + static MAXIMUM_JSON_ATTACHMENT_SIZE = 3 * 1024 * 1024; + + constructor(apiClient: APIClient) { + super(apiClient); + this.smartCompose = new SmartCompose(apiClient); + } + + /** + * Return all Messages + * @return A list of messages + */ + public list({ + identifier, + queryParams, + overrides, + }: ListMessagesParams & Overrides): AsyncListResponse< + NylasListResponse + > { + const modifiedQueryParams: Record | undefined = queryParams + ? { ...queryParams } + : undefined; + + // Transform some query params that are arrays into comma-delimited strings + if (modifiedQueryParams && queryParams) { + if (Array.isArray(queryParams?.anyEmail)) { + delete modifiedQueryParams.anyEmail; + modifiedQueryParams['any_email'] = queryParams.anyEmail.join(','); + } + } + + return super._list>({ + queryParams: modifiedQueryParams, + overrides, + path: makePathParams('/v3/grants/{identifier}/messages', { identifier }), + }); + } + + /** + * Return a Message + * @return The message + */ + public find({ + identifier, + messageId, + overrides, + queryParams, + }: FindMessageParams & Overrides): Promise> { + return super._find({ + path: makePathParams('/v3/grants/{identifier}/messages/{messageId}', { + identifier, + messageId, + }), + overrides, + queryParams, + }); + } + + /** + * Update a Message + * @return The updated message + */ + public update({ + identifier, + messageId, + requestBody, + overrides, + }: UpdateMessageParams & Overrides): Promise> { + return super._update({ + path: makePathParams('/v3/grants/{identifier}/messages/{messageId}', { + identifier, + messageId, + }), + requestBody, + overrides, + }); + } + + /** + * Delete a Message + * @return The deleted message + */ + public destroy({ + identifier, + messageId, + overrides, + }: DestroyMessageParams & Overrides): Promise { + return super._destroy({ + path: makePathParams('/v3/grants/{identifier}/messages/{messageId}', { + identifier, + messageId, + }), + overrides, + }); + } + + /** + * Send an email + * @return The sent message + */ + public async send({ + identifier, + requestBody, + overrides, + }: SendMessageParams & Overrides): Promise> { + const path = makePathParams('/v3/grants/{identifier}/messages/send', { + identifier, + }); + const requestOptions: RequestOptionsParams = { + method: 'POST', + path, + overrides, + }; + + // Use form data if the total payload size (body + attachments) is greater than 3mb + const totalPayloadSize = calculateTotalPayloadSize(requestBody); + + if (totalPayloadSize >= Messages.MAXIMUM_JSON_ATTACHMENT_SIZE) { + requestOptions.form = Messages._buildFormRequest(requestBody); + } else { + if (requestBody.attachments) { + const processedAttachments = await encodeAttachmentContent( + requestBody.attachments + ); + + requestOptions.body = { + ...requestBody, + attachments: processedAttachments, + }; + } else { + requestOptions.body = requestBody; + } + } + + return this.apiClient.request(requestOptions); + } + + /** + * Retrieve your scheduled messages + * @return A list of scheduled messages + */ + public listScheduledMessages({ + identifier, + overrides, + }: ListScheduledMessagesParams & Overrides): Promise< + NylasResponse + > { + return super._find({ + path: makePathParams('/v3/grants/{identifier}/messages/schedules', { + identifier, + }), + overrides, + }); + } + + /** + * Retrieve a scheduled message + * @return The scheduled message + */ + public findScheduledMessage({ + identifier, + scheduleId, + overrides, + }: FindScheduledMessageParams & Overrides): Promise< + NylasResponse + > { + return super._find({ + path: makePathParams( + '/v3/grants/{identifier}/messages/schedules/{scheduleId}', + { identifier, scheduleId } + ), + overrides, + }); + } + + /** + * Stop a scheduled message + * @return The confirmation of the stopped scheduled message + */ + public stopScheduledMessage({ + identifier, + scheduleId, + overrides, + }: StopScheduledMessageParams & Overrides): Promise< + NylasResponse + > { + return super._destroy({ + path: makePathParams( + '/v3/grants/{identifier}/messages/schedules/{scheduleId}', + { identifier, scheduleId } + ), + overrides, + }); + } + + /** + * Remove extra information from a list of messages + * @return The list of cleaned messages + */ + public cleanMessages({ + identifier, + requestBody, + overrides, + }: CleanMessagesParams & Overrides): Promise< + NylasListResponse + > { + return this.apiClient.request>({ + method: 'PUT', + path: makePathParams('/v3/grants/{identifier}/messages/clean', { + identifier, + }), + body: requestBody, + overrides, + }); + } + + static _buildFormRequest( + requestBody: CreateDraftRequest | UpdateDraftRequest | SendMessageRequest + ): FormData { + const form = new FormData(); + + // Split out the message payload from the attachments + const messagePayload = { + ...requestBody, + attachments: undefined, + }; + form.append('message', JSON.stringify(objKeysToSnakeCase(messagePayload))); + + // Add a separate form field for each attachment + if (requestBody.attachments && requestBody.attachments.length > 0) { + requestBody.attachments.map((attachment, index) => { + const contentId = attachment.contentId || `file${index}`; + // Handle different content types for formdata-node + if (typeof attachment.content === 'string') { + // Base64 string - create a Blob + const buffer = Buffer.from(attachment.content, 'base64'); + const blob = new Blob([buffer], { type: attachment.contentType }); + form.append(contentId, blob, attachment.filename); + } else if (Buffer.isBuffer(attachment.content)) { + // Buffer - create a Blob + const blob = new Blob([attachment.content], { + type: attachment.contentType, + }); + form.append(contentId, blob, attachment.filename); + } else { + // ReadableStream - create a proper file-like object according to formdata-node docs + const file = attachmentStreamToFile(attachment); + form.append(contentId, file, attachment.filename); + } + }); + } + + return form; + } +} diff --git a/src/resources/notetakers.ts b/src/resources/notetakers.ts new file mode 100644 index 00000000..146e4c7f --- /dev/null +++ b/src/resources/notetakers.ts @@ -0,0 +1,247 @@ +import { Overrides } from '../config.js'; +import { + CreateNotetakerRequest, + ListNotetakersResponse, + Notetaker, + NotetakerMedia, + UpdateNotetakerRequest, + ListNotetakersQueryParams, + NotetakerLeaveResponse, +} from '../models/notetakers.js'; +import { NylasBaseResponse, NylasResponse } from '../models/response.js'; +import { AsyncListResponse, Resource } from './resource.js'; +import { makePathParams } from '../utils.js'; +/** + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to filter the list of Notetakers + */ +export interface ListNotetakersParams { + identifier?: string; + queryParams?: ListNotetakersQueryParams; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property requestBody The request body to create the Notetaker with + */ +export interface CreateNotetakerParams { + identifier?: string; + requestBody: CreateNotetakerRequest; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property notetakerId The ID of the Notetaker to find + */ +export interface FindNotetakerParams { + identifier?: string; + notetakerId: string; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property notetakerId The ID of the Notetaker to update + * @property requestBody The request body to update the Notetaker with + */ +export interface UpdateNotetakerParams { + identifier?: string; + notetakerId: string; + requestBody: UpdateNotetakerRequest; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property notetakerId The ID of the Notetaker to cancel + */ +export interface CancelNotetakerParams { + identifier?: string; + notetakerId: string; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property notetakerId The ID of the Notetaker to leave + */ +export interface LeaveNotetakerParams { + identifier?: string; + notetakerId: string; +} + +/** + * @property identifier The identifier of the grant to act upon + * @property notetakerId The ID of the Notetaker to download media from + */ +export interface DownloadNotetakerMediaParams { + identifier?: string; + notetakerId: string; +} + +/** + * Nylas Notetakers API + * + * The Nylas Notetakers API allows you to invite a Notetaker bot to meetings. + */ +export class Notetakers extends Resource { + /** + * Return all Notetakers + * @param params The parameters to list Notetakers with + * @return The list of Notetakers + */ + public list({ + identifier, + queryParams, + overrides, + }: ListNotetakersParams & + Overrides): AsyncListResponse { + return super._list({ + path: identifier + ? makePathParams('/v3/grants/{identifier}/notetakers', { identifier }) + : makePathParams('/v3/notetakers', {}), + queryParams, + overrides, + }); + } + + /** + * Invite a Notetaker to a meeting + * @param params The parameters to create the Notetaker with + * @returns Promise resolving to the created Notetaker + */ + public create({ + identifier, + requestBody, + overrides, + }: CreateNotetakerParams & Overrides): Promise> { + return this._create({ + path: identifier + ? makePathParams('/v3/grants/{identifier}/notetakers', { identifier }) + : makePathParams('/v3/notetakers', {}), + requestBody, + overrides, + }); + } + + /** + * Return a single Notetaker + * @param params The parameters to find the Notetaker with + * @returns Promise resolving to the Notetaker + */ + public find({ + identifier, + notetakerId, + overrides, + }: FindNotetakerParams & Overrides): Promise> { + return this._find({ + path: identifier + ? makePathParams('/v3/grants/{identifier}/notetakers/{notetakerId}', { + identifier, + notetakerId, + }) + : makePathParams('/v3/notetakers/{notetakerId}', { notetakerId }), + overrides, + }); + } + + /** + * Update a Notetaker + * @param params The parameters to update the Notetaker with + * @returns Promise resolving to the updated Notetaker + */ + public update({ + identifier, + notetakerId, + requestBody, + overrides, + }: UpdateNotetakerParams & Overrides): Promise> { + return this._updatePatch({ + path: identifier + ? makePathParams('/v3/grants/{identifier}/notetakers/{notetakerId}', { + identifier, + notetakerId, + }) + : makePathParams('/v3/notetakers/{notetakerId}', { notetakerId }), + requestBody, + overrides, + }); + } + + /** + * Cancel a scheduled Notetaker + * @param params The parameters to cancel the Notetaker with + * @returns Promise resolving to the base response with request ID + */ + public cancel({ + identifier, + notetakerId, + overrides, + }: CancelNotetakerParams & Overrides): Promise { + return this._destroy({ + path: identifier + ? makePathParams( + '/v3/grants/{identifier}/notetakers/{notetakerId}/cancel', + { + identifier, + notetakerId, + } + ) + : makePathParams('/v3/notetakers/{notetakerId}/cancel', { + notetakerId, + }), + overrides, + }); + } + + /** + * Remove a Notetaker from a meeting + * @param params The parameters to remove the Notetaker from the meeting + * @returns Promise resolving to a response containing the Notetaker ID and a message + */ + public leave({ + identifier, + notetakerId, + overrides, + }: LeaveNotetakerParams & Overrides): Promise< + NylasResponse + > { + return this.apiClient.request({ + method: 'POST', + path: identifier + ? makePathParams( + '/v3/grants/{identifier}/notetakers/{notetakerId}/leave', + { + identifier, + notetakerId, + } + ) + : makePathParams('/v3/notetakers/{notetakerId}/leave', { notetakerId }), + overrides, + }); + } + + /** + * Download media (recording and transcript) from a Notetaker session + * @param params The parameters to download the Notetaker media + * @returns Promise resolving to the media download response with URLs and sizes + */ + public downloadMedia({ + identifier, + notetakerId, + overrides, + }: DownloadNotetakerMediaParams & Overrides): Promise< + NylasResponse + > { + return this.apiClient.request({ + method: 'GET', + path: identifier + ? makePathParams( + '/v3/grants/{identifier}/notetakers/{notetakerId}/media', + { + identifier, + notetakerId, + } + ) + : makePathParams('/v3/notetakers/{notetakerId}/media', { notetakerId }), + overrides, + }); + } +} diff --git a/src/resources/redirectUris.ts b/src/resources/redirectUris.ts new file mode 100644 index 00000000..5cd8f9cb --- /dev/null +++ b/src/resources/redirectUris.ts @@ -0,0 +1,133 @@ +import { AsyncListResponse, Resource } from './resource.js'; +import { + NylasBaseResponse, + NylasResponse, + NylasListResponse, +} from '../models/response.js'; +import { + CreateRedirectUriRequest, + RedirectUri, + UpdateRedirectUriRequest, +} from '../models/redirectUri.js'; +import { Overrides } from '../config.js'; +import { makePathParams } from '../utils.js'; +/** + * @property redirectUriId The id of the Redirect URI to retrieve. + */ +export interface FindRedirectUrisParams { + redirectUriId: string; +} + +/** + * @property requestBody The values to create the Redirect URI with. + */ +export interface CreateRedirectUrisParams { + requestBody: CreateRedirectUriRequest; +} + +/** + * @property redirectUriId The id of the Redirect URI to update. + * @property requestBody The values to update the Redirect URI with. + */ +export interface UpdateRedirectUrisParams { + redirectUriId: string; + requestBody: UpdateRedirectUriRequest; +} + +/** + * @property redirectUriId The id of the Redirect URI to delete. + */ +export interface DestroyRedirectUrisParams { + redirectUriId: string; +} + +/** + * A collection of redirect URI related API endpoints. + * + * These endpoints allows for the management of redirect URIs. + */ +export class RedirectUris extends Resource { + /** + * Return all Redirect URIs + * @return The list of Redirect URIs + */ + public list({ overrides }: Overrides = {}): AsyncListResponse< + NylasListResponse + > { + return super._list>({ + overrides, + path: makePathParams('/v3/applications/redirect-uris', {}), + }); + } + + /** + * Return a Redirect URI + * @return The Redirect URI + */ + public find({ + redirectUriId, + overrides, + }: FindRedirectUrisParams & Overrides): Promise> { + return super._find({ + overrides, + path: makePathParams('/v3/applications/redirect-uris/{redirectUriId}', { + redirectUriId, + }), + }); + } + + /** + * Create a Redirect URI + * @return The created Redirect URI + */ + public create({ + requestBody, + overrides, + }: CreateRedirectUrisParams & Overrides): Promise< + NylasResponse + > { + return super._create({ + overrides, + path: makePathParams('/v3/applications/redirect-uris', {}), + requestBody, + }); + } + + /** + * Update a Redirect URI + * @return The updated Redirect URI + */ + public update({ + redirectUriId, + requestBody, + overrides, + }: UpdateRedirectUrisParams & Overrides): Promise< + NylasResponse + > { + return super._update({ + overrides, + path: makePathParams('/v3/applications/redirect-uris/{redirectUriId}', { + redirectUriId, + }), + requestBody, + }); + } + + /** + * Delete a Redirect URI + * @return The deleted Redirect URI + */ + public destroy({ + redirectUriId, + overrides, + }: DestroyRedirectUrisParams & Overrides): Promise< + NylasResponse + > { + return super._destroy({ + overrides, + path: makePathParams('/v3/applications/redirect-uris/{redirectUriId}', { + redirectUriId, + }), + }); + } +} diff --git a/src/resources/resource.ts b/src/resources/resource.ts new file mode 100644 index 00000000..57786095 --- /dev/null +++ b/src/resources/resource.ts @@ -0,0 +1,232 @@ +import APIClient from '../apiClient.js'; +import { OverridableNylasConfig } from '../config.js'; +import { ListQueryParams } from '../models/listQueryParams.js'; +import { + NylasResponse, + NylasListResponse, + ListResponseInnerType, +} from '../models/response.js'; + +interface ListParams { + queryParams?: ListQueryParams; + path: string; + overrides?: OverridableNylasConfig; + useGenerator?: boolean; +} + +interface FindParams { + path: string; + queryParams?: Record; + overrides?: OverridableNylasConfig; +} + +interface PayloadParams { + path: string; + queryParams?: Record; + requestBody: Record; + overrides?: OverridableNylasConfig; +} + +interface DestroyParams { + path: string; + queryParams?: Record; + requestBody?: Record; + overrides?: OverridableNylasConfig; +} + +type List = NylasListResponse>; + +/** + * Base class for Nylas API resources + * + * @ignore No public constructor or functions + */ +export class Resource { + protected apiClient: APIClient; + + /** + * @param apiClient client The configured Nylas API client + */ + constructor(apiClient: APIClient) { + this.apiClient = apiClient; + } + + private async fetchList>({ + queryParams, + path, + overrides, + }: ListParams): Promise { + const res = await this.apiClient.request({ + method: 'GET', + path, + queryParams, + overrides, + }); + + if (queryParams?.limit) { + let entriesRemaining = queryParams.limit; + + while (res.data.length != queryParams.limit) { + entriesRemaining = queryParams.limit - res.data.length; + + if (!res.nextCursor) { + break; + } + + const nextRes = await this.apiClient.request({ + method: 'GET', + path, + queryParams: { + ...queryParams, + limit: entriesRemaining, + pageToken: res.nextCursor, + }, + overrides, + }); + + res.data = res.data.concat(nextRes.data); + res.requestId = nextRes.requestId; + res.nextCursor = nextRes.nextCursor; + } + } + + return res; + } + + private async *listIterator>( + listParams: ListParams + ): AsyncGenerator, undefined> { + const first = await this.fetchList(listParams); + + yield first; + + let pageToken = first.nextCursor; + + while (pageToken) { + const res = await this.fetchList({ + ...listParams, + queryParams: pageToken + ? { + ...listParams.queryParams, + pageToken, + } + : listParams.queryParams, + }); + + yield res; + + pageToken = res.nextCursor; + } + + return undefined; + } + + protected _list>( + listParams: ListParams + ): AsyncListResponse { + const iterator = this.listIterator(listParams); + const first = iterator.next().then( + (res) => + ({ + ...res.value, + next: iterator.next.bind(iterator), + }) as ListYieldReturn + ); + + return Object.assign(first, { + [Symbol.asyncIterator]: this.listIterator.bind( + this, + listParams + ) as () => AsyncGenerator, + }); + } + + protected _find({ + path, + queryParams, + overrides, + }: FindParams): Promise> { + return this.apiClient.request>({ + method: 'GET', + path, + queryParams, + overrides, + }); + } + + private payloadRequest( + method: 'POST' | 'PUT' | 'PATCH', + { path, queryParams, requestBody, overrides }: PayloadParams + ): Promise> { + return this.apiClient.request>({ + method, + path, + queryParams, + body: requestBody, + overrides, + }); + } + + protected _create(params: PayloadParams): Promise> { + return this.payloadRequest('POST', params); + } + + protected _update(params: PayloadParams): Promise> { + return this.payloadRequest('PUT', params); + } + + protected _updatePatch( + params: PayloadParams + ): Promise> { + return this.payloadRequest('PATCH', params); + } + + protected _destroy({ + path, + queryParams, + requestBody, + overrides, + }: DestroyParams): Promise { + return this.apiClient.request({ + method: 'DELETE', + path, + queryParams, + body: requestBody, + overrides, + }); + } + + protected _getRaw({ + path, + queryParams, + overrides, + }: FindParams): Promise { + return this.apiClient.requestRaw({ + method: 'GET', + path, + queryParams, + overrides, + }); + } + + protected _getStream({ + path, + queryParams, + overrides, + }: FindParams): Promise> { + return this.apiClient.requestStream({ + method: 'GET', + path, + queryParams, + overrides, + }); + } +} + +type ListYieldReturn = T & { + next: () => Promise>; +}; + +export interface AsyncListResponse extends Promise> { + [Symbol.asyncIterator](): AsyncGenerator; +} diff --git a/src/resources/scheduler.ts b/src/resources/scheduler.ts new file mode 100644 index 00000000..397f5175 --- /dev/null +++ b/src/resources/scheduler.ts @@ -0,0 +1,16 @@ +import { Configurations } from './configurations.js'; +import { Sessions } from './sessions.js'; +import { Bookings } from './bookings.js'; +import APIClient from '../apiClient.js'; + +export class Scheduler { + public configurations: Configurations; + public bookings: Bookings; + public sessions: Sessions; + + constructor(apiClient: APIClient) { + this.configurations = new Configurations(apiClient); + this.bookings = new Bookings(apiClient); + this.sessions = new Sessions(apiClient); + } +} diff --git a/src/resources/sessions.ts b/src/resources/sessions.ts new file mode 100644 index 00000000..410cf2c9 --- /dev/null +++ b/src/resources/sessions.ts @@ -0,0 +1,55 @@ +import { Overrides } from '../config.js'; +import { NylasBaseResponse, NylasResponse } from '../models/response.js'; +import { CreateSessionRequest, Session } from '../models/scheduler.js'; +import { Resource } from './resource.js'; +import { makePathParams } from '../utils.js'; +/** + * The parameters for the {@link Sessions.create} method + * @property identifier The identifier of the grant to act upon + * @property requestBody The request body to create a session + */ +export interface CreateSessionParams { + requestBody: CreateSessionRequest; +} + +/** + * The parameters for the {@link Sessions.destroy} method + * @property identifier The identifier of the grant to act upon + * @property sessionId The id of the Session to retrieve. Use "primary" to refer to the primary session associated with grant. + */ +export interface DestroySessionParams { + sessionId: string; +} + +export class Sessions extends Resource { + /** + * Create a Session + * @return The created session + */ + public create({ + requestBody, + overrides, + }: CreateSessionParams & Overrides): Promise> { + return super._create({ + path: makePathParams('/v3/scheduling/sessions', {}), + requestBody, + overrides, + }); + } + + /** + * Delete a Session + * @return The deleted Session + */ + public destroy({ + sessionId, + overrides, + }: DestroySessionParams & Overrides): Promise { + return super._destroy({ + path: makePathParams('/v3/scheduling/sessions/{sessionId}', { + sessionId, + }), + overrides, + }); + } +} diff --git a/src/resources/smartCompose.ts b/src/resources/smartCompose.ts new file mode 100644 index 00000000..7170ac68 --- /dev/null +++ b/src/resources/smartCompose.ts @@ -0,0 +1,78 @@ +import { Resource } from './resource.js'; +import { + ComposeMessageRequest, + ComposeMessageResponse, +} from '../models/smartCompose.js'; +import { Overrides } from '../config.js'; +import { NylasResponse } from '../models/response.js'; +import { makePathParams } from '../utils.js'; +/** + * The parameters for the {@link SmartCompose.composeMessage} method + * @property identifier The identifier of the grant to act upon + * @property requestBody The prompt that smart compose will use to generate a message suggestion + */ +export interface ComposeMessageParams { + identifier: string; + requestBody: ComposeMessageRequest; +} + +/** + * The parameters for the {@link SmartCompose.composeMessageReply} method + * @property identifier The identifier of the grant to act upon + * @property messageId The id of the message to reply to + * @property requestBody The prompt that smart compose will use to generate a reply suggestion + */ +export interface ComposeMessageReplyParams { + identifier: string; + messageId: string; + requestBody: ComposeMessageRequest; +} + +/** + * A collection of Smart Compose related API endpoints. + * + * These endpoints allow for the generation of message suggestions. + */ +export class SmartCompose extends Resource { + /** + * Compose a message + * @return The generated message + */ + public composeMessage({ + identifier, + requestBody, + overrides, + }: ComposeMessageParams & Overrides): Promise< + NylasResponse + > { + return super._create({ + path: makePathParams('/v3/grants/{identifier}/messages/smart-compose', { + identifier, + }), + requestBody, + overrides, + }); + } + + /** + * Compose a message reply + * @return The generated message reply + */ + public composeMessageReply({ + identifier, + messageId, + requestBody, + overrides, + }: ComposeMessageReplyParams & Overrides): Promise< + NylasResponse + > { + return super._create({ + path: makePathParams( + '/v3/grants/{identifier}/messages/{messageId}/smart-compose', + { identifier, messageId } + ), + requestBody, + overrides, + }); + } +} diff --git a/src/resources/threads.ts b/src/resources/threads.ts new file mode 100644 index 00000000..ee30e2d1 --- /dev/null +++ b/src/resources/threads.ts @@ -0,0 +1,149 @@ +import { + ListThreadsQueryParams, + Thread, + UpdateThreadRequest, +} from '../models/threads.js'; +import { AsyncListResponse, Resource } from './resource.js'; +import { Overrides } from '../config.js'; +import { + NylasBaseResponse, + NylasListResponse, + NylasResponse, +} from '../models/response.js'; +import { makePathParams } from '../utils.js'; + +/** + * The parameters for the {@link Threads.list} method + * @property identifier The identifier of the grant to act upon + * @property queryParams The query parameters to include in the request + */ +export interface ListThreadsParams { + identifier: string; + queryParams?: ListThreadsQueryParams; +} + +/** + * The parameters for the {@link Threads.find} method + * @property identifier The identifier of the grant to act upon + * @property threadId The id of the thread to retrieve. + * @property queryParams The query parameters to include in the request + */ +export interface FindThreadParams { + identifier: string; + threadId: string; +} + +/** + * The parameters for the {@link Threads.update} method + * @property identifier The identifier of the grant to act upon + * @property threadId The id of the thread to update + * @property requestBody The values to update the thread with + */ +export interface UpdateThreadParams { + identifier: string; + threadId: string; + requestBody: UpdateThreadRequest; +} + +/** + * The parameters for the {@link Threads.destroy} method + * @property identifier The identifier of the grant to act upon + * @property threadId The id of the thread to delete + */ +export interface DestroyThreadParams { + identifier: string; + threadId: string; +} + +/** + * Nylas Threads API + * + * The Nylas Threads API allows you to list, find, update, and delete threads on user accounts. + */ +export class Threads extends Resource { + /** + * Return all Threads + * @return A list of threads + */ + public list({ + identifier, + queryParams, + overrides, + }: ListThreadsParams & Overrides): AsyncListResponse< + NylasListResponse + > { + const modifiedQueryParams: Record | undefined = queryParams + ? { ...queryParams } + : undefined; + + // Transform some query params that are arrays into comma-delimited strings + if (modifiedQueryParams && queryParams) { + if (Array.isArray(queryParams?.anyEmail)) { + delete modifiedQueryParams.anyEmail; + modifiedQueryParams['any_email'] = queryParams.anyEmail.join(','); + } + } + + return super._list>({ + queryParams: modifiedQueryParams, + overrides, + path: makePathParams('/v3/grants/{identifier}/threads', { identifier }), + }); + } + + /** + * Return a Thread + * @return The thread + */ + public find({ + identifier, + threadId, + overrides, + }: FindThreadParams & Overrides): Promise> { + return super._find({ + path: makePathParams('/v3/grants/{identifier}/threads/{threadId}', { + identifier, + threadId, + }), + overrides, + }); + } + + /** + * Update a Thread + * @return The updated thread + */ + public update({ + identifier, + threadId, + requestBody, + overrides, + }: UpdateThreadParams & Overrides): Promise> { + return super._update({ + path: makePathParams('/v3/grants/{identifier}/threads/{threadId}', { + identifier, + threadId, + }), + requestBody, + overrides, + }); + } + + /** + * Delete a Thread + * @return The deleted thread + */ + public destroy({ + identifier, + threadId, + overrides, + }: DestroyThreadParams & Overrides): Promise { + return super._destroy({ + path: makePathParams('/v3/grants/{identifier}/threads/{threadId}', { + identifier, + threadId, + }), + overrides, + }); + } +} diff --git a/src/resources/webhooks.ts b/src/resources/webhooks.ts new file mode 100644 index 00000000..5d9b8726 --- /dev/null +++ b/src/resources/webhooks.ts @@ -0,0 +1,168 @@ +import { AsyncListResponse, Resource } from './resource.js'; +import { Overrides } from '../config.js'; +import { NylasResponse, NylasListResponse } from '../models/response.js'; +import { + CreateWebhookRequest, + UpdateWebhookRequest, + Webhook, + WebhookDeleteResponse, + WebhookIpAddressesResponse, + WebhookWithSecret, +} from '../models/webhooks.js'; +import { makePathParams } from '../utils.js'; +/** + * @property webhookId The ID of the webhook destination to update + */ +export interface FindWebhookParams { + webhookId: string; +} + +/** + * @property requestBody The webhook destination details + */ +export interface CreateWebhookParams { + requestBody: CreateWebhookRequest; +} + +/** + * @property webhookId The ID of the webhook destination to update + * @property requestBody The updated webview destination details + */ +export interface UpdateWebhookParams { + webhookId: string; + requestBody: UpdateWebhookRequest; +} + +/** + * @property webhookId The ID of the webhook destination to delete + */ +export interface DestroyWebhookParams { + webhookId: string; +} + +/** + * Nylas Webhooks API + * + * The Nylas Webhooks API allows your application to receive notifications in real-time when certain events occur. + */ +export class Webhooks extends Resource { + /** + * List all webhook destinations for the application + * @returns The list of webhook destinations + */ + public list({ overrides }: Overrides = {}): AsyncListResponse< + NylasListResponse + > { + return super._list>({ + overrides, + path: makePathParams('/v3/webhooks', {}), + }); + } + + /** + * Return a webhook destination + * @return The webhook destination + */ + public find({ + webhookId, + overrides, + }: FindWebhookParams & Overrides): Promise> { + return super._find({ + path: makePathParams('/v3/webhooks/{webhookId}', { webhookId }), + overrides, + }); + } + + /** + * Create a webhook destination + * @returns The created webhook destination + */ + public create({ + requestBody, + overrides, + }: CreateWebhookParams & Overrides): Promise< + NylasResponse + > { + return super._create({ + path: makePathParams('/v3/webhooks', {}), + requestBody, + overrides, + }); + } + + /** + * Update a webhook destination + * @returns The updated webhook destination + */ + public update({ + webhookId, + requestBody, + overrides, + }: UpdateWebhookParams & Overrides): Promise> { + return super._update({ + path: makePathParams('/v3/webhooks/{webhookId}', { webhookId }), + requestBody, + overrides, + }); + } + + /** + * Delete a webhook destination + * @returns The deletion response + */ + public destroy({ + webhookId, + overrides, + }: DestroyWebhookParams & Overrides): Promise { + return super._destroy({ + path: makePathParams('/v3/webhooks/{webhookId}', { webhookId }), + overrides, + }); + } + + /** + * Update the webhook secret value for a destination + * @returns The updated webhook destination with the webhook secret + */ + public rotateSecret({ + webhookId, + overrides, + }: DestroyWebhookParams & Overrides): Promise< + NylasResponse + > { + return super._create({ + path: makePathParams('/v3/webhooks/rotate-secret/{webhookId}', { + webhookId, + }), + requestBody: {}, + overrides, + }); + } + + /** + * Get the current list of IP addresses that Nylas sends webhooks from + * @returns The list of IP addresses that Nylas sends webhooks from + */ + public ipAddresses({ overrides }: Overrides = {}): Promise< + NylasResponse + > { + return super._find({ + path: makePathParams('/v3/webhooks/ip-addresses', {}), + overrides, + }); + } + + /** + * Extract the challenge parameter from a URL + * @param url The URL sent by Nylas containing the challenge parameter + * @returns The challenge parameter + */ + public extractChallengeParameter(url: string): string { + const urlObject = new URL(url); + const challengeParameter = urlObject.searchParams.get('challenge'); + if (!challengeParameter) { + throw new Error('Invalid URL or no challenge parameter found.'); + } + return challengeParameter; + } +} diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 00000000..8782da06 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,301 @@ +import { camelCase, snakeCase } from 'change-case'; +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import * as mime from 'mime-types'; +import { Readable } from 'node:stream'; +import { File as _File, Blob as _Blob } from 'formdata-node'; +import { CreateAttachmentRequest } from './models/attachments.js'; + +export function createFileRequestBuilder( + filePath: string +): CreateAttachmentRequest { + const stats = fs.statSync(filePath); + const filename = path.basename(filePath); + const contentType = mime.lookup(filePath) || 'application/octet-stream'; + const content = fs.createReadStream(filePath); + + return { + filename, + contentType, + content, + size: stats.size, + }; +} + +/** + * Converts a ReadableStream to a base64 encoded string. + * @param stream The ReadableStream containing the binary data. + * @returns The stream base64 encoded to a string. + */ +export function streamToBase64(stream: NodeJS.ReadableStream): Promise { + return new Promise((resolve, reject) => { + const chunks: Buffer[] = []; + stream.on('data', (chunk: Buffer) => { + chunks.push(chunk); + }); + stream.on('end', () => { + const base64 = Buffer.concat(chunks).toString('base64'); + resolve(base64); + }); + stream.on('error', (err) => { + reject(err); + }); + }); +} + +/** + * Converts a ReadableStream to a File-like object that can be used with FormData. + * @param attachment The attachment containing the stream and metadata. + * @param mimeType The MIME type for the file (optional). + * @returns A File-like object that properly handles the stream. + */ +export function attachmentStreamToFile( + attachment: CreateAttachmentRequest, + mimeType?: string +): any { + if (mimeType != null && typeof mimeType !== 'string') { + throw new Error('Invalid mimetype, expected string.'); + } + const content = attachment.content; + if (typeof content === 'string' || Buffer.isBuffer(content)) { + throw new Error('Invalid attachment content, expected ReadableStream.'); + } + + // Create a file-shaped object that FormData can handle properly + const fileObject = { + type: mimeType || attachment.contentType, + name: attachment.filename, + [Symbol.toStringTag]: 'File', + stream(): NodeJS.ReadableStream { + return content; + }, + }; + + // Add size if available + if (attachment.size !== undefined) { + (fileObject as any).size = attachment.size; + } + + return fileObject; +} + +/** + * Encodes the content of each attachment to base64. + * Handles ReadableStream, Buffer, and string content types. + * @param attachments The attachments to encode. + * @returns The attachments with their content encoded to base64. + */ +export async function encodeAttachmentContent( + attachments: CreateAttachmentRequest[] +): Promise { + return await Promise.all( + attachments.map(async (attachment) => { + let base64EncodedContent: string; + + if (attachment.content instanceof Readable) { + // ReadableStream -> base64 + base64EncodedContent = await streamToBase64(attachment.content); + } else if (Buffer.isBuffer(attachment.content)) { + // Buffer -> base64 + base64EncodedContent = attachment.content.toString('base64'); + } else { + // string (assumed to already be base64) + base64EncodedContent = attachment.content as string; + } + + return { ...attachment, content: base64EncodedContent }; + }) + ); +} + +/** + * @deprecated Use encodeAttachmentContent instead. This alias is provided for backwards compatibility. + * Encodes the content of each attachment stream to base64. + * @param attachments The attachments to encode. + * @returns The attachments with their content encoded to base64. + */ +export async function encodeAttachmentStreams( + attachments: CreateAttachmentRequest[] +): Promise { + return encodeAttachmentContent(attachments); +} + +/** + * The type of function that converts a string to a different casing. + * @ignore Not for public use. + */ +type CasingFunction = (input: string, options?: any) => string; + +/** + * Applies the casing function and ensures numeric parts are preceded by underscores in snake_case. + * @param casingFunction The original casing function. + * @param input The string to convert. + * @returns The converted string. + */ +function applyCasing(casingFunction: CasingFunction, input: string): string { + const transformed = casingFunction(input); + + if (casingFunction === snakeCase) { + return transformed.replace(/(\d+)/g, '_$1'); + } else { + return transformed.replace(/_+(\d+)/g, (match, p1) => p1); + } +} + +/** + * A utility function that recursively converts all keys in an object to a given case. + * @param obj The object to convert + * @param casingFunction The function to use to convert the keys + * @param excludeKeys An array of keys to exclude from conversion + * @returns The converted object + * @ignore Not for public use. + */ +function convertCase( + obj: Record, + casingFunction: CasingFunction, + excludeKeys?: string[] +): Record { + const newObj = {} as Record; + for (const key in obj) { + if (excludeKeys?.includes(key)) { + newObj[key] = obj[key]; + } else if (Array.isArray(obj[key])) { + newObj[applyCasing(casingFunction, key)] = (obj[key] as any[]).map( + (item) => { + if (typeof item === 'object') { + return convertCase(item, casingFunction); + } else { + return item; + } + } + ); + } else if (typeof obj[key] === 'object' && obj[key] !== null) { + newObj[applyCasing(casingFunction, key)] = convertCase( + obj[key] as Record, + casingFunction + ); + } else { + newObj[applyCasing(casingFunction, key)] = obj[key]; + } + } + return newObj; +} + +/** + * A utility function that recursively converts all keys in an object to camelCase. + * @param obj The object to convert + * @param exclude An array of keys to exclude from conversion + * @returns The converted object + * @ignore Not for public use. + */ +export function objKeysToCamelCase( + obj: Record, + exclude?: string[] +): any { + return convertCase(obj, camelCase, exclude); +} + +/** + * A utility function that recursively converts all keys in an object to snake_case. + * @param obj The object to convert + * @param exclude An array of keys to exclude from conversion + * @returns The converted object + */ +export function objKeysToSnakeCase( + obj: Record, + exclude?: string[] +): any { + return convertCase(obj, snakeCase, exclude); +} + +/** + * A better "Partial" type that makes all properties optional, including nested ones. + * @see https://grrr.tech/posts/2021/typescript-partial/ + */ +export type Subset = { + [attr in keyof K]?: K[attr] extends object + ? Subset + : K[attr] extends object | null + ? Subset | null + : K[attr] extends object | null | undefined + ? Subset | null | undefined + : K[attr]; +}; + +/** + * Safely encodes a path template with replacements. + * @param pathTemplate The path template to encode. + * @param replacements The replacements to encode. + * @returns The encoded path. + */ +export function safePath( + pathTemplate: string, + replacements: Record +): string { + return pathTemplate.replace(/\{(\w+)\}/g, (_, key) => { + const val = replacements[key]; + if (val == null) throw new Error(`Missing replacement for ${key}`); + + // Decode first (handles already encoded values), then encode + // This prevents double encoding while ensuring everything is properly encoded + try { + const decoded = decodeURIComponent(val); + return encodeURIComponent(decoded); + } catch (error) { + // If decoding fails, the value wasn't properly encoded, so just encode it + return encodeURIComponent(val); + } + }); +} + +// Extracts all {varName} from a string as a union type +export type ExtractPathParams = + S extends `${string}{${infer Param}}${infer Rest}` + ? Param | ExtractPathParams + : never; + +// Type-safe path params object +export interface PathParams { + path: Path; + params: Record, string>; + toString(): string; + toPath(): string; +} + +// Helper to create PathParams with type safety and runtime interpolation +export function makePathParams( + path: Path, + params: Record, string> +): string { + return safePath(path, params); +} + +/** + * Calculates the total payload size for a message request, including body and attachments. + * This is used to determine if multipart/form-data should be used instead of JSON. + * @param requestBody The message request body + * @returns The total estimated payload size in bytes + */ +export function calculateTotalPayloadSize(requestBody: any): number { + let totalSize = 0; + + // Calculate size of the message body (JSON payload without attachments) + const messagePayloadWithoutAttachments = { + ...requestBody, + attachments: undefined, + }; + const messagePayloadString = JSON.stringify( + objKeysToSnakeCase(messagePayloadWithoutAttachments) + ); + totalSize += Buffer.byteLength(messagePayloadString, 'utf8'); + + // Add attachment sizes + const attachmentSize = + requestBody.attachments?.reduce((total: number, attachment: any) => { + return total + (attachment.size || 0); + }, 0) || 0; + + totalSize += attachmentSize; + + return totalSize; +} diff --git a/src/version.ts b/src/version.ts new file mode 100644 index 00000000..199794ff --- /dev/null +++ b/src/version.ts @@ -0,0 +1,2 @@ +// This file is generated by scripts/exportVersion.js +export const SDK_VERSION = '8.0.1'; diff --git a/tests/apiClient.spec.ts b/tests/apiClient.spec.ts new file mode 100644 index 00000000..032a1ba8 --- /dev/null +++ b/tests/apiClient.spec.ts @@ -0,0 +1,876 @@ +import APIClient, { RequestOptionsParams } from '../src/apiClient'; +import { + NylasApiError, + NylasOAuthError, + NylasSdkTimeoutError, +} from '../src/models/error'; +import { SDK_VERSION } from '../src/version'; +import { mockResponse } from './testUtils'; +import { FormData } from 'formdata-node'; +import { Readable } from 'stream'; + +import fetchMock from 'jest-fetch-mock'; + +describe('APIClient', () => { + beforeEach(() => { + fetchMock.resetMocks(); + }); + + describe('constructor', () => { + it('should initialize all the values', () => { + const client = new APIClient({ + apiKey: 'test', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: { + 'X-SDK-Test-Header': 'This is a test', + }, + }); + + expect(client.apiKey).toBe('test'); + expect(client.serverUrl).toBe('https://test.api.nylas.com'); + expect(client.timeout).toBe(30000); + expect(client.headers).toEqual({ + 'X-SDK-Test-Header': 'This is a test', + }); + }); + }); + + describe('request functions', () => { + let client: APIClient; + + beforeAll(() => { + client = new APIClient({ + apiKey: 'testApiKey', + apiUri: 'https://api.us.nylas.com', + timeout: 30, + headers: {}, + }); + }); + + describe('setRequestUrl', () => { + it('should set all the fields properly', () => { + const options = client.requestOptions({ + path: '/test', + method: 'GET', + headers: { 'X-SDK-Test-Header': 'This is a test' }, + queryParams: { param: 'value' }, + body: { id: 'abc123' }, + overrides: { apiUri: 'https://test.api.nylas.com' }, + }); + + expect(options.method).toBe('GET'); + expect(options.headers).toEqual({ + Accept: 'application/json', + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + 'User-Agent': `Nylas Node SDK v${SDK_VERSION}`, + 'X-SDK-Test-Header': 'This is a test', + }); + expect(options.url).toEqual( + new URL('https://test.api.nylas.com/test?param=value') + ); + expect(options.body).toBe('{"id":"abc123"}'); + }); + + it('should use defaults when just the path and method are passed in', () => { + const options = client.requestOptions({ + path: '/test', + method: 'POST', + }); + + expect(options.method).toBe('POST'); + expect(options.headers).toEqual({ + Accept: 'application/json', + Authorization: 'Bearer testApiKey', + 'User-Agent': `Nylas Node SDK v${SDK_VERSION}`, + }); + expect(options.url).toEqual(new URL('https://api.us.nylas.com/test')); + expect(options.body).toBeUndefined(); + }); + + it('should set metadata_pair as a query string', () => { + const options = client.requestOptions({ + path: '/test', + method: 'GET', + queryParams: { + metadataPair: { key: 'value', anotherKey: 'anotherValue' }, + }, + }); + + expect(options.url).toEqual( + new URL( + 'https://api.us.nylas.com/test?metadata_pair=key%3Avalue%2CanotherKey%3AanotherValue' + ) + ); + }); + + it('should handle all the different types of query params', () => { + const options = client.requestOptions({ + path: '/test', + method: 'GET', + queryParams: { + foo: 'bar', + list: ['a', 'b', 'c'], + map: { key1: 'value1', key2: 'value2' }, + }, + }); + + expect(options.url).toEqual( + new URL( + 'https://api.us.nylas.com/test?foo=bar&list=a&list=b&list=c&map=key1%3Avalue1&map=key2%3Avalue2' + ) + ); + }); + + it('should handle repeated query parameters', () => { + const options = client.requestOptions({ + path: '/test', + method: 'GET', + queryParams: { + eventType: ['default', 'outOfOffice', 'focusTime'], + }, + }); + + expect(options.url).toEqual( + new URL( + 'https://api.us.nylas.com/test?event_type=default&event_type=outOfOffice&event_type=focusTime' + ) + ); + }); + + it('should not convert metadata object keys to snake_case', () => { + const metadata = { + key0: 'value', + key1: 'another', + camelCase: true, + snake_case: false, + normal: 'yes', + }; + const expectedBody = JSON.stringify({ + metadata: metadata, + }); + + const options = client.requestOptions({ + path: '/test', + method: 'POST', + body: { + metadata: metadata, + }, + }); + + expect(options.body).toEqual(expectedBody); + }); + }); + + describe('newRequest', () => { + it('should set all the fields properly', async () => { + client.headers = { + 'global-header': 'global-value', + }; + + const options: RequestOptionsParams = { + path: '/test', + method: 'POST', + headers: { 'X-SDK-Test-Header': 'This is a test' }, + queryParams: { param: 'value' }, + body: { id: 'abc123' }, + overrides: { + apiUri: 'https://override.api.nylas.com', + headers: { override: 'bar' }, + }, + }; + const newRequest = await client.newRequest(options); + + expect(newRequest.method).toBe('POST'); + // Native Headers API uses .get() to check individual headers + expect(newRequest.headers.get('Accept')).toEqual('application/json'); + expect(newRequest.headers.get('Authorization')).toEqual( + 'Bearer testApiKey' + ); + expect(newRequest.headers.get('Content-Type')).toEqual( + 'application/json' + ); + expect(newRequest.headers.get('User-Agent')).toEqual( + `Nylas Node SDK v${SDK_VERSION}` + ); + expect(newRequest.headers.get('X-SDK-Test-Header')).toEqual( + 'This is a test' + ); + expect(newRequest.headers.get('global-header')).toEqual('global-value'); + expect(newRequest.headers.get('override')).toEqual('bar'); + expect(newRequest.url).toEqual( + 'https://override.api.nylas.com/test?param=value' + ); + expect(newRequest.body?.toString()).toBe('{"id":"abc123"}'); + }); + }); + + describe('requestWithResponse', () => { + it('should return the data if the response is valid', async () => { + const mockFlowId = 'test-flow-123'; + const mockHeaders = { + 'x-request-id': 'req-123', + 'x-nylas-api-version': 'v3', + }; + + const payload = { + id: 123, + name: 'test', + isValid: true, + }; + + const mockResp = mockResponse(JSON.stringify(payload)); + mockResp.headers.set('x-fastly-id', mockFlowId); + Object.entries(mockHeaders).forEach(([key, value]) => { + mockResp.headers.set(key, value); + }); + + const requestWithResponse = await client.requestWithResponse(mockResp); + + expect(requestWithResponse).toEqual({ + ...payload, + flowId: mockFlowId, + headers: { + xFastlyId: mockFlowId, + xNylasApiVersion: mockHeaders['x-nylas-api-version'], + xRequestId: mockHeaders['x-request-id'], + }, + }); + expect((requestWithResponse as any).flowId).toBe(mockFlowId); + expect((requestWithResponse as any).headers['xFastlyId']).toBe( + mockFlowId + ); + expect((requestWithResponse as any).headers['xRequestId']).toBe( + mockHeaders['x-request-id'] + ); + }); + + it('should include rawHeaders with dashed lowercase keys', async () => { + const mockFlowId = 'test-flow-raw-123'; + const mockHeaders = { + 'x-request-id': 'req-raw-123', + 'x-nylas-api-version': 'v3', + 'x-rate-limit-limit': '100', + 'x-rate-limit-remaining': '99', + }; + + const payload = { + id: 456, + name: 'raw-test', + }; + + const mockResp = mockResponse(JSON.stringify(payload)); + mockResp.headers.set('x-fastly-id', mockFlowId); + Object.entries(mockHeaders).forEach(([key, value]) => { + mockResp.headers.set(key, value); + }); + + const result = await client.requestWithResponse(mockResp); + + expect((result as any).rawHeaders).toBeDefined(); + expect((result as any).rawHeaders['x-fastly-id']).toBe(mockFlowId); + expect((result as any).rawHeaders['x-request-id']).toBe( + mockHeaders['x-request-id'] + ); + expect((result as any).rawHeaders['x-nylas-api-version']).toBe( + mockHeaders['x-nylas-api-version'] + ); + expect((result as any).rawHeaders['x-rate-limit-limit']).toBe('100'); + expect((result as any).rawHeaders['x-rate-limit-remaining']).toBe('99'); + }); + }); + + describe('request', () => { + it('should return a response if the response is valid', async () => { + const mockFlowId = 'test-flow-abc'; + const mockHeaders = { + 'x-request-id': 'req-abc', + 'x-nylas-api-version': 'v3', + }; + + const payload = { + id: 123, + name: 'test', + isValid: true, + }; + + const mockResp = mockResponse(JSON.stringify(payload)); + mockResp.headers.set('x-fastly-id', mockFlowId); + Object.entries(mockHeaders).forEach(([key, value]) => { + mockResp.headers.set(key, value); + }); + + fetchMock.mockImplementationOnce(() => Promise.resolve(mockResp)); + + const response = await client.request({ + path: '/test', + method: 'GET', + }); + + expect(response).toEqual({ + ...payload, + flowId: mockFlowId, + headers: { + xFastlyId: mockFlowId, + xNylasApiVersion: mockHeaders['x-nylas-api-version'], + xRequestId: mockHeaders['x-request-id'], + }, + }); + expect((response as any).flowId).toBe(mockFlowId); + expect((response as any).headers['xFastlyId']).toBe(mockFlowId); + }); + + it('should include rawHeaders on standard responses', async () => { + const mockFlowId = 'test-flow-raw-abc'; + const mockHeaders = { + 'x-request-id': 'req-raw-abc', + 'x-nylas-api-version': 'v3', + 'x-rate-limit-limit': '200', + }; + + const payload = { + id: 789, + name: 'raw', + }; + + const mockResp = mockResponse(JSON.stringify(payload)); + mockResp.headers.set('x-fastly-id', mockFlowId); + Object.entries(mockHeaders).forEach(([key, value]) => { + mockResp.headers.set(key, value); + }); + + fetchMock.mockImplementationOnce(() => Promise.resolve(mockResp)); + + const response = await client.request({ path: '/test', method: 'GET' }); + + expect((response as any).rawHeaders).toBeDefined(); + expect((response as any).rawHeaders['x-fastly-id']).toBe(mockFlowId); + expect((response as any).rawHeaders['x-request-id']).toBe( + mockHeaders['x-request-id'] + ); + expect((response as any).rawHeaders['x-nylas-api-version']).toBe( + mockHeaders['x-nylas-api-version'] + ); + expect((response as any).rawHeaders['x-rate-limit-limit']).toBe('200'); + }); + + it('should throw an error if the response is undefined', async () => { + fetchMock.mockImplementationOnce(() => + Promise.resolve(undefined as any) + ); + + await expect( + client.request({ + path: '/test', + method: 'GET', + }) + ).rejects.toThrow(new Error('Failed to fetch response')); + }); + + it('should throw a general error if the response is an error but cannot be parsed', async () => { + const payload = { + invalid: true, + }; + fetchMock.mockImplementationOnce(() => + Promise.resolve(mockResponse(JSON.stringify(payload), 400)) + ); + + await expect( + client.request({ + path: '/test', + method: 'GET', + }) + ).rejects.toThrow( + new Error( + 'Received an error but could not parse response from the server: {"invalid":true}' + ) + ); + }); + + it('should throw a NylasAuthError if the error comes from connect/token or connect/revoke', async () => { + const mockFlowId = 'auth-flow-123'; + const mockHeaders = { + 'x-request-id': 'auth-req-123', + 'x-nylas-api-version': 'v3', + }; + + const payload = { + requestId: 'abc123', + error: 'Test error', + errorCode: 400, + errorDescription: 'Nylas SDK Test error', + errorUri: 'https://test.api.nylas.com/docs/errors#test-error', + }; + + const mockResp = mockResponse(JSON.stringify(payload), 400); + mockResp.headers.set('x-fastly-id', mockFlowId); + mockResp.headers.set('x-request-id', mockHeaders['x-request-id']); + mockResp.headers.set( + 'x-nylas-api-version', + mockHeaders['x-nylas-api-version'] + ); + + fetchMock.mockImplementation(() => Promise.resolve(mockResp)); + + try { + await client.request({ + path: '/connect/token', + method: 'POST', + }); + fail('Expected error to be thrown'); + } catch (error) { + expect(error).toBeInstanceOf(NylasOAuthError); + expect((error as NylasOAuthError).flowId).toBe(mockFlowId); + expect((error as NylasOAuthError).headers).toBeDefined(); + } + + try { + await client.request({ + path: '/connect/revoke', + method: 'POST', + }); + fail('Expected error to be thrown'); + } catch (error) { + expect(error).toBeInstanceOf(NylasOAuthError); + expect((error as NylasOAuthError).flowId).toBe(mockFlowId); + expect((error as NylasOAuthError).headers).toBeDefined(); + } + }); + + it('should throw a NylasApiError if the error comes from the other non-auth endpoints', async () => { + const mockFlowId = 'api-flow-456'; + const mockHeaders = { + 'x-request-id': 'api-req-456', + 'x-nylas-api-version': 'v3', + }; + + const payload = { + requestId: 'abc123', + error: { + type: 'invalid_request_error', + message: 'Invalid request', + }, + }; + + const mockResp = mockResponse(JSON.stringify(payload), 400); + mockResp.headers.set('x-fastly-id', mockFlowId); + mockResp.headers.set('x-request-id', mockHeaders['x-request-id']); + mockResp.headers.set( + 'x-nylas-api-version', + mockHeaders['x-nylas-api-version'] + ); + + fetchMock.mockImplementation(() => Promise.resolve(mockResp)); + + try { + await client.request({ + path: '/events', + method: 'POST', + }); + fail('Expected error to be thrown'); + } catch (error) { + expect(error).toBeInstanceOf(NylasApiError); + expect((error as NylasApiError).flowId).toBe(mockFlowId); + expect((error as NylasApiError).headers).toBeDefined(); + } + }); + + it('should respect override timeout when provided in seconds (value < 1000)', async () => { + const overrideTimeout = 2; // 2 second timeout + + fetchMock.mockImplementationOnce(() => { + // Immediately throw an AbortError to simulate a timeout + const error = new Error('The operation was aborted'); + error.name = 'AbortError'; + return Promise.reject(error); + }); + + await expect( + client.request({ + path: '/test', + method: 'GET', + overrides: { timeout: overrideTimeout }, + }) + ).rejects.toThrow( + new NylasSdkTimeoutError( + 'https://api.us.nylas.com/test', + overrideTimeout // Should remain as seconds in error + ) + ); + }); + + it('should respect override timeout when provided in milliseconds (value >= 1000) for backward compatibility', async () => { + // We no longer show the console warning since we're using TypeScript annotations instead + const originalWarn = console.warn; + console.warn = jest.fn(); + + try { + const overrideTimeoutMs = 2000; // 2000 milliseconds (2 seconds) + + fetchMock.mockImplementationOnce(() => { + // Immediately throw an AbortError to simulate a timeout + const error = new Error('The operation was aborted'); + error.name = 'AbortError'; + return Promise.reject(error); + }); + + await expect( + client.request({ + path: '/test', + method: 'GET', + overrides: { timeout: overrideTimeoutMs }, + }) + ).rejects.toThrow( + new NylasSdkTimeoutError( + 'https://api.us.nylas.com/test', + overrideTimeoutMs / 1000 // Should be converted to seconds for error + ) + ); + + // No need to check for deprecation warning anymore as we use TypeScript annotations + } finally { + console.warn = originalWarn; + } + }); + + it('should convert override timeout from seconds to milliseconds for setTimeout when value < 1000', async () => { + // We need to mock setTimeout to verify it's called with the correct duration + const originalSetTimeout = global.setTimeout; + const mockSetTimeout = jest.fn().mockImplementation(() => 123); // Return a timeout ID + global.setTimeout = mockSetTimeout as unknown as typeof setTimeout; + + try { + // Mock fetch to return a successful response so we can verify setTimeout + fetchMock.mockImplementationOnce(() => + Promise.resolve(mockResponse(JSON.stringify({ data: 'test' }))) + ); + + const overrideTimeout = 7; // 7 seconds + + await client.request({ + path: '/test', + method: 'GET', + overrides: { timeout: overrideTimeout }, + }); + + // Verify setTimeout was called with the timeout in milliseconds (7 seconds = 7000ms) + expect(mockSetTimeout).toHaveBeenCalledWith( + expect.any(Function), + overrideTimeout * 1000 + ); + } finally { + // Restore the original setTimeout + global.setTimeout = originalSetTimeout; + } + }); + + it('should keep override timeout in milliseconds for setTimeout when value >= 1000 (backward compatibility)', async () => { + // We no longer show the console warning since we're using TypeScript annotations instead + const originalWarn = console.warn; + console.warn = jest.fn(); + + // We need to mock setTimeout to verify it's called with the correct duration + const originalSetTimeout = global.setTimeout; + const mockSetTimeout = jest.fn().mockImplementation(() => 123); // Return a timeout ID + global.setTimeout = mockSetTimeout as unknown as typeof setTimeout; + + try { + // Mock fetch to return a successful response so we can verify setTimeout + fetchMock.mockImplementationOnce(() => + Promise.resolve(mockResponse(JSON.stringify({ data: 'test' }))) + ); + + const overrideTimeoutMs = 5000; // 5000 milliseconds (5 seconds) + + await client.request({ + path: '/test', + method: 'GET', + overrides: { timeout: overrideTimeoutMs }, + }); + + // Verify setTimeout was called with the timeout directly in milliseconds + expect(mockSetTimeout).toHaveBeenCalledWith( + expect.any(Function), + overrideTimeoutMs + ); + + // No need to check for deprecation warning anymore as we use TypeScript annotations + } finally { + // Restore the original setTimeout and console.warn + global.setTimeout = originalSetTimeout; + console.warn = originalWarn; + } + }); + + it('should use default timeout when no override provided', async () => { + fetchMock.mockImplementationOnce(() => { + // Immediately throw an AbortError to simulate a timeout + const error = new Error('The operation was aborted'); + error.name = 'AbortError'; + return Promise.reject(error); + }); + + await expect( + client.request({ + path: '/test', + method: 'GET', + }) + ).rejects.toThrow( + new NylasSdkTimeoutError( + 'https://api.us.nylas.com/test', + client.timeout + ) + ); + }); + + it('should complete request within timeout period', async () => { + const mockFlowId = 'success-flow-789'; + const mockHeaders = { + 'x-request-id': 'success-req-789', + 'x-nylas-api-version': 'v3', + }; + + const payload = { + data: 'test', + }; + + const mockResp = mockResponse(JSON.stringify(payload)); + mockResp.headers.set('x-fastly-id', mockFlowId); + Object.entries(mockHeaders).forEach(([key, value]) => { + mockResp.headers.set(key, value); + }); + + fetchMock.mockImplementationOnce(() => Promise.resolve(mockResp)); + + const result = await client.request({ + path: '/test', + method: 'GET', + }); + + expect(result).toEqual({ + ...payload, + flowId: mockFlowId, + headers: { + xFastlyId: mockFlowId, + xNylasApiVersion: mockHeaders['x-nylas-api-version'], + xRequestId: mockHeaders['x-request-id'], + }, + }); + expect((result as any).flowId).toBe(mockFlowId); + expect((result as any).headers['xFastlyId']).toBe(mockFlowId); + }); + + it('should handle form data in request options', () => { + const formData = new FormData(); + formData.append('message', JSON.stringify({ subject: 'Test' })); + + const options = client.requestOptions({ + path: '/test', + method: 'POST', + form: formData, + }); + + // Body should be a readable stream from FormDataEncoder + expect(options.body).toBeInstanceOf(Readable); + // Content-Type should be set to multipart/form-data with boundary + expect(options.headers['Content-Type']).toMatch( + /^multipart\/form-data; boundary=/ + ); + }); + + it('should throw error when JSON parsing fails in requestWithResponse', async () => { + const invalidJsonResponse = { + ok: true, + status: 200, + text: jest.fn().mockResolvedValue('invalid json content'), + json: jest.fn().mockRejectedValue(new Error('Unexpected token')), + headers: new Map(), + }; + + await expect( + client.requestWithResponse(invalidJsonResponse as any) + ).rejects.toThrow( + 'Could not parse response from the server: invalid json content' + ); + }); + + it('should handle response without headers.entries method', async () => { + const payload = { + id: 123, + name: 'test', + }; + + // Create a mock response without headers.entries + const mockResp = { + ok: true, + status: 200, + text: jest.fn().mockResolvedValue(JSON.stringify(payload)), + json: jest.fn().mockResolvedValue(payload), + headers: { + // No entries method - this tests the branch where entries is falsy + get: jest.fn().mockReturnValue(null), + }, + }; + + fetchMock.mockImplementationOnce(() => + Promise.resolve(mockResp as any) + ); + + const response = await client.request({ + path: '/test', + method: 'GET', + }); + + // Response will include flowId and headers even when entries doesn't exist + expect(response).toMatchObject(payload); + expect((response as any).headers).toEqual({}); + }); + + it('should handle requestWithResponse without headers.entries method', async () => { + const payload = { + id: 456, + name: 'test', + }; + + // Create a mock response without headers.entries + const mockResp = { + ok: true, + status: 200, + text: jest.fn().mockResolvedValue(JSON.stringify(payload)), + json: jest.fn().mockResolvedValue(payload), + headers: { + // No entries method - this tests the branch where entries is falsy + get: jest.fn().mockReturnValue(null), + }, + }; + + const result = await client.requestWithResponse(mockResp as any); + + // Response will include flowId and headers even when entries doesn't exist + expect(result).toMatchObject(payload); + expect((result as any).headers).toEqual({}); + }); + + it('should include duplex option when form data is provided', async () => { + const formData = new FormData(); + formData.append('message', JSON.stringify({ subject: 'Test' })); + + const mockResp = mockResponse(JSON.stringify({ success: true })); + fetchMock.mockImplementationOnce(() => Promise.resolve(mockResp)); + + // Test that the request succeeds with form data (which requires duplex) + // This indirectly tests that duplex was set correctly + const response = await client.request({ + path: '/test', + method: 'POST', + form: formData, + }); + + expect(response).toMatchObject({ success: true }); + }); + + it('should actually trigger timeout and abort request', async () => { + const shortTimeout = 0.001; // 1ms timeout - very short + + // Mock fetch to reject with AbortError when aborted + // This tests the timeout callback that aborts the request (lines 175-176) + fetchMock.mockImplementationOnce(() => { + return new Promise((_, reject) => { + // Simulate abort by rejecting with AbortError after a delay + setTimeout(() => { + const error = new Error('The operation was aborted'); + error.name = 'AbortError'; + reject(error); + }, 5); // Slightly longer than timeout to ensure abort happens + }); + }); + + await expect( + client.request({ + path: '/test', + method: 'GET', + overrides: { timeout: shortTimeout }, + }) + ).rejects.toThrow(NylasSdkTimeoutError); + }); + }); + + describe('requestRaw', () => { + it('should return raw buffer response', async () => { + const testData = 'raw binary data'; + const textEncoder = new TextEncoder(); + const mockResp = { + ok: true, + status: 200, + text: jest.fn().mockResolvedValue(testData), + json: jest.fn(), + headers: new Map(), + // Native fetch uses arrayBuffer() instead of buffer() + arrayBuffer: jest + .fn() + .mockResolvedValue(textEncoder.encode(testData).buffer), + }; + + fetchMock.mockImplementationOnce(() => + Promise.resolve(mockResp as any) + ); + + const result = await client.requestRaw({ + path: '/test', + method: 'GET', + }); + + expect(result).toBeInstanceOf(Buffer); + expect(result.toString()).toBe(testData); + }); + }); + + describe('requestStream', () => { + it('should return readable stream response', async () => { + const mockStream = { pipe: jest.fn(), on: jest.fn() }; + const mockResp = { + ok: true, + status: 200, + text: jest.fn().mockResolvedValue('stream data'), + json: jest.fn(), + headers: new Map(), + body: mockStream, + }; + + fetchMock.mockImplementationOnce(() => + Promise.resolve(mockResp as any) + ); + + const result = await client.requestStream({ + path: '/test', + method: 'GET', + }); + + expect(result).toBe(mockStream); + }); + + it('should throw error when response has no body', async () => { + const mockResp = { + ok: true, + status: 200, + text: jest.fn().mockResolvedValue('data'), + json: jest.fn(), + headers: new Map(), + body: null, + }; + + fetchMock.mockImplementationOnce(() => + Promise.resolve(mockResp as any) + ); + + await expect( + client.requestStream({ + path: '/test', + method: 'GET', + }) + ).rejects.toThrow('No response body'); + }); + }); + }); +}); diff --git a/tests/nylas.spec.ts b/tests/nylas.spec.ts new file mode 100644 index 00000000..67040485 --- /dev/null +++ b/tests/nylas.spec.ts @@ -0,0 +1,48 @@ +import Nylas from '../src/nylas'; + +describe('Nylas', () => { + describe('constructor', () => { + it('should initialize the Nylas object', () => { + const nylas = new Nylas({ + apiKey: 'test', + }); + + expect(nylas.constructor.name).toBe('Nylas'); + }); + + it('should initialize all the resources', () => { + const nylas = new Nylas({ + apiKey: 'test', + }); + + expect(nylas.applications.constructor.name).toBe('Applications'); + expect(nylas.auth.constructor.name).toBe('Auth'); + expect(nylas.calendars.constructor.name).toBe('Calendars'); + expect(nylas.events.constructor.name).toBe('Events'); + expect(nylas.webhooks.constructor.name).toBe('Webhooks'); + expect(nylas.folders.constructor.name).toBe('Folders'); + expect(nylas.attachments.constructor.name).toBe('Attachments'); + }); + + it('should configure the apiClient', () => { + const nylas = new Nylas({ + apiKey: 'test', + apiUri: 'https://test.nylas.com', + timeout: 60, + }); + + expect(nylas.apiClient.apiKey).toBe('test'); + expect(nylas.apiClient.serverUrl).toBe('https://test.nylas.com'); + expect(nylas.apiClient.timeout).toBe(60000); + }); + + it('should use correct defaults', () => { + const nylas = new Nylas({ + apiKey: 'test', + }); + + expect(nylas.apiClient.serverUrl).toBe('https://api.us.nylas.com'); + expect(nylas.apiClient.timeout).toBe(90000); + }); + }); +}); diff --git a/tests/resources/applications.spec.ts b/tests/resources/applications.spec.ts new file mode 100644 index 00000000..5612dfdc --- /dev/null +++ b/tests/resources/applications.spec.ts @@ -0,0 +1,55 @@ +import APIClient from '../../src/apiClient'; +import { Applications } from '../../src/resources/applications'; +jest.mock('../../src/apiClient'); + +describe('Applications', () => { + let apiClient: jest.Mocked; + let applications: Applications; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + applications = new Applications(apiClient); + apiClient.request.mockResolvedValue({}); + }); + + describe('getDetails', () => { + it('should call apiClient.request with the correct params', async () => { + await applications.getDetails({ + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/applications', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should call apiClient.request even without overrides set', async () => { + await applications.getDetails(); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/applications', + }); + }); + }); + + describe('constructor', () => { + it('should initialize the redirect-uri resource', () => { + expect(applications.redirectUris.constructor.name).toBe('RedirectUris'); + }); + }); +}); diff --git a/tests/resources/attachments.spec.ts b/tests/resources/attachments.spec.ts new file mode 100644 index 00000000..3c068b58 --- /dev/null +++ b/tests/resources/attachments.spec.ts @@ -0,0 +1,198 @@ +import APIClient from '../../src/apiClient'; +import { Attachments } from '../../src/resources/attachments'; +jest.mock('../../src/apiClient'); + +describe('Attachments', () => { + let apiClient: jest.Mocked; + let attachments: Attachments; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + attachments = new Attachments(apiClient); + apiClient.request.mockResolvedValue({}); + apiClient.requestRaw.mockResolvedValue(Buffer.from('')); + + // Mock Web ReadableStream (native in Node 18+) + const mockStream = new ReadableStream({ + start(controller) { + controller.enqueue(new Uint8Array([1, 2, 3])); + controller.close(); + }, + }); + apiClient.requestStream.mockResolvedValue(mockStream); + }); + + describe('find', () => { + it('should call apiClient.request with the correct params for attachment metadata', async () => { + await attachments.find({ + identifier: 'id123', + attachmentId: 'attach123', + queryParams: { + messageId: 'message123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/attachments/attach123', + queryParams: { + messageId: 'message123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode identifier and attachmentId in find', async () => { + await attachments.find({ + identifier: 'id 123', + attachmentId: 'attach/123', + queryParams: { messageId: 'message123' }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/attachments/attach%2F123', + }) + ); + }); + + it('should not double encode already-encoded identifier and attachmentId in find', async () => { + await attachments.find({ + identifier: 'id%20123', + attachmentId: 'attach%2F123', + queryParams: { messageId: 'message123' }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/attachments/attach%2F123', + }) + ); + }); + }); + + describe('downloadBytes', () => { + it('should call apiClient.requestRaw with the correct params for downloading an attachment as bytes', async () => { + await attachments.downloadBytes({ + identifier: 'id123', + attachmentId: 'attach123', + queryParams: { + messageId: 'message123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.requestRaw).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/attachments/attach123/download', + queryParams: { + messageId: 'message123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode identifier and attachmentId in downloadBytes', async () => { + await attachments.downloadBytes({ + identifier: 'id 123', + attachmentId: 'attach/123', + queryParams: { messageId: 'message123' }, + overrides: {}, + }); + expect(apiClient.requestRaw).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/attachments/attach%2F123/download', + }) + ); + }); + + it('should not double encode already-encoded identifier and attachmentId in downloadBytes', async () => { + await attachments.downloadBytes({ + identifier: 'id%20123', + attachmentId: 'attach%2F123', + queryParams: { messageId: 'message123' }, + overrides: {}, + }); + expect(apiClient.requestRaw).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/attachments/attach%2F123/download', + }) + ); + }); + }); + + describe('download', () => { + it('should call apiClient.requestStream with the correct params for streaming an attachment', async () => { + await attachments.download({ + identifier: 'id123', + attachmentId: 'attach123', + queryParams: { + messageId: 'message123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.requestStream).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/attachments/attach123/download', + queryParams: { + messageId: 'message123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode identifier and attachmentId in download', async () => { + await attachments.download({ + identifier: 'id 123', + attachmentId: 'attach/123', + queryParams: { messageId: 'message123' }, + overrides: {}, + }); + expect(apiClient.requestStream).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/attachments/attach%2F123/download', + }) + ); + }); + + it('should not double encode already-encoded identifier and attachmentId in download', async () => { + await attachments.download({ + identifier: 'id%20123', + attachmentId: 'attach%2F123', + queryParams: { messageId: 'message123' }, + overrides: {}, + }); + expect(apiClient.requestStream).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/attachments/attach%2F123/download', + }) + ); + }); + }); +}); diff --git a/tests/resources/auth.spec.ts b/tests/resources/auth.spec.ts new file mode 100644 index 00000000..c106d77d --- /dev/null +++ b/tests/resources/auth.spec.ts @@ -0,0 +1,376 @@ +import APIClient from '../../src/apiClient'; +import { Auth } from '../../src/resources/auth'; +import { + CodeExchangeRequest, + TokenExchangeRequest, +} from '../../src/models/auth'; +jest.mock('uuid', () => ({ v4: (): string => 'nylas' })); + +describe('Auth', () => { + let apiClient: APIClient; + let auth: Auth; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }); + + auth = new Auth(apiClient); + jest.spyOn(APIClient.prototype, 'request').mockResolvedValue({}); + }); + + describe('Exchanging tokens', () => { + describe('exchangeCodeForToken', () => { + it('should call apiClient.request with the correct params', async () => { + const payload: CodeExchangeRequest = { + clientId: 'clientId', + clientSecret: 'clientSecret', + redirectUri: 'https://redirect.uri/path', + code: 'code', + }; + await auth.exchangeCodeForToken(payload); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/connect/token', + body: { + clientId: 'clientId', + clientSecret: 'clientSecret', + redirectUri: 'https://redirect.uri/path', + code: 'code', + grantType: 'authorization_code', + }, + }); + }); + + it('should default clientSecret to the API key', async () => { + const payload: CodeExchangeRequest = { + clientId: 'clientId', + redirectUri: 'https://redirect.uri/path', + code: 'code', + }; + await auth.exchangeCodeForToken(payload); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/connect/token', + body: { + clientId: 'clientId', + clientSecret: 'apiKey', + redirectUri: 'https://redirect.uri/path', + code: 'code', + grantType: 'authorization_code', + }, + }); + }); + + it('should set codeVerifier', async () => { + const payload: CodeExchangeRequest = { + clientId: 'clientId', + clientSecret: 'clientSecret', + redirectUri: 'https://redirect.uri/path', + code: 'code', + codeVerifier: 'codeVerifier', + }; + await auth.exchangeCodeForToken(payload); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/connect/token', + body: { + clientId: 'clientId', + clientSecret: 'clientSecret', + redirectUri: 'https://redirect.uri/path', + code: 'code', + grantType: 'authorization_code', + codeVerifier: 'codeVerifier', + }, + }); + }); + }); + + describe('refreshAccessToken', () => { + it('should call apiClient.request with the correct params', async () => { + const payload: TokenExchangeRequest = { + clientId: 'clientId', + clientSecret: 'clientSecret', + redirectUri: 'https://redirect.uri/path', + refreshToken: 'refreshToken', + }; + await auth.refreshAccessToken(payload); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/connect/token', + body: { + clientId: 'clientId', + clientSecret: 'clientSecret', + redirectUri: 'https://redirect.uri/path', + refreshToken: 'refreshToken', + grantType: 'refresh_token', + }, + }); + }); + + it('should default clientSecret to the API key', async () => { + const payload: TokenExchangeRequest = { + clientId: 'clientId', + redirectUri: 'https://redirect.uri/path', + refreshToken: 'refreshToken', + }; + await auth.refreshAccessToken(payload); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/connect/token', + body: { + clientId: 'clientId', + clientSecret: 'apiKey', + redirectUri: 'https://redirect.uri/path', + refreshToken: 'refreshToken', + grantType: 'refresh_token', + }, + }); + }); + }); + }); + describe('customAuthentication', () => { + it('should call apiClient.request with the correct params', async () => { + await auth.customAuthentication({ + requestBody: { + provider: 'google', + settings: { + test_setting: 'abc123', + }, + scope: ['calendar'], + state: 'state123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/connect/custom', + body: { + provider: 'google', + settings: { + test_setting: 'abc123', + }, + scope: ['calendar'], + state: 'state123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + describe('URL building', () => { + describe('urlForAuthentication', () => { + it('should build the correct url', () => { + const url = auth.urlForOAuth2({ + clientId: 'clientId', + redirectUri: 'https://redirect.uri/path', + scope: ['calendar'], + provider: 'google', + includeGrantScopes: true, + }); + + expect(url).toBe( + 'https://test.api.nylas.com/v3/connect/auth?client_id=clientId&redirect_uri=https%3A%2F%2Fredirect.uri%2Fpath&access_type=online&response_type=code&provider=google&include_grant_scopes=true&scope=calendar' + ); + }); + + it('should support zoom as a provider', () => { + const url = auth.urlForOAuth2({ + clientId: 'clientId', + redirectUri: 'https://redirect.uri/path', + scope: ['calendar'], + provider: 'zoom', + includeGrantScopes: true, + }); + + expect(url).toBe( + 'https://test.api.nylas.com/v3/connect/auth?client_id=clientId&redirect_uri=https%3A%2F%2Fredirect.uri%2Fpath&access_type=online&response_type=code&provider=zoom&include_grant_scopes=true&scope=calendar' + ); + }); + + it('should build the correct url if all the fields are set', () => { + const url = auth.urlForOAuth2({ + clientId: 'clientId', + redirectUri: 'https://redirect.uri/path', + scope: ['calendar'], + provider: 'google', + loginHint: 'loginHint', + includeGrantScopes: true, + prompt: 'prompt', + state: 'state', + accessType: 'online', + }); + + expect(url).toBe( + 'https://test.api.nylas.com/v3/connect/auth?client_id=clientId&redirect_uri=https%3A%2F%2Fredirect.uri%2Fpath&access_type=online&response_type=code&provider=google&login_hint=loginHint&include_grant_scopes=true&scope=calendar&prompt=prompt&state=state' + ); + }); + }); + + describe('urlForAuthenticationPKCE', () => { + it('should hash the secret and build the URL correctly', () => { + const pkce = auth.urlForOAuth2PKCE({ + clientId: 'clientId', + redirectUri: 'https://redirect.uri/path', + scope: ['calendar'], + provider: 'google', + includeGrantScopes: true, + }); + const codeChallenge = + 'ZTk2YmY2Njg2YTNjMzUxMGU5ZTkyN2RiNzA2OWNiMWNiYTliOTliMDIyZjQ5NDgzYTZjZTMyNzA4MDllNjhhMg'; + + expect(pkce).toEqual({ + secret: 'nylas', + secretHash: codeChallenge, + url: `https://test.api.nylas.com/v3/connect/auth?client_id=clientId&redirect_uri=https%3A%2F%2Fredirect.uri%2Fpath&access_type=online&response_type=code&provider=google&include_grant_scopes=true&scope=calendar&code_challenge_method=s256&code_challenge=${codeChallenge}`, + }); + }); + }); + + describe('urlForAdminConsent', () => { + it('should build the correct url', () => { + const url = auth.urlForAdminConsent({ + clientId: 'clientId', + redirectUri: 'https://redirect.uri/path', + scope: ['calendar'], + loginHint: 'loginHint', + includeGrantScopes: true, + prompt: 'prompt', + state: 'state', + credentialId: 'credentialId', + }); + + expect(url).toBe( + 'https://test.api.nylas.com/v3/connect/auth?client_id=clientId&redirect_uri=https%3A%2F%2Fredirect.uri%2Fpath&access_type=online&response_type=adminconsent&provider=microsoft&login_hint=loginHint&include_grant_scopes=true&scope=calendar&prompt=prompt&state=state&credential_id=credentialId' + ); + }); + }); + }); + describe('Detect Provider', () => { + it('should call apiClient.request with the correct params', async () => { + await auth.detectProvider({ + email: 'email@example.com', + allProviderTypes: true, + }); + }); + }); + describe('revoke', () => { + it('should call apiClient.request with the correct params', async () => { + await auth.revoke('accessToken123'); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/connect/revoke', + queryParams: { + token: 'accessToken123', + }, + }); + }); + + it('should encode token in queryParams if needed (revoke)', async () => { + await auth.revoke('access token/123'); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + queryParams: expect.objectContaining({ + token: 'access token/123', + }), + }) + ); + }); + it('should not double encode already-encoded token in queryParams (revoke)', async () => { + await auth.revoke('access%20token%2F123'); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + queryParams: expect.objectContaining({ + token: 'access%20token%2F123', + }), + }) + ); + }); + }); + describe('token info', () => { + describe('idTokenInfo', () => { + it('should call getTokenInfo with the correct params', async () => { + await auth.idTokenInfo('idToken123'); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/connect/tokeninfo', + queryParams: { + id_token: 'idToken123', + }, + }); + }); + + it('should encode id_token in queryParams if needed', async () => { + await auth.idTokenInfo('id token/123'); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + queryParams: expect.objectContaining({ + id_token: 'id token/123', + }), + }) + ); + }); + it('should not double encode already-encoded id_token in queryParams', async () => { + await auth.idTokenInfo('id%20token%2F123'); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + queryParams: expect.objectContaining({ + id_token: 'id%20token%2F123', + }), + }) + ); + }); + }); + + describe('accessTokenInfo', () => { + it('should call getTokenInfo with the correct params', async () => { + await auth.accessTokenInfo('accessToken123'); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/connect/tokeninfo', + queryParams: { + access_token: 'accessToken123', + }, + }); + }); + + it('should encode access_token in queryParams if needed', async () => { + await auth.accessTokenInfo('access token/123'); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + queryParams: expect.objectContaining({ + access_token: 'access token/123', + }), + }) + ); + }); + it('should not double encode already-encoded access_token in queryParams', async () => { + await auth.accessTokenInfo('access%20token%2F123'); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + queryParams: expect.objectContaining({ + access_token: 'access%20token%2F123', + }), + }) + ); + }); + }); + }); +}); diff --git a/tests/resources/bookings.spec.ts b/tests/resources/bookings.spec.ts new file mode 100644 index 00000000..590565d8 --- /dev/null +++ b/tests/resources/bookings.spec.ts @@ -0,0 +1,304 @@ +import APIClient from '../../src/apiClient'; +import { Bookings } from '../../src/resources/bookings'; +jest.mock('../../src/apiClient'); + +describe('Bookings', () => { + let apiClient: jest.Mocked; + let bookings: Bookings; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + bookings = new Bookings(apiClient); + apiClient.request.mockResolvedValue({}); + }); + + describe('create', () => { + it('should call apiClient.request with the correct params', async () => { + await bookings.create({ + queryParams: { + configurationId: 'configuration123', + }, + requestBody: { + startTime: 1709643600, + endTime: 1709645400, + guest: { + name: 'Jane Doe', + email: 'jane.doe@example.com', + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/scheduling/bookings', + queryParams: { + configurationId: 'configuration123', + }, + body: { + startTime: 1709643600, + endTime: 1709645400, + guest: { + name: 'Jane Doe', + email: 'jane.doe@example.com', + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + }); + }); + + describe('find', () => { + it('should call apiClient.request with the correct params', async () => { + await bookings.find({ + bookingId: 'booking123', + queryParams: { + configurationId: 'configuration123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/scheduling/bookings/booking123', + queryParams: { + configurationId: 'configuration123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + }); + + it('should URL encode bookingId in find', async () => { + await bookings.find({ + bookingId: 'booking/123', + queryParams: { configurationId: 'configuration123' }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/scheduling/bookings/booking%2F123', + }) + ); + }); + + it('should not double encode already-encoded bookingId in find', async () => { + await bookings.find({ + bookingId: 'booking%2F123', + queryParams: { configurationId: 'configuration123' }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/scheduling/bookings/booking%2F123', + }) + ); + }); + }); + + describe('confirm', () => { + it('should call apiClient.request with the correct params', async () => { + await bookings.confirm({ + bookingId: 'booking123', + queryParams: { + configurationId: 'configuration123', + }, + requestBody: { + salt: '_zgLLAuk_qtcsw', + status: 'cancelled', + cancellationReason: 'I am no longer available at this time.', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/v3/scheduling/bookings/booking123', + queryParams: { + configurationId: 'configuration123', + }, + body: { + salt: '_zgLLAuk_qtcsw', + status: 'cancelled', + cancellationReason: 'I am no longer available at this time.', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + }); + + it('should URL encode bookingId in confirm', async () => { + await bookings.confirm({ + bookingId: 'booking/123', + queryParams: { configurationId: 'configuration123' }, + requestBody: { + salt: 'foo', + status: 'cancelled', + cancellationReason: 'bar', + }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/scheduling/bookings/booking%2F123', + }) + ); + }); + + it('should not double encode already-encoded bookingId in confirm', async () => { + await bookings.confirm({ + bookingId: 'booking%2F123', + queryParams: { configurationId: 'configuration123' }, + requestBody: { + salt: 'foo', + status: 'cancelled', + cancellationReason: 'bar', + }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/scheduling/bookings/booking%2F123', + }) + ); + }); + }); + + describe('reschedule', () => { + it('should call apiClient.request with the correct params', async () => { + await bookings.reschedule({ + bookingId: 'booking123', + queryParams: { + configurationId: 'configuration123', + }, + requestBody: { + startTime: 1708714800, + endTime: 1708722000, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PATCH', + path: '/v3/scheduling/bookings/booking123', + queryParams: { + configurationId: 'configuration123', + }, + body: { + startTime: 1708714800, + endTime: 1708722000, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + }); + + it('should URL encode bookingId in reschedule', async () => { + await bookings.reschedule({ + bookingId: 'booking/123', + queryParams: { configurationId: 'configuration123' }, + requestBody: { startTime: 1, endTime: 2 }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/scheduling/bookings/booking%2F123', + }) + ); + }); + + it('should not double encode already-encoded bookingId in reschedule', async () => { + await bookings.reschedule({ + bookingId: 'booking%2F123', + queryParams: { configurationId: 'configuration123' }, + requestBody: { startTime: 1, endTime: 2 }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/scheduling/bookings/booking%2F123', + }) + ); + }); + }); + + describe('destroy', () => { + it('should call apiClient.request with the correct params', async () => { + await bookings.destroy({ + bookingId: 'booking123', + queryParams: { + configurationId: 'configuration123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/scheduling/bookings/booking123', + queryParams: { + configurationId: 'configuration123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + }); + + it('should URL encode bookingId in destroy', async () => { + await bookings.destroy({ + bookingId: 'booking/123', + queryParams: { configurationId: 'configuration123' }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/scheduling/bookings/booking%2F123', + }) + ); + }); + + it('should not double encode already-encoded bookingId in destroy', async () => { + await bookings.destroy({ + bookingId: 'booking%2F123', + queryParams: { configurationId: 'configuration123' }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/scheduling/bookings/booking%2F123', + }) + ); + }); + }); +}); diff --git a/tests/resources/calendars.spec.ts b/tests/resources/calendars.spec.ts new file mode 100644 index 00000000..b11c2837 --- /dev/null +++ b/tests/resources/calendars.spec.ts @@ -0,0 +1,610 @@ +import APIClient from '../../src/apiClient'; +import { Calendars } from '../../src/resources/calendars'; +import { AvailabilityMethod } from '../../src/models/availability'; +jest.mock('../../src/apiClient'); + +describe('Calendars', () => { + let apiClient: jest.Mocked; + let calendars: Calendars; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + calendars = new Calendars(apiClient); + apiClient.request.mockResolvedValue({}); + }); + + describe('list', () => { + it('should call apiClient.request with the correct params', async () => { + await calendars.list({ + identifier: 'id123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/calendars', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('find', () => { + it('should call apiClient.request with the correct params', async () => { + await calendars.find({ + identifier: 'id123', + calendarId: 'calendar123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/calendars/calendar123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode identifier and calendarId in find', async () => { + await calendars.find({ + identifier: 'id 123', + calendarId: 'calendar/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/calendars/calendar%2F123', + }) + ); + }); + + it('should not double encode already-encoded identifier and calendarId in find', async () => { + await calendars.find({ + identifier: 'id%20123', + calendarId: 'calendar%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/calendars/calendar%2F123', + }) + ); + }); + }); + + describe('create', () => { + it('should call apiClient.request with the correct params', async () => { + await calendars.create({ + identifier: 'id123', + requestBody: { + name: 'My Calendar', + description: "My Calendar's Description", + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/calendars', + body: { + name: 'My Calendar', + description: "My Calendar's Description", + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should call apiClient.request with notetaker settings', async () => { + await calendars.create({ + identifier: 'id123', + requestBody: { + name: 'My Calendar', + description: "My Calendar's Description", + notetaker: { + name: 'Custom Notetaker', + meetingSettings: { + videoRecording: true, + audioRecording: true, + transcription: true, + }, + rules: { + eventSelection: ['internal', 'external'], + participantFilter: { + participantsGte: 3, + participantsLte: 10, + }, + }, + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/calendars', + body: { + name: 'My Calendar', + description: "My Calendar's Description", + notetaker: { + name: 'Custom Notetaker', + meetingSettings: { + videoRecording: true, + audioRecording: true, + transcription: true, + }, + rules: { + eventSelection: ['internal', 'external'], + participantFilter: { + participantsGte: 3, + participantsLte: 10, + }, + }, + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('update', () => { + it('should call apiClient.request with the correct params', async () => { + await calendars.update({ + identifier: 'id123', + calendarId: 'calendar123', + requestBody: { + description: "Updated Calendar's Description", + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/v3/grants/id123/calendars/calendar123', + body: { + description: "Updated Calendar's Description", + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should call apiClient.request with updated notetaker settings', async () => { + await calendars.update({ + identifier: 'id123', + calendarId: 'calendar123', + requestBody: { + notetaker: { + name: 'Updated Notetaker', + meetingSettings: { + videoRecording: false, + audioRecording: true, + transcription: false, + }, + rules: { + eventSelection: ['all'], + participantFilter: { + participantsGte: 5, + }, + }, + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/v3/grants/id123/calendars/calendar123', + body: { + notetaker: { + name: 'Updated Notetaker', + meetingSettings: { + videoRecording: false, + audioRecording: true, + transcription: false, + }, + rules: { + eventSelection: ['all'], + participantFilter: { + participantsGte: 5, + }, + }, + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('destroy', () => { + it('should call apiClient.request with the correct params', async () => { + await calendars.destroy({ + identifier: 'id123', + calendarId: 'calendar123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/grants/id123/calendars/calendar123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('getAvailability', () => { + it('should call apiClient.request with the correct params', async () => { + await calendars.getAvailability({ + requestBody: { + startTime: 123, + endTime: 456, + participants: [], + durationMinutes: 30, + intervalMinutes: 15, + roundTo30Minutes: true, + availabilityRules: { + availabilityMethod: AvailabilityMethod.MaxAvailability, + buffer: { + before: 15, + after: 15, + }, + defaultOpenHours: [ + { + days: [0], + timezone: 'America/Toronto', + start: '09:00', + end: '17:00', + exdates: ['2020-01-01'], + }, + ], + roundRobinEventId: 'event123', + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/calendars/availability', + body: { + startTime: 123, + endTime: 456, + participants: [], + durationMinutes: 30, + intervalMinutes: 15, + roundTo30Minutes: true, + availabilityRules: { + availabilityMethod: AvailabilityMethod.MaxAvailability, + buffer: { + before: 15, + after: 15, + }, + defaultOpenHours: [ + { + days: [0], + timezone: 'America/Toronto', + start: '09:00', + end: '17:00', + exdates: ['2020-01-01'], + }, + ], + roundRobinEventId: 'event123', + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should call apiClient.request with tentativeAsBusy parameter', async () => { + await calendars.getAvailability({ + requestBody: { + startTime: 123, + endTime: 456, + participants: [], + durationMinutes: 30, + intervalMinutes: 15, + availabilityRules: { + availabilityMethod: AvailabilityMethod.MaxAvailability, + buffer: { + before: 15, + after: 15, + }, + defaultOpenHours: [ + { + days: [0], + timezone: 'America/Toronto', + start: '09:00', + end: '17:00', + exdates: ['2020-01-01'], + }, + ], + roundRobinEventId: 'event123', + tentativeAsBusy: false, // Don't treat tentative events as busy + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/calendars/availability', + body: { + startTime: 123, + endTime: 456, + participants: [], + durationMinutes: 30, + intervalMinutes: 15, + availabilityRules: { + availabilityMethod: AvailabilityMethod.MaxAvailability, + buffer: { + before: 15, + after: 15, + }, + defaultOpenHours: [ + { + days: [0], + timezone: 'America/Toronto', + start: '09:00', + end: '17:00', + exdates: ['2020-01-01'], + }, + ], + roundRobinEventId: 'event123', + tentativeAsBusy: false, // Don't treat tentative events as busy + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('getCollectiveAvailability', () => { + it('should call apiClient.request with the correct params', async () => { + await calendars.getAvailability({ + requestBody: { + startTime: 123, + endTime: 456, + participants: [], + durationMinutes: 30, + intervalMinutes: 15, + roundTo30Minutes: true, + availabilityRules: { + availabilityMethod: AvailabilityMethod.Collective, + buffer: { + before: 15, + after: 15, + }, + defaultOpenHours: [ + { + days: [0], + timezone: 'America/Toronto', + start: '09:00', + end: '17:00', + exdates: ['2020-01-01'], + }, + ], + roundRobinEventId: 'event123', + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/calendars/availability', + body: { + startTime: 123, + endTime: 456, + participants: [], + durationMinutes: 30, + intervalMinutes: 15, + roundTo30Minutes: true, + availabilityRules: { + availabilityMethod: AvailabilityMethod.Collective, + buffer: { + before: 15, + after: 15, + }, + defaultOpenHours: [ + { + days: [0], + timezone: 'America/Toronto', + start: '09:00', + end: '17:00', + exdates: ['2020-01-01'], + }, + ], + roundRobinEventId: 'event123', + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('getFreeBusy', () => { + it('should call apiClient.request with the correct params', async () => { + await calendars.getFreeBusy({ + identifier: 'id123', + requestBody: { + startTime: 1609459200, + endTime: 1609545600, + emails: ['test@example.com', 'test2@example.com'], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/calendars/free-busy', + body: { + startTime: 1609459200, + endTime: 1609545600, + emails: ['test@example.com', 'test2@example.com'], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should call apiClient.request with tentativeAsBusy set to false', async () => { + await calendars.getFreeBusy({ + identifier: 'id123', + requestBody: { + startTime: 1609459200, + endTime: 1609545600, + emails: ['test@example.com'], + tentativeAsBusy: false, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/calendars/free-busy', + body: { + startTime: 1609459200, + endTime: 1609545600, + emails: ['test@example.com'], + tentativeAsBusy: false, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should call apiClient.request with tentativeAsBusy set to true', async () => { + await calendars.getFreeBusy({ + identifier: 'id123', + requestBody: { + startTime: 1609459200, + endTime: 1609545600, + emails: ['test@example.com'], + tentativeAsBusy: true, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/calendars/free-busy', + body: { + startTime: 1609459200, + endTime: 1609545600, + emails: ['test@example.com'], + tentativeAsBusy: true, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should handle multiple emails with tentativeAsBusy option', async () => { + await calendars.getFreeBusy({ + identifier: 'grant-123', + requestBody: { + startTime: 1609459200, + endTime: 1609545600, + emails: [ + 'user1@example.com', + 'user2@example.com', + 'user3@example.com', + ], + tentativeAsBusy: false, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/grant-123/calendars/free-busy', + body: { + startTime: 1609459200, + endTime: 1609545600, + emails: [ + 'user1@example.com', + 'user2@example.com', + 'user3@example.com', + ], + tentativeAsBusy: false, + }, + }); + }); + }); +}); diff --git a/tests/resources/configurations.spec.ts b/tests/resources/configurations.spec.ts new file mode 100644 index 00000000..20b43b3c --- /dev/null +++ b/tests/resources/configurations.spec.ts @@ -0,0 +1,260 @@ +import APIClient from '../../src/apiClient'; +import { Configurations } from '../../src/resources/configurations'; +jest.mock('../../src/apiClient'); + +describe('Configurations', () => { + let apiClient: jest.Mocked; + let configurations: Configurations; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + configurations = new Configurations(apiClient); + apiClient.request.mockResolvedValue({}); + }); + + describe('list', () => { + it('should call apiClient.request with correct params', async () => { + await configurations.list({ + identifier: 'grant123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/grant123/scheduling/configurations', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + }); + }); + + describe('find', () => { + it('should call apiClient.request with correct params', async () => { + await configurations.find({ + identifier: 'grant123', + configurationId: 'configuration123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/grant123/scheduling/configurations/configuration123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + }); + + it('should URL encode identifier and configurationId in find', async () => { + await configurations.find({ + identifier: 'grant 123', + configurationId: 'configuration/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/grant%20123/scheduling/configurations/configuration%2F123', + }) + ); + }); + + it('should not double encode already-encoded identifier and configurationId in find', async () => { + await configurations.find({ + identifier: 'grant%20123', + configurationId: 'configuration%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/grant%20123/scheduling/configurations/configuration%2F123', + }) + ); + }); + }); + + describe('create', () => { + it('should call apiClient.request with correct params', async () => { + await configurations.create({ + identifier: 'grant123', + requestBody: { + requiresSessionAuth: false, + participants: [ + { + name: 'Test', + email: 'nylassdk@nylas.com', + availability: { + calendarIds: ['primary'], + }, + booking: { + calendarId: 'primary', + }, + }, + ], + availability: { + durationMinutes: 30, + }, + eventBooking: { + title: 'My test event', + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/grant123/scheduling/configurations', + body: { + requiresSessionAuth: false, + participants: [ + { + name: 'Test', + email: 'nylassdk@nylas.com', + availability: { + calendarIds: ['primary'], + }, + booking: { + calendarId: 'primary', + }, + }, + ], + availability: { + durationMinutes: 30, + }, + eventBooking: { + title: 'My test event', + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + }); + }); + + describe('update', () => { + it('should call apiClient.request with the correct params', async () => { + await configurations.update({ + identifier: 'grant123', + configurationId: 'configuration123', + requestBody: { + eventBooking: { + title: 'Changed Title', + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/v3/grants/grant123/scheduling/configurations/configuration123', + body: { + eventBooking: { + title: 'Changed Title', + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + }); + + it('should URL encode identifier and configurationId in update', async () => { + await configurations.update({ + identifier: 'grant 123', + configurationId: 'configuration/123', + requestBody: { eventBooking: { title: 'Changed Title' } }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/grant%20123/scheduling/configurations/configuration%2F123', + }) + ); + }); + + it('should not double encode already-encoded identifier and configurationId in update', async () => { + await configurations.update({ + identifier: 'grant%20123', + configurationId: 'configuration%2F123', + requestBody: { eventBooking: { title: 'Changed Title' } }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/grant%20123/scheduling/configurations/configuration%2F123', + }) + ); + }); + }); + + describe('destroy', () => { + it('should call apiClient.request with the correct params', async () => { + await configurations.destroy({ + identifier: 'grant123', + configurationId: 'configuration123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/grants/grant123/scheduling/configurations/configuration123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + }); + + it('should URL encode identifier and configurationId in destroy', async () => { + await configurations.destroy({ + identifier: 'grant 123', + configurationId: 'configuration/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/grant%20123/scheduling/configurations/configuration%2F123', + }) + ); + }); + + it('should not double encode already-encoded identifier and configurationId in destroy', async () => { + await configurations.destroy({ + identifier: 'grant%20123', + configurationId: 'configuration%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/grant%20123/scheduling/configurations/configuration%2F123', + }) + ); + }); + }); +}); diff --git a/tests/resources/contacts.spec.ts b/tests/resources/contacts.spec.ts new file mode 100644 index 00000000..5296dfa9 --- /dev/null +++ b/tests/resources/contacts.spec.ts @@ -0,0 +1,302 @@ +import APIClient from '../../src/apiClient'; +import { Contacts } from '../../src/resources/contacts'; +jest.mock('../../src/apiClient'); + +describe('Contacts', () => { + let apiClient: jest.Mocked; + let contacts: Contacts; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + contacts = new Contacts(apiClient); + apiClient.request.mockResolvedValue({}); + }); + + describe('list', () => { + it('should call apiClient.request with the correct params', async () => { + await contacts.list({ + identifier: 'id123', + queryParams: { + email: 'test@email.com', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/contacts', + queryParams: { + email: 'test@email.com', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should paginate correctly if a nextCursor is present', async () => { + apiClient.request.mockResolvedValueOnce({ + requestId: 'request123', + data: [ + { + id: 'id', + name: 'name', + }, + ], + nextCursor: 'cursor123', + }); + const contactList = await contacts.list({ + identifier: 'id123', + queryParams: { + email: 'test@email.com', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + apiClient.request.mockResolvedValueOnce({ + requestId: 'request123', + data: [ + { + id: 'id', + name: 'name', + }, + ], + }); + await contactList.next(); + + expect(apiClient.request).toBeCalledTimes(2); + expect(apiClient.request).toHaveBeenLastCalledWith({ + method: 'GET', + path: '/v3/grants/id123/contacts', + queryParams: { + email: 'test@email.com', + pageToken: 'cursor123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should not paginate if nextCursor is not present', async () => { + apiClient.request.mockResolvedValueOnce({ + requestId: 'request123', + data: [ + { + id: 'id', + name: 'name', + }, + ], + }); + const contactList = await contacts.list({ + identifier: 'id123', + queryParams: { + email: 'test@email.com', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + apiClient.request.mockResolvedValueOnce({ + requestId: 'request123', + data: [ + { + id: 'id', + name: 'name', + }, + ], + }); + await contactList.next(); + + expect(apiClient.request).toBeCalledTimes(1); + }); + + //TODO::More iterator tests + }); + + describe('find', () => { + it('should call apiClient.request with the correct params', async () => { + await contacts.find({ + identifier: 'id123', + contactId: 'contact123', + queryParams: { + profilePicture: true, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/contacts/contact123', + queryParams: { + profilePicture: true, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode identifier and contactId in find', async () => { + await contacts.find({ + identifier: 'id 123', + contactId: 'contact/123', + queryParams: {}, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/contacts/contact%2F123', + }) + ); + }); + + it('should not double encode already-encoded identifier and contactId in find', async () => { + await contacts.find({ + identifier: 'id%20123', + contactId: 'contact%2F123', + queryParams: {}, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/contacts/contact%2F123', + }) + ); + }); + }); + + describe('create', () => { + it('should call apiClient.request with the correct params', async () => { + await contacts.create({ + identifier: 'id123', + requestBody: { + displayName: 'Test', + birthday: '1960-12-31', + companyName: 'Nylas', + emails: [ + { + email: 'test@gmail.com', + type: 'home', + }, + ], + givenName: 'Test', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/contacts', + body: { + displayName: 'Test', + birthday: '1960-12-31', + companyName: 'Nylas', + emails: [ + { + email: 'test@gmail.com', + type: 'home', + }, + ], + givenName: 'Test', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('update', () => { + it('should call apiClient.request with the correct params', async () => { + await contacts.update({ + identifier: 'id123', + contactId: 'contact123', + requestBody: { + birthday: '1960-12-31', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/v3/grants/id123/contacts/contact123', + body: { + birthday: '1960-12-31', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('destroy', () => { + it('should call apiClient.request with the correct params', async () => { + await contacts.destroy({ + identifier: 'id123', + contactId: 'contact123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/grants/id123/contacts/contact123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('contact group', () => { + it('should call apiClient.request with the correct params', async () => { + await contacts.groups({ + identifier: 'id123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/contacts/groups', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); +}); diff --git a/tests/resources/credentials.spec.ts b/tests/resources/credentials.spec.ts new file mode 100644 index 00000000..be803153 --- /dev/null +++ b/tests/resources/credentials.spec.ts @@ -0,0 +1,257 @@ +import APIClient from '../../src/apiClient'; +import { CredentialType } from '../../src/models/credentials'; +import { Credentials } from '../../src/resources/credentials'; +jest.mock('../../src/apiClient'); + +describe('Credentials', () => { + let apiClient: jest.Mocked; + let credentials: Credentials; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + credentials = new Credentials(apiClient); + apiClient.request.mockResolvedValue({}); + }); + + describe('list', () => { + it('should call apiClient.request with the correct params', async () => { + await credentials.list({ + provider: 'microsoft', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/connectors/microsoft/creds', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('find', () => { + it('should call apiClient.request with the correct params', async () => { + await credentials.find({ + provider: 'microsoft', + credentialsId: 'microsoft-id123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/connectors/microsoft/creds/microsoft-id123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode provider and credentialsId in find', async () => { + await credentials.find({ + provider: 'microsoft', + credentialsId: 'id/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/connectors/microsoft/creds/id%2F123', + }) + ); + }); + + it('should not double encode already-encoded provider and credentialsId in find', async () => { + await credentials.find({ + provider: 'microsoft', + credentialsId: 'id%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/connectors/microsoft/creds/id%2F123', + }) + ); + }); + + it('should URL encode credentialsId in find', async () => { + await credentials.find({ + provider: 'microsoft', + credentialsId: 'id/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/connectors/microsoft/creds/id%2F123', + }) + ); + }); + + it('should not double encode already-encoded credentialsId in find', async () => { + await credentials.find({ + provider: 'microsoft', + credentialsId: 'id%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/connectors/microsoft/creds/id%2F123', + }) + ); + }); + }); + + describe('create', () => { + it('should call apiClient.request with the correct params', async () => { + await credentials.create({ + provider: 'microsoft', + requestBody: { + name: 'My Microsoft Connector', + credentialType: CredentialType.CONNECTOR, + credentialData: { + clientID: '', + clientSecret: '', + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/connectors/microsoft/creds', + body: { + name: 'My Microsoft Connector', + credentialType: CredentialType.CONNECTOR, + credentialData: { + clientID: '', + clientSecret: '', + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('update', () => { + it('should call apiClient.request with the correct params', async () => { + await credentials.update({ + provider: 'microsoft', + credentialsId: 'microsoft-123', + requestBody: { + name: 'Changed Name', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/v3/connectors/microsoft/creds/microsoft-123', + body: { + name: 'Changed Name', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode credentialsId in update', async () => { + await credentials.update({ + provider: 'microsoft', + credentialsId: 'id/123', + requestBody: { name: 'Changed Name' }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/connectors/microsoft/creds/id%2F123', + }) + ); + }); + + it('should not double encode already-encoded credentialsId in update', async () => { + await credentials.update({ + provider: 'microsoft', + credentialsId: 'id%2F123', + requestBody: { name: 'Changed Name' }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/connectors/microsoft/creds/id%2F123', + }) + ); + }); + }); + + describe('destroy', () => { + it('should call apiClient.request with the correct params', async () => { + await credentials.destroy({ + provider: 'microsoft', + credentialsId: 'microsoft-1234', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/connectors/microsoft/creds/microsoft-1234', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode credentialsId in destroy', async () => { + await credentials.destroy({ + provider: 'microsoft', + credentialsId: 'id/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/connectors/microsoft/creds/id%2F123', + }) + ); + }); + + it('should not double encode already-encoded credentialsId in destroy', async () => { + await credentials.destroy({ + provider: 'microsoft', + credentialsId: 'id%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/connectors/microsoft/creds/id%2F123', + }) + ); + }); + }); +}); diff --git a/tests/resources/drafts.spec.ts b/tests/resources/drafts.spec.ts new file mode 100644 index 00000000..731cf8c1 --- /dev/null +++ b/tests/resources/drafts.spec.ts @@ -0,0 +1,627 @@ +import APIClient from '../../src/apiClient'; +import { CreateAttachmentRequest } from '../../src/models/attachments'; +import { Drafts } from '../../src/resources/drafts'; +import { objKeysToCamelCase } from '../../src/utils'; +import { createReadableStream, MockedFormData } from '../testUtils'; +jest.mock('../../src/apiClient'); + +// Mock the FormData constructor +jest.mock('formdata-node', () => ({ + FormData: jest.fn().mockImplementation(function (this: MockedFormData) { + const appendedData: Record = {}; + + this.append = (key: string, value: any): void => { + appendedData[key] = value; + }; + + this._getAppendedData = (): Record => appendedData; + }), + Blob: jest.fn().mockImplementation((parts: any[], options?: any) => ({ + type: options?.type || '', + size: parts.reduce((size, part) => size + (part.length || 0), 0), + })), + File: jest + .fn() + .mockImplementation((parts: any[], name: string, options?: any) => ({ + name, + type: options?.type || '', + size: + options?.size || + parts.reduce((size, part) => size + (part.length || 0), 0), + stream: (): ReadableStream => parts[0], + [Symbol.toStringTag]: 'File', + })), +})); + +describe('Drafts', () => { + let apiClient: jest.Mocked; + let drafts: Drafts; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + drafts = new Drafts(apiClient); + apiClient.request.mockResolvedValue({}); + }); + + describe('deserializing', () => { + it('should return a draft object as expected', () => { + const apiDraft = { + body: 'Hello, I just sent a message using Nylas!', + cc: [ + { + email: 'arya.stark@example.com', + }, + ], + attachments: [ + { + content_type: 'text/calendar', + id: '4kj2jrcoj9ve5j9yxqz5cuv98', + size: 1708, + }, + ], + folders: ['8l6c4d11y1p4dm4fxj52whyr9', 'd9zkcr2tljpu3m4qpj7l2hbr0'], + from: [ + { + name: 'Daenerys Targaryen', + email: 'daenerys.t@example.com', + }, + ], + grant_id: '41009df5-bf11-4c97-aa18-b285b5f2e386', + id: '5d3qmne77v32r8l4phyuksl2x', + object: 'draft', + reply_to: [ + { + name: 'Daenerys Targaryen', + email: 'daenerys.t@example.com', + }, + ], + snippet: 'Hello, I just sent a message using Nylas!', + starred: true, + subject: 'Hello from Nylas!', + thread_id: '1t8tv3890q4vgmwq6pmdwm8qgsaer', + to: [ + { + name: 'Jon Snow', + email: 'j.snow@example.com', + }, + ], + date: 1705084742, + }; + + const draft = objKeysToCamelCase(apiDraft); + + expect(draft).toEqual({ + body: 'Hello, I just sent a message using Nylas!', + cc: [ + { + email: 'arya.stark@example.com', + }, + ], + attachments: [ + { + contentType: 'text/calendar', + id: '4kj2jrcoj9ve5j9yxqz5cuv98', + size: 1708, + }, + ], + folders: ['8l6c4d11y1p4dm4fxj52whyr9', 'd9zkcr2tljpu3m4qpj7l2hbr0'], + from: [ + { + name: 'Daenerys Targaryen', + email: 'daenerys.t@example.com', + }, + ], + grantId: '41009df5-bf11-4c97-aa18-b285b5f2e386', + id: '5d3qmne77v32r8l4phyuksl2x', + object: 'draft', + replyTo: [ + { + name: 'Daenerys Targaryen', + email: 'daenerys.t@example.com', + }, + ], + snippet: 'Hello, I just sent a message using Nylas!', + starred: true, + subject: 'Hello from Nylas!', + threadId: '1t8tv3890q4vgmwq6pmdwm8qgsaer', + to: [ + { + name: 'Jon Snow', + email: 'j.snow@example.com', + }, + ], + date: 1705084742, + }); + }); + }); + + describe('list', () => { + it('should call apiClient.request with the correct params', async () => { + await drafts.list({ + identifier: 'id123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/drafts', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('find', () => { + it('should call apiClient.request with the correct params', async () => { + await drafts.find({ + identifier: 'id123', + draftId: 'draft123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/drafts/draft123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode identifier and draftId in find', async () => { + await drafts.find({ + identifier: 'id 123', + draftId: 'draft/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/drafts/draft%2F123', + }) + ); + }); + + it('should not double encode already-encoded identifier and draftId in find', async () => { + await drafts.find({ + identifier: 'id%20123', + draftId: 'draft%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/drafts/draft%2F123', + }) + ); + }); + }); + + describe('create', () => { + it('should call apiClient.request with the correct params', async () => { + const jsonBody = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'This is my test email', + }; + await drafts.create({ + identifier: 'id123', + requestBody: jsonBody, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + expect(capturedRequest.method).toEqual('POST'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/drafts'); + expect(capturedRequest.body).toEqual(jsonBody); + expect(capturedRequest.overrides).toEqual({ + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }); + }); + + it('should attach files less than 3mb', async () => { + const baseJson = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'This is my test email', + }; + const jsonBody = { + ...baseJson, + attachments: [ + { + filename: 'file1.txt', + contentType: 'text/plain', + content: createReadableStream('This is the text from file 1'), + size: 100, + }, + ], + }; + const expectedJson = { + ...baseJson, + attachments: [ + { + filename: 'file1.txt', + contentType: 'text/plain', + content: 'VGhpcyBpcyB0aGUgdGV4dCBmcm9tIGZpbGUgMQ==', + size: 100, + }, + ], + }; + await drafts.create({ + identifier: 'id123', + requestBody: jsonBody, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + expect(capturedRequest.method).toEqual('POST'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/drafts'); + expect(capturedRequest.body).toEqual(expectedJson); + expect(capturedRequest.overrides).toEqual({ + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }); + }); + + it('should attach files 3mb+ properly', async () => { + const messageJson = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'This is my test email', + }; + const fileStream = createReadableStream('This is the text from file 1'); + const file1: CreateAttachmentRequest = { + filename: 'file1.txt', + contentType: 'text/plain', + content: fileStream, + size: 3 * 1024 * 1024, + }; + + await drafts.create({ + identifier: 'id123', + requestBody: { + ...messageJson, + attachments: [file1], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + const formData = ( + capturedRequest.form as any as MockedFormData + )._getAppendedData(); + expect(formData.message).toEqual(JSON.stringify(messageJson)); + // ReadableStream is now wrapped in a file-like object + expect(formData.file0).toEqual({ + type: 'text/plain', + name: 'file1.txt', + size: 3145728, // 3MB as declared in the attachment + stream: expect.any(Function), + [Symbol.toStringTag]: 'File', + }); + expect(capturedRequest.method).toEqual('POST'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/drafts'); + expect(capturedRequest.overrides).toEqual({ + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }); + }); + + it('should use multipart when total payload (body + attachments) exceeds 3MB for create', async () => { + // Create a large message body that, combined with small attachments, exceeds 3MB + const largeBody = 'A'.repeat(3.5 * 1024 * 1024); // 3.5MB body + const messageJson = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'This is my test email with large content', + body: largeBody, + }; + + const fileStream = createReadableStream('Small attachment content'); + const smallAttachment: CreateAttachmentRequest = { + filename: 'small_file.txt', + contentType: 'text/plain', + content: fileStream, + size: 1000, // 1KB attachment - small but total payload > 3MB + }; + + await drafts.create({ + identifier: 'id123', + requestBody: { + ...messageJson, + attachments: [smallAttachment], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + + // Should use form data because total payload exceeds 3MB + expect(capturedRequest.form).toBeDefined(); + expect(capturedRequest.body).toBeUndefined(); + + const formData = ( + capturedRequest.form as any as MockedFormData + )._getAppendedData(); + expect(formData.message).toEqual(JSON.stringify(messageJson)); + // ReadableStream is now wrapped in a file-like object + expect(formData.file0).toEqual({ + type: 'text/plain', + name: 'small_file.txt', + size: 1000, // 1KB as declared in the attachment + stream: expect.any(Function), + [Symbol.toStringTag]: 'File', + }); + expect(capturedRequest.method).toEqual('POST'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/drafts'); + }); + + it('should include isPlaintext in JSON body when provided for create', async () => { + const jsonBody = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'Plain text draft', + body: 'Hello world', + isPlaintext: true, + }; + + await drafts.create({ + identifier: 'id123', + requestBody: jsonBody, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + expect(capturedRequest.method).toEqual('POST'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/drafts'); + expect(capturedRequest.body).toEqual(jsonBody); + }); + + it('should include isPlaintext in multipart form message when provided for create', async () => { + const messageJson = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'Plain text draft', + body: 'Hello world', + isPlaintext: true, + }; + const fileStream = createReadableStream('This is the text from file 1'); + const file1: CreateAttachmentRequest = { + filename: 'file1.txt', + contentType: 'text/plain', + content: fileStream, + size: 3 * 1024 * 1024, + }; + + await drafts.create({ + identifier: 'id123', + requestBody: { + ...messageJson, + attachments: [file1], + }, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + const formData = ( + capturedRequest.form as any as MockedFormData + )._getAppendedData(); + const parsed = JSON.parse(formData.message); + expect(parsed.to).toEqual(messageJson.to); + expect(parsed.subject).toEqual(messageJson.subject); + expect(parsed.body).toEqual(messageJson.body); + expect(parsed.is_plaintext).toBe(true); + expect(capturedRequest.method).toEqual('POST'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/drafts'); + }); + }); + + describe('update', () => { + it('should call apiClient.request with the correct params', async () => { + const baseJson = { + subject: 'updated subject', + }; + const jsonBody = { + ...baseJson, + attachments: [ + { + filename: 'file1.txt', + contentType: 'text/plain', + content: createReadableStream('This is the text from file 1'), + size: 100, + }, + ], + }; + const expectedJson = { + ...baseJson, + attachments: [ + { + filename: 'file1.txt', + contentType: 'text/plain', + content: 'VGhpcyBpcyB0aGUgdGV4dCBmcm9tIGZpbGUgMQ==', + size: 100, + }, + ], + }; + await drafts.update({ + identifier: 'id123', + draftId: 'draft123', + requestBody: jsonBody, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + expect(capturedRequest.method).toEqual('PUT'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/drafts/draft123'); + expect(capturedRequest.body).toEqual(expectedJson); + expect(capturedRequest.overrides).toEqual({ + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }); + }); + + it('should attach files 3mb+ properly', async () => { + const messageJson = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'This is my test email', + }; + const fileStream = createReadableStream('This is the text from file 1'); + const file1: CreateAttachmentRequest = { + filename: 'file1.txt', + contentType: 'text/plain', + content: fileStream, + size: 3 * 1024 * 1024, + }; + + await drafts.update({ + identifier: 'id123', + draftId: 'draft123', + requestBody: { + ...messageJson, + attachments: [file1], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + const formData = ( + capturedRequest.form as any as MockedFormData + )._getAppendedData(); + expect(formData.message).toEqual(JSON.stringify(messageJson)); + // ReadableStream is now wrapped in a file-like object + expect(formData.file0).toEqual({ + type: 'text/plain', + name: 'file1.txt', + size: 3145728, // 3MB as declared in the attachment + stream: expect.any(Function), + [Symbol.toStringTag]: 'File', + }); + expect(capturedRequest.method).toEqual('PUT'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/drafts/draft123'); + expect(capturedRequest.overrides).toEqual({ + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }); + }); + + it('should use multipart when total payload (body + attachments) exceeds 3MB for update', async () => { + // Create a large message body that, combined with small attachments, exceeds 3MB + const largeBody = 'A'.repeat(3.5 * 1024 * 1024); // 3.5MB body + const messageJson = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'This is my test email with large content', + body: largeBody, + }; + + const fileStream = createReadableStream('Small attachment content'); + const smallAttachment: CreateAttachmentRequest = { + filename: 'small_file.txt', + contentType: 'text/plain', + content: fileStream, + size: 1000, // 1KB attachment - small but total payload > 3MB + }; + + await drafts.update({ + identifier: 'id123', + draftId: 'draft123', + requestBody: { + ...messageJson, + attachments: [smallAttachment], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + + // Should use form data because total payload exceeds 3MB + expect(capturedRequest.form).toBeDefined(); + expect(capturedRequest.body).toBeUndefined(); + + const formData = ( + capturedRequest.form as any as MockedFormData + )._getAppendedData(); + expect(formData.message).toEqual(JSON.stringify(messageJson)); + expect(formData.file0).toEqual({ + size: 1000, // 1KB as declared in the attachment + stream: expect.any(Function), + type: 'text/plain', + name: 'small_file.txt', + [Symbol.toStringTag]: 'File', + }); + expect(capturedRequest.method).toEqual('PUT'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/drafts/draft123'); + }); + }); + + describe('destroy', () => { + it('should call apiClient.request with the correct params', async () => { + await drafts.destroy({ + identifier: 'id123', + draftId: 'draft123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/grants/id123/drafts/draft123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('send', () => { + it('should call apiClient.request with the correct params', async () => { + await drafts.send({ + identifier: 'id123', + draftId: 'draft123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/drafts/draft123', + body: {}, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); +}); diff --git a/tests/resources/events.spec.ts b/tests/resources/events.spec.ts new file mode 100644 index 00000000..8c485c2f --- /dev/null +++ b/tests/resources/events.spec.ts @@ -0,0 +1,623 @@ +import APIClient from '../../src/apiClient'; +import { Events } from '../../src/resources/events'; +jest.mock('../../src/apiClient'); + +describe('Events', () => { + let apiClient: jest.Mocked; + let events: Events; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + events = new Events(apiClient); + apiClient.request.mockResolvedValue({}); + }); + + describe('list', () => { + it('should call apiClient.request with the correct params', async () => { + await events.list({ + identifier: 'id123', + queryParams: { + calendarId: 'calendar123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/events', + queryParams: { + calendarId: 'calendar123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should call apiClient.request with tentativeAsBusy parameter', async () => { + await events.list({ + identifier: 'id123', + queryParams: { + calendarId: 'calendar123', + tentativeAsBusy: false, // Don't treat tentative events as busy + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/events', + queryParams: { + calendarId: 'calendar123', + tentativeAsBusy: false, // Don't treat tentative events as busy + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should paginate correctly if a nextCursor is present', async () => { + apiClient.request.mockResolvedValueOnce({ + requestId: 'request123', + data: [ + { + id: 'id', + name: 'name', + }, + ], + nextCursor: 'cursor123', + }); + const eventList = await events.list({ + identifier: 'id123', + queryParams: { + calendarId: 'calendar123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + apiClient.request.mockResolvedValueOnce({ + requestId: 'request123', + data: [ + { + id: 'id', + name: 'name', + }, + ], + }); + await eventList.next(); + + expect(apiClient.request).toBeCalledTimes(2); + expect(apiClient.request).toHaveBeenLastCalledWith({ + method: 'GET', + path: '/v3/grants/id123/events', + queryParams: { + calendarId: 'calendar123', + pageToken: 'cursor123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should not paginate if nextCursor is not present', async () => { + apiClient.request.mockResolvedValueOnce({ + requestId: 'request123', + data: [ + { + id: 'id', + name: 'name', + }, + ], + }); + const eventList = await events.list({ + identifier: 'id123', + queryParams: { + calendarId: 'calendar123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + apiClient.request.mockResolvedValueOnce({ + requestId: 'request123', + data: [ + { + id: 'id', + name: 'name', + }, + ], + }); + await eventList.next(); + + expect(apiClient.request).toBeCalledTimes(1); + }); + + //TODO::More iterator tests + }); + + describe('listImportEvents', () => { + it('should call apiClient.request with the correct params', async () => { + await events.listImportEvents({ + identifier: 'id123', + queryParams: { + calendarId: 'calendar123', + start: 1617235200, + end: 1619827200, + limit: 100, + select: 'id,name', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/events/import', + queryParams: { + calendarId: 'calendar123', + start: 1617235200, + end: 1619827200, + limit: 100, + select: 'id,name', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should paginate correctly with page_token for import events', async () => { + apiClient.request.mockResolvedValueOnce({ + requestId: 'request123', + data: [ + { + id: 'id', + name: 'name', + }, + ], + nextCursor: 'cursor123', + }); + const eventList = await events.listImportEvents({ + identifier: 'id123', + queryParams: { + calendarId: 'calendar123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + apiClient.request.mockResolvedValueOnce({ + requestId: 'request123', + data: [ + { + id: 'id', + name: 'name', + }, + ], + }); + await eventList.next(); + + expect(apiClient.request).toBeCalledTimes(2); + expect(apiClient.request).toHaveBeenLastCalledWith({ + method: 'GET', + path: '/v3/grants/id123/events/import', + queryParams: { + calendarId: 'calendar123', + pageToken: 'cursor123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('find', () => { + it('should call apiClient.request with the correct params', async () => { + await events.find({ + identifier: 'id123', + eventId: 'event123', + queryParams: { + calendarId: 'calendar123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/events/event123', + queryParams: { + calendarId: 'calendar123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode identifier and eventId in find', async () => { + await events.find({ + identifier: 'id 123', + eventId: 'event/123', + queryParams: { calendarId: 'calendar123' }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/events/event%2F123', + }) + ); + }); + + it('should not double encode already-encoded identifier and eventId in find', async () => { + await events.find({ + identifier: 'id%20123', + eventId: 'event%2F123', + queryParams: { calendarId: 'calendar123' }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/events/event%2F123', + }) + ); + }); + }); + + describe('create', () => { + it('should call apiClient.request with the correct params', async () => { + await events.create({ + identifier: 'id123', + requestBody: { + when: { + time: 123, + timezone: 'America/Toronto', + }, + }, + queryParams: { + calendarId: 'calendar123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/events', + body: { + when: { + time: 123, + timezone: 'America/Toronto', + }, + }, + queryParams: { + calendarId: 'calendar123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should call apiClient.request with notetaker settings', async () => { + await events.create({ + identifier: 'id123', + requestBody: { + when: { + time: 123, + timezone: 'America/Toronto', + }, + notetaker: { + name: 'Custom Notetaker', + meetingSettings: { + videoRecording: true, + audioRecording: true, + transcription: true, + }, + }, + }, + queryParams: { + calendarId: 'calendar123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/events', + body: { + when: { + time: 123, + timezone: 'America/Toronto', + }, + notetaker: { + name: 'Custom Notetaker', + meetingSettings: { + videoRecording: true, + audioRecording: true, + transcription: true, + }, + }, + }, + queryParams: { + calendarId: 'calendar123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('update', () => { + it('should call apiClient.request with the correct params', async () => { + await events.update({ + identifier: 'id123', + eventId: 'event123', + requestBody: { + when: { + time: 123, + timezone: 'America/Toronto', + }, + }, + queryParams: { + calendarId: 'calendar123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/v3/grants/id123/events/event123', + body: { + when: { + time: 123, + timezone: 'America/Toronto', + }, + }, + queryParams: { + calendarId: 'calendar123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('destroy', () => { + it('should call apiClient.request with the correct params', async () => { + await events.destroy({ + identifier: 'id123', + eventId: 'event123', + queryParams: { + calendarId: 'calendar123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/grants/id123/events/event123', + queryParams: { + calendarId: 'calendar123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('send-rsvp', () => { + it('should call apiClient.request with the correct params', async () => { + await events.sendRsvp({ + identifier: 'id123', + eventId: 'event123', + queryParams: { + calendarId: 'calendar123', + }, + requestBody: { + status: 'yes', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/events/event123/send-rsvp', + queryParams: { + calendarId: 'calendar123', + }, + body: { + status: 'yes', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('Event model with optional conferencing', () => { + it('should handle events without conferencing property', async () => { + const eventWithoutConferencing = { + requestId: 'request123', + data: { + id: 'event123', + grantId: 'grant123', + object: 'event' as const, + calendarId: 'calendar123', + busy: false, + readOnly: false, + participants: [], + when: { + time: 1617235200, + timezone: 'America/New_York', + object: 'time' as const, + }, + visibility: 'default' as const, + title: 'Event without conferencing', + }, + }; + + apiClient.request.mockResolvedValue(eventWithoutConferencing); + + const result = await events.find({ + identifier: 'id123', + eventId: 'event123', + queryParams: { + calendarId: 'calendar123', + }, + }); + + expect(result.data.conferencing).toBeUndefined(); + expect(result.data.title).toBe('Event without conferencing'); + }); + + it('should handle events with conferencing property', async () => { + const eventWithConferencing = { + requestId: 'request123', + data: { + id: 'event123', + grantId: 'grant123', + object: 'event' as const, + calendarId: 'calendar123', + busy: false, + readOnly: false, + participants: [], + when: { + time: 1617235200, + timezone: 'America/New_York', + object: 'time' as const, + }, + conferencing: { + provider: 'Zoom Meeting' as const, + details: { + url: 'https://zoom.us/j/123456789', + meetingCode: '123456789', + }, + }, + visibility: 'default' as const, + title: 'Event with conferencing', + }, + }; + + apiClient.request.mockResolvedValue(eventWithConferencing); + + const result = await events.find({ + identifier: 'id123', + eventId: 'event456', + queryParams: { + calendarId: 'calendar123', + }, + }); + + expect(result.data.conferencing).toBeDefined(); + expect(result.data.conferencing?.provider).toBe('Zoom Meeting'); + expect(result.data.title).toBe('Event with conferencing'); + }); + + it('should create events without conferencing', async () => { + const eventResponse = { + requestId: 'request123', + data: { + id: 'event123', + grantId: 'grant123', + object: 'event' as const, + calendarId: 'calendar123', + busy: false, + readOnly: false, + participants: [], + when: { + time: 1617235200, + timezone: 'America/New_York', + object: 'time' as const, + }, + visibility: 'default' as const, + title: 'Simple event', + }, + }; + + apiClient.request.mockResolvedValue(eventResponse); + + const result = await events.create({ + identifier: 'id123', + requestBody: { + when: { + time: 1617235200, + timezone: 'America/New_York', + }, + title: 'Simple event', + }, + queryParams: { + calendarId: 'calendar123', + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/events', + body: { + when: { + time: 1617235200, + timezone: 'America/New_York', + }, + title: 'Simple event', + }, + queryParams: { + calendarId: 'calendar123', + }, + }); + expect(result.data.conferencing).toBeUndefined(); + }); + }); +}); diff --git a/tests/resources/folders.spec.ts b/tests/resources/folders.spec.ts new file mode 100644 index 00000000..91baacfb --- /dev/null +++ b/tests/resources/folders.spec.ts @@ -0,0 +1,292 @@ +import APIClient from '../../src/apiClient'; +import { Folders } from '../../src/resources/folders'; +import { objKeysToCamelCase } from '../../src/utils'; +jest.mock('../../src/apiClient'); + +describe('Folders', () => { + let apiClient: jest.Mocked; + let folders: Folders; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + folders = new Folders(apiClient); + apiClient.request.mockResolvedValue({ data: [] }); + }); + + describe('deserializing', () => { + it('should return a folder object as expected', () => { + const apiFolder = { + id: 'SENT', + grant_id: '41009df5-bf11-4c97-aa18-b285b5f2e386', + name: 'SENT', + system_folder: true, + object: 'folder', + unread_count: 0, + child_count: 0, + parent_id: 'ascsf21412', + background_color: '#039BE5', + text_color: '#039BE5', + total_count: 0, + attributes: ['\\SENT'], + }; + + const folder = objKeysToCamelCase(apiFolder); + expect(folder).toEqual({ + id: 'SENT', + grantId: '41009df5-bf11-4c97-aa18-b285b5f2e386', + name: 'SENT', + systemFolder: true, + object: 'folder', + unreadCount: 0, + childCount: 0, + parentId: 'ascsf21412', + backgroundColor: '#039BE5', + textColor: '#039BE5', + totalCount: 0, + attributes: ['\\SENT'], + }); + }); + }); + + describe('list', () => { + it('should call apiClient.request with the correct params', async () => { + await folders.list({ + identifier: 'id123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/folders', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should call apiClient.request with query params including single_level', async () => { + await folders.list({ + identifier: 'id123', + queryParams: { + includeHiddenFolders: true, + singleLevel: true, + parentId: 'parent123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/folders', + queryParams: { + includeHiddenFolders: true, + singleLevel: true, + parentId: 'parent123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should call apiClient.request with all supported query parameters', async () => { + await folders.list({ + identifier: 'id123', + queryParams: { + parentId: 'parent123', + includeHiddenFolders: false, + limit: 10, + pageToken: 'token123', + singleLevel: false, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/folders', + queryParams: { + parentId: 'parent123', + includeHiddenFolders: false, + limit: 10, + pageToken: 'token123', + singleLevel: false, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('find', () => { + it('should call apiClient.request with the correct params', async () => { + await folders.find({ + identifier: 'id123', + folderId: 'folder123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/folders/folder123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode identifier and folderId in find', async () => { + await folders.find({ + identifier: 'id 123', + folderId: 'folder/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/folders/folder%2F123', + }) + ); + }); + + it('should not double encode already-encoded identifier and folderId in find', async () => { + await folders.find({ + identifier: 'id%20123', + folderId: 'folder%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/folders/folder%2F123', + }) + ); + }); + + it('should call apiClient.request with queryParams in find', async () => { + await folders.find({ + identifier: 'id123', + folderId: 'folder123', + queryParams: { + includeHiddenFolders: true, + select: 'id,name,updated_at', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/folders/folder123', + queryParams: { + includeHiddenFolders: true, + select: 'id,name,updated_at', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('create', () => { + it('should call apiClient.request with the correct params', async () => { + await folders.create({ + identifier: 'id123', + requestBody: { + name: 'My Folder', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/folders', + body: { + name: 'My Folder', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('update', () => { + it('should call apiClient.request with the correct params', async () => { + await folders.update({ + identifier: 'id123', + folderId: 'folder123', + requestBody: { + name: 'Updated Folder', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/v3/grants/id123/folders/folder123', + body: { + name: 'Updated Folder', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('destroy', () => { + it('should call apiClient.request with the correct params', async () => { + await folders.destroy({ + identifier: 'id123', + folderId: 'folder123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/grants/id123/folders/folder123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); +}); diff --git a/tests/resources/grants.spec.ts b/tests/resources/grants.spec.ts new file mode 100644 index 00000000..e9dff5d3 --- /dev/null +++ b/tests/resources/grants.spec.ts @@ -0,0 +1,254 @@ +import APIClient from '../../src/apiClient'; +import { Grants } from '../../src/resources/grants'; +jest.mock('../../src/apiClient'); + +describe('Grants', () => { + let apiClient: jest.Mocked; + let grants: Grants; + + beforeEach(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + grants = new Grants(apiClient); + + // Create a spy implementation that captures the inputs + apiClient.request = jest.fn().mockImplementation((input) => { + // eslint-disable-next-line no-console + console.log('Request input:', JSON.stringify(input, null, 2)); + return Promise.resolve({ + data: [], + }); + }); + }); + + describe('list', () => { + it('should call apiClient.request with the correct params', async () => { + await grants.list({ + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + method: 'GET', + path: '/v3/grants', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }) + ); + }); + + it('should call apiClient.request even without overrides set', async () => { + await grants.list(); + + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + method: 'GET', + path: '/v3/grants', + }) + ); + }); + + it('should properly pass queryParams when provided in the first parameter', async () => { + await grants.list({ + queryParams: { + limit: 10, + offset: 5, + provider: 'google', + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + method: 'GET', + path: '/v3/grants', + queryParams: { + limit: 10, + offset: 5, + provider: 'google', + }, + }) + ); + }); + + it('should properly pass both queryParams and overrides when provided', async () => { + await grants.list({ + queryParams: { + limit: 20, + provider: 'microsoft', + }, + overrides: { + apiUri: 'https://custom.api.nylas.com', + headers: { custom: 'header' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + method: 'GET', + path: '/v3/grants', + queryParams: { + limit: 20, + provider: 'microsoft', + }, + overrides: { + apiUri: 'https://custom.api.nylas.com', + headers: { custom: 'header' }, + }, + }) + ); + }); + + it('should support the deprecated _queryParams parameter', async () => { + await grants.list({}, { + limit: 15, + provider: 'imap', + } as any); + + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + method: 'GET', + path: '/v3/grants', + queryParams: { + limit: 15, + provider: 'imap', + }, + }) + ); + }); + + it('should properly handle camelCase query parameters with correct API values', async () => { + await grants.list({ + queryParams: { + limit: 10, + offset: 5, + sortBy: 'created_at', + orderBy: 'desc', + grantStatus: 'valid', + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + method: 'GET', + path: '/v3/grants', + queryParams: { + limit: 10, + offset: 5, + sortBy: 'created_at', + orderBy: 'desc', + grantStatus: 'valid', + }, + }) + ); + }); + }); + + describe('find', () => { + it('should call apiClient.request with the correct params', async () => { + await grants.find({ + grantId: 'grant123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/grant123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode grantId in find', async () => { + await grants.find({ + grantId: 'grant/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/grant%2F123', + }) + ); + }); + + it('should not double encode already-encoded grantId in find', async () => { + await grants.find({ + grantId: 'grant%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/grant%2F123', + }) + ); + }); + }); + + describe('update', () => { + it('should call apiClient.request with the correct params', async () => { + await grants.update({ + grantId: 'grant123', + requestBody: { + settings: { + test_setting: 'abc123', + }, + scope: ['calendar'], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PATCH', + path: '/v3/grants/grant123', + body: { + settings: { + test_setting: 'abc123', + }, + scope: ['calendar'], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('destroy', () => { + it('should call apiClient.request with the correct params', async () => { + await grants.destroy({ + grantId: 'grant123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/grants/grant123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); +}); diff --git a/tests/resources/messages.spec.ts b/tests/resources/messages.spec.ts new file mode 100644 index 00000000..9d02e1af --- /dev/null +++ b/tests/resources/messages.spec.ts @@ -0,0 +1,817 @@ +import APIClient from '../../src/apiClient'; +import { Messages } from '../../src/resources/messages'; +import { createReadableStream, MockedFormData } from '../testUtils'; +import { CreateAttachmentRequest } from '../../src/models/attachments'; +import { + MessageFields, + Message, + MessageTrackingOptions, +} from '../../src/models/messages'; +jest.mock('../../src/apiClient'); + +// Mock the FormData constructor +jest.mock('formdata-node', () => ({ + FormData: jest.fn().mockImplementation(function (this: MockedFormData) { + const appendedData: Record = {}; + + this.append = (key: string, value: any): void => { + appendedData[key] = value; + }; + + this._getAppendedData = (): Record => appendedData; + }), + Blob: jest.fn().mockImplementation((parts: any[], options?: any) => ({ + type: options?.type || '', + size: parts.reduce((size, part) => size + (part.length || 0), 0), + })), + File: jest + .fn() + .mockImplementation((parts: any[], name: string, options?: any) => ({ + name, + type: options?.type || '', + size: + options?.size || + parts.reduce((size, part) => size + (part.length || 0), 0), + stream: (): NodeJS.ReadableStream => parts[0], + [Symbol.toStringTag]: 'File', + })), +})); + +describe('Messages', () => { + let apiClient: jest.Mocked; + let messages: Messages; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + messages = new Messages(apiClient); + apiClient.request.mockResolvedValue({}); + }); + + describe('list', () => { + it('should call apiClient.request with the correct params', async () => { + await messages.list({ + identifier: 'id123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/messages', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should transform anyEmail array into comma-delimited any_email parameter', async () => { + const mockEmails = ['test1@example.com', 'test2@example.com']; + await messages.list({ + identifier: 'id123', + queryParams: { + anyEmail: mockEmails, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/messages', + overrides: undefined, + queryParams: { + any_email: mockEmails.join(','), + }, + }); + }); + + it('should call apiClient.request with fields=include_headers for list', async () => { + await messages.list({ + identifier: 'id123', + queryParams: { + fields: MessageFields.INCLUDE_HEADERS, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/messages', + overrides: undefined, + queryParams: { + fields: MessageFields.INCLUDE_HEADERS, + }, + }); + }); + + it('should call apiClient.request with fields=standard for list', async () => { + await messages.list({ + identifier: 'id123', + queryParams: { + fields: MessageFields.STANDARD, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/messages', + overrides: undefined, + queryParams: { + fields: MessageFields.STANDARD, + }, + }); + }); + }); + + describe('find', () => { + it('should call apiClient.request with the correct params', async () => { + await messages.find({ + identifier: 'id123', + messageId: 'message123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/messages/message123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode identifier and messageId in find', async () => { + await messages.find({ + identifier: 'id 123', + messageId: 'message/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/messages/message%2F123', + }) + ); + }); + + it('should not double encode already-encoded identifier and messageId in find', async () => { + await messages.find({ + identifier: 'id%20123', + messageId: 'message%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/messages/message%2F123', + }) + ); + }); + + it('should call apiClient.request with fields=include_tracking_options', async () => { + await messages.find({ + identifier: 'id123', + messageId: 'message123', + queryParams: { + fields: MessageFields.INCLUDE_TRACKING_OPTIONS, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/messages/message123', + overrides: undefined, + queryParams: { + fields: MessageFields.INCLUDE_TRACKING_OPTIONS, + }, + }); + }); + + it('should call apiClient.request with fields=raw_mime', async () => { + await messages.find({ + identifier: 'id123', + messageId: 'message123', + queryParams: { + fields: MessageFields.RAW_MIME, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/messages/message123', + overrides: undefined, + queryParams: { + fields: MessageFields.RAW_MIME, + }, + }); + }); + + it('should call apiClient.request with fields=include_headers for list', async () => { + await messages.list({ + identifier: 'id123', + queryParams: { + fields: MessageFields.INCLUDE_HEADERS, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/messages', + overrides: undefined, + queryParams: { + fields: MessageFields.INCLUDE_HEADERS, + }, + }); + }); + + it('should call apiClient.request with fields=standard for list', async () => { + await messages.list({ + identifier: 'id123', + queryParams: { + fields: MessageFields.STANDARD, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/messages', + overrides: undefined, + queryParams: { + fields: MessageFields.STANDARD, + }, + }); + }); + }); + + describe('update', () => { + it('should call apiClient.request with the correct params', async () => { + await messages.update({ + identifier: 'id123', + messageId: 'message123', + requestBody: { + starred: true, + unread: false, + folders: ['folder123'], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/v3/grants/id123/messages/message123', + body: { + starred: true, + unread: false, + folders: ['folder123'], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('destroy', () => { + it('should call apiClient.request with the correct params', async () => { + await messages.destroy({ + identifier: 'id123', + messageId: 'message123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/grants/id123/messages/message123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('send', () => { + it('should call apiClient.request with the correct params', async () => { + const jsonBody = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'This is my test email', + }; + await messages.send({ + identifier: 'id123', + requestBody: jsonBody, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + expect(capturedRequest.method).toEqual('POST'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/messages/send'); + expect(capturedRequest.body).toEqual(jsonBody); + expect(capturedRequest.overrides).toEqual({ + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }); + }); + + it('should attach files less than 3mb', async () => { + const baseJson = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'This is my test email', + }; + const jsonBody = { + ...baseJson, + attachments: [ + { + filename: 'file1.txt', + contentType: 'text/plain', + content: createReadableStream('This is the text from file 1'), + size: 100, + }, + ], + }; + const expectedJson = { + ...baseJson, + attachments: [ + { + filename: 'file1.txt', + contentType: 'text/plain', + content: 'VGhpcyBpcyB0aGUgdGV4dCBmcm9tIGZpbGUgMQ==', + size: 100, + }, + ], + }; + await messages.send({ + identifier: 'id123', + requestBody: jsonBody, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + expect(capturedRequest.method).toEqual('POST'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/messages/send'); + expect(capturedRequest.body).toEqual(expectedJson); + expect(capturedRequest.overrides).toEqual({ + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }); + }); + + it('should attach files 3mb+ properly', async () => { + const messageJson = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'This is my test email', + }; + const fileStream = createReadableStream('This is the text from file 1'); + const file1: CreateAttachmentRequest = { + filename: 'file1.txt', + contentType: 'text/plain', + content: fileStream, + size: 3 * 1024 * 1024, + }; + + await messages.send({ + identifier: 'id123', + requestBody: { + ...messageJson, + attachments: [file1], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + const formData = ( + capturedRequest.form as any as MockedFormData + )._getAppendedData(); + expect(formData.message).toEqual(JSON.stringify(messageJson)); + // ReadableStream is now wrapped in a file-like object + expect(formData.file0).toEqual({ + type: 'text/plain', + name: 'file1.txt', + size: 3145728, // 3MB as declared in the attachment + stream: expect.any(Function), + [Symbol.toStringTag]: 'File', + }); + expect(capturedRequest.method).toEqual('POST'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/messages/send'); + expect(capturedRequest.overrides).toEqual({ + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }); + }); + + it('should use multipart when total payload (body + attachments) exceeds 3MB', async () => { + // Create a large message body that, combined with small attachments, exceeds 3MB + const largeBody = 'A'.repeat(3.5 * 1024 * 1024); // 3.5MB body + const messageJson = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'This is my test email with large content', + body: largeBody, + }; + + const fileStream = createReadableStream('Small attachment content'); + const smallAttachment: CreateAttachmentRequest = { + filename: 'small_file.txt', + contentType: 'text/plain', + content: fileStream, + size: 1000, // 1KB attachment - small but total payload > 3MB + }; + + await messages.send({ + identifier: 'id123', + requestBody: { + ...messageJson, + attachments: [smallAttachment], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + + // Should use form data because total payload exceeds 3MB + expect(capturedRequest.form).toBeDefined(); + expect(capturedRequest.body).toBeUndefined(); + + const formData = ( + capturedRequest.form as any as MockedFormData + )._getAppendedData(); + expect(formData.message).toEqual(JSON.stringify(messageJson)); + // ReadableStream is now wrapped in a file-like object + expect(formData.file0).toEqual({ + type: 'text/plain', + name: 'small_file.txt', + size: 1000, // 1KB as declared in the attachment + stream: expect.any(Function), + [Symbol.toStringTag]: 'File', + }); + expect(capturedRequest.method).toEqual('POST'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/messages/send'); + }); + + it('should use JSON when total payload (body + attachments) is under 3MB', async () => { + // Create a message with body + attachments under 3MB + const smallBody = 'Small message content'; + const messageJson = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'This is my test email', + body: smallBody, + }; + + const smallAttachment: CreateAttachmentRequest = { + filename: 'small_file.txt', + contentType: 'text/plain', + content: createReadableStream('Small attachment content'), + size: 1000, // 1KB attachment + }; + + await messages.send({ + identifier: 'id123', + requestBody: { + ...messageJson, + attachments: [smallAttachment], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + + // Should use JSON body because total payload is under 3MB + expect(capturedRequest.body).toBeDefined(); + expect(capturedRequest.form).toBeUndefined(); + expect(capturedRequest.method).toEqual('POST'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/messages/send'); + }); + + it('should include isPlaintext in JSON body when provided', async () => { + const jsonBody = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'Plain text email', + body: 'Hello world', + isPlaintext: true, + }; + + await messages.send({ + identifier: 'id123', + requestBody: jsonBody, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + expect(capturedRequest.method).toEqual('POST'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/messages/send'); + expect(capturedRequest.body).toEqual(jsonBody); + }); + + it('should include isPlaintext in multipart form message when provided', async () => { + const messageJson = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'Plain text email', + body: 'Hello world', + isPlaintext: true, + }; + const fileStream = createReadableStream('This is the text from file 1'); + const file1: CreateAttachmentRequest = { + filename: 'file1.txt', + contentType: 'text/plain', + content: fileStream, + size: 3 * 1024 * 1024, + }; + + await messages.send({ + identifier: 'id123', + requestBody: { + ...messageJson, + attachments: [file1], + }, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + const formData = ( + capturedRequest.form as any as MockedFormData + )._getAppendedData(); + const parsed = JSON.parse(formData.message); + expect(parsed.to).toEqual(messageJson.to); + expect(parsed.subject).toEqual(messageJson.subject); + expect(parsed.body).toEqual(messageJson.body); + expect(parsed.is_plaintext).toBe(true); + expect(capturedRequest.method).toEqual('POST'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/messages/send'); + }); + + it('should handle base64 string attachments in multipart form', async () => { + const messageJson = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'This is my test email', + }; + const base64Content = 'VGhpcyBpcyBhIGJhc2U2NCBzdHJpbmc='; // "This is a base64 string" + const file1: CreateAttachmentRequest = { + filename: 'file1.txt', + contentType: 'text/plain', + content: base64Content, + size: 3 * 1024 * 1024, // Large enough to trigger multipart + }; + + await messages.send({ + identifier: 'id123', + requestBody: { + ...messageJson, + attachments: [file1], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + const formData = ( + capturedRequest.form as any as MockedFormData + )._getAppendedData(); + + expect(capturedRequest.method).toEqual('POST'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/messages/send'); + expect(formData.message).toEqual(JSON.stringify(messageJson)); + // The base64 string should have been converted to a Blob and attached to the form + expect(formData.file0).toBeDefined(); + expect(typeof formData.file0).toBe('object'); + // Note: The exact structure of the Blob mock may vary, but it should exist + }); + + it('should handle Buffer attachments in multipart form', async () => { + const messageJson = { + to: [{ name: 'Test', email: 'test@example.com' }], + subject: 'This is my test email', + }; + const bufferContent = Buffer.from('This is buffer content', 'utf8'); + const file1: CreateAttachmentRequest = { + filename: 'file1.txt', + contentType: 'text/plain', + content: bufferContent, + size: 3 * 1024 * 1024, // Large enough to trigger multipart + }; + + await messages.send({ + identifier: 'id123', + requestBody: { + ...messageJson, + attachments: [file1], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + const capturedRequest = apiClient.request.mock.calls[0][0]; + const formData = ( + capturedRequest.form as any as MockedFormData + )._getAppendedData(); + + expect(capturedRequest.method).toEqual('POST'); + expect(capturedRequest.path).toEqual('/v3/grants/id123/messages/send'); + expect(formData.message).toEqual(JSON.stringify(messageJson)); + // The Buffer should have been converted to a Blob and attached to the form + expect(formData.file0).toBeDefined(); + expect(typeof formData.file0).toBe('object'); + // Note: The exact structure of the Blob mock may vary, but it should exist + }); + }); + + describe('scheduledMessages', () => { + it('listing should call apiClient.request with the correct params', async () => { + await messages.listScheduledMessages({ + identifier: 'id123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/messages/schedules', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('finding should call apiClient.request with the correct params', async () => { + await messages.findScheduledMessage({ + identifier: 'id123', + scheduleId: 'schedule123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/messages/schedules/schedule123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('stopping should call apiClient.request with the correct params', async () => { + await messages.stopScheduledMessage({ + identifier: 'id123', + scheduleId: 'schedule123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/grants/id123/messages/schedules/schedule123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('cleanMessages', () => { + it('should call apiClient.request with the correct params', async () => { + await messages.cleanMessages({ + identifier: 'id123', + requestBody: { + messageId: ['message123'], + ignoreImages: true, + ignoreLinks: true, + ignoreTables: true, + imagesAsMarkdown: true, + removeConclusionPhrases: true, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/v3/grants/id123/messages/clean', + body: { + messageId: ['message123'], + ignoreImages: true, + ignoreLinks: true, + ignoreTables: true, + imagesAsMarkdown: true, + removeConclusionPhrases: true, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('MessageTrackingOptions interface', () => { + it('should have the correct structure for MessageTrackingOptions', () => { + const trackingOptions: MessageTrackingOptions = { + opens: true, + threadReplies: false, + links: true, + label: 'Test tracking label', + }; + + expect(trackingOptions.opens).toBe(true); + expect(trackingOptions.threadReplies).toBe(false); + expect(trackingOptions.links).toBe(true); + expect(trackingOptions.label).toBe('Test tracking label'); + }); + + it('should allow Message interface to include trackingOptions', () => { + const message: Partial = { + id: 'message123', + grantId: 'grant123', + object: 'message', + date: 1234567890, + folders: ['folder1'], + to: [{ name: 'Test User', email: 'test@example.com' }], + trackingOptions: { + opens: true, + threadReplies: false, + links: true, + label: 'Test tracking', + }, + }; + + expect(message.trackingOptions).toBeDefined(); + expect(message.trackingOptions?.opens).toBe(true); + expect(message.trackingOptions?.threadReplies).toBe(false); + expect(message.trackingOptions?.links).toBe(true); + expect(message.trackingOptions?.label).toBe('Test tracking'); + }); + + it('should allow Message interface to include rawMime', () => { + const message: Partial = { + id: 'message123', + grantId: 'grant123', + object: 'message', + rawMime: 'base64-encoded-mime-content-example', + }; + + expect(message.rawMime).toBeDefined(); + expect(message.rawMime).toBe('base64-encoded-mime-content-example'); + }); + + it('should allow Message interface to include both trackingOptions and rawMime', () => { + const message: Partial = { + id: 'message123', + grantId: 'grant123', + object: 'message', + date: 1234567890, + folders: ['folder1'], + to: [{ name: 'Test User', email: 'test@example.com' }], + trackingOptions: { + opens: true, + threadReplies: false, + links: true, + label: 'Test tracking', + }, + rawMime: 'base64-encoded-mime-content-example', + }; + + expect(message.trackingOptions).toBeDefined(); + expect(message.rawMime).toBeDefined(); + expect(message.rawMime).toBe('base64-encoded-mime-content-example'); + }); + }); +}); diff --git a/tests/resources/notetakers.spec.ts b/tests/resources/notetakers.spec.ts new file mode 100644 index 00000000..0ea5beba --- /dev/null +++ b/tests/resources/notetakers.spec.ts @@ -0,0 +1,767 @@ +import APIClient from '../../src/apiClient'; +import { Notetakers } from '../../src/resources/notetakers'; +jest.mock('../../src/apiClient'); + +describe('Notetakers', () => { + let apiClient: jest.Mocked; + let notetakers: Notetakers; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + notetakers = new Notetakers(apiClient); + apiClient.request.mockResolvedValue({}); + }); + + describe('list', () => { + it('should call apiClient.request with the correct params', async () => { + await notetakers.list({ + identifier: 'id123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/notetakers', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should call apiClient.request without identifier', async () => { + await notetakers.list({}); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/notetakers', + }); + }); + + it('should support filtering by state', async () => { + await notetakers.list({ + queryParams: { + state: 'attending', + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/notetakers', + queryParams: { + state: 'attending', + }, + }); + }); + + it('should support filtering by join time range', async () => { + await notetakers.list({ + queryParams: { + joinTimeStart: 1683936000, + joinTimeEnd: 1684022400, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/notetakers', + queryParams: { + joinTimeStart: 1683936000, + joinTimeEnd: 1684022400, + }, + }); + }); + + it('should support pagination parameters', async () => { + apiClient.request.mockResolvedValueOnce({ + data: [], + requestId: 'test-request-id', + nextCursor: 'next_cursor', + prevCursor: 'prev_cursor', + }); + + await notetakers.list({ + queryParams: { + limit: 10, + pageToken: 'next_page_token', + prevPageToken: 'prev_page_token', + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/notetakers', + queryParams: { + limit: 10, + pageToken: 'next_page_token', + prevPageToken: 'prev_page_token', + }, + }); + }); + + it('should support combining multiple query parameters', async () => { + apiClient.request.mockResolvedValueOnce({ + data: [], + requestId: 'test-request-id', + nextCursor: 'next_cursor', + }); + + await notetakers.list({ + identifier: 'id123', + queryParams: { + state: 'media_processing', + joinTimeStart: 1683936000, + limit: 25, + pageToken: 'next_page_token', + orderBy: 'name', + orderDirection: 'desc', + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/notetakers', + queryParams: { + state: 'media_processing', + joinTimeStart: 1683936000, + limit: 25, + pageToken: 'next_page_token', + orderBy: 'name', + orderDirection: 'desc', + }, + }); + }); + + it('should support ordering by name', async () => { + await notetakers.list({ + queryParams: { + orderBy: 'name', + orderDirection: 'asc', + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/notetakers', + queryParams: { + orderBy: 'name', + orderDirection: 'asc', + }, + }); + }); + + it('should use default order direction when not specified', async () => { + await notetakers.list({ + queryParams: { + orderBy: 'name', + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/notetakers', + queryParams: { + orderBy: 'name', + }, + }); + }); + + it('should use default order by when only direction specified', async () => { + await notetakers.list({ + queryParams: { + orderDirection: 'desc', + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/notetakers', + queryParams: { + orderDirection: 'desc', + }, + }); + }); + + it('should support ordering by join_time', async () => { + await notetakers.list({ + queryParams: { + orderBy: 'join_time', + orderDirection: 'asc', + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/notetakers', + queryParams: { + orderBy: 'join_time', + orderDirection: 'asc', + }, + }); + }); + + it('should support ordering by created_at', async () => { + await notetakers.list({ + queryParams: { + orderBy: 'created_at', + orderDirection: 'desc', + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/notetakers', + queryParams: { + orderBy: 'created_at', + orderDirection: 'desc', + }, + }); + }); + + it('should support combining ordering with other filters', async () => { + await notetakers.list({ + queryParams: { + state: 'attending', + joinTimeStart: 1683936000, + orderBy: 'name', + orderDirection: 'desc', + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/notetakers', + queryParams: { + state: 'attending', + joinTimeStart: 1683936000, + orderBy: 'name', + orderDirection: 'desc', + }, + }); + }); + }); + + describe('create', () => { + it('should create a notetaker with all properties', async () => { + const requestBody = { + meetingLink: 'https://meet.google.com/abc-def-ghi', + joinTime: 1234567890, + name: 'Custom Notetaker', + meetingSettings: { + videoRecording: true, + audioRecording: true, + transcription: true, + }, + }; + + await notetakers.create({ + identifier: 'id123', + requestBody, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/notetakers', + body: requestBody, + }); + }); + + it('should create a notetaker without identifier', async () => { + const requestBody = { + meetingLink: 'https://meet.google.com/abc-def-ghi', + }; + + await notetakers.create({ + requestBody, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/notetakers', + body: requestBody, + }); + }); + + it('should create a notetaker with only required properties', async () => { + const requestBody = { + meetingLink: 'https://meet.google.com/abc-def-ghi', + }; + + await notetakers.create({ + identifier: 'id123', + requestBody, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/notetakers', + body: requestBody, + }); + }); + + it('should create a notetaker with partial meeting settings', async () => { + const requestBody = { + meetingLink: 'https://meet.google.com/abc-def-ghi', + meetingSettings: { + videoRecording: false, + audioRecording: true, + }, + }; + + await notetakers.create({ + identifier: 'id123', + requestBody, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/notetakers', + body: requestBody, + }); + }); + }); + + describe('find', () => { + it('should find a notetaker by ID', async () => { + await notetakers.find({ + identifier: 'id123', + notetakerId: 'notetaker123', + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/notetakers/notetaker123', + }); + }); + + it('should URL encode identifier and notetakerId in find', async () => { + await notetakers.find({ + identifier: 'id 123', + notetakerId: 'notetaker/123', + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/notetakers/notetaker%2F123', + }) + ); + }); + + it('should not double encode already-encoded identifier and notetakerId in find', async () => { + await notetakers.find({ + identifier: 'id%20123', + notetakerId: 'notetaker%2F123', + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/notetakers/notetaker%2F123', + }) + ); + }); + + it('should find a notetaker without identifier', async () => { + await notetakers.find({ + notetakerId: 'notetaker123', + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/notetakers/notetaker123', + }); + }); + }); + + describe('update', () => { + it('should update a notetaker', async () => { + const requestBody = { + joinTime: 1234567890, + name: 'Updated Notetaker', + meetingSettings: { + videoRecording: false, + audioRecording: true, + transcription: true, + }, + }; + + await notetakers.update({ + identifier: 'id123', + notetakerId: 'notetaker123', + requestBody, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PATCH', + path: '/v3/grants/id123/notetakers/notetaker123', + body: requestBody, + }); + }); + + it('should update a notetaker with partial data', async () => { + const requestBody = { + name: 'Updated Notetaker', + }; + + await notetakers.update({ + identifier: 'id123', + notetakerId: 'notetaker123', + requestBody, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PATCH', + path: '/v3/grants/id123/notetakers/notetaker123', + body: requestBody, + }); + }); + + it('should update a notetaker without identifier', async () => { + const requestBody = { + name: 'Updated Notetaker', + }; + + await notetakers.update({ + notetakerId: 'notetaker123', + requestBody, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PATCH', + path: '/v3/notetakers/notetaker123', + body: requestBody, + }); + }); + + it('should URL encode identifier and notetakerId in update', async () => { + await notetakers.update({ + identifier: 'id 123', + notetakerId: 'notetaker/123', + requestBody: { name: 'Updated Notetaker' }, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/notetakers/notetaker%2F123', + }) + ); + }); + + it('should not double encode already-encoded identifier and notetakerId in update', async () => { + await notetakers.update({ + identifier: 'id%20123', + notetakerId: 'notetaker%2F123', + requestBody: { name: 'Updated Notetaker' }, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/notetakers/notetaker%2F123', + }) + ); + }); + }); + + describe('cancel', () => { + it('should cancel a notetaker by ID', async () => { + await notetakers.cancel({ + identifier: 'id123', + notetakerId: 'notetaker123', + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/grants/id123/notetakers/notetaker123/cancel', + }); + }); + + it('should cancel a notetaker with overrides', async () => { + await notetakers.cancel({ + identifier: 'id123', + notetakerId: 'notetaker123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/grants/id123/notetakers/notetaker123/cancel', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should cancel a notetaker without identifier', async () => { + await notetakers.cancel({ + notetakerId: 'notetaker123', + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/notetakers/notetaker123/cancel', + }); + }); + + it('should URL encode identifier and notetakerId in cancel', async () => { + await notetakers.cancel({ + identifier: 'id 123', + notetakerId: 'notetaker/123', + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/notetakers/notetaker%2F123/cancel', + }) + ); + }); + + it('should not double encode already-encoded identifier and notetakerId in cancel', async () => { + await notetakers.cancel({ + identifier: 'id%20123', + notetakerId: 'notetaker%2F123', + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/notetakers/notetaker%2F123/cancel', + }) + ); + }); + }); + + describe('leave', () => { + it('should remove a notetaker from a meeting', async () => { + const mockResponse = { + requestId: 'req-123', + data: { + id: 'notetaker123', + message: 'Notetaker has left the meeting successfully', + }, + }; + + apiClient.request.mockResolvedValueOnce(mockResponse); + + const response = await notetakers.leave({ + identifier: 'id123', + notetakerId: 'notetaker123', + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/notetakers/notetaker123/leave', + }); + + expect(response).toEqual(mockResponse); + expect(response.data.id).toBe('notetaker123'); + expect(response.data.message).toBe( + 'Notetaker has left the meeting successfully' + ); + }); + + it('should remove a notetaker from a meeting with overrides', async () => { + const mockResponse = { + requestId: 'req-456', + data: { + id: 'notetaker123', + message: 'Notetaker has left the meeting successfully', + }, + }; + + apiClient.request.mockResolvedValueOnce(mockResponse); + + const response = await notetakers.leave({ + identifier: 'id123', + notetakerId: 'notetaker123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/notetakers/notetaker123/leave', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(response).toEqual(mockResponse); + }); + + it('should remove a notetaker from a meeting without identifier', async () => { + const mockResponse = { + requestId: 'req-789', + data: { + id: 'notetaker123', + message: 'Notetaker has left the meeting successfully', + }, + }; + + apiClient.request.mockResolvedValueOnce(mockResponse); + + const response = await notetakers.leave({ + notetakerId: 'notetaker123', + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/notetakers/notetaker123/leave', + }); + + expect(response).toEqual(mockResponse); + }); + + it('should URL encode identifier and notetakerId in leave', async () => { + await notetakers.leave({ + identifier: 'id 123', + notetakerId: 'notetaker/123', + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/notetakers/notetaker%2F123/leave', + }) + ); + }); + + it('should not double encode already-encoded identifier and notetakerId in leave', async () => { + await notetakers.leave({ + identifier: 'id%20123', + notetakerId: 'notetaker%2F123', + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/notetakers/notetaker%2F123/leave', + }) + ); + }); + }); + + describe('downloadMedia', () => { + it('should download media with identifier', async () => { + const mockResponse = { + requestId: 'req-123', + data: { + recording: { + size: 21550491, + name: 'meeting_recording.mp4', + type: 'video/mp4', + createdAt: 1744222418, + expiresAt: 1744481618, + url: 'url_for_recording', + ttl: 259106, + }, + transcript: { + size: 862, + name: 'raw_transcript.json', + type: 'application/json', + createdAt: 1744222418, + expiresAt: 1744481618, + url: 'url_for_transcript', + ttl: 259106, + }, + }, + }; + + apiClient.request.mockResolvedValueOnce(mockResponse); + + const response = await notetakers.downloadMedia({ + identifier: 'id123', + notetakerId: 'notetaker123', + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/notetakers/notetaker123/media', + }); + + expect(response).toEqual(mockResponse); + + expect(response.data.recording.size).toBe(21550491); + expect(response.data.recording.name).toBe('meeting_recording.mp4'); + expect(response.data.recording.type).toBe('video/mp4'); + expect(response.data.recording.createdAt).toBe(1744222418); + expect(response.data.recording.expiresAt).toBe(1744481618); + expect(response.data.recording.url).toBe('url_for_recording'); + expect(response.data.recording.ttl).toBe(259106); + + expect(response.data.transcript.size).toBe(862); + expect(response.data.transcript.name).toBe('raw_transcript.json'); + expect(response.data.transcript.type).toBe('application/json'); + expect(response.data.transcript.createdAt).toBe(1744222418); + expect(response.data.transcript.expiresAt).toBe(1744481618); + expect(response.data.transcript.url).toBe('url_for_transcript'); + expect(response.data.transcript.ttl).toBe(259106); + }); + + it('should download media without identifier', async () => { + const mockResponse = { + requestId: 'req-456', + data: { + recording: { + size: 21550491, + name: 'meeting_recording.mp4', + type: 'video/mp4', + createdAt: 1744222418, + expiresAt: 1744481618, + url: 'url_for_recording', + ttl: 259106, + }, + transcript: { + size: 862, + name: 'raw_transcript.json', + type: 'application/json', + createdAt: 1744222418, + expiresAt: 1744481618, + url: 'url_for_transcript', + ttl: 259106, + }, + }, + }; + + apiClient.request.mockResolvedValueOnce(mockResponse); + + const response = await notetakers.downloadMedia({ + notetakerId: 'notetaker123', + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/notetakers/notetaker123/media', + }); + + expect(response).toEqual(mockResponse); + }); + + it('should URL encode identifier and notetakerId in downloadMedia', async () => { + await notetakers.downloadMedia({ + identifier: 'id 123', + notetakerId: 'notetaker/123', + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/notetakers/notetaker%2F123/media', + }) + ); + }); + + it('should not double encode already-encoded identifier and notetakerId in downloadMedia', async () => { + await notetakers.downloadMedia({ + identifier: 'id%20123', + notetakerId: 'notetaker%2F123', + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/notetakers/notetaker%2F123/media', + }) + ); + }); + }); +}); diff --git a/tests/resources/redirectUris.spec.ts b/tests/resources/redirectUris.spec.ts new file mode 100644 index 00000000..51b68390 --- /dev/null +++ b/tests/resources/redirectUris.spec.ts @@ -0,0 +1,262 @@ +import APIClient from '../../src/apiClient'; +import { RedirectUris } from '../../src/resources/redirectUris'; +jest.mock('../../src/apiClient'); + +describe('RedirectUris', () => { + let apiClient: jest.Mocked; + let redirectUris: RedirectUris; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + redirectUris = new RedirectUris(apiClient); + apiClient.request.mockResolvedValue({}); + }); + + describe('list', () => { + it('should call apiClient.request with the correct params', async () => { + await redirectUris.list({ + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/applications/redirect-uris', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should call apiClient.request even without overrides set', async () => { + await redirectUris.list(); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/applications/redirect-uris', + }); + }); + }); + + describe('find', () => { + it('should call apiClient.request with the correct params', async () => { + await redirectUris.find({ + redirectUriId: 'redirect123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/applications/redirect-uris/redirect123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode redirectUriId in find', async () => { + await redirectUris.find({ + redirectUriId: 'redirect/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/applications/redirect-uris/redirect%2F123', + }) + ); + }); + + it('should not double encode already-encoded redirectUriId in find', async () => { + await redirectUris.find({ + redirectUriId: 'redirect%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/applications/redirect-uris/redirect%2F123', + }) + ); + }); + }); + + describe('create', () => { + it('should call apiClient.request with the correct params', async () => { + await redirectUris.create({ + requestBody: { + url: 'https://test.com', + platform: 'google', + settings: { + origin: 'https://origin.com', + bundleId: 'com.test', + appStoreId: '123', + teamId: '123', + packageName: 'com.test', + sha1CertificateFingerprint: 'abc123', + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/applications/redirect-uris', + body: { + url: 'https://test.com', + platform: 'google', + settings: { + origin: 'https://origin.com', + bundleId: 'com.test', + appStoreId: '123', + teamId: '123', + packageName: 'com.test', + sha1CertificateFingerprint: 'abc123', + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('update', () => { + it('should call apiClient.request with the correct params', async () => { + await redirectUris.update({ + redirectUriId: 'redirect123', + requestBody: { + url: 'https://test.com', + platform: 'google', + settings: { + origin: 'https://origin.com', + bundleId: 'com.test', + appStoreId: '123', + teamId: '123', + packageName: 'com.test', + sha1CertificateFingerprint: 'abc123', + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/v3/applications/redirect-uris/redirect123', + body: { + url: 'https://test.com', + platform: 'google', + settings: { + origin: 'https://origin.com', + bundleId: 'com.test', + appStoreId: '123', + teamId: '123', + packageName: 'com.test', + sha1CertificateFingerprint: 'abc123', + }, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode redirectUriId in update', async () => { + await redirectUris.update({ + redirectUriId: 'redirect/123', + requestBody: { + url: 'https://test.com', + platform: 'google', + settings: {}, + }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/applications/redirect-uris/redirect%2F123', + }) + ); + }); + + it('should not double encode already-encoded redirectUriId in update', async () => { + await redirectUris.update({ + redirectUriId: 'redirect%2F123', + requestBody: { + url: 'https://test.com', + platform: 'google', + settings: {}, + }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/applications/redirect-uris/redirect%2F123', + }) + ); + }); + }); + + describe('destroy', () => { + it('should call apiClient.request with the correct params', async () => { + await redirectUris.destroy({ + redirectUriId: 'redirect123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/applications/redirect-uris/redirect123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode redirectUriId in destroy', async () => { + await redirectUris.destroy({ + redirectUriId: 'redirect/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/applications/redirect-uris/redirect%2F123', + }) + ); + }); + + it('should not double encode already-encoded redirectUriId in destroy', async () => { + await redirectUris.destroy({ + redirectUriId: 'redirect%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/applications/redirect-uris/redirect%2F123', + }) + ); + }); + }); +}); diff --git a/tests/resources/sessions.spec.ts b/tests/resources/sessions.spec.ts new file mode 100644 index 00000000..d14a4596 --- /dev/null +++ b/tests/resources/sessions.spec.ts @@ -0,0 +1,93 @@ +import APIClient from '../../src/apiClient'; +import { Sessions } from '../../src/resources/sessions'; +jest.mock('../../src/apiClient'); + +describe('Sessions', () => { + let apiClient: jest.Mocked; + let sessions: Sessions; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + sessions = new Sessions(apiClient); + apiClient.request.mockResolvedValue({}); + }); + + describe('create', () => { + it('should call apiClient.request with the correct params', async () => { + await sessions.create({ + requestBody: { + configurationId: 'configuration123', + timeToLive: 30, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/scheduling/sessions', + body: { + configurationId: 'configuration123', + timeToLive: 30, + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + }); + }); + + describe('destroy', () => { + it('should call apiClient.request with the correct params', async () => { + await sessions.destroy({ + sessionId: 'session123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/scheduling/sessions/session123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + }); + + it('should URL encode sessionId in destroy', async () => { + await sessions.destroy({ + sessionId: 'session/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/scheduling/sessions/session%2F123', + }) + ); + }); + + it('should not double encode already-encoded sessionId in destroy', async () => { + await sessions.destroy({ + sessionId: 'session%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/scheduling/sessions/session%2F123', + }) + ); + }); + }); +}); diff --git a/tests/resources/smartCompose.spec.ts b/tests/resources/smartCompose.spec.ts new file mode 100644 index 00000000..e922710d --- /dev/null +++ b/tests/resources/smartCompose.spec.ts @@ -0,0 +1,129 @@ +import APIClient from '../../src/apiClient'; +import { SmartCompose } from '../../src/resources/smartCompose'; +jest.mock('../../src/apiClient'); + +describe('SmartCompose', () => { + let apiClient: jest.Mocked; + let smartCompose: SmartCompose; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + smartCompose = new SmartCompose(apiClient); + apiClient.request.mockResolvedValue({}); + }); + + describe('composeMessage', () => { + it('should call apiClient.request with the correct params', async () => { + await smartCompose.composeMessage({ + identifier: 'id123', + requestBody: { + prompt: 'This is an example prompt', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/messages/smart-compose', + body: { + prompt: 'This is an example prompt', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode identifier in composeMessage', async () => { + await smartCompose.composeMessage({ + identifier: 'id 123', + requestBody: { prompt: 'Prompt' }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/messages/smart-compose', + }) + ); + }); + + it('should not double encode already-encoded identifier in composeMessage', async () => { + await smartCompose.composeMessage({ + identifier: 'id%20123', + requestBody: { prompt: 'Prompt' }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/messages/smart-compose', + }) + ); + }); + }); + + describe('composeMessageReply', () => { + it('should call apiClient.request with the correct params', async () => { + await smartCompose.composeMessageReply({ + identifier: 'id123', + messageId: 'message123', + requestBody: { + prompt: 'This is an example prompt', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/grants/id123/messages/message123/smart-compose', + body: { + prompt: 'This is an example prompt', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode identifier and messageId in composeMessageReply', async () => { + await smartCompose.composeMessageReply({ + identifier: 'id 123', + messageId: 'message/123', + requestBody: { prompt: 'Prompt' }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/messages/message%2F123/smart-compose', + }) + ); + }); + + it('should not double encode already-encoded identifier and messageId in composeMessageReply', async () => { + await smartCompose.composeMessageReply({ + identifier: 'id%20123', + messageId: 'message%2F123', + requestBody: { prompt: 'Prompt' }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/messages/message%2F123/smart-compose', + }) + ); + }); + }); +}); diff --git a/tests/resources/threads.spec.ts b/tests/resources/threads.spec.ts new file mode 100644 index 00000000..b50d587d --- /dev/null +++ b/tests/resources/threads.spec.ts @@ -0,0 +1,162 @@ +import APIClient from '../../src/apiClient'; +import { Threads } from '../../src/resources/threads'; +jest.mock('../../src/apiClient'); + +describe('Threads', () => { + let apiClient: jest.Mocked; + let threads: Threads; + + beforeEach(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + threads = new Threads(apiClient); + apiClient.request.mockResolvedValue({}); + }); + + describe('list', () => { + it('should call apiClient.request with the correct params', async () => { + await threads.list({ + identifier: 'id123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/threads', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should transform anyEmail array into comma-delimited any_email parameter', async () => { + const mockEmails = ['test1@example.com', 'test2@example.com']; + await threads.list({ + identifier: 'id123', + queryParams: { + anyEmail: mockEmails, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/threads', + overrides: undefined, + queryParams: { + any_email: mockEmails.join(','), + }, + }); + }); + }); + + describe('find', () => { + it('should call apiClient.request with the correct params', async () => { + await threads.find({ + identifier: 'id123', + threadId: 'thread123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/grants/id123/threads/thread123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode identifier and threadId in find', async () => { + await threads.find({ + identifier: 'id 123', + threadId: 'thread/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/threads/thread%2F123', + }) + ); + }); + + it('should not double encode already-encoded identifier and threadId in find', async () => { + await threads.find({ + identifier: 'id%20123', + threadId: 'thread%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/grants/id%20123/threads/thread%2F123', + }) + ); + }); + }); + + describe('update', () => { + it('should call apiClient.request with the correct params', async () => { + await threads.update({ + identifier: 'id123', + threadId: 'thread123', + requestBody: { + starred: true, + unread: false, + folders: ['folder123'], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/v3/grants/id123/threads/thread123', + body: { + starred: true, + unread: false, + folders: ['folder123'], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('destroy', () => { + it('should call apiClient.request with the correct params', async () => { + await threads.destroy({ + identifier: 'id123', + threadId: 'thread123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/grants/id123/threads/thread123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); +}); diff --git a/tests/resources/webhooks.spec.ts b/tests/resources/webhooks.spec.ts new file mode 100644 index 00000000..740df236 --- /dev/null +++ b/tests/resources/webhooks.spec.ts @@ -0,0 +1,323 @@ +import APIClient from '../../src/apiClient'; +import { Webhooks } from '../../src/resources/webhooks'; +import { WebhookTriggers } from '../../src/models/webhooks'; + +jest.mock('../../src/apiClient'); + +describe('Webhooks', () => { + let apiClient: jest.Mocked; + let webhooks: Webhooks; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + webhooks = new Webhooks(apiClient); + apiClient.request.mockResolvedValue({}); + }); + + describe('list', () => { + it('should call apiClient.request with the correct params', async () => { + await webhooks.list(); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/webhooks', + }); + }); + + it('should call apiClient.request with overrides', async () => { + await webhooks.list({ + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/webhooks', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('find', () => { + it('should call apiClient.request with the correct params', async () => { + await webhooks.find({ + webhookId: 'webhook123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/webhooks/webhook123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode webhookId in find', async () => { + await webhooks.find({ + webhookId: 'webhook/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/webhooks/webhook%2F123', + }) + ); + }); + + it('should not double encode already-encoded webhookId in find', async () => { + await webhooks.find({ + webhookId: 'webhook%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/webhooks/webhook%2F123', + }) + ); + }); + }); + + describe('create', () => { + it('should call apiClient.request with the correct params', async () => { + await webhooks.create({ + requestBody: { + triggerTypes: [WebhookTriggers.CalendarCreated], + webhookUrl: 'https://test.callback.com', + description: "My Webhook's Description", + notificationEmailAddresses: ['notification@example.com'], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/webhooks', + body: { + triggerTypes: [WebhookTriggers.CalendarCreated], + webhookUrl: 'https://test.callback.com', + description: "My Webhook's Description", + notificationEmailAddresses: ['notification@example.com'], + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('update', () => { + it('should call apiClient.request with the correct params', async () => { + await webhooks.update({ + webhookId: 'webhook123', + requestBody: { + description: "Updated Calendar's Description", + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/v3/webhooks/webhook123', + body: { + description: "Updated Calendar's Description", + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode webhookId in update', async () => { + await webhooks.update({ + webhookId: 'webhook/123', + requestBody: { description: 'desc' }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/webhooks/webhook%2F123', + }) + ); + }); + + it('should not double encode already-encoded webhookId in update', async () => { + await webhooks.update({ + webhookId: 'webhook%2F123', + requestBody: { description: 'desc' }, + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/webhooks/webhook%2F123', + }) + ); + }); + }); + + describe('destroy', () => { + it('should call apiClient.request with the correct params', async () => { + await webhooks.destroy({ + webhookId: 'webhook123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'DELETE', + path: '/v3/webhooks/webhook123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode webhookId in destroy', async () => { + await webhooks.destroy({ + webhookId: 'webhook/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/webhooks/webhook%2F123', + }) + ); + }); + + it('should not double encode already-encoded webhookId in destroy', async () => { + await webhooks.destroy({ + webhookId: 'webhook%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/webhooks/webhook%2F123', + }) + ); + }); + }); + + describe('rotateSecret', () => { + it('should call apiClient.request with the correct params', async () => { + await webhooks.rotateSecret({ + webhookId: 'webhook123', + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/webhooks/rotate-secret/webhook123', + body: {}, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + + it('should URL encode webhookId in rotateSecret', async () => { + await webhooks.rotateSecret({ + webhookId: 'webhook/123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/webhooks/rotate-secret/webhook%2F123', + }) + ); + }); + + it('should not double encode already-encoded webhookId in rotateSecret', async () => { + await webhooks.rotateSecret({ + webhookId: 'webhook%2F123', + overrides: {}, + }); + expect(apiClient.request).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/v3/webhooks/rotate-secret/webhook%2F123', + }) + ); + }); + }); + + describe('ipAddresses', () => { + it('should call apiClient.request with the correct params', async () => { + await webhooks.ipAddresses(); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/webhooks/ip-addresses', + body: undefined, + }); + }); + + it('should call apiClient.request with overrides', async () => { + await webhooks.ipAddresses({ + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/webhooks/ip-addresses', + body: undefined, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'bar' }, + }, + }); + }); + }); + + describe('extractChallengeParameter', () => { + it('should extract the challenge parameter from a valid URL', () => { + const url = 'https://example.com?challenge=testValue'; + const result = webhooks.extractChallengeParameter(url); + expect(result).toBe('testValue'); + }); + + it('should throw an error if the challenge parameter is missing', () => { + const url = 'https://example.com?otherParam=value'; + expect(() => webhooks.extractChallengeParameter(url)).toThrow( + 'Invalid URL or no challenge parameter found.' + ); + }); + + it('should throw an error for an invalid URL', () => { + const url = 'not-a-valid-url'; + expect(() => webhooks.extractChallengeParameter(url)).toThrow(); + }); + }); +}); diff --git a/tests/setupTests.ts b/tests/setupTests.ts new file mode 100644 index 00000000..c4e6c932 --- /dev/null +++ b/tests/setupTests.ts @@ -0,0 +1,6 @@ +import { enableFetchMocks } from 'jest-fetch-mock'; + +enableFetchMocks(); + +// Export for TypeScript module resolution +export {}; diff --git a/tests/testUtils.ts b/tests/testUtils.ts new file mode 100644 index 00000000..a2f1255e --- /dev/null +++ b/tests/testUtils.ts @@ -0,0 +1,65 @@ +/* istanbul ignore file */ +import { Readable } from 'stream'; + +export interface MockedFormData { + append(key: string, value: any): void; + _getAppendedData(): Record; +} + +export const mockResponse = (body: string, status = 200): any => { + const headers: Record = {}; + + const headersObj = { + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type + entries() { + return Object.entries(headers); + }, + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type + get(key: string) { + return headers[key]; + }, + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type + set(key: string, value: string) { + headers[key] = value; + return headers; + }, + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type + raw() { + const rawHeaders: Record = {}; + Object.keys(headers).forEach((key) => { + rawHeaders[key] = [headers[key]]; + }); + return rawHeaders; + }, + }; + + return { + status, + text: jest.fn().mockResolvedValue(body), + json: jest.fn().mockResolvedValue(JSON.parse(body)), + headers: headersObj, + }; +}; + +export const createReadableStream = (text: string): NodeJS.ReadableStream => { + return new Readable({ + read(): void { + this.push(text); + this.push(null); + }, + }); +}; + +export class MockFormData implements MockedFormData { + private data: Record = {}; + + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type + append(key: string, value: any) { + this.data[key] = value; + } + + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type + _getAppendedData() { + return this.data; + } +} diff --git a/tests/utils.spec.ts b/tests/utils.spec.ts new file mode 100644 index 00000000..2b5c07d0 --- /dev/null +++ b/tests/utils.spec.ts @@ -0,0 +1,803 @@ +import { + createFileRequestBuilder, + objKeysToCamelCase, + objKeysToSnakeCase, + makePathParams, + encodeAttachmentContent, + encodeAttachmentStreams, + attachmentStreamToFile, + streamToBase64, + calculateTotalPayloadSize, +} from '../src/utils'; +import { Readable } from 'stream'; +import { CreateAttachmentRequest } from '../src/models/attachments'; + +jest.mock('node:fs', () => { + return { + statSync: jest.fn(), + createReadStream: jest.fn(), + }; +}); + +jest.mock('mime-types', () => { + return { + lookup: jest.fn(), + }; +}); + +describe('createFileRequestBuilder', () => { + const MOCK_FILE_PATH = 'path/to/mock/file.txt'; + const mockedStatSync = { + size: 100, + }; + const mockedReadStream = {}; + + beforeEach(() => { + jest.resetAllMocks(); + require('node:fs').statSync.mockReturnValue(mockedStatSync); + require('node:fs').createReadStream.mockReturnValue(mockedReadStream); + }); + + it('should return correct file details for a given filePath', () => { + require('mime-types').lookup.mockReturnValue('text/plain'); + + const result = createFileRequestBuilder(MOCK_FILE_PATH); + + expect(result).toEqual({ + filename: 'file.txt', + contentType: 'text/plain', + content: mockedReadStream, + size: mockedStatSync.size, + }); + }); + + it('should default contentType to application/octet-stream if mime lookup fails', () => { + require('mime-types').lookup.mockReturnValue(null); + + const result = createFileRequestBuilder(MOCK_FILE_PATH); + + expect(result.contentType).toBe('application/octet-stream'); + }); + + it('should default contentType to application/octet-stream for files without extensions', () => { + require('mime-types').lookup.mockReturnValue(null); + + const result = createFileRequestBuilder('path/to/mock/fileWithoutExt'); + + expect(result.contentType).toBe('application/octet-stream'); + }); +}); + +describe('convertCase', () => { + it('should convert basic object keys to camelCase', () => { + const obj = { first_name: 'John', last_name: 'Doe' }; + const result = objKeysToCamelCase(obj); + expect(result).toEqual({ firstName: 'John', lastName: 'Doe' }); + }); + + it('should convert nested object keys to camelCase', () => { + const obj = { user_data: { first_name: 'John', last_name: 'Doe' } }; + const result = objKeysToCamelCase(obj); + expect(result).toEqual({ + userData: { firstName: 'John', lastName: 'Doe' }, + }); + }); + + it('should handle arrays correctly for camelCase', () => { + const obj = { + names: ['John', 'Jane'], + users: [ + { user_id: 1, user_name: 'John' }, + { user_id: 2, user_name: 'Jane' }, + ], + }; + const result = objKeysToCamelCase(obj); + expect(result).toEqual({ + names: ['John', 'Jane'], + users: [ + { userId: 1, userName: 'John' }, + { userId: 2, userName: 'Jane' }, + ], + }); + }); + + it('should convert basic object keys to snake_case', () => { + const obj = { firstName: 'John', lastName: 'Doe' }; + const result = objKeysToSnakeCase(obj); + expect(result).toEqual({ first_name: 'John', last_name: 'Doe' }); + }); + + it('should convert nested object keys to snake_case', () => { + const obj = { userData: { firstName: 'John', lastName: 'Doe' } }; + const result = objKeysToSnakeCase(obj); + expect(result).toEqual({ + user_data: { first_name: 'John', last_name: 'Doe' }, + }); + }); + + it('should handle arrays correctly for snake_case', () => { + const obj = { + names: ['John', 'Jane'], + users: [ + { userId: 1, userName: 'John' }, + { userId: 2, userName: 'Jane' }, + ], + }; + const result = objKeysToSnakeCase(obj); + expect(result).toEqual({ + names: ['John', 'Jane'], + users: [ + { user_id: 1, user_name: 'John' }, + { user_id: 2, user_name: 'Jane' }, + ], + }); + }); + + it('should exclude specified keys from camelCase conversion', () => { + const obj = { first_name: 'John', last_name: 'Doe' }; + const result = objKeysToCamelCase(obj, ['last_name']); + expect(result).toEqual({ firstName: 'John', last_name: 'Doe' }); + }); + + it('should exclude specified keys from snake_case conversion', () => { + const obj = { firstName: 'John', lastName: 'Doe' }; + const result = objKeysToSnakeCase(obj, ['lastName']); + expect(result).toEqual({ first_name: 'John', lastName: 'Doe' }); + }); + + it('should handle null and undefined values in camelCase conversion', () => { + const obj = { first_name: 'John', address_data: null, user_age: undefined }; + const result = objKeysToCamelCase(obj); + expect(result).toEqual({ + firstName: 'John', + addressData: null, + userAge: undefined, + }); + }); + + it('should handle null and undefined values in snake_case conversion', () => { + const obj = { firstName: 'John', addressData: null, userAge: undefined }; + const result = objKeysToSnakeCase(obj); + expect(result).toEqual({ + first_name: 'John', + address_data: null, + user_age: undefined, + }); + }); + + it('should handle numerical key names in snake_case conversion', () => { + const obj = { firstName: 'John', current2024Status: 'confirmed' }; + const result = objKeysToSnakeCase(obj); + expect(result).toEqual({ + first_name: 'John', + current_2024_status: 'confirmed', + }); + }); + + it('should handle numerical key names in camelCase conversion', () => { + const obj = { first_name: 'John', current_2024_status: 'confirmed' }; + const result = objKeysToCamelCase(obj); + expect(result).toEqual({ + firstName: 'John', + current2024Status: 'confirmed', + }); + }); +}); + +describe('makePathParams and safePath', () => { + it('should URL encode path params with special characters', () => { + const path = makePathParams( + '/v3/grants/{identifier}/contacts/{contactId}', + { + identifier: 'id 123', + contactId: 'contact/123', + } + ); + expect(path).toBe('/v3/grants/id%20123/contacts/contact%2F123'); + }); + + it('should not double encode already-encoded params (backwards compatibility)', () => { + const path = makePathParams( + '/v3/grants/{identifier}/contacts/{contactId}', + { + identifier: 'id%20123', // already encoded + contactId: 'contact%2F123', // already encoded + } + ); + expect(path).toBe('/v3/grants/id%20123/contacts/contact%2F123'); + }); + + it('should throw if a required param is missing', () => { + expect(() => + makePathParams('/v3/grants/{identifier}/contacts/{contactId}', { + identifier: 'id123', + // contactId missing + } as any) + ).toThrow('Missing replacement for contactId'); + }); + + it('should work with no params in the path', () => { + const path = makePathParams('/v3/grants', {}); + expect(path).toBe('/v3/grants'); + }); + + it('should handle params that need no encoding', () => { + const path = makePathParams('/v3/grants/{identifier}', { + identifier: 'plainid', + }); + expect(path).toBe('/v3/grants/plainid'); + }); + + // Additional tests for the improved safePath implementation + it('should handle mixed encoded and unencoded content correctly', () => { + const path = makePathParams('/v3/grants/{identifier}', { + identifier: 'test%20already encoded', // partially encoded + }); + expect(path).toBe('/v3/grants/test%20already%20encoded'); + }); + + it('should handle malformed percent encoding gracefully', () => { + const path = makePathParams('/v3/grants/{identifier}', { + identifier: 'test%2 incomplete', // incomplete percent encoding + }); + expect(path).toBe('/v3/grants/test%252%20incomplete'); + }); + + it('should handle unicode characters correctly', () => { + const path = makePathParams('/v3/grants/{identifier}', { + identifier: 'test δΈ­ζ–‡ unicode', + }); + expect(path).toBe('/v3/grants/test%20%E4%B8%AD%E6%96%87%20unicode'); + }); + + it('should handle complex URI components with multiple special characters', () => { + const path = makePathParams('/v3/grants/{identifier}', { + identifier: 'user@domain.com/folder?query=value#anchor', + }); + expect(path).toBe( + '/v3/grants/user%40domain.com%2Ffolder%3Fquery%3Dvalue%23anchor' + ); + }); + + it('should preserve correctly encoded URIs with complex characters', () => { + const path = makePathParams('/v3/grants/{identifier}', { + identifier: 'user%40domain.com%2Ffolder%3Fquery%3Dvalue%23anchor', // pre-encoded + }); + expect(path).toBe( + '/v3/grants/user%40domain.com%2Ffolder%3Fquery%3Dvalue%23anchor' + ); + }); + + it('should handle empty strings', () => { + const path = makePathParams('/v3/grants/{identifier}', { + identifier: '', + }); + expect(path).toBe('/v3/grants/'); + }); + + it('should handle strings with only special characters', () => { + const path = makePathParams('/v3/grants/{identifier}', { + identifier: '/@#$%^&*()', + }); + expect(path).toBe('/v3/grants/%2F%40%23%24%25%5E%26*()'); + }); +}); + +describe('encodeAttachmentContent', () => { + // Helper function to create a readable stream from a string + const createReadableStream = (content: string): NodeJS.ReadableStream => { + const stream = new Readable(); + stream.push(content); + stream.push(null); // Signal end of stream + return stream; + }; + + it('should encode Buffer content to base64', async () => { + const testContent = 'Hello, World!'; + const buffer = Buffer.from(testContent, 'utf8'); + const expectedBase64 = buffer.toString('base64'); + + const attachments: CreateAttachmentRequest[] = [ + { + filename: 'test.txt', + contentType: 'text/plain', + content: buffer, + size: buffer.length, + }, + ]; + + const result = await encodeAttachmentContent(attachments); + + expect(result).toHaveLength(1); + expect(result[0].content).toBe(expectedBase64); + expect(result[0].filename).toBe('test.txt'); + expect(result[0].contentType).toBe('text/plain'); + expect(result[0].size).toBe(buffer.length); + }); + + it('should encode ReadableStream content to base64', async () => { + const testContent = 'Stream content test'; + const stream = createReadableStream(testContent); + const expectedBase64 = Buffer.from(testContent, 'utf8').toString('base64'); + + const attachments: CreateAttachmentRequest[] = [ + { + filename: 'stream.txt', + contentType: 'text/plain', + content: stream, + size: testContent.length, + }, + ]; + + const result = await encodeAttachmentContent(attachments); + + expect(result).toHaveLength(1); + expect(result[0].content).toBe(expectedBase64); + expect(result[0].filename).toBe('stream.txt'); + expect(result[0].contentType).toBe('text/plain'); + }); + + it('should pass through string content unchanged', async () => { + const base64Content = 'SGVsbG8sIFdvcmxkIQ=='; // "Hello, World!" in base64 + + const attachments: CreateAttachmentRequest[] = [ + { + filename: 'string.txt', + contentType: 'text/plain', + content: base64Content, + size: 13, + }, + ]; + + const result = await encodeAttachmentContent(attachments); + + expect(result).toHaveLength(1); + expect(result[0].content).toBe(base64Content); + expect(result[0].filename).toBe('string.txt'); + expect(result[0].contentType).toBe('text/plain'); + }); + + it('should handle mixed content types in a single request', async () => { + const bufferContent = Buffer.from('Buffer content', 'utf8'); + const streamContent = createReadableStream('Stream content'); + const stringContent = 'U3RyaW5nIGNvbnRlbnQ='; // Already base64 + + const attachments: CreateAttachmentRequest[] = [ + { + filename: 'buffer.txt', + contentType: 'text/plain', + content: bufferContent, + size: bufferContent.length, + }, + { + filename: 'stream.txt', + contentType: 'text/plain', + content: streamContent, + size: 14, + }, + { + filename: 'string.txt', + contentType: 'text/plain', + content: stringContent, + size: 13, + }, + ]; + + const result = await encodeAttachmentContent(attachments); + + expect(result).toHaveLength(3); + + // Buffer should be converted to base64 + expect(result[0].content).toBe(bufferContent.toString('base64')); + expect(result[0].filename).toBe('buffer.txt'); + + // Stream should be converted to base64 + expect(result[1].content).toBe( + Buffer.from('Stream content', 'utf8').toString('base64') + ); + expect(result[1].filename).toBe('stream.txt'); + + // String should be passed through + expect(result[2].content).toBe(stringContent); + expect(result[2].filename).toBe('string.txt'); + }); + + it('should handle binary Buffer content correctly', async () => { + // Create a buffer with binary data (some non-text bytes) + const binaryData = new Uint8Array([0x00, 0x01, 0x02, 0xff, 0xfe, 0xfd]); + const buffer = Buffer.from(binaryData); + const expectedBase64 = buffer.toString('base64'); + + const attachments: CreateAttachmentRequest[] = [ + { + filename: 'binary.bin', + contentType: 'application/octet-stream', + content: buffer, + size: buffer.length, + }, + ]; + + const result = await encodeAttachmentContent(attachments); + + expect(result).toHaveLength(1); + expect(result[0].content).toBe(expectedBase64); + expect(result[0].filename).toBe('binary.bin'); + expect(result[0].contentType).toBe('application/octet-stream'); + }); + + it('should handle empty Buffer', async () => { + const emptyBuffer = Buffer.alloc(0); + const expectedBase64 = emptyBuffer.toString('base64'); // Should be empty string + + const attachments: CreateAttachmentRequest[] = [ + { + filename: 'empty.txt', + contentType: 'text/plain', + content: emptyBuffer, + size: 0, + }, + ]; + + const result = await encodeAttachmentContent(attachments); + + expect(result).toHaveLength(1); + expect(result[0].content).toBe(expectedBase64); + expect(result[0].filename).toBe('empty.txt'); + }); + + it('should handle large Buffer content', async () => { + // Create a 1KB buffer with repeating pattern + const largeContent = 'A'.repeat(1024); + const largeBuffer = Buffer.from(largeContent, 'utf8'); + const expectedBase64 = largeBuffer.toString('base64'); + + const attachments: CreateAttachmentRequest[] = [ + { + filename: 'large.txt', + contentType: 'text/plain', + content: largeBuffer, + size: largeBuffer.length, + }, + ]; + + const result = await encodeAttachmentContent(attachments); + + expect(result).toHaveLength(1); + expect(result[0].content).toBe(expectedBase64); + expect(result[0].filename).toBe('large.txt'); + expect(result[0].size).toBe(1024); + }); +}); + +describe('encodeAttachmentStreams (backwards compatibility)', () => { + it('should work the same as encodeAttachmentContent', async () => { + const testContent = 'Backwards compatibility test'; + const buffer = Buffer.from(testContent, 'utf8'); + + const attachments: CreateAttachmentRequest[] = [ + { + filename: 'compat.txt', + contentType: 'text/plain', + content: buffer, + size: buffer.length, + }, + ]; + + const newResult = await encodeAttachmentContent(attachments); + const oldResult = await encodeAttachmentStreams(attachments); + + expect(oldResult).toEqual(newResult); + expect(oldResult[0].content).toBe(buffer.toString('base64')); + }); +}); + +describe('streamToBase64', () => { + // Helper function to create a readable stream from a string + const createReadableStream = (content: string): NodeJS.ReadableStream => { + const stream = new Readable(); + stream.push(content); + stream.push(null); // Signal end of stream + return stream; + }; + + it('should convert stream to base64', async () => { + const testContent = 'Hello, World!'; + const stream = createReadableStream(testContent); + const expectedBase64 = Buffer.from(testContent, 'utf8').toString('base64'); + + const result = await streamToBase64(stream); + + expect(result).toBe(expectedBase64); + }); + + it('should handle stream errors', async () => { + const errorStream = new Readable({ + read(): void { + // Implement _read to avoid the "not implemented" error + }, + }); + const testError = new Error('Stream error test'); + + // Emit error after a short delay to ensure the error handler is set up + setTimeout(() => { + errorStream.emit('error', testError); + }, 10); + + await expect(streamToBase64(errorStream)).rejects.toThrow( + 'Stream error test' + ); + }); + + it('should handle empty stream', async () => { + const emptyStream = createReadableStream(''); + const result = await streamToBase64(emptyStream); + expect(result).toBe(''); + }); +}); + +describe('attachmentStreamToFile', () => { + // Helper function to create a readable stream from a string + const createReadableStream = (content: string): NodeJS.ReadableStream => { + const stream = new Readable(); + stream.push(content); + stream.push(null); // Signal end of stream + return stream; + }; + + it('should convert stream attachment to file object', () => { + const stream = createReadableStream('test content'); + const attachment: CreateAttachmentRequest = { + filename: 'test.txt', + contentType: 'text/plain', + content: stream, + size: 12, + }; + + const result = attachmentStreamToFile(attachment); + + expect(result.name).toBe('test.txt'); + expect(result.type).toBe('text/plain'); + expect(result.size).toBe(12); + expect(typeof result.stream).toBe('function'); + expect(result.stream()).toBe(stream); + expect(result[Symbol.toStringTag]).toBe('File'); + }); + + it('should use mimeType parameter when provided', () => { + const stream = createReadableStream('test content'); + const attachment: CreateAttachmentRequest = { + filename: 'test.txt', + contentType: 'text/plain', + content: stream, + }; + + const result = attachmentStreamToFile(attachment, 'application/json'); + + expect(result.type).toBe('application/json'); + }); + + it('should throw error for invalid mimeType parameter', () => { + const stream = createReadableStream('test content'); + const attachment: CreateAttachmentRequest = { + filename: 'test.txt', + contentType: 'text/plain', + content: stream, + }; + + expect(() => { + attachmentStreamToFile(attachment, 123 as any); + }).toThrow('Invalid mimetype, expected string.'); + }); + + it('should throw error for string content', () => { + const attachment: CreateAttachmentRequest = { + filename: 'test.txt', + contentType: 'text/plain', + content: 'string content', + }; + + expect(() => { + attachmentStreamToFile(attachment); + }).toThrow('Invalid attachment content, expected ReadableStream.'); + }); + + it('should throw error for Buffer content', () => { + const attachment: CreateAttachmentRequest = { + filename: 'test.txt', + contentType: 'text/plain', + content: Buffer.from('buffer content'), + }; + + expect(() => { + attachmentStreamToFile(attachment); + }).toThrow('Invalid attachment content, expected ReadableStream.'); + }); + + it('should handle attachment without size', () => { + const stream = createReadableStream('test content'); + const attachment: CreateAttachmentRequest = { + filename: 'test.txt', + contentType: 'text/plain', + content: stream, + }; + + const result = attachmentStreamToFile(attachment); + + expect(result.name).toBe('test.txt'); + expect(result.type).toBe('text/plain'); + expect(result.size).toBeUndefined(); + expect(result.stream()).toBe(stream); + }); + + it('should return content stream when stream() method is called', () => { + const stream = createReadableStream('test content'); + const attachment: CreateAttachmentRequest = { + filename: 'test.txt', + contentType: 'text/plain', + content: stream, + }; + + const result = attachmentStreamToFile(attachment); + const returnedStream = result.stream(); + + expect(returnedStream).toBe(stream); + }); +}); + +describe('calculateTotalPayloadSize', () => { + it('should calculate total payload size including message body and attachments', () => { + const requestBody = { + to: [{ email: 'test@example.com' }], + subject: 'Test', + body: 'Test body', + attachments: [ + { filename: 'file1.txt', size: 100 }, + { filename: 'file2.txt', size: 200 }, + ], + }; + + const result = calculateTotalPayloadSize(requestBody); + + // Should include JSON body size + attachment sizes + expect(result).toBeGreaterThan(0); + expect(result).toBeGreaterThanOrEqual(300); // At least the attachment sizes + }); + + it('should calculate size without attachments', () => { + const requestBody = { + to: [{ email: 'test@example.com' }], + subject: 'Test', + body: 'Test body', + }; + + const result = calculateTotalPayloadSize(requestBody); + + // Should only include JSON body size + expect(result).toBeGreaterThan(0); + expect(result).toBeLessThan(1000); // Should be relatively small without attachments + }); + + it('should handle empty attachments array', () => { + const requestBody = { + to: [{ email: 'test@example.com' }], + subject: 'Test', + attachments: [], + }; + + const result = calculateTotalPayloadSize(requestBody); + + expect(result).toBeGreaterThan(0); + }); + + it('should handle attachments without size property', () => { + const requestBody = { + to: [{ email: 'test@example.com' }], + subject: 'Test', + attachments: [ + { filename: 'file1.txt' }, + { filename: 'file2.txt', size: 200 }, + ], + }; + + const result = calculateTotalPayloadSize(requestBody); + + // Should only count attachments with size property + expect(result).toBeGreaterThanOrEqual(200); + }); + + it('should handle undefined attachments', () => { + const requestBody = { + to: [{ email: 'test@example.com' }], + subject: 'Test', + }; + + const result = calculateTotalPayloadSize(requestBody); + + expect(result).toBeGreaterThan(0); + }); + + it('should handle large attachments', () => { + const requestBody = { + to: [{ email: 'test@example.com' }], + subject: 'Test', + attachments: [ + { filename: 'large1.txt', size: 1000000 }, + { filename: 'large2.txt', size: 2000000 }, + ], + }; + + const result = calculateTotalPayloadSize(requestBody); + + expect(result).toBeGreaterThanOrEqual(3000000); + }); +}); + +describe('convertCase with nested arrays', () => { + it('should recursively convert object items in arrays to camelCase', () => { + const obj = { + items: [ + { user_id: 1, user_name: 'John' }, + { user_id: 2, user_name: 'Jane' }, + 'plain string', + 123, + ], + }; + const result = objKeysToCamelCase(obj); + expect(result).toEqual({ + items: [ + { userId: 1, userName: 'John' }, + { userId: 2, userName: 'Jane' }, + 'plain string', + 123, + ], + }); + }); + + it('should recursively convert object items in arrays to snake_case', () => { + const obj = { + items: [ + { userId: 1, userName: 'John' }, + { userId: 2, userName: 'Jane' }, + 'plain string', + 123, + ], + }; + const result = objKeysToSnakeCase(obj); + expect(result).toEqual({ + items: [ + { user_id: 1, user_name: 'John' }, + { user_id: 2, user_name: 'Jane' }, + 'plain string', + 123, + ], + }); + }); + + it('should handle deeply nested objects in arrays', () => { + const obj = { + users: [ + { + user_id: 1, + profile: { first_name: 'John', last_name: 'Doe' }, + }, + { + user_id: 2, + profile: { first_name: 'Jane', last_name: 'Smith' }, + }, + ], + }; + const result = objKeysToCamelCase(obj); + expect(result).toEqual({ + users: [ + { + userId: 1, + profile: { firstName: 'John', lastName: 'Doe' }, + }, + { + userId: 2, + profile: { firstName: 'Jane', lastName: 'Smith' }, + }, + ], + }); + }); +}); diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json new file mode 100644 index 00000000..4b2a2637 --- /dev/null +++ b/tsconfig.cjs.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "outDir": "lib/cjs", + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "moduleResolution": "node" + }, + "exclude": ["src/utils/fetchWrapper-esm.ts"] +} diff --git a/tsconfig.esm.json b/tsconfig.esm.json new file mode 100644 index 00000000..b66b56f4 --- /dev/null +++ b/tsconfig.esm.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "es2020", + "outDir": "lib/esm" + }, + "exclude": ["src/utils/fetchWrapper-cjs.ts"] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..f09b6124 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "es2021", + "declaration": true, + "declarationDir": "lib/types", + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "strict": true, + "noImplicitAny": true, + "noImplicitThis": true, + "baseUrl": "./src" + }, + "typedocOptions": { + "entryPointStrategy": "expand", + "entryPoints": ["./src"], + "exclude": ["src/version.ts"], + "out": "docs", + "plugin": ["typedoc-plugin-rename-defaults"], + "excludeExternals": true, + "excludePrivate": true, + "excludeInternal": true, + }, + "include": ["src/**/*"], + "exclude": ["tests", "lib", "scripts"] +} diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 00000000..de985200 --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "allowJs": true, + "declaration": true, + } +} diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index 5a463e28..00000000 --- a/yarn.lock +++ /dev/null @@ -1,3490 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -JSONStream@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.0.4.tgz#aa86d6a89c8e77f206cd542581b563e7eee32459" - dependencies: - jsonparse "~1.0.0" - through ">=2.2.7 <3" - -abab@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - -acorn-globals@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-3.1.0.tgz#fd8270f71fbb4996b004fa880ee5d46573a731bf" - dependencies: - acorn "^4.0.4" - -acorn-jsx@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" - dependencies: - acorn "^3.0.4" - -acorn@^3.0.4: - version "3.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" - -acorn@^4.0.4: - version "4.0.13" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" - -acorn@^5.4.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.4.1.tgz#fdc58d9d17f4a4e98d102ded826a9b9759125102" - -ajv-keywords@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" - -ajv@^4.9.1: - version "4.11.8" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" - dependencies: - co "^4.6.0" - json-stable-stringify "^1.0.1" - -ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0: - version "5.5.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" - dependencies: - co "^4.6.0" - fast-deep-equal "^1.0.0" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" - -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" - -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - -ansi-escapes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - -ansi-styles@^3.1.0, ansi-styles@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" - dependencies: - color-convert "^1.9.0" - -anymatch@^1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" - dependencies: - micromatch "^2.1.5" - normalize-path "^2.0.0" - -append-transform@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" - dependencies: - default-require-extensions "^1.0.0" - -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - -are-we-there-yet@~1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -argparse@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - dependencies: - arr-flatten "^1.0.1" - -arr-flatten@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - -array-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" - -array-union@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - dependencies: - array-uniq "^1.0.1" - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - -arrify@^1.0.0, arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - -asn1@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - -assert-plus@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - -async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - -async@0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/async/-/async-0.9.0.tgz#ac3613b1da9bed1b47510bb4651b8931e47146c7" - -async@^1.4.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - -async@^2.1.4: - version "2.6.0" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" - dependencies: - lodash "^4.14.0" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - -aws-sign2@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - -aws4@^1.2.1, aws4@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" - -babel-cli@6: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" - dependencies: - babel-core "^6.26.0" - babel-polyfill "^6.26.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - commander "^2.11.0" - convert-source-map "^1.5.0" - fs-readdir-recursive "^1.0.0" - glob "^7.1.2" - lodash "^4.17.4" - output-file-sync "^1.1.2" - path-is-absolute "^1.0.1" - slash "^1.0.0" - source-map "^0.5.6" - v8flags "^2.1.1" - optionalDependencies: - chokidar "^1.6.1" - -babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-core@^6.0.0, babel-core@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.0" - debug "^2.6.8" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.7" - slash "^1.0.0" - source-map "^0.5.6" - -babel-generator@^6.18.0, babel-generator@^6.26.0: - version "6.26.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.17.4" - source-map "^0.5.7" - trim-right "^1.0.1" - -babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" - dependencies: - babel-helper-explode-assignable-expression "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-call-delegate@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-define-map@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-explode-assignable-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-function-name@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" - dependencies: - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-get-function-arity@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-hoist-variables@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-optimise-call-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-regex@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-remap-async-to-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-replace-supers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" - dependencies: - babel-helper-optimise-call-expression "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helpers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-jest@^21.2.0: - version "21.2.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-21.2.0.tgz#2ce059519a9374a2c46f2455b6fbef5ad75d863e" - dependencies: - babel-plugin-istanbul "^4.0.0" - babel-preset-jest "^21.2.0" - -babel-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-check-es2015-constants@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-istanbul@^4.0.0: - version "4.1.5" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.5.tgz#6760cdd977f411d3e175bb064f2bc327d99b2b6e" - dependencies: - find-up "^2.1.0" - istanbul-lib-instrument "^1.7.5" - test-exclude "^4.1.1" - -babel-plugin-jest-hoist@^21.2.0: - version "21.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-21.2.0.tgz#2cef637259bd4b628a6cace039de5fcd14dbb006" - -babel-plugin-syntax-async-functions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" - -babel-plugin-syntax-exponentiation-operator@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" - -babel-plugin-syntax-object-rest-spread@^6.13.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" - -babel-plugin-syntax-trailing-function-commas@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" - -babel-plugin-transform-async-to-generator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" - dependencies: - babel-helper-remap-async-to-generator "^6.24.1" - babel-plugin-syntax-async-functions "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-arrow-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoping@^6.23.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" - dependencies: - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-plugin-transform-es2015-classes@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" - dependencies: - babel-helper-define-map "^6.24.1" - babel-helper-function-name "^6.24.1" - babel-helper-optimise-call-expression "^6.24.1" - babel-helper-replace-supers "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-computed-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-destructuring@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-duplicate-keys@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-for-of@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-function-name@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" - dependencies: - babel-plugin-transform-es2015-modules-commonjs "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" - dependencies: - babel-plugin-transform-strict-mode "^6.24.1" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-types "^6.26.0" - -babel-plugin-transform-es2015-modules-systemjs@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-umd@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" - dependencies: - babel-plugin-transform-es2015-modules-amd "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-object-super@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" - dependencies: - babel-helper-replace-supers "^6.24.1" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-parameters@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" - dependencies: - babel-helper-call-delegate "^6.24.1" - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-shorthand-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-spread@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-sticky-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-template-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-typeof-symbol@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-unicode-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - regexpu-core "^2.0.0" - -babel-plugin-transform-exponentiation-operator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" - dependencies: - babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" - babel-plugin-syntax-exponentiation-operator "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-regenerator@^6.22.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" - dependencies: - regenerator-transform "^0.10.0" - -babel-plugin-transform-strict-mode@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-polyfill@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" - dependencies: - babel-runtime "^6.26.0" - core-js "^2.5.0" - regenerator-runtime "^0.10.5" - -babel-preset-env@^1.6.0: - version "1.6.1" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48" - dependencies: - babel-plugin-check-es2015-constants "^6.22.0" - babel-plugin-syntax-trailing-function-commas "^6.22.0" - babel-plugin-transform-async-to-generator "^6.22.0" - babel-plugin-transform-es2015-arrow-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoping "^6.23.0" - babel-plugin-transform-es2015-classes "^6.23.0" - babel-plugin-transform-es2015-computed-properties "^6.22.0" - babel-plugin-transform-es2015-destructuring "^6.23.0" - babel-plugin-transform-es2015-duplicate-keys "^6.22.0" - babel-plugin-transform-es2015-for-of "^6.23.0" - babel-plugin-transform-es2015-function-name "^6.22.0" - babel-plugin-transform-es2015-literals "^6.22.0" - babel-plugin-transform-es2015-modules-amd "^6.22.0" - babel-plugin-transform-es2015-modules-commonjs "^6.23.0" - babel-plugin-transform-es2015-modules-systemjs "^6.23.0" - babel-plugin-transform-es2015-modules-umd "^6.23.0" - babel-plugin-transform-es2015-object-super "^6.22.0" - babel-plugin-transform-es2015-parameters "^6.23.0" - babel-plugin-transform-es2015-shorthand-properties "^6.22.0" - babel-plugin-transform-es2015-spread "^6.22.0" - babel-plugin-transform-es2015-sticky-regex "^6.22.0" - babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol "^6.23.0" - babel-plugin-transform-es2015-unicode-regex "^6.22.0" - babel-plugin-transform-exponentiation-operator "^6.22.0" - babel-plugin-transform-regenerator "^6.22.0" - browserslist "^2.1.2" - invariant "^2.2.2" - semver "^5.3.0" - -babel-preset-jest@^21.2.0: - version "21.2.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-21.2.0.tgz#ff9d2bce08abd98e8a36d9a8a5189b9173b85638" - dependencies: - babel-plugin-jest-hoist "^21.2.0" - babel-plugin-syntax-object-rest-spread "^6.13.0" - -babel-register@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" - dependencies: - babel-core "^6.26.0" - babel-runtime "^6.26.0" - core-js "^2.5.0" - home-or-tmp "^2.0.0" - lodash "^4.17.4" - mkdirp "^0.5.1" - source-map-support "^0.4.15" - -babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - dependencies: - babel-runtime "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - lodash "^4.17.4" - -babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - dependencies: - babel-code-frame "^6.26.0" - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - debug "^2.6.8" - globals "^9.18.0" - invariant "^2.2.2" - lodash "^4.17.4" - -babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - -backoff@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.4.1.tgz#2f68c50e0dd789dbefe24200a62efb04d2456d68" - dependencies: - precond "0.2" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - -bcrypt-pbkdf@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" - dependencies: - tweetnacl "^0.14.3" - -binary-extensions@^1.0.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" - -block-stream@*: - version "0.0.9" - resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" - dependencies: - inherits "~2.0.0" - -bluebird@^2.9.13: - version "2.11.0" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" - -boom@2.x.x: - version "2.10.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" - dependencies: - hoek "2.x.x" - -boom@4.x.x: - version "4.3.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" - dependencies: - hoek "4.x.x" - -boom@5.x.x: - version "5.2.0" - resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" - dependencies: - hoek "4.x.x" - -brace-expansion@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - -browser-resolve@^1.11.2: - version "1.11.2" - resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" - dependencies: - resolve "1.1.7" - -browserslist@^2.1.2: - version "2.11.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.3.tgz#fe36167aed1bbcde4827ebfe71347a2cc70b99b2" - dependencies: - caniuse-lite "^1.0.30000792" - electron-to-chromium "^1.3.30" - -bser@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" - dependencies: - node-int64 "^0.4.0" - -builtin-modules@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - -caller-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" - dependencies: - callsites "^0.2.0" - -callsites@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - -camelcase@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - -camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - -caniuse-lite@^1.0.30000792: - version "1.0.30000803" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000803.tgz#9939c37149d38d5f4540430490d240c03106a0f5" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - -chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" - dependencies: - ansi-styles "^3.1.0" - escape-string-regexp "^1.0.5" - supports-color "^4.0.0" - -chardet@^0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" - -chokidar@^1.6.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" - dependencies: - anymatch "^1.3.0" - async-each "^1.0.0" - glob-parent "^2.0.0" - inherits "^2.0.1" - is-binary-path "^1.0.0" - is-glob "^2.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.0.0" - optionalDependencies: - fsevents "^1.0.0" - -ci-info@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.2.tgz#03561259db48d0474c8bdc90f5b47b068b6bbfb4" - -circular-json@^0.3.1: - version "0.3.3" - resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" - -cli-cursor@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - dependencies: - restore-cursor "^2.0.0" - -cli-width@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" - -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - -clone@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.1.tgz#0b08a631bc6a4a41b89ce2a3d43f8a84d66b4d4b" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - -color-convert@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" - dependencies: - color-name "^1.1.1" - -color-name@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - -combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" - dependencies: - delayed-stream "~1.0.0" - -commander@^2.11.0: - version "2.14.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.0.tgz#7b25325963e6aace20d3a9285b09379b0c2208b5" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - -concat-stream@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" - dependencies: - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - -content-type-parser@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.2.tgz#caabe80623e63638b2502fd4c7f12ff4ce2352e7" - -convert-source-map@^1.4.0, convert-source-map@^1.5.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - -cookie@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" - -core-js@^2.4.0, core-js@^2.5.0: - version "2.5.3" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - -crc@3.4.4: - version "3.4.4" - resolved "https://registry.yarnpkg.com/crc/-/crc-3.4.4.tgz#9da1e980e3bd44fc5c93bf5ab3da3378d85e466b" - -cross-spawn@^5.0.1, cross-spawn@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cryptiles@2.x.x: - version "2.0.5" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" - dependencies: - boom "2.x.x" - -cryptiles@3.x.x: - version "3.1.2" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" - dependencies: - boom "5.x.x" - -cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": - version "0.3.2" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b" - -"cssstyle@>= 0.2.37 < 0.3.0": - version "0.2.37" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-0.2.37.tgz#541097234cb2513c83ceed3acddc27ff27987d54" - dependencies: - cssom "0.3.x" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - dependencies: - assert-plus "^1.0.0" - -debug@2.6.9, debug@^2.2.0, debug@^2.6.8: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - dependencies: - ms "2.0.0" - -debug@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - dependencies: - ms "2.0.0" - -decamelize@^1.0.0, decamelize@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - -deep-extend@~0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" - -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - -default-require-extensions@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" - dependencies: - strip-bom "^2.0.0" - -del@^2.0.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" - dependencies: - globby "^5.0.0" - is-path-cwd "^1.0.0" - is-path-in-cwd "^1.0.0" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - rimraf "^2.2.8" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - -depd@~1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - dependencies: - repeating "^2.0.0" - -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - -diff@^3.2.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - dependencies: - esutils "^2.0.2" - -ecc-jsbn@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" - dependencies: - jsbn "~0.1.0" - -electron-to-chromium@^1.3.30: - version "1.3.32" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.32.tgz#11d0684c0840e003c4be8928f8ac5f35dbc2b4e6" - -errno@^0.1.4: - version "0.1.6" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.6.tgz#c386ce8a6283f14fc09563b71560908c9bf53026" - dependencies: - prr "~1.0.1" - -error-ex@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" - dependencies: - is-arrayish "^0.2.1" - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - -escodegen@^1.6.1: - version "1.9.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.0.tgz#9811a2f265dc1cd3894420ee3717064b632b8852" - dependencies: - esprima "^3.1.3" - estraverse "^4.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.5.6" - -eslint-config-prettier@^2.6.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-2.9.0.tgz#5ecd65174d486c22dff389fe036febf502d468a3" - dependencies: - get-stdin "^5.0.1" - -eslint-plugin-prettier@^2.3.1: - version "2.6.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.6.0.tgz#33e4e228bdb06142d03c560ce04ec23f6c767dd7" - dependencies: - fast-diff "^1.1.1" - jest-docblock "^21.0.0" - -eslint-scope@^3.7.1: - version "3.7.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-visitor-keys@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" - -eslint@^4.8.0: - version "4.17.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.17.0.tgz#dc24bb51ede48df629be7031c71d9dc0ee4f3ddf" - dependencies: - ajv "^5.3.0" - babel-code-frame "^6.22.0" - chalk "^2.1.0" - concat-stream "^1.6.0" - cross-spawn "^5.1.0" - debug "^3.1.0" - doctrine "^2.1.0" - eslint-scope "^3.7.1" - eslint-visitor-keys "^1.0.0" - espree "^3.5.2" - esquery "^1.0.0" - esutils "^2.0.2" - file-entry-cache "^2.0.0" - functional-red-black-tree "^1.0.1" - glob "^7.1.2" - globals "^11.0.1" - ignore "^3.3.3" - imurmurhash "^0.1.4" - inquirer "^3.0.6" - is-resolvable "^1.0.0" - js-yaml "^3.9.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.4" - minimatch "^3.0.2" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.2" - path-is-inside "^1.0.2" - pluralize "^7.0.0" - progress "^2.0.0" - require-uncached "^1.0.3" - semver "^5.3.0" - strip-ansi "^4.0.0" - strip-json-comments "~2.0.1" - table "^4.0.1" - text-table "~0.2.0" - -espree@^3.5.2: - version "3.5.3" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.3.tgz#931e0af64e7fbbed26b050a29daad1fc64799fa6" - dependencies: - acorn "^5.4.0" - acorn-jsx "^3.0.0" - -esprima@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" - -esprima@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" - -esquery@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" - dependencies: - estraverse "^4.0.0" - -esrecurse@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" - dependencies: - estraverse "^4.1.0" - object-assign "^4.0.1" - -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - -esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - -exec-sh@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.1.tgz#163b98a6e89e6b65b47c2a28d215bc1f63989c38" - dependencies: - merge "^1.1.3" - -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - dependencies: - is-posix-bracket "^0.1.0" - -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - dependencies: - fill-range "^2.1.0" - -expect@^21.2.1: - version "21.2.1" - resolved "https://registry.yarnpkg.com/expect/-/expect-21.2.1.tgz#003ac2ac7005c3c29e73b38a272d4afadd6d1d7b" - dependencies: - ansi-styles "^3.2.0" - jest-diff "^21.2.1" - jest-get-type "^21.2.0" - jest-matcher-utils "^21.2.1" - jest-message-util "^21.2.1" - jest-regex-util "^21.2.0" - -express-session@^1.15.6: - version "1.15.6" - resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.15.6.tgz#47b4160c88f42ab70fe8a508e31cbff76757ab0a" - dependencies: - cookie "0.3.1" - cookie-signature "1.0.6" - crc "3.4.4" - debug "2.6.9" - depd "~1.1.1" - on-headers "~1.0.1" - parseurl "~1.3.2" - uid-safe "~2.1.5" - utils-merge "1.0.1" - -extend@~3.0.0, extend@~3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" - -external-editor@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.1.0.tgz#3d026a21b7f95b5726387d4200ac160d372c3b48" - dependencies: - chardet "^0.4.0" - iconv-lite "^0.4.17" - tmp "^0.0.33" - -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - dependencies: - is-extglob "^1.0.0" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - -fast-deep-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" - -fast-diff@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154" - -fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - -fast-levenshtein@~2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - -fb-watchman@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" - dependencies: - bser "^2.0.0" - -figures@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" - dependencies: - flat-cache "^1.2.1" - object-assign "^4.0.1" - -filename-regex@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - -fileset@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" - dependencies: - glob "^7.0.3" - minimatch "^3.0.3" - -fill-range@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^1.1.3" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - dependencies: - locate-path "^2.0.0" - -flat-cache@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" - dependencies: - circular-json "^0.3.1" - del "^2.0.2" - graceful-fs "^4.1.2" - write "^0.2.1" - -for-in@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - -for-own@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" - dependencies: - for-in "^1.0.1" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - -form-data@~2.1.1: - version "2.1.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" - -form-data@~2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" - -fs-readdir-recursive@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - -fsevents@^1.0.0, fsevents@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8" - dependencies: - nan "^2.3.0" - node-pre-gyp "^0.6.39" - -fstream-ignore@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" - dependencies: - fstream "^1.0.0" - inherits "2" - minimatch "^3.0.0" - -fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: - version "1.0.11" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -get-caller-file@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" - -get-stdin@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - dependencies: - assert-plus "^1.0.0" - -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - dependencies: - is-glob "^2.0.0" - -glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.0.1: - version "11.3.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.3.0.tgz#e04fdb7b9796d8adac9c8f64c14837b2313378b0" - -globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - -globby@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" - dependencies: - array-union "^1.0.1" - arrify "^1.0.0" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - -growly@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - -handlebars@^4.0.3: - version "4.0.11" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" - dependencies: - async "^1.4.0" - optimist "^0.6.1" - source-map "^0.4.4" - optionalDependencies: - uglify-js "^2.6" - -har-schema@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - -har-validator@~4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" - dependencies: - ajv "^4.9.1" - har-schema "^1.0.5" - -har-validator@~5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" - dependencies: - ajv "^5.1.0" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - dependencies: - ansi-regex "^2.0.0" - -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - -has-flag@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - -hawk@3.1.3, hawk@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" - dependencies: - boom "2.x.x" - cryptiles "2.x.x" - hoek "2.x.x" - sntp "1.x.x" - -hawk@~6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" - dependencies: - boom "4.x.x" - cryptiles "3.x.x" - hoek "4.x.x" - sntp "2.x.x" - -hoek@2.x.x: - version "2.16.3" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" - -hoek@4.x.x: - version "4.2.0" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" - -home-or-tmp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" - -hosted-git-info@^2.1.4: - version "2.5.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" - -html-encoding-sniffer@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" - dependencies: - whatwg-encoding "^1.0.1" - -http-signature@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" - dependencies: - assert-plus "^0.2.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -iconv-lite@0.4.19, iconv-lite@^0.4.17: - version "0.4.19" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" - -ignore@^3.3.3: - version "3.3.7" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - -ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - -inquirer@^3.0.6: - version "3.3.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^2.0.4" - figures "^2.0.0" - lodash "^4.3.0" - mute-stream "0.0.7" - run-async "^2.2.0" - rx-lite "^4.0.8" - rx-lite-aggregates "^4.0.8" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - -invariant@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" - dependencies: - loose-envify "^1.0.0" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - dependencies: - binary-extensions "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - -is-builtin-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" - dependencies: - builtin-modules "^1.0.0" - -is-ci@^1.0.10: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5" - dependencies: - ci-info "^1.0.0" - -is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - dependencies: - is-primitive "^2.0.0" - -is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - -is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - dependencies: - is-extglob "^1.0.0" - -is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - dependencies: - kind-of "^3.0.2" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - dependencies: - kind-of "^3.0.2" - -is-path-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" - -is-path-in-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" - dependencies: - is-path-inside "^1.0.0" - -is-path-inside@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" - dependencies: - path-is-inside "^1.0.1" - -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - -is-promise@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - -is-resolvable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - -isarray@1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - dependencies: - isarray "1.0.0" - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - -istanbul-api@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.2.1.tgz#0c60a0515eb11c7d65c6b50bba2c6e999acd8620" - dependencies: - async "^2.1.4" - fileset "^2.0.2" - istanbul-lib-coverage "^1.1.1" - istanbul-lib-hook "^1.1.0" - istanbul-lib-instrument "^1.9.1" - istanbul-lib-report "^1.1.2" - istanbul-lib-source-maps "^1.2.2" - istanbul-reports "^1.1.3" - js-yaml "^3.7.0" - mkdirp "^0.5.1" - once "^1.4.0" - -istanbul-lib-coverage@^1.0.1, istanbul-lib-coverage@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da" - -istanbul-lib-hook@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz#8538d970372cb3716d53e55523dd54b557a8d89b" - dependencies: - append-transform "^0.4.0" - -istanbul-lib-instrument@^1.4.2, istanbul-lib-instrument@^1.7.5, istanbul-lib-instrument@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz#250b30b3531e5d3251299fdd64b0b2c9db6b558e" - dependencies: - babel-generator "^6.18.0" - babel-template "^6.16.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - babylon "^6.18.0" - istanbul-lib-coverage "^1.1.1" - semver "^5.3.0" - -istanbul-lib-report@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz#922be27c13b9511b979bd1587359f69798c1d425" - dependencies: - istanbul-lib-coverage "^1.1.1" - mkdirp "^0.5.1" - path-parse "^1.0.5" - supports-color "^3.1.2" - -istanbul-lib-source-maps@^1.1.0, istanbul-lib-source-maps@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz#750578602435f28a0c04ee6d7d9e0f2960e62c1c" - dependencies: - debug "^3.1.0" - istanbul-lib-coverage "^1.1.1" - mkdirp "^0.5.1" - rimraf "^2.6.1" - source-map "^0.5.3" - -istanbul-reports@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.3.tgz#3b9e1e8defb6d18b1d425da8e8b32c5a163f2d10" - dependencies: - handlebars "^4.0.3" - -jest-changed-files@^21.2.0: - version "21.2.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-21.2.0.tgz#5dbeecad42f5d88b482334902ce1cba6d9798d29" - dependencies: - throat "^4.0.0" - -jest-cli@^21.2.1: - version "21.2.1" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-21.2.1.tgz#9c528b6629d651911138d228bdb033c157ec8c00" - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.1" - glob "^7.1.2" - graceful-fs "^4.1.11" - is-ci "^1.0.10" - istanbul-api "^1.1.1" - istanbul-lib-coverage "^1.0.1" - istanbul-lib-instrument "^1.4.2" - istanbul-lib-source-maps "^1.1.0" - jest-changed-files "^21.2.0" - jest-config "^21.2.1" - jest-environment-jsdom "^21.2.1" - jest-haste-map "^21.2.0" - jest-message-util "^21.2.1" - jest-regex-util "^21.2.0" - jest-resolve-dependencies "^21.2.0" - jest-runner "^21.2.1" - jest-runtime "^21.2.1" - jest-snapshot "^21.2.1" - jest-util "^21.2.1" - micromatch "^2.3.11" - node-notifier "^5.0.2" - pify "^3.0.0" - slash "^1.0.0" - string-length "^2.0.0" - strip-ansi "^4.0.0" - which "^1.2.12" - worker-farm "^1.3.1" - yargs "^9.0.0" - -jest-config@^21.2.1: - version "21.2.1" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-21.2.1.tgz#c7586c79ead0bcc1f38c401e55f964f13bf2a480" - dependencies: - chalk "^2.0.1" - glob "^7.1.1" - jest-environment-jsdom "^21.2.1" - jest-environment-node "^21.2.1" - jest-get-type "^21.2.0" - jest-jasmine2 "^21.2.1" - jest-regex-util "^21.2.0" - jest-resolve "^21.2.0" - jest-util "^21.2.1" - jest-validate "^21.2.1" - pretty-format "^21.2.1" - -jest-diff@^21.2.1: - version "21.2.1" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-21.2.1.tgz#46cccb6cab2d02ce98bc314011764bb95b065b4f" - dependencies: - chalk "^2.0.1" - diff "^3.2.0" - jest-get-type "^21.2.0" - pretty-format "^21.2.1" - -jest-docblock@^21.0.0, jest-docblock@^21.2.0: - version "21.2.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" - -jest-environment-jsdom@^21.2.1: - version "21.2.1" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-21.2.1.tgz#38d9980c8259b2a608ec232deee6289a60d9d5b4" - dependencies: - jest-mock "^21.2.0" - jest-util "^21.2.1" - jsdom "^9.12.0" - -jest-environment-node@^21.2.1: - version "21.2.1" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-21.2.1.tgz#98c67df5663c7fbe20f6e792ac2272c740d3b8c8" - dependencies: - jest-mock "^21.2.0" - jest-util "^21.2.1" - -jest-get-type@^21.2.0: - version "21.2.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-21.2.0.tgz#f6376ab9db4b60d81e39f30749c6c466f40d4a23" - -jest-haste-map@^21.2.0: - version "21.2.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-21.2.0.tgz#1363f0a8bb4338f24f001806571eff7a4b2ff3d8" - dependencies: - fb-watchman "^2.0.0" - graceful-fs "^4.1.11" - jest-docblock "^21.2.0" - micromatch "^2.3.11" - sane "^2.0.0" - worker-farm "^1.3.1" - -jest-jasmine2@^21.2.1: - version "21.2.1" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-21.2.1.tgz#9cc6fc108accfa97efebce10c4308548a4ea7592" - dependencies: - chalk "^2.0.1" - expect "^21.2.1" - graceful-fs "^4.1.11" - jest-diff "^21.2.1" - jest-matcher-utils "^21.2.1" - jest-message-util "^21.2.1" - jest-snapshot "^21.2.1" - p-cancelable "^0.3.0" - -jest-matcher-utils@^21.2.1: - version "21.2.1" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-21.2.1.tgz#72c826eaba41a093ac2b4565f865eb8475de0f64" - dependencies: - chalk "^2.0.1" - jest-get-type "^21.2.0" - pretty-format "^21.2.1" - -jest-message-util@^21.2.1: - version "21.2.1" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-21.2.1.tgz#bfe5d4692c84c827d1dcf41823795558f0a1acbe" - dependencies: - chalk "^2.0.1" - micromatch "^2.3.11" - slash "^1.0.0" - -jest-mock@^21.2.0: - version "21.2.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-21.2.0.tgz#7eb0770e7317968165f61ea2a7281131534b3c0f" - -jest-regex-util@^21.2.0: - version "21.2.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-21.2.0.tgz#1b1e33e63143babc3e0f2e6c9b5ba1eb34b2d530" - -jest-resolve-dependencies@^21.2.0: - version "21.2.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-21.2.0.tgz#9e231e371e1a736a1ad4e4b9a843bc72bfe03d09" - dependencies: - jest-regex-util "^21.2.0" - -jest-resolve@^21.2.0: - version "21.2.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-21.2.0.tgz#068913ad2ba6a20218e5fd32471f3874005de3a6" - dependencies: - browser-resolve "^1.11.2" - chalk "^2.0.1" - is-builtin-module "^1.0.0" - -jest-runner@^21.2.1: - version "21.2.1" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-21.2.1.tgz#194732e3e518bfb3d7cbfc0fd5871246c7e1a467" - dependencies: - jest-config "^21.2.1" - jest-docblock "^21.2.0" - jest-haste-map "^21.2.0" - jest-jasmine2 "^21.2.1" - jest-message-util "^21.2.1" - jest-runtime "^21.2.1" - jest-util "^21.2.1" - pify "^3.0.0" - throat "^4.0.0" - worker-farm "^1.3.1" - -jest-runtime@^21.2.1: - version "21.2.1" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-21.2.1.tgz#99dce15309c670442eee2ebe1ff53a3cbdbbb73e" - dependencies: - babel-core "^6.0.0" - babel-jest "^21.2.0" - babel-plugin-istanbul "^4.0.0" - chalk "^2.0.1" - convert-source-map "^1.4.0" - graceful-fs "^4.1.11" - jest-config "^21.2.1" - jest-haste-map "^21.2.0" - jest-regex-util "^21.2.0" - jest-resolve "^21.2.0" - jest-util "^21.2.1" - json-stable-stringify "^1.0.1" - micromatch "^2.3.11" - slash "^1.0.0" - strip-bom "3.0.0" - write-file-atomic "^2.1.0" - yargs "^9.0.0" - -jest-snapshot@^21.2.1: - version "21.2.1" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-21.2.1.tgz#29e49f16202416e47343e757e5eff948c07fd7b0" - dependencies: - chalk "^2.0.1" - jest-diff "^21.2.1" - jest-matcher-utils "^21.2.1" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - pretty-format "^21.2.1" - -jest-util@^21.2.1: - version "21.2.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-21.2.1.tgz#a274b2f726b0897494d694a6c3d6a61ab819bb78" - dependencies: - callsites "^2.0.0" - chalk "^2.0.1" - graceful-fs "^4.1.11" - jest-message-util "^21.2.1" - jest-mock "^21.2.0" - jest-validate "^21.2.1" - mkdirp "^0.5.1" - -jest-validate@^21.2.1: - version "21.2.1" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-21.2.1.tgz#cc0cbca653cd54937ba4f2a111796774530dd3c7" - dependencies: - chalk "^2.0.1" - jest-get-type "^21.2.0" - leven "^2.1.0" - pretty-format "^21.2.1" - -jest@^21.2.1: - version "21.2.1" - resolved "https://registry.yarnpkg.com/jest/-/jest-21.2.1.tgz#c964e0b47383768a1438e3ccf3c3d470327604e1" - dependencies: - jest-cli "^21.2.1" - -js-tokens@^3.0.0, js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - -js-yaml@^3.7.0, js-yaml@^3.9.1: - version "3.10.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - -jsdom@^9.12.0: - version "9.12.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-9.12.0.tgz#e8c546fffcb06c00d4833ca84410fed7f8a097d4" - dependencies: - abab "^1.0.3" - acorn "^4.0.4" - acorn-globals "^3.1.0" - array-equal "^1.0.0" - content-type-parser "^1.0.1" - cssom ">= 0.3.2 < 0.4.0" - cssstyle ">= 0.2.37 < 0.3.0" - escodegen "^1.6.1" - html-encoding-sniffer "^1.0.1" - nwmatcher ">= 1.3.9 < 2.0.0" - parse5 "^1.5.1" - request "^2.79.0" - sax "^1.2.1" - symbol-tree "^3.2.1" - tough-cookie "^2.3.2" - webidl-conversions "^4.0.0" - whatwg-encoding "^1.0.1" - whatwg-url "^4.3.0" - xml-name-validator "^2.0.1" - -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - -json-schema-traverse@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - dependencies: - jsonify "~0.0.0" - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - -json5@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - -jsonparse@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.0.0.tgz#2622f4e66c08e1aac7edbeb76053c9b7e1211f76" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -kind-of@^3.0.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - dependencies: - is-buffer "^1.1.5" - -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - dependencies: - invert-kv "^1.0.0" - -leven@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -lodash@^4.14.0, lodash@^4.17.4, lodash@^4.3.0: - version "4.17.5" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" - -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - -loose-envify@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" - dependencies: - js-tokens "^3.0.0" - -lru-cache@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -makeerror@1.0.x: - version "1.0.11" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" - dependencies: - tmpl "1.0.x" - -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - dependencies: - mimic-fn "^1.0.0" - -merge@^1.1.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da" - -micromatch@^2.1.5, micromatch@^2.3.11: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - -mime-db@~1.30.0: - version "1.30.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" - -mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.7: - version "2.1.17" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" - dependencies: - mime-db "~1.30.0" - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - -minimist@^1.1.1, minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - -"mkdirp@>=0.5 0", mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - dependencies: - minimist "0.0.8" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - -nan@^2.3.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - -node-notifier@^5.0.2: - version "5.2.1" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.2.1.tgz#fa313dd08f5517db0e2502e5758d664ac69f9dea" - dependencies: - growly "^1.3.0" - semver "^5.4.1" - shellwords "^0.1.1" - which "^1.3.0" - -node-pre-gyp@^0.6.39: - version "0.6.39" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649" - dependencies: - detect-libc "^1.0.2" - hawk "3.1.3" - mkdirp "^0.5.1" - nopt "^4.0.1" - npmlog "^4.0.2" - rc "^1.1.7" - request "2.81.0" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^2.2.1" - tar-pack "^3.4.0" - -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - dependencies: - abbrev "1" - osenv "^0.1.4" - -normalize-package-data@^2.3.2: - version "2.4.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" - dependencies: - hosted-git-info "^2.1.4" - is-builtin-module "^1.0.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^2.0.0, normalize-path@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - dependencies: - remove-trailing-separator "^1.0.1" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - dependencies: - path-key "^2.0.0" - -npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - -"nwmatcher@>= 1.3.9 < 2.0.0": - version "1.4.3" - resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.3.tgz#64348e3b3d80f035b40ac11563d278f8b72db89c" - -oauth-sign@~0.8.1, oauth-sign@~0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - -object-assign@^4.0.1, object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - -on-headers@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" - -once@^1.3.0, once@^1.3.3, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - dependencies: - wrappy "1" - -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - dependencies: - mimic-fn "^1.0.0" - -optimist@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" - -optionator@^0.8.1, optionator@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.4" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - wordwrap "~1.0.0" - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - -os-locale@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" - dependencies: - execa "^0.7.0" - lcid "^1.0.0" - mem "^1.1.0" - -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - -osenv@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - -output-file-sync@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" - dependencies: - graceful-fs "^4.1.4" - mkdirp "^0.5.1" - object-assign "^4.1.0" - -p-cancelable@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - -p-limit@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" - dependencies: - p-try "^1.0.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - dependencies: - p-limit "^1.1.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - dependencies: - error-ex "^1.2.0" - -parse5@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94" - -parseurl@~1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - -path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - -path-is-inside@^1.0.1, path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - -path-key@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - -path-parse@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - dependencies: - pify "^2.0.0" - -performance-now@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - -pluralize@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" - -precond@0.2: - version "0.2.3" - resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - -prettier@^1.7.4: - version "1.10.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.10.2.tgz#1af8356d1842276a99a5b5529c82dd9e9ad3cc93" - -pretty-format@^21.2.1: - version "21.2.1" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-21.2.1.tgz#ae5407f3cf21066cd011aa1ba5fce7b6a2eddb36" - dependencies: - ansi-regex "^3.0.0" - ansi-styles "^3.2.0" - -private@^0.1.6, private@^0.1.7: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - -process-nextick-args@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" - -progress@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - -qs@~6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" - -qs@~6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" - -random-bytes@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" - -randomatic@^1.1.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -rc@^1.1.7: - version "1.2.5" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.5.tgz#275cd687f6e3b36cc756baa26dfee80a790301fd" - dependencies: - deep-extend "~0.4.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - -readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - safe-buffer "~5.1.1" - string_decoder "~1.0.3" - util-deprecate "~1.0.1" - -readdirp@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" - dependencies: - graceful-fs "^4.1.2" - minimatch "^3.0.2" - readable-stream "^2.0.2" - set-immediate-shim "^1.0.1" - -regenerate@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" - -regenerator-runtime@^0.10.5: - version "0.10.5" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" - -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - -regenerator-transform@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" - dependencies: - babel-runtime "^6.18.0" - babel-types "^6.19.0" - private "^0.1.6" - -regex-cache@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" - dependencies: - is-equal-shallow "^0.1.3" - -regexpu-core@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - -regjsgen@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" - -regjsparser@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" - dependencies: - jsesc "~0.5.0" - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - -repeat-element@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" - -repeat-string@^1.5.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - dependencies: - is-finite "^1.0.0" - -request@2.81.0: - version "2.81.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~2.1.1" - har-validator "~4.2.1" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - oauth-sign "~0.8.1" - performance-now "^0.2.0" - qs "~6.4.0" - safe-buffer "^5.0.1" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "^0.6.0" - uuid "^3.0.0" - -request@^2.63.0, request@^2.79.0: - version "2.83.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.6.0" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.1" - forever-agent "~0.6.1" - form-data "~2.3.1" - har-validator "~5.0.3" - hawk "~6.0.2" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.17" - oauth-sign "~0.8.2" - performance-now "^2.1.0" - qs "~6.5.1" - safe-buffer "^5.1.1" - stringstream "~0.0.5" - tough-cookie "~2.3.3" - tunnel-agent "^0.6.0" - uuid "^3.1.0" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - -require-uncached@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" - dependencies: - caller-path "^0.1.0" - resolve-from "^1.0.0" - -resolve-from@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" - -resolve@1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - dependencies: - align-text "^0.1.1" - -rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - dependencies: - glob "^7.0.5" - -run-async@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - dependencies: - is-promise "^2.1.0" - -rx-lite-aggregates@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" - dependencies: - rx-lite "*" - -rx-lite@*, rx-lite@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" - -safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - -sane@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-2.3.0.tgz#3f3df584abf69e63d4bb74f0f8c42468e4d7d46b" - dependencies: - anymatch "^1.3.0" - exec-sh "^0.2.0" - fb-watchman "^2.0.0" - minimatch "^3.0.2" - minimist "^1.1.1" - walker "~1.0.5" - watch "~0.18.0" - optionalDependencies: - fsevents "^1.1.1" - -sax@^1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1: - version "5.5.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" - -set-blocking@^2.0.0, set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - -shellwords@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - -slice-ansi@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" - dependencies: - is-fullwidth-code-point "^2.0.0" - -sntp@1.x.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" - dependencies: - hoek "2.x.x" - -sntp@2.x.x: - version "2.1.0" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" - dependencies: - hoek "4.x.x" - -source-map-support@^0.4.15: - version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" - dependencies: - source-map "^0.5.6" - -source-map@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" - dependencies: - amdefine ">=0.0.4" - -source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1, source-map@~0.5.6: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - -spdx-correct@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" - dependencies: - spdx-license-ids "^1.0.2" - -spdx-expression-parse@~1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" - -spdx-license-ids@^1.0.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - -sshpk@^1.7.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - dashdash "^1.12.0" - getpass "^0.1.1" - optionalDependencies: - bcrypt-pbkdf "^1.0.0" - ecc-jsbn "~0.1.1" - jsbn "~0.1.0" - tweetnacl "~0.14.0" - -string-length@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" - dependencies: - astral-regex "^1.0.0" - strip-ansi "^4.0.0" - -string-width@^1.0.1, string-width@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string_decoder@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" - dependencies: - safe-buffer "~5.1.0" - -stringstream@~0.0.4, stringstream@~0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - dependencies: - ansi-regex "^3.0.0" - -strip-bom@3.0.0, strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - dependencies: - is-utf8 "^0.2.0" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - -supports-color@^3.1.2: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - dependencies: - has-flag "^1.0.0" - -supports-color@^4.0.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" - dependencies: - has-flag "^2.0.0" - -symbol-tree@^3.2.1: - version "3.2.2" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" - -table@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" - dependencies: - ajv "^5.2.3" - ajv-keywords "^2.1.0" - chalk "^2.1.0" - lodash "^4.17.4" - slice-ansi "1.0.0" - string-width "^2.1.1" - -tar-pack@^3.4.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f" - dependencies: - debug "^2.2.0" - fstream "^1.0.10" - fstream-ignore "^1.0.5" - once "^1.3.3" - readable-stream "^2.1.4" - rimraf "^2.5.1" - tar "^2.2.1" - uid-number "^0.0.6" - -tar@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" - dependencies: - block-stream "*" - fstream "^1.0.2" - inherits "2" - -test-exclude@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26" - dependencies: - arrify "^1.0.1" - micromatch "^2.3.11" - object-assign "^4.1.0" - read-pkg-up "^1.0.1" - require-main-filename "^1.0.1" - -text-table@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - -throat@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" - -"through@>=2.2.7 <3", through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - dependencies: - os-tmpdir "~1.0.2" - -tmpl@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" - -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - -tough-cookie@^2.3.2, tough-cookie@~2.3.0, tough-cookie@~2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" - dependencies: - punycode "^1.4.1" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - dependencies: - prelude-ls "~1.1.2" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - -uglify-js@^2.6: - version "2.8.29" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" - dependencies: - source-map "~0.5.1" - yargs "~3.10.0" - optionalDependencies: - uglify-to-browserify "~1.0.0" - -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" - -uid-number@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" - -uid-safe@~2.1.5: - version "2.1.5" - resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a" - dependencies: - random-bytes "~1.0.0" - -underscore@^1.7.0: - version "1.8.3" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" - -user-home@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - -uuid@^3.0.0, uuid@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" - -v8flags@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" - dependencies: - user-home "^1.1.1" - -validate-npm-package-license@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" - dependencies: - spdx-correct "~1.0.0" - spdx-expression-parse "~1.0.0" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -walker@~1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" - dependencies: - makeerror "1.0.x" - -watch@~0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" - dependencies: - exec-sh "^0.2.0" - minimist "^1.2.0" - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - -webidl-conversions@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - -whatwg-encoding@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz#57c235bc8657e914d24e1a397d3c82daee0a6ba3" - dependencies: - iconv-lite "0.4.19" - -whatwg-url@^4.3.0: - version "4.8.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-4.8.0.tgz#d2981aa9148c1e00a41c5a6131166ab4683bbcc0" - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - -which@^1.2.12, which@^1.2.9, which@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" - dependencies: - string-width "^1.0.2" - -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - -wordwrap@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - -worker-farm@^1.3.1: - version "1.5.2" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.5.2.tgz#32b312e5dc3d5d45d79ef44acc2587491cd729ae" - dependencies: - errno "^0.1.4" - xtend "^4.0.1" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - -write-file-atomic@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - -write@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" - dependencies: - mkdirp "^0.5.1" - -xml-name-validator@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635" - -xtend@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - -y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - -yargs-parser@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" - dependencies: - camelcase "^4.1.0" - -yargs@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c" - dependencies: - camelcase "^4.1.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - read-pkg-up "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^7.0.0" - -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0"
, ,