diff --git a/.dependency-cruiser.cjs b/.dependency-cruiser.cjs new file mode 100644 index 0000000..aa53a3f --- /dev/null +++ b/.dependency-cruiser.cjs @@ -0,0 +1,48 @@ +// Owners and constraints for this repository's actual runtime roots. +module.exports = { + forbidden: [ + { + name: 'no-runtime-cycles', + severity: 'error', + from: {}, + to: { + circular: true, + dependencyTypesNot: ['type-only'], + }, + }, + { + name: 'no-unresolved-dependencies', + severity: 'error', + from: {}, + to: { + couldNotResolve: true, + }, + }, + { + name: 'no-runtime-test-dependencies', + severity: 'error', + from: { + path: '^(?:typescript/src)/', + pathNot: '(?:__tests__|test|tests)/|\\.(?:test|spec)\\.', + }, + to: { + path: '(?:^|/)(?:__tests__|tests|test)/|(?:^|node_modules/)(?:jest|vitest|ts-jest)', + }, + }, + ], + options: { + doNotFollow: { + path: 'node_modules|typescript/src/generated', + }, + tsConfig: { + fileName: require('node:path').resolve(__dirname, 'typescript/tsconfig.quality.json'), + }, + tsPreCompilationDeps: true, + enhancedResolveOptions: { + exportsFields: ['exports'], + conditionNames: ['types', 'require', 'node', 'default'], + extensions: ['.js', '.jsx', '.mjs', '.cjs', '.ts', '.tsx', '.mts', '.cts', '.json'], + }, + exclude: '(?:^|/)node_modules/', + }, +}; diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml new file mode 100644 index 0000000..4874c41 --- /dev/null +++ b/.github/workflows/quality.yml @@ -0,0 +1,58 @@ +name: Quality +on: + pull_request: + push: + branches: [main] +permissions: + contents: read +concurrency: + group: quality-${{ github.ref }} + cancel-in-progress: true +jobs: + checks: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-node@v4 + with: + node-version: '24.19.0' + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '24.0.2' + - run: npm ci + - run: npm --prefix tools/quality ci + - run: npm run test:preset + - run: npm run quality:guards + - run: npm run format:check + - run: npm run lint:static + - run: npm run lint:typed + - run: npm run typecheck + - run: npm run lint:arch + - run: npm run lint:unused:production + - run: npm run lint:unused:full + - run: npm run lint:duplicates + - run: npm run lint:duplicates:full + - run: npm run lint:complexity + - run: npm run test:exceptions + - run: npm run test:generated + - run: npm run test:quality + - run: npm test + - run: npm run build + - run: npm run test:pack + - uses: actions/upload-artifact@v4 + if: always() + with: + name: quality-reports + path: quality/reports/ + if-no-files-found: error + quality-required: + if: always() + needs: [checks] + runs-on: ubuntu-24.04 + steps: + - env: + RESULTS: ${{ toJSON(needs) }} + run: node -e 'const jobs=JSON.parse(process.env.RESULTS); if(!Object.values(jobs).every(job=>job.result==="success")) process.exit(1)' diff --git a/.gitignore b/.gitignore index c2658d7..d8c40d1 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ node_modules/ + +typescript/dist/ +quality/reports/ + +tools/quality/node_modules diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..81e401a --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +node tools/quality/node_modules/lint-staged/bin/lint-staged.js diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..60ade1a --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +24.19.0 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..8f31617 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,15 @@ +node_modules +**/node_modules +tools/quality +typescript/dist +typescript/src/generated +quality/reports +quality/generator/openapi.yaml +quality/generator/postprocess.cjs +java +kotlin +scala +csharp +python +rust +ruby diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..2fec1f2 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,5 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "printWidth": 100 +} diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..7fc2b45 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,24 @@ +# Repository quality and ownership + +The TypeScript wrapper uses the strict authored TypeScript profile; generated TypeScript uses profile D. Run `npm ci`, `npm --prefix tools/quality ci`, then the scripts in `.github/workflows/quality.yml`. Build and tests are offline and must not contact a live instance. Never publish or deploy as part of quality checks. + +`typescript/src/generated/src` is reproduced by `node quality/generator/generate.mjs` from the pinned public contract, OpenAPI Generator 7.22.0 JAR checksum and checksummed TypeScript producer. Edit the contract/producer and intentionally run `--write`; review the entire output inventory. Never hand-edit generated code or broaden ignores. + +Authored functions and methods require useful comments explaining purpose, inputs/results and relevant edge cases or I/O. Document ownership, error handling and async lifecycles for AI readers. Keep comments accurate; do not paraphrase the method name. The wrapper owns client configuration; generated API groups own wire serialization. Runtime modules cannot import tests; cycles and unresolved dependencies fail. + +Seven other language trees currently have addressed temporary exceptions in `quality/exceptions/inventory.json`, owned by 1MSG SDK maintainers and expiring 2026-12-11 under 1MSG-156. Their generator/build/native tests are **not verified**. CI verifies every byte against the adoption commit and rejects additions (including ignored files), deletions, edits, expiry and exception renewal. Replace an exception with a reviewed native generation/build/contract/package profile before changing that language. A passing exception guard does not mean native tests passed. + +Historical Knip, clone and maintainability debt is finding-specific, owned and dated. CI cannot add baselines; new or larger findings fail. Shared preset 1.0.12 is sealed; update it through the common producer, never by local edits. + +The `quality-required` aggregate fails on unsuccessful prerequisites. Repository branch protection must separately require this job; workflow naming alone does not enable protection. + +The root quality program resolves ambient types from both root and TypeScript workspace installations so the existing Jest tests retain their real declarations. No test is excluded. `knip.config.mjs` uses the same source inventory for both graphs; the Java binary prerequisite is declared only when its generator exists in the analyzed source, including trusted-base replays. No source files or issue categories are suppressed. + +The current TypeScript contract and generated documentation were replayed from API +commit `929c4526d3c914984be5a9bab561890a5c610433`. The provenance release record +identifies an offline validation artifact (`offline-1msg-156-final`), not an npm +publication. All 113 generated runtime files reproduce exactly and remain +unchanged. The producer now transfers a checksummed same-run envelope, preserves +consumer tests/configuration/locks, and runs every consumer gate before a sync +commit/push. Runtime packaging or generator changes require a reviewed consumer +update; synchronization must never replace this repository's quality policy. diff --git a/README.md b/README.md index 5695390..08f7f49 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,14 @@ Official client SDKs for the [1MSG](https://1msg.io) WhatsApp Business API. -| | | -|---|---| -| **API docs** | [docs.1msg.io](https://docs.1msg.io/) | -| **Platform** | [platform.1msg.io](https://platform.1msg.io/) | +| | | +| --------------- | ---------------------------------------------------------------------------- | +| **API docs** | [docs.1msg.io](https://docs.1msg.io/) | +| **Platform** | [platform.1msg.io](https://platform.1msg.io/) | | **Quick start** | [help.1msg.io](https://help.1msg.io/platform-1msg/getting-start/quick-start) | -| **Changelog** | [CHANGELOG.md](./CHANGELOG.md) | -| **Versioning** | [docs/VERSIONING.md](./docs/VERSIONING.md) | -| **Support** | support@1msg.io | +| **Changelog** | [CHANGELOG.md](./CHANGELOG.md) | +| **Versioning** | [docs/VERSIONING.md](./docs/VERSIONING.md) | +| **Support** | support@1msg.io | Public OpenAPI contract: `1.0.0`. 1MSG API service (git tags): `v3.3.0`. SDK packages track the public contract (`1.0.x`). Where a registry already @@ -163,17 +163,17 @@ Source: [github.com/1msg/1msg-sdk-cpp](https://github.com/1msg/1msg-sdk-cpp) ## Published versions -| Language | Registry name | Version | -|----------|---------------|---------| -| TypeScript | `@1msg/sdk` | 1.0.3 | -| Python | `one-msg-sdk` | 1.0.2 | -| Java | `io.1msg:sdk` | 1.0.2 | -| Kotlin | `io.1msg:sdk-kotlin` | 1.0.3 | -| Scala | `io.1msg:sdk-scala` | 1.0.3 | -| C# | `OneMsg.Sdk` | 2.0.1 | -| Rust | `one-msg-sdk` | 2.0.2 | -| Ruby | `one_msg_sdk` | 2.0.2 | -| Go | `github.com/1msg/1msg-sdk-go` | v1.1.1 | -| Swift | `1msg/1msg-sdk-swift` | 1.1.1 | -| PHP | `1msg/sdk` | 1.1.1 (repo) | -| C++ | `one-msg-sdk` | 1.0.1 (repo) | +| Language | Registry name | Version | +| ---------- | ----------------------------- | ------------ | +| TypeScript | `@1msg/sdk` | 1.0.3 | +| Python | `one-msg-sdk` | 1.0.2 | +| Java | `io.1msg:sdk` | 1.0.2 | +| Kotlin | `io.1msg:sdk-kotlin` | 1.0.3 | +| Scala | `io.1msg:sdk-scala` | 1.0.3 | +| C# | `OneMsg.Sdk` | 2.0.1 | +| Rust | `one-msg-sdk` | 2.0.2 | +| Ruby | `one_msg_sdk` | 2.0.2 | +| Go | `github.com/1msg/1msg-sdk-go` | v1.1.1 | +| Swift | `1msg/1msg-sdk-swift` | 1.1.1 | +| PHP | `1msg/sdk` | 1.1.1 (repo) | +| C++ | `one-msg-sdk` | 1.0.1 (repo) | diff --git a/docs/VERSIONING.md b/docs/VERSIONING.md index 23b58ca..e5c652b 100644 --- a/docs/VERSIONING.md +++ b/docs/VERSIONING.md @@ -4,11 +4,11 @@ `1msg-api` has three numbers that look like versions: -| Number | Where | What it is | -|--------|-------|------------| -| `v3.3.0` | git tags + `CHANGELOG.md` | Service / deploy version of 1msg-api | -| `1.0.0` | `public/openapi.bundled.yaml` `info.version` | Public API **contract** customers integrate against | -| `1.0.1` | root / Nest `package.json` | Stale npm workspace field; not the release number | +| Number | Where | What it is | +| -------- | -------------------------------------------- | --------------------------------------------------- | +| `v3.3.0` | git tags + `CHANGELOG.md` | Service / deploy version of 1msg-api | +| `1.0.0` | `public/openapi.bundled.yaml` `info.version` | Public API **contract** customers integrate against | +| `1.0.1` | root / Nest `package.json` | Stale npm workspace field; not the release number | SDK packages track the **public contract** (`1.0.x`), not the service tag (`v3.3.0`). Jumping every SDK to `3.3.0` would be a fake major and would not diff --git a/eslint.complexity.config.mjs b/eslint.complexity.config.mjs new file mode 100644 index 0000000..e86d9e9 --- /dev/null +++ b/eslint.complexity.config.mjs @@ -0,0 +1,28 @@ +import { maintainabilityConfig, tseslint } from './tools/quality/eslint.mjs'; +export default [ + { files: ['**/*.jsx'], languageOptions: { parserOptions: { ecmaFeatures: { jsx: true } } } }, + { linterOptions: { reportUnusedDisableDirectives: 'off' } }, + { + ignores: [ + '**/node_modules/**', + '**/dist/**', + '**/tools/quality/**', + '**/quality/reports/**', + 'typescript/src/generated/**', + 'quality/generator/postprocess.cjs', + 'java/**', + 'kotlin/**', + 'scala/**', + 'csharp/**', + 'python/**', + 'rust/**', + 'ruby/**', + ], + }, + { + files: ['**/*.{ts,tsx,cts,mts}'], + languageOptions: { parser: tseslint.parser }, + plugins: { '@typescript-eslint': tseslint.plugin }, + }, + ...maintainabilityConfig(), +]; diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..34698b8 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,31 @@ +import { staticConfig, globals } from './tools/quality/eslint.mjs'; + +export default [ + { files: ['**/*.jsx'], languageOptions: { parserOptions: { ecmaFeatures: { jsx: true } } } }, + { + ignores: [ + '**/node_modules/**', + '**/dist/**', + '**/tools/quality/**', + '**/quality/reports/**', + 'typescript/src/generated/**', + 'quality/generator/postprocess.cjs', + 'java/**', + 'kotlin/**', + 'scala/**', + 'csharp/**', + 'python/**', + 'rust/**', + 'ruby/**', + ], + }, + ...staticConfig({ globals: { ...globals.node, ...globals.jest } }), + { + settings: { + 'import/resolver': { + typescript: { project: './typescript/tsconfig.quality.json' }, + node: { extensions: ['.js', '.json', '.ts', '.mjs', '.cjs'] }, + }, + }, + }, +]; diff --git a/eslint.typed.config.mjs b/eslint.typed.config.mjs new file mode 100644 index 0000000..a7974c3 --- /dev/null +++ b/eslint.typed.config.mjs @@ -0,0 +1,24 @@ +import { typedConfig } from './tools/quality/eslint.mjs'; +export default [ + { + ignores: [ + '**/node_modules/**', + '**/dist/**', + '**/tools/quality/**', + '**/quality/reports/**', + 'typescript/src/generated/**', + 'quality/generator/postprocess.cjs', + 'java/**', + 'kotlin/**', + 'scala/**', + 'csharp/**', + 'python/**', + 'rust/**', + 'ruby/**', + ], + }, + ...typedConfig({ + project: './tsconfig.quality.json', + tsconfigRootDir: import.meta.dirname, + }), +]; diff --git a/knip.config.mjs b/knip.config.mjs new file mode 100644 index 0000000..6df0e75 --- /dev/null +++ b/knip.config.mjs @@ -0,0 +1,42 @@ +import { existsSync } from 'node:fs'; + +const inventory = { + workspaces: { + '.': { + entry: [ + 'scripts/pack-smoke.mjs', + 'scripts/quality-negative.mjs', + 'scripts/quality-hook.test.mjs', + 'scripts/quality-extensions.test.mjs', + 'quality/generator/generate.mjs!', + 'quality/generator/verify-negative.mjs', + 'quality/generator/exact-optional.test.mjs', + 'quality/exceptions/verify.mjs', + 'quality/exceptions/verify.test.mjs', + 'eslint*.mjs', + 'quality.config.mjs', + 'knip.config.mjs', + ], + project: [ + 'scripts/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}!', + 'quality/generator/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}!', + 'quality/exceptions/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}!', + ], + }, + typescript: { + entry: ['src/index.ts!', 'src/__tests__/**/*.{spec,test}.{js,jsx,mjs,cjs,ts,tsx,mts,cts}'], + project: [ + 'src/**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}!', + 'src/generated/**/*.ts!', + 'src/__tests__/**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}', + ], + }, + }, + ignore: ['tools/quality/**', 'typescript/src/generated/**'], +}; + +// Java belongs to the pinned generator. Trusted-base replays before that generator +// existed must not inherit an exclusion for a binary absent from their graph. +const hasGenerator = existsSync(new URL('./quality/generator/generate.mjs', import.meta.url)); +const config = { ...inventory, ignoreBinaries: hasGenerator ? ['java'] : [] }; +export default config; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..46fd0c2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3312 @@ +{ + "name": "1msg-sdk-quality", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "1msg-sdk-quality", + "version": "1.0.0", + "workspaces": [ + "typescript" + ], + "engines": { + "node": "24.x" + } + }, + "node_modules/@1msg/sdk": { + "resolved": "typescript", + "link": true + }, + "typescript": { + "name": "@1msg/sdk", + "version": "1.0.4", + "license": "MIT", + "devDependencies": { + "@types/jest": "^29.5.14", + "jest": "^29.5.0", + "ts-jest": "^29.1.0", + "typescript": "^5.1.3" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "typescript/node_modules/@babel/code-frame": { + "version": "7.29.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "typescript/node_modules/@babel/compat-data": { + "version": "7.29.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "typescript/node_modules/@babel/core": { + "version": "7.29.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "typescript/node_modules/@babel/generator": { + "version": "7.29.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "typescript/node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "typescript/node_modules/@babel/helper-globals": { + "version": "7.29.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "typescript/node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "typescript/node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "typescript/node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "typescript/node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "typescript/node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "typescript/node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "typescript/node_modules/@babel/helpers": { + "version": "7.29.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "typescript/node_modules/@babel/parser": { + "version": "7.29.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.29.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-jsx": { + "version": "7.29.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/plugin-syntax-typescript": { + "version": "7.29.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "typescript/node_modules/@babel/template": { + "version": "7.29.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "typescript/node_modules/@babel/traverse": { + "version": "7.29.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.9", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "typescript/node_modules/@babel/types": { + "version": "7.29.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "typescript/node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "dev": true, + "license": "ISC", + "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" + } + }, + "typescript/node_modules/@istanbuljs/schema": { + "version": "0.1.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/@jest/console": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/@jest/core": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@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.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "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 + } + } + }, + "typescript/node_modules/@jest/environment": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/@jest/expect": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/@jest/expect-utils": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/@jest/fake-timers": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/@jest/globals": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/@jest/reporters": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@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": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "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 + } + } + }, + "typescript/node_modules/@jest/schemas": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/@jest/source-map": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "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" + } + }, + "typescript/node_modules/@jest/test-result": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/@jest/transform": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@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.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "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" + } + }, + "typescript/node_modules/@jest/types": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@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" + } + }, + "typescript/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "typescript/node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "typescript/node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "typescript/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "typescript/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/@sinonjs/commons": { + "version": "3.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "typescript/node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "typescript/node_modules/@types/babel__core": { + "version": "7.20.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "typescript/node_modules/@types/babel__generator": { + "version": "7.27.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "typescript/node_modules/@types/babel__template": { + "version": "7.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "typescript/node_modules/@types/babel__traverse": { + "version": "7.28.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "typescript/node_modules/@types/graceful-fs": { + "version": "4.1.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "typescript/node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "typescript/node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "typescript/node_modules/@types/jest": { + "version": "29.5.14", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "typescript/node_modules/@types/node": { + "version": "26.6.5", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~8.9.0" + } + }, + "typescript/node_modules/@types/stack-utils": { + "version": "2.0.3", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/@types/yargs": { + "version": "17.0.35", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "typescript/node_modules/@types/yargs-parser": { + "version": "21.0.3", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/ansi-escapes": { + "version": "4.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "typescript/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "typescript/node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "typescript/node_modules/argparse": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "typescript/node_modules/babel-jest": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "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" + } + }, + "typescript/node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "dev": true, + "license": "BSD-3-Clause", + "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" + } + }, + "typescript/node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "dev": true, + "license": "BSD-3-Clause", + "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" + } + }, + "typescript/node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "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" + } + }, + "typescript/node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@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-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "typescript/node_modules/babel-preset-jest": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "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" + } + }, + "typescript/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/baseline-browser-mapping": { + "version": "2.11.28", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "typescript/node_modules/brace-expansion": { + "version": "1.1.21", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "typescript/node_modules/braces": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/browserslist": { + "version": "4.29.3", + "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" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.11.26", + "caniuse-lite": "^1.0.30001813", + "electron-to-chromium": "^1.5.439", + "node-releases": "^2.0.57", + "update-browserslist-db": "^1.3.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "typescript/node_modules/bs-logger": { + "version": "0.2.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "typescript/node_modules/bser": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "typescript/node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "typescript/node_modules/camelcase": { + "version": "5.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "typescript/node_modules/caniuse-lite": { + "version": "1.0.30001815", + "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" + } + ], + "license": "CC-BY-4.0" + }, + "typescript/node_modules/chalk": { + "version": "4.1.2", + "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" + } + }, + "typescript/node_modules/char-regex": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "typescript/node_modules/ci-info": { + "version": "3.9.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/cjs-module-lexer": { + "version": "1.4.3", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/cliui": { + "version": "8.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "typescript/node_modules/co": { + "version": "4.6.0", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "typescript/node_modules/collect-v8-coverage": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "typescript/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/convert-source-map": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/create-jest": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/cross-spawn": { + "version": "7.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "typescript/node_modules/debug": { + "version": "4.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "typescript/node_modules/dedent": { + "version": "1.7.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "typescript/node_modules/deepmerge": { + "version": "4.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "typescript/node_modules/detect-newline": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/diff-sequences": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/electron-to-chromium": { + "version": "1.5.452", + "dev": true, + "license": "ISC" + }, + "typescript/node_modules/emittery": { + "version": "0.13.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "typescript/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/error-ex": { + "version": "1.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "typescript/node_modules/es-errors": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "typescript/node_modules/escalade": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "typescript/node_modules/escape-string-regexp": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/esprima": { + "version": "4.0.1", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "typescript/node_modules/execa": { + "version": "5.1.1", + "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" + } + }, + "typescript/node_modules/exit": { + "version": "0.1.2", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "typescript/node_modules/expect": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/fb-watchman": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "bser": "2.1.2" + } + }, + "typescript/node_modules/fill-range": { + "version": "7.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "typescript/node_modules/fsevents": { + "version": "2.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "typescript/node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "typescript/node_modules/gensync": { + "version": "1.0.0-beta.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "typescript/node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "typescript/node_modules/get-package-type": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "typescript/node_modules/get-stream": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "typescript/node_modules/glob": { + "version": "7.2.3", + "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" + } + }, + "typescript/node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "typescript/node_modules/handlebars": { + "version": "4.7.10", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.8", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "typescript/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/hasown": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "typescript/node_modules/html-escaper": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/human-signals": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "typescript/node_modules/import-local": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "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" + } + }, + "typescript/node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "typescript/node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "typescript/node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "typescript/node_modules/is-arrayish": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/is-core-module": { + "version": "2.17.0", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "typescript/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/is-generator-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "typescript/node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "typescript/node_modules/is-stream": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "typescript/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "typescript/node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "typescript/node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.8.5", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "typescript/node_modules/istanbul-lib-report": { + "version": "3.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "typescript/node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "typescript/node_modules/istanbul-reports": { + "version": "3.2.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/jest": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "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 + } + } + }, + "typescript/node_modules/jest-changed-files": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-circus": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "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" + } + }, + "typescript/node_modules/jest-cli": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "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 + } + } + }, + "typescript/node_modules/jest-config": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "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.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "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 + } + } + }, + "typescript/node_modules/jest-diff": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-docblock": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-each": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-environment-node": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-get-type": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-haste-map": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@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.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "typescript/node_modules/jest-leak-detector": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-matcher-utils": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-message-util": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-mock": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "typescript/node_modules/jest-regex-util": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-resolve": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-runner": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-runtime": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@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.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-snapshot": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "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.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-snapshot/node_modules/semver": { + "version": "7.8.5", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "typescript/node_modules/jest-util": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@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" + } + }, + "typescript/node_modules/jest-validate": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "typescript/node_modules/jest-watcher": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-worker": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "typescript/node_modules/js-tokens": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/js-yaml": { + "version": "3.15.2", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "typescript/node_modules/jsesc": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "typescript/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/json5": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "typescript/node_modules/kleur": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "typescript/node_modules/leven": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "typescript/node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/lodash.memoize": { + "version": "4.1.2", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/lru-cache": { + "version": "5.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "typescript/node_modules/make-dir": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "typescript/node_modules/make-dir/node_modules/semver": { + "version": "7.8.5", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "typescript/node_modules/make-error": { + "version": "1.3.6", + "dev": true, + "license": "ISC" + }, + "typescript/node_modules/makeerror": { + "version": "1.0.12", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "typescript/node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/micromatch": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "typescript/node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "typescript/node_modules/minimatch": { + "version": "3.1.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "typescript/node_modules/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "typescript/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/natural-compare": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/neo-async": { + "version": "2.6.2", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/node-int64": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/node-releases": { + "version": "2.0.58", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "typescript/node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "typescript/node_modules/npm-run-path": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "typescript/node_modules/onetime": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "typescript/node_modules/p-limit": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "typescript/node_modules/p-locate": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "typescript/node_modules/p-try": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "typescript/node_modules/parse-json": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "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" + } + }, + "typescript/node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "typescript/node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/picocolors": { + "version": "1.1.1", + "dev": true, + "license": "ISC" + }, + "typescript/node_modules/picomatch": { + "version": "2.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "typescript/node_modules/pirates": { + "version": "4.0.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "typescript/node_modules/pkg-dir": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/pretty-format": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "typescript/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "typescript/node_modules/prompts": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "typescript/node_modules/pure-rand": { + "version": "6.1.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "typescript/node_modules/react-is": { + "version": "18.3.1", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "typescript/node_modules/resolve": { + "version": "1.22.13", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.17.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "typescript/node_modules/resolve-cwd": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/resolve-from": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/resolve.exports": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "typescript/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "typescript/node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "typescript/node_modules/sisteransi": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/slash": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "typescript/node_modules/source-map-support": { + "version": "0.5.13", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "typescript/node_modules/sprintf-js": { + "version": "1.0.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "typescript/node_modules/stack-utils": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "typescript/node_modules/string-length": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "typescript/node_modules/string-width": { + "version": "4.2.3", + "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" + } + }, + "typescript/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/strip-bom": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/strip-final-newline": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "typescript/node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "typescript/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "typescript/node_modules/test-exclude": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "typescript/node_modules/tmpl": { + "version": "1.0.5", + "dev": true, + "license": "BSD-3-Clause" + }, + "typescript/node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "typescript/node_modules/ts-jest": { + "version": "29.4.14", + "dev": true, + "license": "MIT", + "dependencies": { + "bs-logger": "^0.2.6", + "fast-json-stable-stringify": "^2.1.0", + "handlebars": "^4.7.9", + "json5": "^2.2.3", + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.8.5", + "type-fest": "^4.41.0", + "yargs-parser": "^21.1.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <9", + "@jest/transform": "^29.0.0 || ^30.0.0", + "@jest/types": "^29.0.0 || ^30.0.0", + "babel-jest": "^29.0.0 || ^30.0.0", + "jest": "^29.0.0 || ^30.0.0", + "jest-util": "^29.0.0 || ^30.0.0", + "typescript": ">=4.3 <7" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/transform": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jest-util": { + "optional": true + } + } + }, + "typescript/node_modules/ts-jest/node_modules/semver": { + "version": "7.8.5", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "typescript/node_modules/ts-jest/node_modules/type-fest": { + "version": "4.41.0", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "typescript/node_modules/type-detect": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "typescript/node_modules/type-fest": { + "version": "0.21.3", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "typescript/node_modules/typescript": { + "version": "5.9.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "typescript/node_modules/uglify-js": { + "version": "3.19.3", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "typescript/node_modules/undici-types": { + "version": "8.9.0", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/update-browserslist-db": { + "version": "1.3.4", + "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" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "typescript/node_modules/v8-to-istanbul": { + "version": "9.3.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "typescript/node_modules/walker": { + "version": "1.0.8", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "typescript/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "typescript/node_modules/wordwrap": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "typescript/node_modules/wrap-ansi": { + "version": "7.0.0", + "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" + } + }, + "typescript/node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "typescript/node_modules/write-file-atomic": { + "version": "4.0.2", + "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" + } + }, + "typescript/node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "typescript/node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "license": "ISC" + }, + "typescript/node_modules/yargs": { + "version": "17.7.3", + "dev": true, + "license": "MIT", + "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" + } + }, + "typescript/node_modules/yargs-parser": { + "version": "21.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "typescript/node_modules/yocto-queue": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..ac66836 --- /dev/null +++ b/package.json @@ -0,0 +1,48 @@ +{ + "name": "1msg-sdk-quality", + "private": true, + "version": "1.0.0", + "engines": { + "node": "24.x" + }, + "packageManager": "npm@11.17.0", + "workspaces": [ + "typescript" + ], + "scripts": { + "typecheck": "node tools/quality/node_modules/typescript/bin/tsc -p tsconfig.quality.json", + "lint:static": "node tools/quality/node_modules/eslint/bin/eslint.js . --max-warnings=0", + "lint:typed": "node tools/quality/node_modules/eslint/bin/eslint.js -c eslint.typed.config.mjs . --max-warnings=0", + "lint:arch": "node tools/quality/node_modules/dependency-cruiser/bin/dependency-cruiser.mjs --config .dependency-cruiser.cjs typescript/src", + "test": "npm --prefix typescript test -- --runInBand", + "build": "npm --prefix typescript run build", + "test:pack": "node scripts/pack-smoke.mjs", + "test:generated": "node --test quality/generator/exact-optional.test.mjs && node quality/generator/generate.mjs && node quality/generator/verify-negative.mjs", + "test:exceptions": "node quality/exceptions/verify.mjs && node --test quality/exceptions/verify.test.mjs", + "test:quality": "node scripts/quality-negative.mjs typescript/src && node --test --test-concurrency=1 scripts/quality-hook.test.mjs scripts/quality-extensions.test.mjs", + "test:preset": "node --test tools/quality/test/*.test.mjs", + "quality:guards": "node tools/quality/run.mjs guards", + "lint:complexity": "node tools/quality/run.mjs report --kind eslint --name complexity -- node tools/quality/node_modules/eslint/bin/eslint.js -c eslint.complexity.config.mjs . --format json", + "format": "node tools/quality/node_modules/prettier/bin/prettier.cjs --write .", + "format:check": "node tools/quality/node_modules/prettier/bin/prettier.cjs --check .", + "hooks:install": "node tools/quality/node_modules/husky/bin.js", + "lint:unused:production": "node tools/quality/run.mjs unused-production", + "lint:unused:full": "node tools/quality/run.mjs unused-full", + "lint:duplicates": "node tools/quality/run.mjs duplicates", + "lint:duplicates:full": "node tools/quality/run.mjs duplicates-full" + }, + "lint-staged": { + "*.{js,jsx,mjs,cjs}": [ + "node tools/quality/staged.mjs --config eslint.config.mjs --", + "node tools/quality/node_modules/prettier/bin/prettier.cjs --write", + "node tools/quality/node_modules/eslint/bin/eslint.js --config eslint.config.mjs --max-warnings=0 --no-warn-ignored" + ], + "*.{ts,tsx,mts,cts}": [ + "node tools/quality/staged.mjs --config eslint.config.mjs --", + "node tools/quality/node_modules/prettier/bin/prettier.cjs --write", + "node tools/quality/node_modules/eslint/bin/eslint.js --config eslint.config.mjs --max-warnings=0 --no-warn-ignored", + "node tools/quality/node_modules/eslint/bin/eslint.js --config eslint.typed.config.mjs --max-warnings=0 --no-warn-ignored" + ], + "*.{json,md,yml,yaml}": "node tools/quality/node_modules/prettier/bin/prettier.cjs --write" + } +} diff --git a/quality.config.mjs b/quality.config.mjs new file mode 100644 index 0000000..37fd22e --- /dev/null +++ b/quality.config.mjs @@ -0,0 +1,62 @@ +export default { + schemaVersion: 1, + profile: 'D', + defaultBranch: 'main', + sourceRoots: [ + 'typescript/src', + 'typescript/jest.config.js', + 'quality/generator', + 'quality/exceptions', + 'scripts', + 'eslint.config.mjs', + 'eslint.typed.config.mjs', + 'eslint.complexity.config.mjs', + '.dependency-cruiser.cjs', + 'quality.config.mjs', + 'knip.config.mjs', + ], + generated: [ + { + pattern: 'typescript/src/generated/**', + producer: + 'node quality/generator/generate.mjs --write (pinned OpenAPI Generator 7.22.0 + checksummed producer)', + }, + { + pattern: 'quality/generator/postprocess.cjs', + producer: 'Vendored API generator; checksum checked by quality/generator/generate.mjs', + }, + ], + comments: { + full: [ + 'typescript/src/client.ts', + 'typescript/src/client-config.ts', + 'scripts/**', + 'quality/exceptions/**', + 'quality/generator/*.mjs', + ], + }, + knipConfig: 'knip.config.mjs', + duplicatePaths: [ + 'typescript/src', + 'typescript/jest.config.js', + 'scripts', + 'quality/generator', + 'quality/exceptions', + ], + duplicateIgnore: [ + 'typescript/src/generated/**', + 'quality/generator/postprocess.cjs', + '**/__tests__/**', + '**/*.test.*', + ], + baselineDir: 'quality/baselines', + duplicateMaxPercentage: 5, + duplicateFullPaths: [ + 'typescript/src', + 'typescript/jest.config.js', + 'scripts', + 'quality/generator', + 'quality/exceptions', + ], + duplicateFullIgnore: ['typescript/src/generated/**', 'quality/generator/postprocess.cjs'], +}; diff --git a/quality/baselines/complexity.json b/quality/baselines/complexity.json new file mode 100644 index 0000000..6d9a980 --- /dev/null +++ b/quality/baselines/complexity.json @@ -0,0 +1,5 @@ +{ + "schemaVersion": 1, + "adoptionBase": "802e13a13a3bb11ec25e68258c3bd0518dec8d53", + "entries": [] +} diff --git a/quality/baselines/duplicates.json b/quality/baselines/duplicates.json new file mode 100644 index 0000000..6d9a980 --- /dev/null +++ b/quality/baselines/duplicates.json @@ -0,0 +1,5 @@ +{ + "schemaVersion": 1, + "adoptionBase": "802e13a13a3bb11ec25e68258c3bd0518dec8d53", + "entries": [] +} diff --git a/quality/baselines/unused-full.json b/quality/baselines/unused-full.json new file mode 100644 index 0000000..6d9a980 --- /dev/null +++ b/quality/baselines/unused-full.json @@ -0,0 +1,5 @@ +{ + "schemaVersion": 1, + "adoptionBase": "802e13a13a3bb11ec25e68258c3bd0518dec8d53", + "entries": [] +} diff --git a/quality/baselines/unused-production.json b/quality/baselines/unused-production.json new file mode 100644 index 0000000..6d9a980 --- /dev/null +++ b/quality/baselines/unused-production.json @@ -0,0 +1,5 @@ +{ + "schemaVersion": 1, + "adoptionBase": "802e13a13a3bb11ec25e68258c3bd0518dec8d53", + "entries": [] +} diff --git a/quality/exceptions/inventory.json b/quality/exceptions/inventory.json new file mode 100644 index 0000000..f4a66f3 --- /dev/null +++ b/quality/exceptions/inventory.json @@ -0,0 +1,1694 @@ +{ + "schemaVersion": 1, + "defaultBranch": "main", + "exceptions": [ + { + "id": "native-java", + "owner": "1MSG SDK maintainers", + "issue": "https://plane.1msg.io/1msg/browse/1MSG-156/", + "expires": "2026-12-11", + "reason": "Native java generation, frozen dependencies, build and offline contract tests have not been verified. Sources remain byte-for-byte frozen until a reviewed language-specific quality profile replaces this exception.", + "requiredWork": [ + "Pin and replay the actual language generator", + "Freeze dependencies and verify native build", + "Add offline required/optional/error serialization and package consumer tests" + ], + "baselineCommit": "802e13a13a3bb11ec25e68258c3bd0518dec8d53", + "roots": ["java"], + "files": { + "java/.github/workflows/maven.yml": "b89934363471aa14e2c6d36038945075827d9adfa23d334aeb9fff47375f2d96", + "java/.gitignore": "e3c5446fda0f835a43af32ef2740eb63fec31dd00e91e41df90bb6ab957758d7", + "java/.openapi-generator-ignore": "a6ed8f4e275eee926d27e0c52f30f2d1c4d8409465ac1fbc4511f7cc62de51db", + "java/.travis.yml": "dea1d2f486e4b45ab45c67864ce68a167bc25d5731f0969c79a4a7e72df40310", + "java/AGENTS.md": "92c2892502fbcc86a37820385df727d9c21333af488e40c2440a076c30dbf08f", + "java/LICENSE": "88170a8e4e7b68f13a057d5b9e1882d4b60c71e0a762b5a95651931a219835ee", + "java/README.md": "3cf4b36870ca9a722a371fd16b0e199de4074463a69e0dffa373a03c692e166f", + "java/build.gradle": "24489718dd34b052550d6ba475415951f6965be29b5dc731de4b6f7f60894900", + "java/build.sbt": "0e478b525adbeeb1b1de7674e1a00353d1d75eee666537ff0c1c13d3187322fe", + "java/docs/AddTemplateRequest.md": "421d8cc7193a22ed763546081377064e06b7a2dd7dcc7261098fdc8aa63eed5a", + "java/docs/BlockUserRequest.md": "d59bf62264a714e962ae826b3b7b2ac27403dad0a77de5ffa22757e8eb82d220", + "java/docs/CallingApi.md": "ca66650ddee7bff246bdb7694a5de43e196352ac3ef8669075821aafc5558691", + "java/docs/CallingSettings.md": "1c6f179b14e87fbdd22513becba4cb661220678b9f7cab45d42bf3e5d0af2f06", + "java/docs/CallingSettingsCalling.md": "172a2186635961ede717cbe4bf78171ce83f966b0c8a45f6908c91fe36c6a900", + "java/docs/CallingSettingsCallingAudio.md": "df72c78957f919aa8a6e3cf131aa8f7451cdae99bd828d8da066660e3245dc66", + "java/docs/CallingSettingsCallingCallHours.md": "4623ecfdc02f5ac49d7d0495df682edc327d5223b872676af5778650b034ba2c", + "java/docs/CallingSettingsCallingSip.md": "22fe38f57449b6614a2a1948c273571855af004f8c840aafcde8bf48b1d78aac", + "java/docs/CallingSettingsCallingSipServersInner.md": "749132592f7918c1ec4d6cb74718d26fafae0dd599559549f294166f9f36bc94", + "java/docs/CallingSettingsCallingVideo.md": "4804d5cfb860bd1f313bef5fab060a3c8b6336eb42b39e365946f02694cdb49d", + "java/docs/CatalogApi.md": "49980ce283785f97d807909b0a30a02499cc8d650a2256019cf6863fa05617b8", + "java/docs/ChannelApi.md": "391da522e643f4245f7ee50975223a4486eb20012f3da8f1f61723f715632a9f", + "java/docs/ConversationalAutomation.md": "0aee71e0cf2e37226fceb444c038371f1f93e95dbe6fc7cdbc60851249657e56", + "java/docs/ConversationalAutomationCommandsInner.md": "3cd64e95395cee417185b0dff7d74efdeda81d527905990c7e6d05ba211f9c9b", + "java/docs/CreateCommerce200Response.md": "abe55dc25f959a79efe2db2dc86d603d516027ed3d550847a75e77074c355d28", + "java/docs/CreateCommerceRequest.md": "8f947db4ba661c0f0a09d0c5f0b3f6d1961e651c43dea39b15b4e49da4bbced8", + "java/docs/CreateCommerceRequestParams.md": "b694f5a1dd64ef1dad7a089b15c688a8696601643a0d082dd7c32b70020cdf27", + "java/docs/CreateGroups200Response.md": "6432942d7842854d0d221e7d33a026465d7199513a65ad78ebf2d4102533239c", + "java/docs/CreateReadMessage200Response.md": "a40003a991e72dc17df21ca3a01317c6c46fe9695b426b4b931894220ca80d07", + "java/docs/CreateReadMessage401Response.md": "d061d30b403c4c7bac46cac7cfab54e64d96c8bed962b113259a51f601a2c157", + "java/docs/CreateReadMessageRequest.md": "93bc0bb6bba37ba8a87e212f188f305854ed4303811acd406daa75f7982ab592", + "java/docs/DeleteFlowsFlowId200Response.md": "7d51d55d2b01554014606403133c91b85db57f70573f7e0a9edb5a7b2781655f", + "java/docs/DeleteGroupsGroupId200Response.md": "eedf92e69973c5704f964a56831d033091ba9d948fad67127db115d133fbb4f6", + "java/docs/DeleteMediaLegacyRequest.md": "b1615114290a3f5dfecf00abacf527801d6d1bbec248512eae29511d8cb847f4", + "java/docs/ErrorResponse.md": "db87453fcd67ab68465b0d66bc12efdb7741bcb4912a4ecd85e4b4c3e2724c1c", + "java/docs/FlowsApi.md": "c20998601f4511ca12c4c19407aa99855548ba7adc27e09d4c40d729c2550699", + "java/docs/GetCommerce200ResponseInner.md": "f74416d11df014ca6db76600394f11ab75e6d0a9e6ba661048b5c76bbb016283", + "java/docs/GetMmLiteStatus200Response.md": "523da37b5d5d640bd3e775b0bb18e9a9876f75702b81cadc776a799cf9531fa3", + "java/docs/GetWebhook200Response.md": "1041e6a45857a9c1512ac0b1af41f3007c30879c46802135bc044d98e83a4027", + "java/docs/GetWhatsappBusinessEncryption200Response.md": "63c407d0fb4b31fe51fbc26305181ffb14f5448b6b483f1e0eb63a1de5c3fdf6", + "java/docs/GroupsApi.md": "9d6df1f190a26ce524b5b239ace220944fd34276c56ccebdf17e4f732afeafe3", + "java/docs/InitiateCallRequest.md": "f6a91a21fe28b413a0ad2b8a26a21d16b6a50840a640d8ed481a4cbc3b4d6ba2", + "java/docs/InitiateCallRequestSession.md": "9aedadad889db50fb5258890cde9ece0b41df0615cbe7862953a42be7d043fb4", + "java/docs/InitiateCallResponse.md": "ef669fe430287a2d5ea0c165c9299d8ec2acf2d8833b9a46d62c4295faff2832", + "java/docs/InitiateCallResponseCallsInner.md": "0ef3c9724be505405f757bbb902f163fd979708c2274f1db0c8de04786b97923", + "java/docs/InitiateCallResponseResponse.md": "1fc53fbc7106583b138ab90bcb9b99fad826483bf6234721493ffb9eb4967d59", + "java/docs/ListBlockedUsers200Response.md": "2946e2aa5d18d2405f59113faaf5f7564ba17395c300915f581fa7a5054548b3", + "java/docs/ListFlows200Response.md": "503d12ae604f7035410f7be3fbb936f902a8cb62b6261edeca1cc1d0a5b2218e", + "java/docs/ListMessages200Response.md": "0270daadf57fe104fdae63139525d8732366431bb0d3a170caa70a4967348f0f", + "java/docs/ListTemplates200Response.md": "ededf6eb0ed54e3922206d504d3bbd111546e00d918144a31d2bf2d54906071e", + "java/docs/MessageSentResponse.md": "eccfa67ec660a4cec6fff23c02b9cbf9c52070c55debd420ee89955157b6dcdb", + "java/docs/MessagingApi.md": "6f446d10638e7b5e429e076469131831ce50c0409a92b91fcdd972b94a81d1f1", + "java/docs/PatchFlowsFlowIdAssets200Response.md": "da2101e031e661edded296979305bbf37ef3f97660acca6467c16b162b9032c6", + "java/docs/ProfileApi.md": "3f20195dd7144cbabaf51b3ee6419a3bef81fe0e8627df6178859ea31dea41b0", + "java/docs/ProfileInfo.md": "c0b60559645f1888bd5087a2ef445c8b20c909cd7189345792efe7799ea8c304", + "java/docs/RetrieveMedia200Response.md": "96d2df2f5f3d0da0442c374f599f126ccfc7db70972a5436ac194993c12895a5", + "java/docs/SendAddressMessageRequest.md": "0f828e9069c43dfccae4bc9d40b922f1dfa1f0202615960f3ee2e495d3d72599", + "java/docs/SendButtonRequest.md": "f5c2d054c4199a92011f9b00b128098b6dcff7a0ff09da038bf1ac9ba6c0a291", + "java/docs/SendButtonRequestSectionsInner.md": "d691012a85ac0da615f08d0b763d7ed6f793908ba27b3ccbc8292822851a3705", + "java/docs/SendButtonRequestSectionsInnerReply.md": "00da1709749aea77989eb5d44fe56b8c4f089f09a81f7060a2a63d47c50f63ca", + "java/docs/SendCarouselRequest1.md": "d6b89137f8c30f4ee6e6e21a063c587dfa8567aec0b3a0fd6972a80def6a6ac3", + "java/docs/SendContactRequest.md": "613d32beca899257915796cb1b76d32ae52f5953c2fa11f2cc76d8ea00fe190a", + "java/docs/SendContactRequestContactsInner.md": "30d3cdc22f4303e4a88fe20527b73bef704966a8bd6fdaf8e28194191c91e2e8", + "java/docs/SendContactRequestContactsInnerName.md": "e90d154dd74fe07bba53fffc8daa5625ebc9fd8e7b0e297ae584ff463eba4ac2", + "java/docs/SendContactRequestContactsInnerOrg.md": "fc3877bab4114ac5d92da6cee7aca9cf0b04ce55e4d74c66ef79301dd8b73722", + "java/docs/SendContactRequestContactsInnerPhonesInner.md": "6a5d8adba64f6e2d2408d289365cb9211517b6e83903fb2feea506d147c98813", + "java/docs/SendCtaUrlRequest.md": "6fa55295f84b3d1e9898db104fd36a01b90d758e52f3d82701ad8d84a5ecc6ff", + "java/docs/SendFileRequest.md": "be09d7a56ca0cc442c813b9b4bd86f6d9d7d7e934b9c299abb5b89ed1a14f8d1", + "java/docs/SendFlowRequest1.md": "3ecada9841eb00bc8632b72101101e23d6fa8ce366a5b9a54ea416029c535d60", + "java/docs/SendFlowRequest1Header.md": "a8076944f7b586016e04c15693e720e42769b4debf6a49f2807f9fd83a126fc6", + "java/docs/SendFlowRequestHeader.md": "1bf7667f0b5536e289ae5b24b6f33d752bf4ec18019e4cdcec4b3c436cc98089", + "java/docs/SendListRequest.md": "36a6bf7cd349a8e75b8672624cc4f96427c41f592d728d58f4e40b7998b9891f", + "java/docs/SendListRequestSectionsInner.md": "3a9127e29fda8ad84ecf797ba9ddda01bd933012aee1a587ef7938056145d3b3", + "java/docs/SendListRequestSectionsInnerRowsInner.md": "4cd042752f27b3643d7dc34084296ff42c6c8eb6f9631770ce27c9f18db97bb9", + "java/docs/SendLocationRequest1.md": "35fa7fcbfe91f1a3c5a88de40ef8cf913e3fc7cab85610313258efb94f6d6043", + "java/docs/SendLocationRequestRequest.md": "507b25a2fd0b1d071e239f24511e6c3b3c00c40ced9a5f368f413348e8799910", + "java/docs/SendMessageRequest.md": "86f3dd3530c37d4de04702b7ab49c80adeba4f69f44c4687648200eb238495b5", + "java/docs/SendOrderDetailsRequest.md": "b32e2fd4e4ba7558b0107c3c530ff517c6a6f032a7c6b8dfc660cb1c44b77e0d", + "java/docs/SendOrderDetailsRequestLanguage.md": "17c2af457761b22983b5b3f1aa3ea249bc436a2c18a853d704e898ae520da898", + "java/docs/SendOrderDetailsRequestOrder.md": "36d85c66454b8bf3cb529dc7689c2207b5da8f7bdcc47e53b56d387f6094b08b", + "java/docs/SendOrderDetailsRequestOrderItemsInner.md": "09dedb31164f9114d61a73f13cd63f4501681c2496055cae8e9ada0ba1657d98", + "java/docs/SendOrderDetailsRequestOrderItemsInnerAmount.md": "ac81275a89945074408d165d832276a02a3c4fc3ee059da913078adc22b48165", + "java/docs/SendPaymentRequestRequest.md": "f98167c773ecd8e1158bdeba6a804b29dd1a4c894ee14ca6cee9881f418e4fa4", + "java/docs/SendReactionRequest.md": "aa9f4b0e4c0c490d0e15d19c08d0f0e94ba93433f0d96ad2aaf98333a36777d2", + "java/docs/SendStickerRequest.md": "9f2b3d077bd3f6521b464ed8412ff8bf14a75747d1a20975091221ef80c8edc1", + "java/docs/SendTemplateRequest.md": "264d8cbff7d1ee41bdb7cb1f11c91e90cc78840894ed0241a8b1e87e1689dffa", + "java/docs/SendTemplateRequestLanguage.md": "199a0bd6811762a5a2e8643e700e7de79c5776fa224f33597848b6b1c6c95e01", + "java/docs/SetWhatsappBusinessEncryptionRequest.md": "b6408b43aaae1c2431dea486d7e685e009ffd590859dfffcccd37bfcf1c98be8", + "java/docs/SuccessResponse.md": "2b195ef606905dbb7744bdb396f6aa58acd26e563a43cb0fbededaacaa7fc614", + "java/docs/TemplatesApi.md": "eed376fde2b3a1aad9f505284f9e1b3311f9bd8f283f1f9e4e00f85538a1ee7d", + "java/docs/UpdateCallingSettings200Response.md": "c8ae661f9e014a11340c24829d36f49ba396aa2bf6256dfa27684630622e47f0", + "java/docs/UpdateCallingSettings200ResponseResponse.md": "b47d4b52155e2fd12eabbbf3b3de5f15cbef45c7319756efbb6c112bb2673961", + "java/docs/UpdateMeRequest.md": "89a509bb39abbd29e258eaaa5d99d81e5245ee0861aa92bf040b07d42cb04391", + "java/docs/UsersApi.md": "6898be26155ee0834f7f2fba4b9593084f6ed9534545decfe5efbb0bda6d6e91", + "java/docs/WebhooksApi.md": "c524b74935fd5ba9ad2a8680b49484e405eade66ddc66f82015015da355dd421", + "java/git_push.sh": "9b8b2e7dcae7d87ff8c3098e9391771df54d533daca205f6473b7e2c2dce86c6", + "java/gradle.properties": "5b1ba6ab64d9629afbbf2a851ff460cd43acba63f1ab32f36822bb3dfbaef374", + "java/gradle/wrapper/gradle-wrapper.jar": "cb0da6751c2b753a16ac168bb354870ebb1e162e9083f116729cec9c781156b8", + "java/gradle/wrapper/gradle-wrapper.properties": "712d9bc912d4b0d42b0faf8c6afeed13ae31ced75ca28463b1dfc4ced1a4bc9a", + "java/gradlew": "211b176cd033866b3d40159e58d7f0120c5a620056ae85f83567880f6de15b1d", + "java/gradlew.bat": "95e8ae8e8a256a2f066cdd745d56f7a3fc87aa058a2e4beb483300db7171bd1f", + "java/maven-central.gradle": "b164a2ce9ee141c33493e6925126edcb4269d99db29bdc1a6e95534f79a942db", + "java/pom.xml": "a026fc44c6c2fd99b8ef5e5beb2a36ef08becc990e61d87a6ddba8acf85d0aaf", + "java/settings.gradle": "f857869f9ce553e1cb42eac3b867d3ef17bb9a7da82bc1f856154d4cc69abd54", + "java/src/main/AndroidManifest.xml": "b49b480f92bcd33225cb9c2a51abbb06edcb77eba0332bef34967c5813ab773d", + "java/src/main/java/io/onemsg/sdk/ApiClient.java": "fa0211058a6ccd9b128f9ebc2e4adfdb6c6a964f78ae95fbdeb327b0c03646a2", + "java/src/main/java/io/onemsg/sdk/ApiException.java": "864c7ade63d9a48a97311a7d15112045aedc1ab79b04a394aac40923781589e0", + "java/src/main/java/io/onemsg/sdk/ApiResponse.java": "756ae813f94df484826d03169b4966e2590e1791d42f72019a9cf7d4b6269c24", + "java/src/main/java/io/onemsg/sdk/Configuration.java": "bc9f4ab458828b348358df56a4d96852ff58f2413324972bda771317471f7c06", + "java/src/main/java/io/onemsg/sdk/JSON.java": "ff7b99ec5adbf94936a47dfac23e9b86b619b891168a9c270b2cfc336241d8c7", + "java/src/main/java/io/onemsg/sdk/Pair.java": "a77cb502a4b7e18d5688690135e3d79c88880465526413ee15370cc7381560a8", + "java/src/main/java/io/onemsg/sdk/RFC3339DateFormat.java": "574bf436e68d29539145cf67e1fa81f871207284b17ee085791b16022d2d9be3", + "java/src/main/java/io/onemsg/sdk/RFC3339InstantDeserializer.java": "10afb9173d007f2d66d9141b9329fe168cd5625a90d0c66eaf46ab3dd7eac9e2", + "java/src/main/java/io/onemsg/sdk/RFC3339JavaTimeModule.java": "29cacfdae118ff276a783193ec052d6dade6074c18d36e3f5c1788121f5970a0", + "java/src/main/java/io/onemsg/sdk/ServerConfiguration.java": "39276e79729e124b291f04c0df363df6054d6f10bf965ab42842505d5767c730", + "java/src/main/java/io/onemsg/sdk/ServerVariable.java": "8c8ce3ff378a8c77c8ee1e5589c6f67166fc8c64c107def9a415545eabb8f4da", + "java/src/main/java/io/onemsg/sdk/model/AbstractOpenApiSchema.java": "86d329d5e3581c2fe2bba987b646386d4ad94310089c6e85399ffb42e0242f08", + "java/src/main/java/io/onemsg/sdk/model/AddTemplateRequest.java": "5db937c6d8718c2e6f3c0f5edfce5a6248b81b38166ee0bf2744a0552b859d42", + "java/src/main/java/io/onemsg/sdk/model/BlockUserRequest.java": "d05dab9b050dfe8aa48866b43ac3c78b053f7a1822a5e1cc0abd2e87e5eca0d3", + "java/src/main/java/io/onemsg/sdk/model/CallingSettings.java": "525ba5f00f6acdc3cfce179575c87f8505955d7c349b070f00a4dd257aef308e", + "java/src/main/java/io/onemsg/sdk/model/CallingSettingsCalling.java": "ef9320b88d041434ba8e0fccddc2586a8c0586e01ee01b34e15d6af929b7ed56", + "java/src/main/java/io/onemsg/sdk/model/CallingSettingsCallingAudio.java": "0b80ab80fb70f16a9211c435764201bc55a207a0db7b40ed8fd61ca5be3041af", + "java/src/main/java/io/onemsg/sdk/model/CallingSettingsCallingCallHours.java": "055a563fc7f2d30f5687bb60d1f3b4e0279750c1b2a7e8193ec7a6f2b1be51c4", + "java/src/main/java/io/onemsg/sdk/model/CallingSettingsCallingSip.java": "c70b45b6c994fec150959691af5bbad4a6f293396d8d953e8f753ebec28d3332", + "java/src/main/java/io/onemsg/sdk/model/CallingSettingsCallingSipServersInner.java": "d759b16d96f2e6c103dae69bf2cf654e1c5ba599c24f1e95e43e5befd5661f89", + "java/src/main/java/io/onemsg/sdk/model/CallingSettingsCallingVideo.java": "18874f6c4be511eb652c16845715c131434d20e184aea592afb751771dd7eadd", + "java/src/main/java/io/onemsg/sdk/model/ConversationalAutomation.java": "968aa1fc6e660e89770c775f2f48b92dd224e29467393d187384c24ea0df410b", + "java/src/main/java/io/onemsg/sdk/model/ConversationalAutomationCommandsInner.java": "9e7c21aae3e410bf7b4d3882ed92914eec425f5f2aea400962b4b98abc119978", + "java/src/main/java/io/onemsg/sdk/model/CreateCommerce200Response.java": "78c3e7744f3e02835f03a7b1c8950ee8fe2b1be1ed6c2e71ce73baa7b1b699e7", + "java/src/main/java/io/onemsg/sdk/model/CreateCommerceRequest.java": "198535b3526b9b550eee669a1f36b5d56eeb4265d5112ff9711add7073fe394e", + "java/src/main/java/io/onemsg/sdk/model/CreateCommerceRequestParams.java": "0e9247baa82f8ad472e75763118aa5049dcea83465ea04ef4528a9a976f381d4", + "java/src/main/java/io/onemsg/sdk/model/CreateGroups200Response.java": "f43c3d2dc8970129bc93a8db01b18f44d5b2382415216d719458214778401d75", + "java/src/main/java/io/onemsg/sdk/model/CreateReadMessage200Response.java": "6ac68382125ba75edb27522329e5957466196b7712163c9b9bd387713b17cac9", + "java/src/main/java/io/onemsg/sdk/model/CreateReadMessage401Response.java": "06c67ae60951313b77529d5b3777d724851cc83ba42290c69c196dbe29b60702", + "java/src/main/java/io/onemsg/sdk/model/CreateReadMessageRequest.java": "a88873b6a52dfa6b69dd8b4c47d05b305ceeeec3df1f7cf2f96b143e286cbca6", + "java/src/main/java/io/onemsg/sdk/model/DeleteFlowsFlowId200Response.java": "e3a66be1fc0c34cfbc6688b737835af06b02e0d5f77fa2ed5ac8ed136fcb4815", + "java/src/main/java/io/onemsg/sdk/model/DeleteGroupsGroupId200Response.java": "be1d85ef77f9ea9e6b06dd2b2c1b3bbde851a2f56e583057ae38d382b6ce3737", + "java/src/main/java/io/onemsg/sdk/model/DeleteMediaLegacyRequest.java": "da447ba53a4980403aa50e4b9d94aeffb230494b51edab6db6da2b7afed73c7c", + "java/src/main/java/io/onemsg/sdk/model/ErrorResponse.java": "642de2043e09fac62af4edaf9a747c2699e16efbb9ae47594555e65f3af24d3b", + "java/src/main/java/io/onemsg/sdk/model/GetCommerce200ResponseInner.java": "ca6aec7a8cf469a839a3eb8f137d51b8e13aec0d445efd923eec43588328a47f", + "java/src/main/java/io/onemsg/sdk/model/GetMmLiteStatus200Response.java": "bdac1d1aab42b8cb112fd375aee6ff0b9d4e47d356b420a64a03033d726f5a72", + "java/src/main/java/io/onemsg/sdk/model/GetWebhook200Response.java": "6daed56e674e0ef4c51d5da134cc5739432b058e50ceb9108c80aceb649de1d1", + "java/src/main/java/io/onemsg/sdk/model/GetWhatsappBusinessEncryption200Response.java": "e4381c0b1cd21c91c5727d801978174058ee4ce92433fcde8adcbb72c1ca9fb2", + "java/src/main/java/io/onemsg/sdk/model/InitiateCallRequest.java": "c103c46ddc81ae8299aa5639a2bfe1cfc54e497d8debda52be04d1232451f205", + "java/src/main/java/io/onemsg/sdk/model/InitiateCallRequestSession.java": "a226b335e7ae3be7c64e72dd8ff0c0ac24d00f399fe5b66f31c3fee932de7828", + "java/src/main/java/io/onemsg/sdk/model/InitiateCallResponse.java": "97e6c0aa08afb781f6965ef5277bf934b75945c89b88913a37f1b1ecdfbd7fcc", + "java/src/main/java/io/onemsg/sdk/model/InitiateCallResponseCallsInner.java": "c4e249f74d808510fe36606e3ad581920def713f3f18a8939ed9e1256925bcca", + "java/src/main/java/io/onemsg/sdk/model/InitiateCallResponseResponse.java": "e2f6354ce25a8a024052f2d8d0006d59cadd66d29901f421af733d558a3056f1", + "java/src/main/java/io/onemsg/sdk/model/ListBlockedUsers200Response.java": "e8d633e41028154f574f37a218d2854fae0065672f792b3f366080ad57a3d770", + "java/src/main/java/io/onemsg/sdk/model/ListFlows200Response.java": "ca42c526c8b105e1ef57d1426f0dbdf379156398d293c81233c2cde3ad18cd6e", + "java/src/main/java/io/onemsg/sdk/model/ListMessages200Response.java": "7e06a7669fef170459a93a9534e8b504a9aceae4777dc0ab7567eacf4a0c60dc", + "java/src/main/java/io/onemsg/sdk/model/ListTemplates200Response.java": "9aceb89b0b6a2faf87d663dd92d8ca48f5720cc76440c994a4dbae317982707e", + "java/src/main/java/io/onemsg/sdk/model/MessageSentResponse.java": "4568185d2ebb0e4e082f08bacca57a667ae4a72e7beff259afda1c4be15ec595", + "java/src/main/java/io/onemsg/sdk/model/PatchFlowsFlowIdAssets200Response.java": "cd3ec79de3667ccaca824a07d15d531c8702fbc13bef74bf2bfaa96a42122439", + "java/src/main/java/io/onemsg/sdk/model/ProfileInfo.java": "9e76ad74b6e0f0ee6300a62fb9717104d968718bd57699641e6dfca2b1213683", + "java/src/main/java/io/onemsg/sdk/model/RetrieveMedia200Response.java": "ccea32be9ae70ce092524e0b035f6044a39615e58ffe32f591e96bf151b0d3d1", + "java/src/main/java/io/onemsg/sdk/model/SendAddressMessageRequest.java": "21aa78a9d4b2823712ee013d07fa14789c91e2ed8a7f50f4fbe9a047d89e6c9d", + "java/src/main/java/io/onemsg/sdk/model/SendButtonRequest.java": "b98a92e34a59da63c5eee797d77b6c2009573ef6e2ba4a31b8b5aded05d5e802", + "java/src/main/java/io/onemsg/sdk/model/SendButtonRequestSectionsInner.java": "1c45843e45df3f9e9b814e613ac268c3c8f684c8fd67def1d7ad7bf978b56715", + "java/src/main/java/io/onemsg/sdk/model/SendButtonRequestSectionsInnerReply.java": "47f17347db1c0801e905ba2db4a85ebd791a33898b5bf59de65b8d5a351ae618", + "java/src/main/java/io/onemsg/sdk/model/SendCarouselRequest1.java": "440c6129b4b1e5f9b9cab13abe90631802732b0da1d940b9289d31a9b6f672c1", + "java/src/main/java/io/onemsg/sdk/model/SendContactRequest.java": "14c37ffcde1454e5a78059b7ecc577d9d96ff0056307d7ce43b1c90342137292", + "java/src/main/java/io/onemsg/sdk/model/SendContactRequestContactsInner.java": "e375c482ef2a7a853ed0f7c1c0b6e951e1f3b53365a2dfbb4b2f30cb62f6abb8", + "java/src/main/java/io/onemsg/sdk/model/SendContactRequestContactsInnerName.java": "880c0a0bbd4f3924e70425dd96df809da7f841cfa2a5f4d872681f30c394a25b", + "java/src/main/java/io/onemsg/sdk/model/SendContactRequestContactsInnerOrg.java": "39991b63b0a5f9ecbb0f2b571818f5599173da28d1631a0169d338020f8dfa84", + "java/src/main/java/io/onemsg/sdk/model/SendContactRequestContactsInnerPhonesInner.java": "7edf5067a8ce52ba5afa036d71971868be7093afe361040b0770900d3e546040", + "java/src/main/java/io/onemsg/sdk/model/SendCtaUrlRequest.java": "c6be635b6445064af3cf1cf3a593fce8a0265dcbbd2618991e89756315323376", + "java/src/main/java/io/onemsg/sdk/model/SendFileRequest.java": "adb08fab1d230461dea041b50a512d14688135da5f78af168c6fd3436e50179d", + "java/src/main/java/io/onemsg/sdk/model/SendFlowRequest1.java": "f9aa82451adce314d28d5b98cc7429d1d06d178e8b34b5772c2a291c479668fe", + "java/src/main/java/io/onemsg/sdk/model/SendFlowRequest1Header.java": "ac2150bfd560e64512ce9a30ef6246c192bfef902991e25bc7fb75b9917f0b8f", + "java/src/main/java/io/onemsg/sdk/model/SendFlowRequestHeader.java": "a0b1596473a4a59fedf627e77106d08c624b86eed9cae0eebbae314932e52aa2", + "java/src/main/java/io/onemsg/sdk/model/SendListRequest.java": "62d7b3405bced2dc309c7df311efff6e3c5bc3d43eddd4ba019f47fb815329ef", + "java/src/main/java/io/onemsg/sdk/model/SendListRequestSectionsInner.java": "12d961b92481e0db2a4859ddff9c71584ec9b564fe71eb64e94311f2d3f55de4", + "java/src/main/java/io/onemsg/sdk/model/SendListRequestSectionsInnerRowsInner.java": "2fd62c865e9cb6a94cb1b1c3434f382a346339de20647c946387e19b7e2b4a04", + "java/src/main/java/io/onemsg/sdk/model/SendLocationRequest1.java": "eacf7f1953559ca6ad1b2c43b5e22ebd8862bf8c64aa2422c0db33efaeb2ac0f", + "java/src/main/java/io/onemsg/sdk/model/SendLocationRequestRequest.java": "fca1da21fc5c7e7c8b78b6bc48394e6d5825e147c09dc41b7fc1444102e84b4a", + "java/src/main/java/io/onemsg/sdk/model/SendMessageRequest.java": "2eca00320a820623c177a214030e106ac741332a58d1095569036ebb1d7cf418", + "java/src/main/java/io/onemsg/sdk/model/SendOrderDetailsRequest.java": "467b72d0f7efccf496d406f876cca88906a0cca633dade1f1470d41950a3b70b", + "java/src/main/java/io/onemsg/sdk/model/SendOrderDetailsRequestLanguage.java": "0143487b89d5445b32c9564c99df433dd26e1359d34e4b5ede6052d9b7b4cbf2", + "java/src/main/java/io/onemsg/sdk/model/SendOrderDetailsRequestOrder.java": "7047ff3875ee948e6d6ce6b7a43b0560dd3e88c73ee41d6977ee7ef49aa3d6eb", + "java/src/main/java/io/onemsg/sdk/model/SendOrderDetailsRequestOrderItemsInner.java": "da66e2b8d755c68a332cd4f183a65380a9733e0a9cc094006fefcaeb88fe95fe", + "java/src/main/java/io/onemsg/sdk/model/SendOrderDetailsRequestOrderItemsInnerAmount.java": "da9f0968233a77526c36f5e23f96bafb857819ef41691c3f588c81a823e70f3f", + "java/src/main/java/io/onemsg/sdk/model/SendPaymentRequestRequest.java": "ab165f9bbca1266be1b0b7dfa02c0a8441955b668dac9e9aa1972207ae2526e2", + "java/src/main/java/io/onemsg/sdk/model/SendReactionRequest.java": "cf23b7793b764abb740c946c8d16504f7aa12f49246d27cd3bb8982c591b7136", + "java/src/main/java/io/onemsg/sdk/model/SendStickerRequest.java": "8a94a9908a67898fd7e11f441208c11e410fa3aed55ffe017950446ff38d03cd", + "java/src/main/java/io/onemsg/sdk/model/SendTemplateRequest.java": "f12749e4fea5574771cc4eed23a70515c3999fabeed3d6e7c08ee4d26cba5290", + "java/src/main/java/io/onemsg/sdk/model/SendTemplateRequestLanguage.java": "950969379d2f8526a7653bd1a7f0f7b583398b1d8a2ee4f4eec4ac24fe18733a", + "java/src/main/java/io/onemsg/sdk/model/SetWhatsappBusinessEncryptionRequest.java": "8a2d475fad294455f83f5195d3df0b074d1f554b3364a367cfef9a5aaf3a5d75", + "java/src/main/java/io/onemsg/sdk/model/SuccessResponse.java": "49045cf637c2922f1a17e5e8572fe5d5305efd4bea3259d57a0932ae8cba5a42", + "java/src/main/java/io/onemsg/sdk/model/UpdateCallingSettings200Response.java": "e9dcbd5a5f5e12ed17dd25c6ecd06eb46f94d8200a2f8316cbe33bf68e8804cc", + "java/src/main/java/io/onemsg/sdk/model/UpdateCallingSettings200ResponseResponse.java": "b3de9457081d77c0b9a72eebf10ddf468d05349e33f588960f354295237990a0", + "java/src/main/java/io/onemsg/sdk/model/UpdateMeRequest.java": "a30558a61746f09364f5ae633d6b8d7be8b87fd9f2fc43fd84ab716fcf6789a0", + "java/src/test/java/io/onemsg/sdk/model/AddTemplateRequestTest.java": "6e41039bbf5d150589c536d75907112eb582925e8e845172f74353c04b24ed64", + "java/src/test/java/io/onemsg/sdk/model/BlockUserRequestTest.java": "650cc6f7c551659bd6eb0bdca7c0749a6f79d025f4eb6d15a78a9eebc2659818", + "java/src/test/java/io/onemsg/sdk/model/CallingSettingsCallingAudioTest.java": "8d74dd275e653aba0321fd464b7f34fb5e71b6a9d7bf71379375e34e6ad5b258", + "java/src/test/java/io/onemsg/sdk/model/CallingSettingsCallingCallHoursTest.java": "164b737fe96976ea338596cc518b1e65babfcd31352355b5c2d96b87b3826ef0", + "java/src/test/java/io/onemsg/sdk/model/CallingSettingsCallingSipServersInnerTest.java": "73ed0bec4ac7eeedabe05842c8d13c1a1384e2bc8339a7bd39808e61a06bba2c", + "java/src/test/java/io/onemsg/sdk/model/CallingSettingsCallingSipTest.java": "409a7c08bedf7681a21959ce20c50d5200f875d5ee9aec8f5057a7f42ae2ffff", + "java/src/test/java/io/onemsg/sdk/model/CallingSettingsCallingTest.java": "f9e280b2e4679cc01a167efef0112a01910a8940527b4f998fb47186d262b28a", + "java/src/test/java/io/onemsg/sdk/model/CallingSettingsCallingVideoTest.java": "7f87dedc5baea4b8c06d4f280a84ea5f65c3b55dbc21a8bb085c1adbe0d27a17", + "java/src/test/java/io/onemsg/sdk/model/CallingSettingsTest.java": "33964960b8b9b77f95fef3a88325c5fd884a716743cb88ba00cb2bd0873022e3", + "java/src/test/java/io/onemsg/sdk/model/ConversationalAutomationCommandsInnerTest.java": "b728500df65316a0f36e0c78c5f7045fbd8b835715b1c82f3f23a67503252a99", + "java/src/test/java/io/onemsg/sdk/model/ConversationalAutomationTest.java": "b8a1fede79a5f2446ed8b0b49d4cde5759ec55c4283a8ce22b003e7979ed1e34", + "java/src/test/java/io/onemsg/sdk/model/CreateCommerce200ResponseTest.java": "db35b24a38d02572b36d0585ba52438fccd3ae2f363a3849acdfc871703f59fa", + "java/src/test/java/io/onemsg/sdk/model/CreateCommerceRequestParamsTest.java": "c7dc8b409560b54b9f260d06bbc0e662898b3b5fb0e04d695274fd2f1a742d94", + "java/src/test/java/io/onemsg/sdk/model/CreateCommerceRequestTest.java": "adc879357b486c15e82f0589f86c2f6ed3375bde697e10e4313b8b6dbb9ce733", + "java/src/test/java/io/onemsg/sdk/model/CreateGroups200ResponseTest.java": "218d45f9d385013e196b3966ae90d35dd1e6aa4190b3b97be8d760a675e81994", + "java/src/test/java/io/onemsg/sdk/model/CreateReadMessage200ResponseTest.java": "d0d0bc445f926e0cc94a9a145c886d3b5ca0bb1f95a5f1bafc445d9e929cda62", + "java/src/test/java/io/onemsg/sdk/model/CreateReadMessage401ResponseTest.java": "73fa34631e4ffb810164ef92fbac06a41913e664aae782c0322ae387eb1ee31d", + "java/src/test/java/io/onemsg/sdk/model/CreateReadMessageRequestTest.java": "49491f45bf159848d7dd0d5754363fa2fa8483c6d6e392ebe5a8a133e38b4267", + "java/src/test/java/io/onemsg/sdk/model/DeleteFlowsFlowId200ResponseTest.java": "4a9775ed956c3557f2d233c777bf091ccd07712584fe5113a5bfca0baaebf253", + "java/src/test/java/io/onemsg/sdk/model/DeleteGroupsGroupId200ResponseTest.java": "25ab58fc1120617c1da804d87f1a75027381d7fbed416636042f2895f16ec30e", + "java/src/test/java/io/onemsg/sdk/model/DeleteMediaLegacyRequestTest.java": "83dc161a5b65bd45f5eb0993ad3b1e7d5be2ae8fc4d601e88f20e19059f0580d", + "java/src/test/java/io/onemsg/sdk/model/ErrorResponseTest.java": "5c2e9c0005b9ca4916547efec784daa3a36d440501a3340400052a3fedb16700", + "java/src/test/java/io/onemsg/sdk/model/GetCommerce200ResponseInnerTest.java": "ebaf02f2aae249481e8afe6715d2a44a16d2de3f2c5472df1c96063f099545e4", + "java/src/test/java/io/onemsg/sdk/model/GetMmLiteStatus200ResponseTest.java": "c1861dcc0f3fd450a05ca7bde8c08422ca2e2730522f14a1603556875428c047", + "java/src/test/java/io/onemsg/sdk/model/GetWebhook200ResponseTest.java": "54730ec6a4d8befe8b625a879ffc134184ff685496279f9bc4af2561b8aabe5b", + "java/src/test/java/io/onemsg/sdk/model/GetWhatsappBusinessEncryption200ResponseTest.java": "6d27df3930e279618bab2b757ab0a58c8cb6a17d0763ff1a5856b5a5c9b047b8", + "java/src/test/java/io/onemsg/sdk/model/InitiateCallRequestSessionTest.java": "a335ca3e3d4f1713824d8d53c69c6577bb9b7fec8b28d834100be99c3816593c", + "java/src/test/java/io/onemsg/sdk/model/InitiateCallRequestTest.java": "d7ec18cc0c5e72645667c7bd29ca218c468c5d1ef31179525a5a8df31457e0bb", + "java/src/test/java/io/onemsg/sdk/model/InitiateCallResponseCallsInnerTest.java": "392bac00f7aa2c726bb92ecf173235fc4777c2d824241a3cc061651b7b07cc03", + "java/src/test/java/io/onemsg/sdk/model/InitiateCallResponseResponseTest.java": "18116be76a01cd7ca172c5ad4fa6ccb2650a4bfa4d0087f3e0230c58005aaa50", + "java/src/test/java/io/onemsg/sdk/model/InitiateCallResponseTest.java": "cb9548e2061afcdf804e9ea9800dc62fc02ee7ce4131ee124627a062ed945e5b", + "java/src/test/java/io/onemsg/sdk/model/ListBlockedUsers200ResponseTest.java": "faac2787e2a3f8fb30865fc69cdade3b816ce8c316cdcbeff888664091a3b8ad", + "java/src/test/java/io/onemsg/sdk/model/ListFlows200ResponseTest.java": "0c55259435131f54e359f967385ff9882dd22d2105e705ee7a16cf256f18d5a2", + "java/src/test/java/io/onemsg/sdk/model/ListMessages200ResponseTest.java": "ff5e682630aef1dc1d40f3240fe50f94e7ba29c421a35da324f6b315b0e908d9", + "java/src/test/java/io/onemsg/sdk/model/ListTemplates200ResponseTest.java": "3eb35f7b84f36432f12642be72e35fa3061b894274591870f7640002288468e8", + "java/src/test/java/io/onemsg/sdk/model/MessageSentResponseTest.java": "1ce05d11198d789cc885b08358c1eb52d910929faabb30ee79fb2f0b47500fbf", + "java/src/test/java/io/onemsg/sdk/model/PatchFlowsFlowIdAssets200ResponseTest.java": "d1e0fcf7219cb39651c57a31990b5819eb72d2d3f3ec24aba476e93b32955a67", + "java/src/test/java/io/onemsg/sdk/model/ProfileInfoTest.java": "6a10523c6f1ac4119734668e9f8f91627b0e29dcff75fbd1b7d232b4a34b71c8", + "java/src/test/java/io/onemsg/sdk/model/RetrieveMedia200ResponseTest.java": "a1e6bee3000a4ef1c917126d7d2d7453c8764810acaf0b4a27d003d2763406a2", + "java/src/test/java/io/onemsg/sdk/model/SendAddressMessageRequestTest.java": "9efcdcf1d74e56189bdbb8ae2b9e3553b1eda5c2cc6f933e2cfa8ad84c77a0fd", + "java/src/test/java/io/onemsg/sdk/model/SendButtonRequestSectionsInnerReplyTest.java": "928199bcacdf40efdf0e5bfc875116258477b043bd130815dd0bf46eeff122b8", + "java/src/test/java/io/onemsg/sdk/model/SendButtonRequestSectionsInnerTest.java": "ff79c82849a116b299bfedf92dfd5e4fa7b11dec1075f9fc829234e485c6ce1b", + "java/src/test/java/io/onemsg/sdk/model/SendButtonRequestTest.java": "efb88a2f2f5ca5b3d6b11ac7cb6e91f6ed71b11aa2358e2b4334cb84c0c77a6c", + "java/src/test/java/io/onemsg/sdk/model/SendCarouselRequest1Test.java": "8fc930cc21648f7f3e489018507c8284bdaeea767441adc3feba8c6155305629", + "java/src/test/java/io/onemsg/sdk/model/SendContactRequestContactsInnerNameTest.java": "976c551422bee75b93feba09e3816f676dc9c1546207061891b75f8c48e5cfdb", + "java/src/test/java/io/onemsg/sdk/model/SendContactRequestContactsInnerOrgTest.java": "9e3154e7d1705d04f7410dc23f9bfdf9c30ff3ecd59509a646ae15124adb9ff5", + "java/src/test/java/io/onemsg/sdk/model/SendContactRequestContactsInnerPhonesInnerTest.java": "f9e92b85a9a7a439dab769476ad1113d94e0b39fad899ed26e1e4281dcc4702d", + "java/src/test/java/io/onemsg/sdk/model/SendContactRequestContactsInnerTest.java": "37ba983c9629d1c81e35c0758c02f0d01c77d85adc51e891f309856d1eb89f56", + "java/src/test/java/io/onemsg/sdk/model/SendContactRequestTest.java": "249e1e81ca085d0c41e5fe80e6b2882b45a9a9805d13a6417b1a8c850b964837", + "java/src/test/java/io/onemsg/sdk/model/SendCtaUrlRequestTest.java": "9725eb2eb91c060137ba575204b8f4ad4325b03274ac8f8928399a6054871d49", + "java/src/test/java/io/onemsg/sdk/model/SendFileRequestTest.java": "2db505e10030cd64f640716b0b43a42007bc7d659b3a0708f6130c9c79402a3a", + "java/src/test/java/io/onemsg/sdk/model/SendFlowRequest1HeaderTest.java": "f3eb191f84a09cd581ff6cebb4ab3f424cedd86a886167b63898d76aff2e2535", + "java/src/test/java/io/onemsg/sdk/model/SendFlowRequest1Test.java": "8a78882aef3369bf17de18c747f52f48e152b2f53e33c79385f2f8ac13dc9a4b", + "java/src/test/java/io/onemsg/sdk/model/SendFlowRequestHeaderTest.java": "0dda3b999944a78eba6facca8d1ec8df4d474ffd0a16622ed7b60453569b31c3", + "java/src/test/java/io/onemsg/sdk/model/SendListRequestSectionsInnerRowsInnerTest.java": "2f1b8ae04b4de8e12556106822e5175607ced93efc40658ac598f0e98a9ab69b", + "java/src/test/java/io/onemsg/sdk/model/SendListRequestSectionsInnerTest.java": "cd9441b7329c94439c00f65d9aa9ece560e3e8c55cbe7e3de1c63d7c9ef06ec5", + "java/src/test/java/io/onemsg/sdk/model/SendListRequestTest.java": "6543ebbf2278e347c5fbb4c9a1bbef83e4b2cccddc76f3cb5ce82d97b20a2647", + "java/src/test/java/io/onemsg/sdk/model/SendLocationRequest1Test.java": "f29e61e4948735119a1240127b636b16cd011661031381d8301478c85996d8c4", + "java/src/test/java/io/onemsg/sdk/model/SendLocationRequestRequestTest.java": "bfe903a49a80f01c025c389e467c6941c194aae3b5a9892622384949721b8377", + "java/src/test/java/io/onemsg/sdk/model/SendMessageRequestTest.java": "df3d96a04915c122453b8844fc885dbbb7ed00625a47dceb68fbda24eadca987", + "java/src/test/java/io/onemsg/sdk/model/SendOrderDetailsRequestLanguageTest.java": "9bfa6a90758f260ed2c272cc9231dcaa250f4466dd50459c7000180ab95b59ea", + "java/src/test/java/io/onemsg/sdk/model/SendOrderDetailsRequestOrderItemsInnerAmountTest.java": "5c0c9b7d1e437fc559681e76e186b8c2444f59d40606ebea0c90f12886ae141e", + "java/src/test/java/io/onemsg/sdk/model/SendOrderDetailsRequestOrderItemsInnerTest.java": "cca554b8482cdea18eae01013097c9dfcbb1447cf6ec693119bb4d33cdf64bba", + "java/src/test/java/io/onemsg/sdk/model/SendOrderDetailsRequestOrderTest.java": "fe9e238ca71edc88922175887d760fdcf3e7c70d82e123ca2014b46b20541c49", + "java/src/test/java/io/onemsg/sdk/model/SendOrderDetailsRequestTest.java": "e43f53009aeecbb7a78695eeb04d336c9fb89685be2ee548b1c22c87a81fe5df", + "java/src/test/java/io/onemsg/sdk/model/SendPaymentRequestRequestTest.java": "9ba6ddb752f83543acc46abc0decb95a0b1c3e95c2d8ab0e26a1ab3bfad21bab", + "java/src/test/java/io/onemsg/sdk/model/SendReactionRequestTest.java": "9e53ccfa1be7faf1ee57e54811e0956c7388b8914722abd47ccd3585dfafd4ce", + "java/src/test/java/io/onemsg/sdk/model/SendStickerRequestTest.java": "890703db4143880010856c21edfc0b677cdb154307230b5c82a2f174e67574e2", + "java/src/test/java/io/onemsg/sdk/model/SendTemplateRequestLanguageTest.java": "4136b1d548deb326c17d2f1c6aef73c393c13532bf2c05816477fe9e8cce6074", + "java/src/test/java/io/onemsg/sdk/model/SendTemplateRequestTest.java": "706d0541941765a9f0b0a2428a3bf974b4dd36b31cfa06739b57c2d01e012601", + "java/src/test/java/io/onemsg/sdk/model/SetWhatsappBusinessEncryptionRequestTest.java": "851b882b295aeab75f965fab6f33f888564cdd6e70e0dd326fc72672cd00d0cd", + "java/src/test/java/io/onemsg/sdk/model/SuccessResponseTest.java": "c184b009d1dde01928b680a5930766a080c4c510003b2393d680411c7b1adad6", + "java/src/test/java/io/onemsg/sdk/model/UpdateCallingSettings200ResponseResponseTest.java": "509837071f96dcd64c44dd10d755a8b17807539a80bfae0b2afcf496d505e79c", + "java/src/test/java/io/onemsg/sdk/model/UpdateCallingSettings200ResponseTest.java": "b01c624da50d8534548c6bc2bbdaf5b109d4bd2e689304ef1f8b0b40bd00d4b6", + "java/src/test/java/io/onemsg/sdk/model/UpdateMeRequestTest.java": "1822c3b0ac2ea1c0673113d9c398462c698687f286c7c921659f4a5f82337d50" + } + }, + { + "id": "native-kotlin", + "owner": "1MSG SDK maintainers", + "issue": "https://plane.1msg.io/1msg/browse/1MSG-156/", + "expires": "2026-12-11", + "reason": "Native kotlin generation, frozen dependencies, build and offline contract tests have not been verified. Sources remain byte-for-byte frozen until a reviewed language-specific quality profile replaces this exception.", + "requiredWork": [ + "Pin and replay the actual language generator", + "Freeze dependencies and verify native build", + "Add offline required/optional/error serialization and package consumer tests" + ], + "baselineCommit": "802e13a13a3bb11ec25e68258c3bd0518dec8d53", + "roots": ["kotlin"], + "files": { + "kotlin/.openapi-generator-ignore": "a6ed8f4e275eee926d27e0c52f30f2d1c4d8409465ac1fbc4511f7cc62de51db", + "kotlin/AGENTS.md": "cad31d43755e04addfc0b3324df9c04c33a13bf60c785e854558df2757f6905e", + "kotlin/LICENSE": "88170a8e4e7b68f13a057d5b9e1882d4b60c71e0a762b5a95651931a219835ee", + "kotlin/README.md": "3f8b8418a818026afcae1e17347ee33e66d296fa584b4996a1c0e6be11cdab67", + "kotlin/build.gradle": "b3317ec76fcbb1dc9f1d8102e478bb3a43c246bb79d7b8ae4a41183b10f95f56", + "kotlin/gradle/wrapper/gradle-wrapper.jar": "498495120a03b9a6ab5d155f5de3c8f0d986a449153702fb80fc80e134484f17", + "kotlin/gradle/wrapper/gradle-wrapper.properties": "9a479a85aa879bb55284fc16d0de5b81a745c3854f4e2d88c42e7debaf007435", + "kotlin/gradlew": "fecdc6c20679342c8623b72eeb8d7155ee9d9151bd2c0d5a4c7486e62ad8de72", + "kotlin/gradlew.bat": "2209f919a22528af59a2af2ad97e8d056cca18e39f7d87aa3fd549a73b180150", + "kotlin/maven-central.gradle": "10a3b7298e17e22569b03d17b0db83db6a5d220c7510b692b6e4f777ffe9a590", + "kotlin/settings.gradle": "3ca7d3c81d8fecc60f061b5532c056ab0827e95dac867eb4a691eb5405161a15", + "kotlin/src/main/kotlin/io/onemsg/sdk/api/CallingApi.kt": "6fb8020256417b9681cb4dca2a57dbf28ae442431078891d5f2713868bc437f3", + "kotlin/src/main/kotlin/io/onemsg/sdk/api/CatalogApi.kt": "a3e0fe2b49f9ff78ee961ee7e42cf810812954222bd98b3d5319b13cfd335a84", + "kotlin/src/main/kotlin/io/onemsg/sdk/api/ChannelApi.kt": "5999269bbb5d06e79f3756737ce0c570abce031b081c2bb3bceb49e7a0431196", + "kotlin/src/main/kotlin/io/onemsg/sdk/api/FlowsApi.kt": "29b9016a09e42bddeae9ca9868687021e6d748d29dec050859b90c26f34e24f0", + "kotlin/src/main/kotlin/io/onemsg/sdk/api/GroupsApi.kt": "3d8c8fd7f09826bb3a9ea5d301a579cdc5759991f38fb2a8b6d8b3e2a0429418", + "kotlin/src/main/kotlin/io/onemsg/sdk/api/MessagingApi.kt": "4859e8106cc8645ea3e611e0862a60f883870b46ef84a8440408f7cb8384405d", + "kotlin/src/main/kotlin/io/onemsg/sdk/api/ProfileApi.kt": "1426abeae1555474a6cc05f038436cd98f3fd3138a62c90bdd86d90a35ce2489", + "kotlin/src/main/kotlin/io/onemsg/sdk/api/TemplatesApi.kt": "c5c0b1315d3b8e25d13eccfcc860d62517a057b92259f96e61646e716868fce6", + "kotlin/src/main/kotlin/io/onemsg/sdk/api/UsersApi.kt": "3fc5f417572807c400c7d017e232970aa60d2ed9c89b0518321b9814c2dd6f1a", + "kotlin/src/main/kotlin/io/onemsg/sdk/api/WebhooksApi.kt": "3a34849935dd70b09fae6ee2398ee9d6fd33034f82581636841f627817c01716", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/ApiAbstractions.kt": "6e8aa25c99847ef269b0b080546abe8f08ecc4517e6c9d7bade55dd7f6a6709c", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/ApiClient.kt": "b701f58472b1c2ef7b1a0211ab69d96cc64d94ef21c3d90198c93a3b2b161ad3", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/ApiResponse.kt": "c8317ca968f6a46066acff6b1860fb1dafddd58c821d61b78e596e8d6b1e303a", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/BigDecimalAdapter.kt": "58848640a7f03cc055ebf32cc1da9f7bd80144d5f3aa842269a19f63d15ccdac", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/BigIntegerAdapter.kt": "b46d2f6676d75f2988d20631b39e59748770e8de3f5202657b38e3f3284a3626", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/ByteArrayAdapter.kt": "568e131a610d4ba0fa2a0049fd1a3c8ff40b1ce383f708507dcfcd95e71283aa", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/Errors.kt": "ec87ab9c07ecf41450796eaf47470c118b2bb880fa5e3ba2997386fad3e37e45", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/LocalDateAdapter.kt": "504b9263bbc3065fe278c3f88c750fc8924648f7c6cbf45469dd93c39d28878b", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/LocalDateTimeAdapter.kt": "f691b98844dea02e20e7258420c83eb21c28608a350ede2e5625ca8ffd1be601", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/OffsetDateTimeAdapter.kt": "8bf96b2eeed6036fe346465152d0386da3c3bdecb75b63b4837e367329581c3a", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/PartConfig.kt": "cf513a020e72966e93db9f0b2fdca32a12a41f38991c701a590a0246aedd0a55", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/RequestConfig.kt": "351f703400b32f811a43d776b4ec351ff48dcc294483eb52b9772395d3bd4ec0", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/RequestMethod.kt": "5e8b5bd044ed4fbcd598d2ac33644408217cc82e9bbce494e53155b15ca04115", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/ResponseExtensions.kt": "71f1c180d389acfd229e5e61e97a2e89010105444c1730346bcdec8fc108665d", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/Serializer.kt": "10318d30262fae6256a47f352532cffde7b60fed1c0ddeeaa6f91e73b9e10e4d", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/URIAdapter.kt": "3db82c589d9387a8387e128913c7d5ceadd6af38f349c73c8477e7b0c6ed5a4c", + "kotlin/src/main/kotlin/io/onemsg/sdk/infrastructure/UUIDAdapter.kt": "8018e435c7c54b75ad11109905968ad55b5183e02d08901ebefcc52d6b324f6b", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/AddTemplateRequest.kt": "269e345bdc078c55b125792e7a86f762f3dcd44a11307f0ba3af993e60ce1bb8", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/BlockUserRequest.kt": "c47391a7eb34f8d76f1062ddf560c0ff3fb2cd4ca1bfb6bc60cc6de79b207185", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/CallingSettings.kt": "1f3a4be4f6fe6fad899403a6262f7ee552f125d8dcbdc6a4b2425470cd743119", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/CallingSettingsCalling.kt": "8364a2737cbac5352f11011b4bc42bfe91745f7f8c46676301e7676a3550e772", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/CallingSettingsCallingAudio.kt": "48c6328cf2b799d8a920907bc4dfbaddeb740e8c0c54be27587f7767d39b7128", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/CallingSettingsCallingCallHours.kt": "72c5e2a0efb1f742de3969a7ba59279876081f0efb27bde68ad34810a22dbd60", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/CallingSettingsCallingSip.kt": "0d90f2be15765c134a785ff27952b361701ec91de8660d132b45810abe60cf3e", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/CallingSettingsCallingSipServersInner.kt": "ee4b2eba2e8771d4e546eef0767b38ca03789d4166109e73f7717e2594c8cb12", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/CallingSettingsCallingVideo.kt": "b19ed652cc338228eb3383cfb52cdc76740604494b629bb7084001631c4ebef2", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/ConversationalAutomation.kt": "ff24721bd7ad138e8d676af6cd2c91a4f26b0ac4049ac72196328bacb093101b", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/ConversationalAutomationCommandsInner.kt": "cfcf9b7c58c882437f69c6a8fa26442e97f5a403c04afba0bc861a4b1b243cfd", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/CreateCommerce200Response.kt": "ee280892609b02339140cb1071c9b4e2f502f212b4926a61e366fcff81080eab", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/CreateCommerceRequest.kt": "488e5e51872f3e1e66c97da51c6658e31884d1c5526ab261c9a73790c22c5dea", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/CreateCommerceRequestParams.kt": "64e680e57723ef5d71a208f7368dd7f21c36d28f062704c7a6bc411b4d2c2030", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/CreateGroups200Response.kt": "363a19cb93d81631ec999876fe5a2e4e7ef4e05abc08aca739ec6cf0cea43f45", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/CreateReadMessage200Response.kt": "62cbdc9e7b6c42709494be80cf3c9d59765dd1b5a95a2aa5faf822d3f20088da", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/CreateReadMessage401Response.kt": "9fdbaa8c54ba46df5e901b300b6abfae72d6195d5b1d9426d6979757597dce3e", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/CreateReadMessageRequest.kt": "0d7ae101b08e25a540a36384ce7436ba1fe1e4042aa892edc04c64c03f1c7081", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/DeleteFlowsFlowId200Response.kt": "de6d3820b68de43c55149b45402284fa81f1b018a44e9d60f3615c4e8e94ee2f", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/DeleteGroupsGroupId200Response.kt": "b403ed2e5140326d0b8b010074e4e8cfd1ae6e8f73331562cb32289b5d9bfe04", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/DeleteMediaLegacyRequest.kt": "1baf616da46aec58e9244a66470f403b8990ab15264030709ecfdafcb7c0462c", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/ErrorResponse.kt": "91be2a5dbe62ecc746ba44c7bc234ff65e7a5fc65be9a1657b05d7dd498bbcaf", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/GetCommerce200ResponseInner.kt": "210671898158092073ae7327b05c92ffec4631ff615b1e106c67138109a2747e", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/GetMmLiteStatus200Response.kt": "a9f23397337a70b8b76fd9d83a65ad64d949d68e24abe95602f2f88cc7267841", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/GetWebhook200Response.kt": "501d89db12ab314d3859d8b04127dc4cbf55d841d77f31fb74815b49ee79e46f", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/GetWhatsappBusinessEncryption200Response.kt": "e19c1fb4be1d34d040deaac497ad895589b34cfa411206e4762d1448e462ea30", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/InitiateCallRequest.kt": "3104c5f4ddc643a64da3f8c3863c33167adcf9eda09706e14a1e29872774108f", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/InitiateCallRequestSession.kt": "1c1eb43d4bc227c6143da2d471421b9e5905db61d4284f4fa7d1c9a04effb894", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/InitiateCallResponse.kt": "73d5d617f760df1377ac0e36c1517e061cd5b473f394e13a60a5af557f1bfb8b", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/InitiateCallResponseCallsInner.kt": "284ad75ce9a725ed03bf42e059b5701b87282e10638d05fb344263d9283ff3b0", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/InitiateCallResponseResponse.kt": "a9d932b914cd73ca8fea6dbda37fb4c9f90c55c91141abf27d8e9ea3eff32121", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/ListBlockedUsers200Response.kt": "d68f1d2fa51cbc6a250883f293a4589b8f375242e1d79ad0a4a363cc0fe9c5c0", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/ListFlows200Response.kt": "5624c73e76626a5b374f73c0c48ced32437ceb4b939eaf3be27b4bd6388abb4d", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/ListMessages200Response.kt": "fd2df61d51a7e6d6e9ad61cff812f293b4628135005aa9f415a475665b1c5d27", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/ListTemplates200Response.kt": "5cd2ef129ea994a6b9ec7b6363a2b20586fe41e8d963eaa6e5dd3585b6f0d429", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/MessageSentResponse.kt": "e9964368d7ce5402e73f30aa89c3f529b5152ac1fedf75ee646d54b75044642e", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/PatchFlowsFlowIdAssets200Response.kt": "1c6b1ada66f9134d767e1ce5352ca907faf30439cc678e7e455b933c6c5e2aef", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/ProfileInfo.kt": "d22950a30c03a3070f3be2073bbfa769c9210fa77868c4b349b34df4be179b16", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/RetrieveMedia200Response.kt": "36927e6a147c4a5aa441ad35c1649c4da89ec60c81680dc202c0066658a10770", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendAddressMessageRequest.kt": "409bf759ffe26fa16c5d7aed859e0109ce8ffbc45fc75addb432d8596c754460", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendButtonRequest.kt": "7f6c425fb7bea898838997e42a0739fefdf37887e7968c4b951b47b5c96b6c6c", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendButtonRequestSectionsInner.kt": "42784ea11ad354ceab10abf6c49e782dc04aaeb33fd8705ecfb0c0dfd9650941", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendButtonRequestSectionsInnerReply.kt": "2d701a1734fb98eb6e893207f547cfa75aa14bcb2054009db2b442f4c285e56b", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendCarouselRequest1.kt": "3f2b550c5b9aba97bcc13dc84a9821b58463824354b74514234ea91bd16008f4", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendContactRequest.kt": "828029ca21c7ae62d34bfd2ecec9b560b8828c9d69e3b9d6e10f9f43cd514422", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendContactRequestContactsInner.kt": "9ca531186a084c361de32e066cab5163664502eca977407226c9d4b2bac8957c", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendContactRequestContactsInnerName.kt": "6b6bc9b4be8360f8c6632751ef431ca61c92b026ad23a46a34ab2c8eb1dd1e10", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendContactRequestContactsInnerOrg.kt": "608cbe96ea32486c6178d817a47f87e39eb76e8969ea416936e866e199f9a097", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendContactRequestContactsInnerPhonesInner.kt": "bc027e99867b69c6ac047c7d6509dde97659caeaabeff40dd688a8ed1542e886", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendCtaUrlRequest.kt": "14911e5b791c3f2d969e422d58c1ac168022ebf0330b0fdb6a0f69a9b1ac3dbf", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendFileRequest.kt": "881dbca64b9cf862d2b4b62db897d3ed277ed30a1b9154740715688f82f09944", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendFlowRequest1.kt": "b6b009d767fd2f4a4cca1a2137c3ad574e5c200c16e227f38f8170f241a260ac", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendFlowRequest1Header.kt": "affab87c70f288efab623c95ba23ec1ba29dcd7597dc3eebff81ab6edae861d3", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendFlowRequestHeader.kt": "f6771274447bccd469a9ee109b4daa16d1eb77477d8320ae7adf51eade84775a", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendListRequest.kt": "bbed11fc5e7593ec0e121d8636bc1f8ab114ffd4d622cd4a0d43356b8463c0a7", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendListRequestSectionsInner.kt": "50545dc21d39aac87d31ed709d0af1fdb0de810486d13a5013c7b339c255739f", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendListRequestSectionsInnerRowsInner.kt": "6861855d485e620a6d92f2c2a73bba14a82e6b58551494b19804159cb8e04985", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendLocationRequest1.kt": "c1a57a406d93a594cb6912c3dc3c8e61a7775eae2aecaff5a2d9217685e79e91", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendLocationRequestRequest.kt": "103952d903b5e85799aa2ffe2df0a576be84119853bd0fe3bb4e826aaa149cd4", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendMessageRequest.kt": "0056bcde6359bb6cb14477d4d39e99ca9b68b30e78d87b0515bdc4298fa7e99d", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendOrderDetailsRequest.kt": "c6dd173c496b5252b6483b42ab3ad34c421bc69907427b8f6abbe1de9a192428", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendOrderDetailsRequestLanguage.kt": "4874f3005132c68987ef250adb428cae66647099a6741f31d058ed4d56692446", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendOrderDetailsRequestOrder.kt": "c283ea589f7531de274614c4cf6b24553bea998e9cd69e95d4a9bd86f8e79f79", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendOrderDetailsRequestOrderItemsInner.kt": "2f9ae156126803981b3c16373b02891dbd4909a22b3ced9c1db1a7548ca62119", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendOrderDetailsRequestOrderItemsInnerAmount.kt": "26bb26cbc5b18a0a8c318b3b1aab01ba3e289ddfd3caabab72434408e97190cf", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendPaymentRequestRequest.kt": "7ea070e968ea38d70d579d3bb428a39463bc6c3b83d0bffbb20ffa0312b1ca02", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendReactionRequest.kt": "d46b4e908edde651f3bbe213592618b3d71cdec920e671a5b2ecf1dc441221a3", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendStickerRequest.kt": "8e3b9d1c5c449fce696285afd4bcf376c8d917dabed15112c5a5f0cbd2a1c5dd", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendTemplateRequest.kt": "996592247f27f1671f1080236ebd03137ded6b8b2b70a0ecc87c5fa5317f1cb3", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SendTemplateRequestLanguage.kt": "310dc6a530522afebb96383c89efea7a549124d162746a3b37c33c739f528c33", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SetWhatsappBusinessEncryptionRequest.kt": "8bba2fbd859070ea0401242f62946e6db2b36663f2594076b2fef6e2dde3ce57", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/SuccessResponse.kt": "5503a2b8d02ba1a6ca73eb955ee5cad9f57d172f5410eff74778e2639e5cfd51", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/UpdateCallingSettings200Response.kt": "4d7ee769120f269e8aadcf58f902b174514107e1ed01ce574a3d8d4efc450d2a", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/UpdateCallingSettings200ResponseResponse.kt": "7e11696ff5414f15d11237fdcca264c3b2c3717faabd30c7be7fae87e7d4a9d1", + "kotlin/src/main/kotlin/io/onemsg/sdk/model/UpdateMeRequest.kt": "4460e65b7d69dd852f6fad6acf0d50020bedc34bfcb1b703f049f9e8e475c745", + "kotlin/src/test/kotlin/io/onemsg/sdk/api/CallingApiTest.kt": "c420aa22b8adf71003ea5db3eee6cc70524bc0befd67ab6d2118f5e041c85637", + "kotlin/src/test/kotlin/io/onemsg/sdk/api/CatalogApiTest.kt": "84095b4bd29459382cf06c1e75f56a0a2a76632737e001b0c0101770e93ce033", + "kotlin/src/test/kotlin/io/onemsg/sdk/api/ChannelApiTest.kt": "09d2ece12fa953d0a4ccd3d5864e443ebe637b2c849cdaf06561eeb914aae983", + "kotlin/src/test/kotlin/io/onemsg/sdk/api/FlowsApiTest.kt": "ac723de78d5964ed3bfdf661af8dbb86619c914ebaf83eb066c80f6612d5a98c", + "kotlin/src/test/kotlin/io/onemsg/sdk/api/GroupsApiTest.kt": "63878da6d5f1f533b7b1ab7f4e9f300c4f52a5f989e454ed83e3f3b25d8a7c64", + "kotlin/src/test/kotlin/io/onemsg/sdk/api/MessagingApiTest.kt": "92c6cbb045619fb519e19c60cd75729245ed3dee98637ad63d17b5d6771b34db", + "kotlin/src/test/kotlin/io/onemsg/sdk/api/ProfileApiTest.kt": "07c773b436f37d15a7e36ccb9de9262c02d20455e24c1b92f9d811177d2f1d9d", + "kotlin/src/test/kotlin/io/onemsg/sdk/api/TemplatesApiTest.kt": "6987bf871c6d567be62ffdf561eb1f1adf017f8946f8360338db0e0301b37704", + "kotlin/src/test/kotlin/io/onemsg/sdk/api/UsersApiTest.kt": "d2f3d5d3d01f1bb5d58e49b10687f356cb2bf2609c3f9766d9cf7bad03c938c5", + "kotlin/src/test/kotlin/io/onemsg/sdk/api/WebhooksApiTest.kt": "5a2609b268d627ac30cd4f217c6c7d9710e7c42e59664fec8090714000903af7", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/AddTemplateRequestTest.kt": "dc9921a72553e3f035ec65428a0391108b1d4223fbec16fffb84b1781cf2ab0c", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/BlockUserRequestTest.kt": "40b2e3341d48f2cb38a9612ca65f442d9e87e1cf167a46c42cb94125ee4905a3", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/CallingSettingsCallingAudioTest.kt": "119ff5ae7356dd3567e0e1ccde307108056ffa14a2939773ea9599fb262daca7", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/CallingSettingsCallingCallHoursTest.kt": "a17c75f741db258e0659bf335031f2c7927ae05640ee1d2b7724f783781918dc", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/CallingSettingsCallingSipServersInnerTest.kt": "82d1e4d7f1ad68cf79e5f3e3a261f81bcce8b17c05d00b91d2d6c7720edd2518", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/CallingSettingsCallingSipTest.kt": "08e921634e1dfe02983a7bcd3ec9a7789aae9f6d2b840ae5adddd6ba009f714c", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/CallingSettingsCallingTest.kt": "7d2e2dcf6a208c7eb83421f4b3fdd37da7180dec38632364fec1c0c7f1d6d0cf", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/CallingSettingsCallingVideoTest.kt": "b94ad97bff3507e119e8f51342bcfa7af4f560df29a36d6e75cd27a7b12ef12c", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/CallingSettingsTest.kt": "c356394ee244f3b9ef1cd7c7dbf3e98a975da943d96edc9401d2321c4f8cad51", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/ConversationalAutomationCommandsInnerTest.kt": "03807e3407dd3d9404c6966cb53786bfc227e00259343daca8a3584da9a018d5", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/ConversationalAutomationTest.kt": "edab4618048fc0506bf3818b063e5be09a0f0b5761fc3063490b640d456e0ad0", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/CreateCommerce200ResponseTest.kt": "a39db5fb1fdfc73546572d9fc03f47273ebc503b3001e723760fd3389606d2b8", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/CreateCommerceRequestParamsTest.kt": "ccf4e020893f7d1f5d2b145feab7032fd0573d7f6b69400969fcc81384501abd", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/CreateCommerceRequestTest.kt": "3a38e7f551ba3b54d71972ed371b7744e7ba05af00f76bf1681b56fdd858d681", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/CreateGroups200ResponseTest.kt": "4e4fae49e42ccecc2ba75c34142b5f30c3b0c620d45739437b99b5b17fda1118", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/CreateReadMessage200ResponseTest.kt": "42bd339f69d9fb50ff397cf51f9d25a907d9ecfde566854d01399c70062e6359", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/CreateReadMessage401ResponseTest.kt": "9193741f75231e9f6ab9671070bc7da8cf3e30e9c313913789386730a73c3ff2", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/CreateReadMessageRequestTest.kt": "1b858ea6170358f23ec72eebf346f8dd363973e52082b69139c966af89e08172", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/DeleteFlowsFlowId200ResponseTest.kt": "f9b0d1b34c734b30dad203626450ff5903916bbb444356f91d988069f197e93e", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/DeleteGroupsGroupId200ResponseTest.kt": "fb34e9faad1b86e29d0c2786f408c5821446e25837bb32ffdb9f6d7ca0a6bc86", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/DeleteMediaLegacyRequestTest.kt": "c46c751e1f552d0271e6deaf9980646c92976875e22e3f1d96d99ac1aa232521", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/ErrorResponseTest.kt": "75c77acaa9c313881f2bd3c70e55a3f16eb3d11f1bb2be24704a8361622e778d", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/GetCommerce200ResponseInnerTest.kt": "c1f87201c0bcfdd575f269cdad5dac3fdfcd510995620bfe74dfcd75db1eb087", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/GetMmLiteStatus200ResponseTest.kt": "73e07091a27b1a5b440c735b0a81eeac274bc38e11a890112901ea240bf9820f", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/GetWebhook200ResponseTest.kt": "ee337a6fafd181aa63c886f0a1dc947fbbf93461d8a8493988387c6cde7b0503", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/GetWhatsappBusinessEncryption200ResponseTest.kt": "d4ba2ac4d4e5fdcd5e9eef13ca3fa140d2b55ee7360086564e225954d4a8c546", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/InitiateCallRequestSessionTest.kt": "ec45d36d8d35d07446ac48f2b23f4788280e826754ac92cc65e51999c99a1f44", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/InitiateCallRequestTest.kt": "46f4fcd6e342d62490aa405a345ecd40b557753d3e3586de0a9de7b573014803", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/InitiateCallResponseCallsInnerTest.kt": "0555eb7fddbc4371e197f7f46484c2ad5f76933436d3a22f9bfffecd19deffe3", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/InitiateCallResponseResponseTest.kt": "dbc4d2535806f69b166552dacd13bd3729de65b096791d31e070a748932130e6", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/InitiateCallResponseTest.kt": "b5bc8f93eb25b906ca48a58fcb3b2b8636d8f6a1b7e25787412a2c3381758cf5", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/ListBlockedUsers200ResponseTest.kt": "dae2dd0ca5440ebea6eda3d569bc44b8e15b1d18fc9461ac98ba0b9bef4f11b5", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/ListFlows200ResponseTest.kt": "1546cedecec10dfcf5e4500aa412f78a9872be2fb4dc81ad2bb1077251c44460", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/ListMessages200ResponseTest.kt": "887945ff2552884d03c08fe5bd588d62066acc7f290ba08ddb5e535537ce17d3", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/ListTemplates200ResponseTest.kt": "5f778d88304052f3ab26e7d4c452fc910761cd8bb0d5ff291a5e5ff483187733", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/MessageSentResponseTest.kt": "87f0ec38694d2c501112ff17dd58e8f92e8b589529829123641cb72f864d9f19", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/PatchFlowsFlowIdAssets200ResponseTest.kt": "b59f4ef7adefbdbe0ae7ebd2d5c3729f61fe7c86db286c08913c6af167377273", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/ProfileInfoTest.kt": "2310afe6f5c1ad3b0fa478a6faf7ff2c32b004b9155f0e818e1882c2bae6d3ee", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/RetrieveMedia200ResponseTest.kt": "98bc982eb87a61aa941c402dfbd4915cb5de853e9ebbe75dc1e16bf81d896ed5", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendAddressMessageRequestTest.kt": "f533dcc6805f80d211b72394c8ae0a791914e6db7cc0a478538fa60a59042ba5", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendButtonRequestSectionsInnerReplyTest.kt": "09ab63c4e1457615ebff4f954c70a7032f8524931c40f84deb0a4627635b491b", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendButtonRequestSectionsInnerTest.kt": "1880589dd9252ba9c426f6786d1cdf6b0610bea643c91a1346a02f3c2b3ffa28", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendButtonRequestTest.kt": "f459c86ce90cf3ed2af50b5d69fa29b8f8a8b73509d1560425b09b8a94df61fd", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendCarouselRequest1Test.kt": "639e636a1d916383b014886820da38e9951db2e5564eed2ae2fe4087f783539d", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendContactRequestContactsInnerNameTest.kt": "e16661a8ff7ca76f90aaf33f9e70f47c779c5b515a1e7087f354b7ca12a56eda", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendContactRequestContactsInnerOrgTest.kt": "ee8f9ff801b42fda3ee17d5cd52497bb5bf697dde3f5011923add76907caec7a", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendContactRequestContactsInnerPhonesInnerTest.kt": "d019e37d00fbaf652f370e15a2f41f0ecd01dbe1db6bf7487f5534fc294ee806", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendContactRequestContactsInnerTest.kt": "e149de7139d7db87decfa995daf9e64b39888d718acb89e39e86833d2b567a58", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendContactRequestTest.kt": "29a6a6363f080f562f24697bbebb85a5a6c3a51e047e5baf90a6cb59df3cb2d3", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendCtaUrlRequestTest.kt": "adc69447459c533e41857d0fe236a42c3a099f034bdd773f0ef8f623a95f2c00", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendFileRequestTest.kt": "a7ae3571ac202a7f009416b7fc6580fb74d65b5149d3fb69b0fb9b0517743b45", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendFlowRequest1HeaderTest.kt": "0b64f5c8cd8586a37252b01109af7ed7a5d7fdefe028de8dbb8bf5ac2a7f9c47", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendFlowRequest1Test.kt": "2623905f9ba06956c65ae79ebdc96ad7aa32eeef5f40593cc38ba3e5d1dccbb8", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendFlowRequestHeaderTest.kt": "5ce4f9f3aef44a972eff88d381e5aba7a57ecf476d9e4e5aa6043a9b6e799538", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendListRequestSectionsInnerRowsInnerTest.kt": "1a8e03525e81c81a3c5fa088d9d4fc97d67c1a7c5d5a65371179219d0f818a13", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendListRequestSectionsInnerTest.kt": "aae54a68d593fe0468a5879ea5b1abd4d044c7730aff7413878b0fe01584b579", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendListRequestTest.kt": "9f3d55142172bd61ddbcbf6344f5a890bfda400e427d3a57729f11379c8cf394", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendLocationRequest1Test.kt": "145bf7a631895d6c393ba150937349db400eed69a6e151f4db649c5d8fe14ca5", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendLocationRequestRequestTest.kt": "5a51e417a9601f03c765bbba6a5f2d187507cbbe2be2c295bc137f267097bc8e", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendMessageRequestTest.kt": "53a0736a16663a55d57159cabaa91cfc19a44a28c4d039bd9a2938e63b63f024", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendOrderDetailsRequestLanguageTest.kt": "aceac494757f68d0f7e182266743a4360a108f888f16a0ef0d8e40219a186d5a", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendOrderDetailsRequestOrderItemsInnerAmountTest.kt": "6941013d7f2772bf8ae42d173ce4983bbc5a052f5c2175518acac32b3be56287", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendOrderDetailsRequestOrderItemsInnerTest.kt": "6f154388a7816e31f704f3c4f4911c098b6a0ecc70c8dfa7b46c8716cde49ae8", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendOrderDetailsRequestOrderTest.kt": "e2aae492989f3eb4288e24a959fb686bfdfa7c8b112946fb78c24120eca781eb", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendOrderDetailsRequestTest.kt": "6303c8c8efc236102936d66c4a34a9d7af9e0ab6ac89c00fd29c9dfac9733514", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendPaymentRequestRequestTest.kt": "780dcbecefe29bc64e545560a4bee270d1fa70a6a8683a9d5ccccdca4dc4df93", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendReactionRequestTest.kt": "d89f64e5b95fec5628cbf3bcbecb8d612112c0e96a998568cdc2436654a89b2f", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendStickerRequestTest.kt": "2fc650347223215a55f25b9cad55b0650d9a83252a5c26f2ddaf0aa4f8a9d905", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendTemplateRequestLanguageTest.kt": "491037ce36be88b1a3f8a40ed6dc320688d271a71979bae19114f5fd36a1919f", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SendTemplateRequestTest.kt": "533436e0b15b55acd66871308bada6dc187e1914acd745c2fdb650b91216266c", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SetWhatsappBusinessEncryptionRequestTest.kt": "5f7832a784c8a20bab0657fecf819fe2ce6b8635921bb31005d3bf3bc43e30ac", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/SuccessResponseTest.kt": "c0e3dd4346153ffdcdd04d4e10f7589743eb9dee62b0d10d9344d2f220ce1d08", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/UpdateCallingSettings200ResponseResponseTest.kt": "541eed32912ff9d5a317f371a6faac08868e573bf6fda990223f3c17b141e468", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/UpdateCallingSettings200ResponseTest.kt": "e24309948a98ace38ac0f9e49c1f7b6454aab92788248acff6072e79d7ae9275", + "kotlin/src/test/kotlin/io/onemsg/sdk/model/UpdateMeRequestTest.kt": "bcd0536bb67f5ad91f93d6e945c04b9dc0a6ff7a90186633be9aa8b6bb5bfe37" + } + }, + { + "id": "native-scala", + "owner": "1MSG SDK maintainers", + "issue": "https://plane.1msg.io/1msg/browse/1MSG-156/", + "expires": "2026-12-11", + "reason": "Native scala generation, frozen dependencies, build and offline contract tests have not been verified. Sources remain byte-for-byte frozen until a reviewed language-specific quality profile replaces this exception.", + "requiredWork": [ + "Pin and replay the actual language generator", + "Freeze dependencies and verify native build", + "Add offline required/optional/error serialization and package consumer tests" + ], + "baselineCommit": "802e13a13a3bb11ec25e68258c3bd0518dec8d53", + "roots": ["scala"], + "files": { + "scala/.openapi-generator-ignore": "a6ed8f4e275eee926d27e0c52f30f2d1c4d8409465ac1fbc4511f7cc62de51db", + "scala/.scalafmt.conf": "7850b3281866564fe2a857f2538935b95edc12e975c6a3c9cc31b0d29343c324", + "scala/AGENTS.md": "d653e746d10331673c30558704ad3f2b095f069cc5c8baee6cf69046d02c75b9", + "scala/LICENSE": "88170a8e4e7b68f13a057d5b9e1882d4b60c71e0a762b5a95651931a219835ee", + "scala/README.md": "80f4a39dc85e58a18b57992ceab6157bb71ca645ab358df87d34d0043af7c905", + "scala/build.sbt": "a68c899920e03585c7b35b373c41f9ffe4307cd9e21328f3ceb1f92e31d61901", + "scala/maven-central.sbt": "bc67307842d8a412cae7597826b78af2318190e417b1e8dc8559275fd1b10b25", + "scala/project/build.properties": "38901e157e1ca1e142d978bc5254ddb83e0f6765747f5668351996fdb606000b", + "scala/project/maven-central-plugins.sbt": "180dea5d939c07113b3f3b254042c35a6eb752de4e3838c47e2133c89c43c93a", + "scala/project/plugins.sbt": "6291ea6660fdcca794cba9a3b5fe06c27da1acfaf3da1f5373430f0515ba5652", + "scala/src/main/scala/io/onemsg/sdk/api/CallingApi.scala": "8065e7034779331d98e1ed869f8fee80b5d003b425a6beec06e083d32361429a", + "scala/src/main/scala/io/onemsg/sdk/api/CatalogApi.scala": "720b115f1c025e02c1dc70cebe83ec27c9b79498acf16235b61a77c87deab1b3", + "scala/src/main/scala/io/onemsg/sdk/api/ChannelApi.scala": "2f5cd4ad21374444291b02e8905e3f3c157d3e735d5fc6bc0c14376873a3ea01", + "scala/src/main/scala/io/onemsg/sdk/api/FlowsApi.scala": "409f8669828b61e44eb797eb4515c5a803a42048162b5f0e12f03456ffa18462", + "scala/src/main/scala/io/onemsg/sdk/api/GroupsApi.scala": "44e0e91fc457cc60d214bbf3c0fabee14a3408a2ce5a01756f474009100f024f", + "scala/src/main/scala/io/onemsg/sdk/api/MessagingApi.scala": "281c0f3edeb879882f5c41ea5df4094ac47810d0b4672357d16d9717b60ce3a7", + "scala/src/main/scala/io/onemsg/sdk/api/ProfileApi.scala": "e41732fd2ba4fba95897cc81af4b4a446f636d417388c52f4f2a780bbb358a73", + "scala/src/main/scala/io/onemsg/sdk/api/TemplatesApi.scala": "296b7f5441cf519e271d3cc9fcd2e372541f39716be7e9eea778342101d89d10", + "scala/src/main/scala/io/onemsg/sdk/api/UsersApi.scala": "a80d8cbf11795b5750aed57e510373b7a0dd1d17ff21d702abde9ecce3ce6cd4", + "scala/src/main/scala/io/onemsg/sdk/api/WebhooksApi.scala": "e1a6355eb0b4e3e321fe6db9ff4b680cc73712e0c6f0ccf220bf22f6f6a0fdf2", + "scala/src/main/scala/io/onemsg/sdk/core/AdditionalTypeSerializers.scala": "356f966fbd466479e47b37f6f01b46aa61d5a15b28ef5cdc233743c01c02b8e0", + "scala/src/main/scala/io/onemsg/sdk/core/DateSerializers.scala": "57de46fc6dde02aca71c4706248a7276a06f04a7d0b6b159c6a6b5ac7fc65d2d", + "scala/src/main/scala/io/onemsg/sdk/core/FormSupport.scala": "e5b41b70562a1acfe448d37e056d0311bee007d4b366409e4255aaee4f6c31ca", + "scala/src/main/scala/io/onemsg/sdk/core/JsonSupport.scala": "6474bd769073cd315c3bbf8aa0b817cde2aaaf21efda81973cefbae30c1c5d20", + "scala/src/main/scala/io/onemsg/sdk/model/AddTemplateRequest.scala": "c4802f3f1686788f4c715b29696282ecca454199328e9d499e6b2b9755aaf05d", + "scala/src/main/scala/io/onemsg/sdk/model/BlockUserRequest.scala": "6b0c742f293b4c7d5ef9a89106ec85da5ab62293b5030465d3f2e3f7e484cdac", + "scala/src/main/scala/io/onemsg/sdk/model/CallingSettings.scala": "d21c66609e11e7f10143298a85b5c8c9393a9a2593d8ce5517689abf00f9ab41", + "scala/src/main/scala/io/onemsg/sdk/model/CallingSettingsCalling.scala": "4b89c2bdcc842c0971003dc0f7882ab3c5f679f07e1968f360f0b5fad7e65a0e", + "scala/src/main/scala/io/onemsg/sdk/model/CallingSettingsCallingAudio.scala": "11dc967ebfde910145d97832569103b2805ac7bca10b4599fdd2c775d92b021a", + "scala/src/main/scala/io/onemsg/sdk/model/CallingSettingsCallingCallHours.scala": "d08da09c4e0d0e7f243e2c0d53173b5e2eb6b06dcbe79fad36b473c632b92b20", + "scala/src/main/scala/io/onemsg/sdk/model/CallingSettingsCallingSip.scala": "5012bfe842ba8ad4115f1b320c3ed2f51fd984a31ded689d4fc018269c4bd650", + "scala/src/main/scala/io/onemsg/sdk/model/CallingSettingsCallingSipServersInner.scala": "0d31fe999082bc00f2a1e0332348f514365d6fad5a33cf155b5e992810fcd028", + "scala/src/main/scala/io/onemsg/sdk/model/CallingSettingsCallingVideo.scala": "d069f4aaff3f0e2c2e6a53a2ea7de0dd804d08eabec3fa85a5e985a65a5a1dbd", + "scala/src/main/scala/io/onemsg/sdk/model/ConversationalAutomation.scala": "c171242788c7ea2b683b5d0b263edb3d14d9e382cab9967905bcfc47f248faf2", + "scala/src/main/scala/io/onemsg/sdk/model/ConversationalAutomationCommandsInner.scala": "3964594614557ae7ab980efcff27767d7225c039e768294e475e5d203f6fa827", + "scala/src/main/scala/io/onemsg/sdk/model/CreateCommerce200Response.scala": "eca2863815899c526628d3fc706f35bcb0fa6f2d4b0a76a8a41ab9da7cabe4a2", + "scala/src/main/scala/io/onemsg/sdk/model/CreateCommerceRequest.scala": "88fe1b76109184f31743ac6807c8b8d36786dade8f6bc27834f03943f927659a", + "scala/src/main/scala/io/onemsg/sdk/model/CreateCommerceRequestParams.scala": "1c6b53ccfb2f0ea08f52ad37e0d439e9a429423e6b2baa58bee0c27a5cf3dc05", + "scala/src/main/scala/io/onemsg/sdk/model/CreateGroups200Response.scala": "6ccff51b3e735c12209fcf1fca4190b1ff3fc1ddebf47a97d772385edb78c2bd", + "scala/src/main/scala/io/onemsg/sdk/model/CreateReadMessage200Response.scala": "1b93a650c2e4b5b9986de86ae620c2187413649e0ac6eb0aa670693c9724b7d0", + "scala/src/main/scala/io/onemsg/sdk/model/CreateReadMessage401Response.scala": "e6b205c4f9cae89f188da3877f58f674f43b7f51f5fe0bb10be48f0b1559eb9d", + "scala/src/main/scala/io/onemsg/sdk/model/CreateReadMessageRequest.scala": "0fbccb0cdab4a3f3b85a1e4b5654507ab5fbe8a9db27e04d8e0c143e374cefb0", + "scala/src/main/scala/io/onemsg/sdk/model/DeleteFlowsFlowId200Response.scala": "8bccc36bb434e286ce429546a8e1d0dce6853329521f071a74b9c486b1060a61", + "scala/src/main/scala/io/onemsg/sdk/model/DeleteGroupsGroupId200Response.scala": "582439ab4137e6c90c34764056d79cca71717eb49926b5885b464479b0eddc85", + "scala/src/main/scala/io/onemsg/sdk/model/DeleteMediaLegacyRequest.scala": "eb8ae81e4f0c0ee51ea3e0eeead65b7ac5780764fdcf93bb48d0d804333665f4", + "scala/src/main/scala/io/onemsg/sdk/model/ErrorResponse.scala": "128817a8f01a6cc74e45dbc08bca7c0a0285f2024ba8a26670aa28cf81cd7e6a", + "scala/src/main/scala/io/onemsg/sdk/model/GetCommerce200ResponseInner.scala": "a0bda39f7f2c66d4523e7b92b44cb14d65e557387adf2d1f6c9ce29bec318a9e", + "scala/src/main/scala/io/onemsg/sdk/model/GetMmLiteStatus200Response.scala": "df15c03245329a046a47372d64707464865eb02b279b2eb6f2ea47289978721b", + "scala/src/main/scala/io/onemsg/sdk/model/GetWebhook200Response.scala": "028b8cc16e1b9821e86dd627ba8d901a16fb49103fb7e0355424469715ff5759", + "scala/src/main/scala/io/onemsg/sdk/model/GetWhatsappBusinessEncryption200Response.scala": "717d084459e9af1741b5f400f685753960cf3aa8acb6a6015a7e56b82f91ae0e", + "scala/src/main/scala/io/onemsg/sdk/model/InitiateCallRequest.scala": "9bdf56e23bdebc26c3b547a000b258a5af15bdebcf146cce08ee378b607d4daf", + "scala/src/main/scala/io/onemsg/sdk/model/InitiateCallRequestSession.scala": "c78a3b0134e119bb892f85115f33eb19c07b765fcbf656aec8389c1027db15f9", + "scala/src/main/scala/io/onemsg/sdk/model/InitiateCallResponse.scala": "4a443b1da584bad1b823cfa5e1af23ba4fb492ac912a600ee817444268c6bb69", + "scala/src/main/scala/io/onemsg/sdk/model/InitiateCallResponseCallsInner.scala": "9d0d7b2bd1bbcea43bc50118e1f7e37897690bf35fd87b468bbae774fa0ec168", + "scala/src/main/scala/io/onemsg/sdk/model/InitiateCallResponseResponse.scala": "90a46b565942504299543e6ed0b1b58ca20a56df528376e7a49d03d933a874a4", + "scala/src/main/scala/io/onemsg/sdk/model/ListBlockedUsers200Response.scala": "04905c442471bf29dcfdfa56dce5f4b833d6e1267c8eec2050b35865adbc01db", + "scala/src/main/scala/io/onemsg/sdk/model/ListFlows200Response.scala": "622051dd442a4a756a363c23192045b5c2578ac050236522e1d5cb1128affc84", + "scala/src/main/scala/io/onemsg/sdk/model/ListMessages200Response.scala": "be292543600caf2b1b8da14c67a8987d55f05e1807f9debafa8c564ec08da96c", + "scala/src/main/scala/io/onemsg/sdk/model/ListTemplates200Response.scala": "2a8d1e186ec873bd6e6f6721bdf25e897f1e7a21dcab11706a84101ecb1e84d7", + "scala/src/main/scala/io/onemsg/sdk/model/MessageSentResponse.scala": "106a75c02c1393f6ff1958331b102934da9fe8f4d0e50501e79450338f2d0619", + "scala/src/main/scala/io/onemsg/sdk/model/PatchFlowsFlowIdAssets200Response.scala": "222d76783f5476cec3335cc972631554853e610f99db3c11b450b368fa49e732", + "scala/src/main/scala/io/onemsg/sdk/model/ProfileInfo.scala": "cf74d5127b6d8991d5c502254c861a0e394083f9232bc1792258963208416b4a", + "scala/src/main/scala/io/onemsg/sdk/model/RetrieveMedia200Response.scala": "7bcc7a053f3d82141df8592a9fac543d2be0e9eeab45451d6ca91d591da9a4ab", + "scala/src/main/scala/io/onemsg/sdk/model/SendAddressMessageRequest.scala": "0071b6dabb8948316edb2340a28ef7e5f8ae6a82cb8673d705c5ed73e394b262", + "scala/src/main/scala/io/onemsg/sdk/model/SendButtonRequest.scala": "dfb81b45b4b000b5bb0d9fad8d3e7fe69b697e9259427261a0af6f8471c3eb56", + "scala/src/main/scala/io/onemsg/sdk/model/SendButtonRequestSectionsInner.scala": "6f2f22e45d853670264649da2f9d76d2d820b6a7a39d2e5c0915c06701ba5bd6", + "scala/src/main/scala/io/onemsg/sdk/model/SendButtonRequestSectionsInnerReply.scala": "f56b2700f3252fb8dd5bb3bbd3367b302cc8beea346ebd0146bcf6d72d5a8431", + "scala/src/main/scala/io/onemsg/sdk/model/SendCarouselRequest1.scala": "ef8b0596d03020afb42a4d3fe004d47309607884c62946fb2b81d27f2c25c8ca", + "scala/src/main/scala/io/onemsg/sdk/model/SendContactRequest.scala": "42b65717e5e8848fd8da879ab80731cf71cb5c535a2a4c50c7b3f5fb0a1717ad", + "scala/src/main/scala/io/onemsg/sdk/model/SendContactRequestContactsInner.scala": "af2db02c9f082dbe9443781fedf7dbbdd8439aa0979ef52ec292b2d5eea80508", + "scala/src/main/scala/io/onemsg/sdk/model/SendContactRequestContactsInnerName.scala": "c621370389ed8acda4a015efc062c5662acb213d9788c68c001e77ac3a6f8946", + "scala/src/main/scala/io/onemsg/sdk/model/SendContactRequestContactsInnerOrg.scala": "6f156857e1158e95f44b9fc12769743459a467e046ddb4429bc41166039215d3", + "scala/src/main/scala/io/onemsg/sdk/model/SendContactRequestContactsInnerPhonesInner.scala": "b0f2d46d12f833e8e6c9d521e6acacb7197ff348a03d085ae110b80eb8076f86", + "scala/src/main/scala/io/onemsg/sdk/model/SendCtaUrlRequest.scala": "39909e90fb6e1abc2de34d12ea0274ebb44e51091876fc7871cf7d14b1323beb", + "scala/src/main/scala/io/onemsg/sdk/model/SendFileRequest.scala": "4be4916451a2564c4e8def34f67310ebc378f23edc0fa570ccb8172c4e84049c", + "scala/src/main/scala/io/onemsg/sdk/model/SendFlowRequest1.scala": "951b0e9aec4153626effebf33d8f133351e29c1a1ffa25362b7403280f821768", + "scala/src/main/scala/io/onemsg/sdk/model/SendFlowRequest1Header.scala": "1f92f747c0e0a3bb0428e45cc9f2ea2207e26650fa6d60d7163fece6f0c57e90", + "scala/src/main/scala/io/onemsg/sdk/model/SendFlowRequestHeader.scala": "b410b1e5c9a75fe2d968db6fbe747449ade847545085b58c636851f1d0aadb26", + "scala/src/main/scala/io/onemsg/sdk/model/SendListRequest.scala": "fafc3fa006d02619048eb9e877c3ab6742aa95f417e8f10d7654d277ffc0588b", + "scala/src/main/scala/io/onemsg/sdk/model/SendListRequestSectionsInner.scala": "5f060addb69f0c2a062ab13a5c0b68c73c0ab3ab895a9944f4f79a3b9013a49a", + "scala/src/main/scala/io/onemsg/sdk/model/SendListRequestSectionsInnerRowsInner.scala": "3ef3954702bf1c41252fdc01f72f9b407da1b42632b1b93c56fdbae59bd1cbce", + "scala/src/main/scala/io/onemsg/sdk/model/SendLocationRequest1.scala": "13924b5f2fd35d709a50af2a73ea73589704d3ba842390e30f6fdfe2b06566d7", + "scala/src/main/scala/io/onemsg/sdk/model/SendLocationRequestRequest.scala": "b13bcd387365b157293389f1d2a5f6c174a8dcc5ff5a9db0a8043536726676d8", + "scala/src/main/scala/io/onemsg/sdk/model/SendMessageRequest.scala": "1d703316cd0ef52134db5b22061a4407fbebe16d91bd66550efd60f8d0fc3e8b", + "scala/src/main/scala/io/onemsg/sdk/model/SendOrderDetailsRequest.scala": "54d0bca20b9246e4ef0d999eade903f68383da1e8af11fd7810f071b1b43b13f", + "scala/src/main/scala/io/onemsg/sdk/model/SendOrderDetailsRequestLanguage.scala": "11a02d86be3a087bc3506fd2957021d7864b7e14418c3a84c8d130b6bc8a2d0b", + "scala/src/main/scala/io/onemsg/sdk/model/SendOrderDetailsRequestOrder.scala": "9a3500c2448bf461eb654f3ae80212e762fb759a4554ae1d99e87aff519df61c", + "scala/src/main/scala/io/onemsg/sdk/model/SendOrderDetailsRequestOrderItemsInner.scala": "6b60ecb1a50de78a3d5332284c4cc257c89ef01cc0d3e33bc55785d4ddd52681", + "scala/src/main/scala/io/onemsg/sdk/model/SendOrderDetailsRequestOrderItemsInnerAmount.scala": "fec659e73740b0c9a49bd3dd06b95582829c5954a581fcc9e26602a72775dc4e", + "scala/src/main/scala/io/onemsg/sdk/model/SendPaymentRequestRequest.scala": "a5e38bd8b0c72e9e1569110d6b228ca2526da71a2f95dac5ac775a68f45915ca", + "scala/src/main/scala/io/onemsg/sdk/model/SendReactionRequest.scala": "6c098d262e73119de175a81be09544d1eb0355112acf646c4c0d58d3302369da", + "scala/src/main/scala/io/onemsg/sdk/model/SendStickerRequest.scala": "1c7d6bd6a75ebd03be40fafbe32b2397e5d24423ee34a673c8548edf455b953e", + "scala/src/main/scala/io/onemsg/sdk/model/SendTemplateRequest.scala": "868f5d260d493e971cf821296b7cd883308af3792d93bd51c3968b279266b023", + "scala/src/main/scala/io/onemsg/sdk/model/SendTemplateRequestLanguage.scala": "6661938db4688a6736088a2e3f8f70d4eda8be2c363b9055bebc1e94fa17b4f2", + "scala/src/main/scala/io/onemsg/sdk/model/SetWhatsappBusinessEncryptionRequest.scala": "08902193ae41caab57753654fb08fb2a9ec95e0f2019a0100dfad1dcc97e9ce3", + "scala/src/main/scala/io/onemsg/sdk/model/SuccessResponse.scala": "62e93269aac81a18f5cb47f05e9f17d0487211fed3c806ff22c9fbcd47c7927d", + "scala/src/main/scala/io/onemsg/sdk/model/UpdateCallingSettings200Response.scala": "7e96e3bcf6af2355377f36441a7eba583a6d5360b6dcdc63d5d4eb49c77666ca", + "scala/src/main/scala/io/onemsg/sdk/model/UpdateCallingSettings200ResponseResponse.scala": "0387f9745b1c6bbbe592015c1b8e00a2525e754a7f90bcd3ca1520e51472bfdf", + "scala/src/main/scala/io/onemsg/sdk/model/UpdateMeRequest.scala": "1c23c992d86774dd90cb2cd1415304c3c4b6f385d8f318bb775d49075f99a093" + } + }, + { + "id": "native-csharp", + "owner": "1MSG SDK maintainers", + "issue": "https://plane.1msg.io/1msg/browse/1MSG-156/", + "expires": "2026-12-11", + "reason": "Native csharp generation, frozen dependencies, build and offline contract tests have not been verified. Sources remain byte-for-byte frozen until a reviewed language-specific quality profile replaces this exception.", + "requiredWork": [ + "Pin and replay the actual language generator", + "Freeze dependencies and verify native build", + "Add offline required/optional/error serialization and package consumer tests" + ], + "baselineCommit": "802e13a13a3bb11ec25e68258c3bd0518dec8d53", + "roots": ["csharp"], + "files": { + "csharp/.gitignore": "dcb5ba5843cc20e74a9b9f1220daee080768b19b5ce26b01800dea797b52f391", + "csharp/.openapi-generator-ignore": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "csharp/AGENTS.md": "c41cc5deef805c749f7ad167d2e6c7b844e46e76c3997fb84e41192f1c6812cf", + "csharp/LICENSE": "88170a8e4e7b68f13a057d5b9e1882d4b60c71e0a762b5a95651931a219835ee", + "csharp/OneMsg.Sdk.sln": "24c15ca61830bda95d6c5cd3b13e4403bb07f77f422331793d965654838d22c1", + "csharp/README.md": "4b5b0e298227800df2b69b5ee8a7979435ea9a977c0a4f414869c5972cf960c7", + "csharp/appveyor.yml": "3655140080a56d7e305e5ad702ecc596a9c289ede319efb4b3db14bd59413b02", + "csharp/docs/AddTemplateRequest.md": "b8a56f37e747954f892fb6cc722f1a3438df381074a6adf5751172fa61cd8952", + "csharp/docs/BlockUserRequest.md": "c7f5e4d7b5abb2ce12c7a187ac302ca0bb04036e6d39e30a89967e3385633a62", + "csharp/docs/CallingApi.md": "5f252e5386ffb79a9820e7b6ac18a8b9ccd650dbacba0c5a787a5a020bb37bdb", + "csharp/docs/CallingSettings.md": "b69eb365d791068e8d38db0785cec319c6c539d56441099f7ba0cc393fc3aa7b", + "csharp/docs/CallingSettingsCalling.md": "cb54394832d82e806f2ce1102c2b0bf865905e4082a8a6c2062823d6b96ea449", + "csharp/docs/CallingSettingsCallingAudio.md": "57d4f9ca8ee06ec22c8c6860e1037bb55b6dc4d002bc6fb99fec1aebbce93db6", + "csharp/docs/CallingSettingsCallingCallHours.md": "2966ffc31db355877f34f4afdb75f8e471d96a6a0c5a429e815b20cbaa64f826", + "csharp/docs/CallingSettingsCallingSip.md": "30bdc5f555f35632a03a074c8313ebb6ae713dcc0db31ceae62d1c8adc6be6b0", + "csharp/docs/CallingSettingsCallingSipServersInner.md": "48e7406a673c2c1030b8e2e166a3e3f9e4ef123213ba25094bddecbb267b6f9e", + "csharp/docs/CallingSettingsCallingVideo.md": "782dc197aadcf66e824ea97d4e44c0d50cc896b0441153ba39781508f6f357eb", + "csharp/docs/CatalogApi.md": "8ee8e7fa9835b6241b43effe2f29fcdd25b936b0fdbd5155b5bf896c87bf2099", + "csharp/docs/ChannelApi.md": "13616fbbb6c4907ffd6f4471f75284e2eb6c71b13a2c046f70fdd9ec7933088f", + "csharp/docs/ConversationalAutomation.md": "4864fb0ea4682610644ce9f20aa7f8f52078ea79cc0a7462bbff3a8a02b9f706", + "csharp/docs/ConversationalAutomationCommandsInner.md": "9c9f7c9d5ceeeab1b55966d87cad22732cc1ddb426446b2536c7a4f7eef3dd1c", + "csharp/docs/CreateCommerce200Response.md": "6d73eb91ff255222e9daa31008a04a056eeb77aaa1588e430a7e22e9ddc20716", + "csharp/docs/CreateCommerceRequest.md": "8a7e083ed97b68eea79336e586f51e5cefa28f8ee9307e8ef9bb497677e1d6a4", + "csharp/docs/CreateCommerceRequestParams.md": "2c730536f749d886263fcac00d0160958dcdca464f8fe735fc750aa1d24f3f15", + "csharp/docs/CreateGroups200Response.md": "19c15c48ad9893236ab98537822b4a6a69f34bf5e02f6e4f20f93cef65bda3b8", + "csharp/docs/CreateReadMessage200Response.md": "780950a919c55dd1019ccf0f0397b0818699be0847417c09651afe769faccd5a", + "csharp/docs/CreateReadMessage401Response.md": "3d0edf37043045f6f0fa0ae60bbc9c3f298ec7d8a773fa0f818de25b37158377", + "csharp/docs/CreateReadMessageRequest.md": "b00ea0b572e25d311e5cd5c1ee990b22a3d6f37c8c43b0102c6edb93d3d30f38", + "csharp/docs/DeleteFlowsFlowId200Response.md": "0af82eaa0e73317d09256b41805e9ebb99f2f372cec4c2fe7762e68f0591cae5", + "csharp/docs/DeleteGroupsGroupId200Response.md": "df7cea19182768f50f212eddf6d309fc8e81dd44b3746d57efc9ee7382fbb85b", + "csharp/docs/DeleteMediaLegacyRequest.md": "2b5db93f11e1c8962740efdb26a897b84f00809b3ee80dd172108f6252717e53", + "csharp/docs/ErrorResponse.md": "73ef7be56e21afcbf7c0b61c6603c10bb2e37c2bfef6f7c8cac086b454668996", + "csharp/docs/FlowsApi.md": "00ea22742eb1713228076079d19fb51a88434a139d5c82b1e3346f1f11719761", + "csharp/docs/GetCommerce200ResponseInner.md": "bf3e0f057794dfdc04f084ae39e358fc43488a1a341428f9ccfadf057bd468d8", + "csharp/docs/GetMmLiteStatus200Response.md": "588734bc83c0ab5e1838faae999e4204916c42c3e913b008e7deae5fd5f00723", + "csharp/docs/GetWebhook200Response.md": "dbcc636b876a617b0ee3f0cf4e1b25202112f07ed371c49344c5c5ce71ed156a", + "csharp/docs/GetWhatsappBusinessEncryption200Response.md": "c72f5bc95c5646651c22568bbe611a6547fbaeb80a84a34302f4d4a0fa1c9496", + "csharp/docs/GroupsApi.md": "d1c533dab37261ab00253a98a082fb7a3928fcb0acdeed113bdf7d28ad5b8e14", + "csharp/docs/InitiateCallRequest.md": "2ac9bb09e7c3d1d8bcf953306e78a637e1d400c491a95db2a7d3ebe0f270a49b", + "csharp/docs/InitiateCallRequestSession.md": "cac41ed7e33e86b077153856822f6d844d687e5c64cbda427a9d4bc9a2361cc7", + "csharp/docs/InitiateCallResponse.md": "3ade1643955a2936576603c57efac5a70564cc846fd9c0c6e62ae94ba4d9661b", + "csharp/docs/InitiateCallResponseCallsInner.md": "894b18374ceb6f692c46dc2e64446165e7fe450e740e14ed64c195f224646487", + "csharp/docs/InitiateCallResponseResponse.md": "f7d5d43f2419d4f9d2fe1e9585aa160f3f6da7c48cc2aa28ebe02f6e2b959920", + "csharp/docs/ListBlockedUsers200Response.md": "0b74101650c8bf11c37253c49c2d77e378e80c877550b53589c79692a0c71fa8", + "csharp/docs/ListFlows200Response.md": "023c8689c04e8be3f0226835b1b8e54a254467b1712930dcd5aef1cca136ca51", + "csharp/docs/ListMessages200Response.md": "fd74372a6c8397e15202ce07640cd69d516dd06862de58679b1cad1e7b74266e", + "csharp/docs/ListTemplates200Response.md": "1facb0ce9936820bd907c876475fcec0f8cf72b02562ba046d11c77da161d638", + "csharp/docs/MessageSentResponse.md": "62390b84002e60575950735704e09772283ee5e27fb1570b05cee5f7f603efdf", + "csharp/docs/MessagingApi.md": "0523af6f32adae8951fb83769d0d70a45c993e40a8ce8356c9ad7f7008933e48", + "csharp/docs/PatchFlowsFlowIdAssets200Response.md": "9262f7d7e352cbb52016de79a94751927bbd94f450a995d8d1eb1f997f311975", + "csharp/docs/ProfileApi.md": "f9a41edbe61e87f3543c5e3b1c76f6fbf7951ecc6cf37f734666b0e5a87b3076", + "csharp/docs/ProfileInfo.md": "cac7036500b3b2d784325f2e1cae8361aed2f79bdc4bb12505f2fb724e2198be", + "csharp/docs/RetrieveMedia200Response.md": "816b1fec2a587bb37228a040425b973eb322b21a674666fe950099b6d506f4cf", + "csharp/docs/SendAddressMessageRequest.md": "45b10203645137fb5651a99ccfda58652655d3fc39419ff9562df2ef65b97e84", + "csharp/docs/SendButtonRequest.md": "4a9c64ff3e426d5670947697dc293a8e36d85dda29a216973db2e15136c3f62c", + "csharp/docs/SendButtonRequestSectionsInner.md": "28690f5f50ef01d05ab85db81e37f5e7fe27027b5e81e4c33a30f5b48f669d70", + "csharp/docs/SendButtonRequestSectionsInnerReply.md": "017aa84182c7f98cf4034887b760ff80e300d11a6a6b4899170e9ccc7b7af9aa", + "csharp/docs/SendCarouselRequest1.md": "087ef2f613ca01caff2df12a016b213143d24d04c31f7fd412adbb07406ad60b", + "csharp/docs/SendContactRequest.md": "d789efc2c7cadfd6d90085bd104985e3373c720c0fb113fe607752bfd57314d7", + "csharp/docs/SendContactRequestContactsInner.md": "096f6f778857954d5b4e1e77ce900862354b20a74451f1a1711d4fb23b6ab0ad", + "csharp/docs/SendContactRequestContactsInnerName.md": "bc24b41cf885c1d629e652e93d43eb829017d36d0af343d3afb0bda6b124dad5", + "csharp/docs/SendContactRequestContactsInnerOrg.md": "7d8408c44b022cd628e06daaf93a0d9f0bf1806fe5d6c757ac36db8ad89a334e", + "csharp/docs/SendContactRequestContactsInnerPhonesInner.md": "1667b1f5befc7cb78825865702f7c3bfc0203dea366a9fdec634a85d85bbe4de", + "csharp/docs/SendCtaUrlRequest.md": "84a1a9f367a3fa44f231f755dda14a6e1a9110b85644eac383b64e41dbcb9347", + "csharp/docs/SendFileRequest.md": "80a465f427f9983c284b836500882aa7c41c1f7cd2e3359d681d2cf60f4618b8", + "csharp/docs/SendFlowRequest1.md": "9644a3bca38522b931cc519f6e100aaadc462882b211406098736ac67d2ed084", + "csharp/docs/SendFlowRequest1Header.md": "73e8fa0b050ebb8414b906e3d643791382dcfcce59f95b3e8ee230d4559bbadd", + "csharp/docs/SendFlowRequestHeader.md": "50806afa23b54611b7dee7c14a0cad86943a422963abe25dafe2d27ec71dd03f", + "csharp/docs/SendListRequest.md": "197ff1815c7aa273939acf5ffa149c5adcfe61ee2662a56113d3d17d0e73642a", + "csharp/docs/SendListRequestSectionsInner.md": "350ce8533ff3b544a4dcfc2473a9f02a08bae002a83d53963eb0778048ac81ed", + "csharp/docs/SendListRequestSectionsInnerRowsInner.md": "c983f174c2b02cd1ecef0ceda5c6e6d1f1d6241041791f61b2ef574b00b7db0b", + "csharp/docs/SendLocationRequest1.md": "ba45965453879e93f6ea9040b53bf2f29f56315b40df0ed04bd06f60f4d8a470", + "csharp/docs/SendLocationRequestRequest.md": "85bdcd5ba8732303408b3e51e68ecda4ae76b06562b0c12b1409dbcfd8ba3def", + "csharp/docs/SendMessageRequest.md": "082387b85f3388d4041a97c43d7cd81605b39b5a6dff1d002f947aac4dbe454e", + "csharp/docs/SendOrderDetailsRequest.md": "d0cc8274f3ba00cc3387d3a1aa5c3ee14b4b82355a69a501a198c8022690e775", + "csharp/docs/SendOrderDetailsRequestLanguage.md": "1779e5c596527aa6ee4de9c379ea679893a2c985fd7fd3da6d06ff26f5d07e2d", + "csharp/docs/SendOrderDetailsRequestOrder.md": "d3f83bfca0cf234d1c7cb0fa69eb49677dfad7fd9c2ddcce0ee1b4a45fd7e179", + "csharp/docs/SendOrderDetailsRequestOrderItemsInner.md": "be068e01888fde18271d8f97038cc991746e694304cde5f2be703a41e6e09a21", + "csharp/docs/SendOrderDetailsRequestOrderItemsInnerAmount.md": "e3e40f75d904276bdcc6c022f26cc42e47413e85354b928b1f9e0f36520615af", + "csharp/docs/SendPaymentRequestRequest.md": "d9222b18dab50b3b61c1a31468196a07190022a1946f0fc0897b7f852d5b2083", + "csharp/docs/SendReactionRequest.md": "1d342ffa4041ebd092414514b3a7f16be888b638d2c65fa9aae0746188855d84", + "csharp/docs/SendStickerRequest.md": "fa240c76cb78e61504c3d6ba911e2d098b9a33a8048953ec2a4c9451baebcdbd", + "csharp/docs/SendTemplateRequest.md": "4a96cd81656fcc4fcdfb7488e685d0748e8d0579942a4d9ea67314e7dcb7b33e", + "csharp/docs/SendTemplateRequestLanguage.md": "33a4150ad8a3b14ab8828687ceb04ee2162a4b6663fd3cace8a5f2b608e9383b", + "csharp/docs/SetWhatsappBusinessEncryptionRequest.md": "5366347dcb0b5a0bbc50ec280292f57a71caff03fab573c8dc4b60369c514865", + "csharp/docs/SuccessResponse.md": "f315aade96d346983bcaa090ec209fe4ce38ad5d079b6763f7d507027f7da3aa", + "csharp/docs/TemplatesApi.md": "a3ab2fa0f66d097a526416232f12d23146624a6931cd5a2843a483a545d51668", + "csharp/docs/UpdateCallingSettings200Response.md": "2ddb0171560543b607b332736ed5f1d64af02a0e1b7b701975e626414aceca29", + "csharp/docs/UpdateCallingSettings200ResponseResponse.md": "0f6d140279991c2cb83df9dca7d177398896e2f5af0fc3add828f3f3c1bb432d", + "csharp/docs/UpdateMeRequest.md": "43c64cb12de30d5b3cf153855d5de851e2e7e6273e28d897d58c8c9cf477a9ce", + "csharp/docs/UsersApi.md": "db8f2f6511fe49e602a8c61f16e80f5c9e77a74bd9b76252721884c6f604ff60", + "csharp/docs/WebhooksApi.md": "7482796f6a03090e5826c7d7d7fff0bb42293c72a6d1e668124103ee7b2e2f32", + "csharp/git_push.sh": "9b8b2e7dcae7d87ff8c3098e9391771df54d533daca205f6473b7e2c2dce86c6", + "csharp/src/OneMsg.Sdk.Test/Api/CallingApiTests.cs": "e7642ec137539ced03a94fda80758837ddf49f474539bbe3b340a6419d83d324", + "csharp/src/OneMsg.Sdk.Test/Api/CatalogApiTests.cs": "0eeff4985f7d1aa0f0d72697cc62746de69aa740b4b08145db6a74ff38e3dabf", + "csharp/src/OneMsg.Sdk.Test/Api/ChannelApiTests.cs": "22d4bcb20ee561cb69785139728bb9d6c0299f9388706b28aea8542e4e39d625", + "csharp/src/OneMsg.Sdk.Test/Api/FlowsApiTests.cs": "3429467353766819e66ad0681be5f030a75258f189d93bb09ccb3346fb515777", + "csharp/src/OneMsg.Sdk.Test/Api/GroupsApiTests.cs": "36fc7c9b5095a068f4c810b579ead7be273877ca1a17f1ed1f164cfd28b2f3ef", + "csharp/src/OneMsg.Sdk.Test/Api/MessagingApiTests.cs": "b50d60a631fd302636f103fd84dc3665a37ce2ba95db8b2f8b569894d797e114", + "csharp/src/OneMsg.Sdk.Test/Api/ProfileApiTests.cs": "bc8c447f8fe0d16a44fa27800533f90846428a93ed13972a7cd9d748f1c998c6", + "csharp/src/OneMsg.Sdk.Test/Api/TemplatesApiTests.cs": "c22a5991a6941fdf2389f4d83f201f1a4eba8581a468d7a8473f23953cc611ee", + "csharp/src/OneMsg.Sdk.Test/Api/UsersApiTests.cs": "e98038d1f7c64169d7c8fec8edeef28328a8ed4eb1eec65f234e1b99479c8f5e", + "csharp/src/OneMsg.Sdk.Test/Api/WebhooksApiTests.cs": "040bc86e9bb3c398265f683056ffce304f66184f976ac4e2e76b157e9b9ab742", + "csharp/src/OneMsg.Sdk.Test/Model/AddTemplateRequestTests.cs": "d2c20cde4fc56fb2132e7e3b604c6435f5c1e9b474924f0b875cc7bf7d4aa963", + "csharp/src/OneMsg.Sdk.Test/Model/BlockUserRequestTests.cs": "d51268bcf400e981db88ea6d9b6a3502a6a5306cfb7a1750283c69c3c9150fe0", + "csharp/src/OneMsg.Sdk.Test/Model/CallingSettingsCallingAudioTests.cs": "f6a6552545a50b625ef658fa7a82a61ed51fb54bfd863d6af1dd28665dddf015", + "csharp/src/OneMsg.Sdk.Test/Model/CallingSettingsCallingCallHoursTests.cs": "c561d1c739fb29e150b3096e8019ac5ba37139552b2776ed00148b1ff7aec69b", + "csharp/src/OneMsg.Sdk.Test/Model/CallingSettingsCallingSipServersInnerTests.cs": "2711ade35cabf5418b5b241d42a5ffa881c02a7550a522d6fc30eb393ecdac7e", + "csharp/src/OneMsg.Sdk.Test/Model/CallingSettingsCallingSipTests.cs": "65e4aa19bb0a8ec08c61c4a5ce9c0dfe66fb3ca0f1bf78941e6a4b95c63aca57", + "csharp/src/OneMsg.Sdk.Test/Model/CallingSettingsCallingTests.cs": "15d30852deceef19494f91ecb5700f386c039cceb49c571b346905b294943fa4", + "csharp/src/OneMsg.Sdk.Test/Model/CallingSettingsCallingVideoTests.cs": "c2dea60e02ccd284f8cc1bc517c398f6d7f15bcdab1fde495d6fc3904c9c676f", + "csharp/src/OneMsg.Sdk.Test/Model/CallingSettingsTests.cs": "d8e2dd68d6c37cf5e4cd6eb98f0ecbe6570e3852205c85f22ae3139e0ef674c1", + "csharp/src/OneMsg.Sdk.Test/Model/ConversationalAutomationCommandsInnerTests.cs": "4cd7927630f63f3e477d650e12d8961e2b3bb3d06547e089135b8a3d7f6bc437", + "csharp/src/OneMsg.Sdk.Test/Model/ConversationalAutomationTests.cs": "b988ef7e47fa94153379eff3e27c6e33eebed18171acf5c22e6a402a409afa58", + "csharp/src/OneMsg.Sdk.Test/Model/CreateCommerce200ResponseTests.cs": "ec2448ce1c86da83622d8b25df3b205042dc23ef3955cd4cb243dc519fdb0089", + "csharp/src/OneMsg.Sdk.Test/Model/CreateCommerceRequestParamsTests.cs": "39fa8ec08da32ab797f4393debf87a5d865a45a4d08cd232bfc7e0cfe3265ffb", + "csharp/src/OneMsg.Sdk.Test/Model/CreateCommerceRequestTests.cs": "56fc8731c74abdb14fab9c87cc8a2a572993cba17c2051eec63341fb613b58eb", + "csharp/src/OneMsg.Sdk.Test/Model/CreateGroups200ResponseTests.cs": "7e3246ce265d0b21654250c57ddd4fa9b216a15702edfa1e15db69fa3f2c693e", + "csharp/src/OneMsg.Sdk.Test/Model/CreateReadMessage200ResponseTests.cs": "2ad15d5aa3eb09a333652f86eeb7a07ce510329e11c7cd78d4b1983643328d7a", + "csharp/src/OneMsg.Sdk.Test/Model/CreateReadMessage401ResponseTests.cs": "fe30398f0ccd7f08bb0f1f91bf0cee9f8eb3866307e1b0413713c11ff14320f8", + "csharp/src/OneMsg.Sdk.Test/Model/CreateReadMessageRequestTests.cs": "6affd39900f272b3cd3e98ed1b246d764b2a4534c8bb51d73891a714bdbafc7e", + "csharp/src/OneMsg.Sdk.Test/Model/DeleteFlowsFlowId200ResponseTests.cs": "7c69fcccaf8f51cf234d2b9c366636e9907bc5bef2d89c24913e8bbc31be4f8d", + "csharp/src/OneMsg.Sdk.Test/Model/DeleteGroupsGroupId200ResponseTests.cs": "762f92ef822ad4efd2f099030d3897dded818d9a5fd7acbfc8b1fe5fb7e0e582", + "csharp/src/OneMsg.Sdk.Test/Model/DeleteMediaLegacyRequestTests.cs": "2695b2326fc091264a528ff7ebf85935ff4ab75fa224a2f50158f4aeb71945c7", + "csharp/src/OneMsg.Sdk.Test/Model/ErrorResponseTests.cs": "6bb94d51cabd46ddede5c775b2085a2560c03ccf2823c4b7a35920638b2cbbb0", + "csharp/src/OneMsg.Sdk.Test/Model/GetCommerce200ResponseInnerTests.cs": "5cfa007d7da6242a4daa25f90d83dccac2ce83f795638efb00a68dbcc8cd7c27", + "csharp/src/OneMsg.Sdk.Test/Model/GetMmLiteStatus200ResponseTests.cs": "f50dc78d6cc2e04daa32c9c3d20085c4de57cfa84e506f0bf6117c5b645b4f68", + "csharp/src/OneMsg.Sdk.Test/Model/GetWebhook200ResponseTests.cs": "b64c2599637620e68fb515d8644b924df6f12422ab63ae097ce145fb8fc3b9d8", + "csharp/src/OneMsg.Sdk.Test/Model/GetWhatsappBusinessEncryption200ResponseTests.cs": "70569591bfff09ff230ed49436a9abaf4003392e31ba4a8863b9fade3e341f91", + "csharp/src/OneMsg.Sdk.Test/Model/InitiateCallRequestSessionTests.cs": "8e4e039d913027d584f90935cd703f473399a97099cdd05753e6e6b3300b3626", + "csharp/src/OneMsg.Sdk.Test/Model/InitiateCallRequestTests.cs": "fe3440debd465ab07e0b4de1120c038f52e2d928494f08c0481c18279dd90e4f", + "csharp/src/OneMsg.Sdk.Test/Model/InitiateCallResponseCallsInnerTests.cs": "1c4866caa041a82eb48a8e0b1faa1346878cb4206f6d0d15ed151f4de71081e9", + "csharp/src/OneMsg.Sdk.Test/Model/InitiateCallResponseResponseTests.cs": "13955dabf21727cf52fa1d8e440f28fa9dbf171b3bb43bdeae1bda6be1742db6", + "csharp/src/OneMsg.Sdk.Test/Model/InitiateCallResponseTests.cs": "598b6e4143335655ca61e1f0e700395a81c4bb2664f9ed84699e3f0725326eb1", + "csharp/src/OneMsg.Sdk.Test/Model/ListBlockedUsers200ResponseTests.cs": "4463164fc5103fd5e93ddf75a646598e4b8613ac5f96c509f486a49cd89c7475", + "csharp/src/OneMsg.Sdk.Test/Model/ListFlows200ResponseTests.cs": "17d0a48acd06ea4d32b472f1fb16f8711d71e3d0563d1f7802e445f4a7b24d24", + "csharp/src/OneMsg.Sdk.Test/Model/ListMessages200ResponseTests.cs": "53dd71fc70a684c41f9786a05d3b91344ce6219e57cd17f1baa4850747d01d67", + "csharp/src/OneMsg.Sdk.Test/Model/ListTemplates200ResponseTests.cs": "1aa66af190f29e5cae50d6b121c7dc1bd06f7a25b7cbb4b734cdfdc1fe0234be", + "csharp/src/OneMsg.Sdk.Test/Model/MessageSentResponseTests.cs": "2bc2ed79bec3930fa85bac87601b6433aca32ed2dfab9e113961cb4152bfe68c", + "csharp/src/OneMsg.Sdk.Test/Model/PatchFlowsFlowIdAssets200ResponseTests.cs": "603f0bd71ac4d4415a80b92c3f274cdb5f45c6fe1f6eb03e8d655c54323ea412", + "csharp/src/OneMsg.Sdk.Test/Model/ProfileInfoTests.cs": "b160bfe8430ede4bd3d6fd00ad59d7fe03d2b37056d9e0db4e982fd95c3ec69e", + "csharp/src/OneMsg.Sdk.Test/Model/RetrieveMedia200ResponseTests.cs": "fefc8981be4c5210e8e3e2159efa145c82bbe38d047bacf64b46ca1318b4a552", + "csharp/src/OneMsg.Sdk.Test/Model/SendAddressMessageRequestTests.cs": "0e48ad8f45af600a66970b8b13b640e60040466eee87dd0712564e198efbb9c4", + "csharp/src/OneMsg.Sdk.Test/Model/SendButtonRequestSectionsInnerReplyTests.cs": "73d2770411b0b529d6e46104e6ab6db99e2625d98bdd88a1a8ed182d6e03059d", + "csharp/src/OneMsg.Sdk.Test/Model/SendButtonRequestSectionsInnerTests.cs": "0b68abe35e297fed94e14f94d184afc64f00db49af6ee58c7310e9108067de38", + "csharp/src/OneMsg.Sdk.Test/Model/SendButtonRequestTests.cs": "e229a36d5c6986d2945e5d835d036db457bc22b54bfdbee6d0cbddb0dde15906", + "csharp/src/OneMsg.Sdk.Test/Model/SendCarouselRequest1Tests.cs": "f4e24fd9de742b4cb701ffd4443efe1b452c578bbc101d0d268450ae0ce1a7c9", + "csharp/src/OneMsg.Sdk.Test/Model/SendContactRequestContactsInnerNameTests.cs": "7063e9b444c85519771cfd635e9241d636fc914800bc8fac2e1d4a5f23bffbf1", + "csharp/src/OneMsg.Sdk.Test/Model/SendContactRequestContactsInnerOrgTests.cs": "438b64cd762574b9ac7778cd625ba1dee9471e4c3eb051808d3ae27041cede99", + "csharp/src/OneMsg.Sdk.Test/Model/SendContactRequestContactsInnerPhonesInnerTests.cs": "256df222f1bca0091000261d2a790a28b1ebdb61f70758815fa20a657e10dfc5", + "csharp/src/OneMsg.Sdk.Test/Model/SendContactRequestContactsInnerTests.cs": "33e2680f4a50b9f32f2f4d5a8c1b10c380e02f1e6fea31b6c1070482ea1741ae", + "csharp/src/OneMsg.Sdk.Test/Model/SendContactRequestTests.cs": "7031260ad46064b54e95d3fff31ad09326ac6132f83abc00cdd6796df31503d0", + "csharp/src/OneMsg.Sdk.Test/Model/SendCtaUrlRequestTests.cs": "a558ec389e43c7111f0f3c883e94e6f5732058b870f3b5de29b7674004b75a75", + "csharp/src/OneMsg.Sdk.Test/Model/SendFileRequestTests.cs": "3dd9cab162673224937673ff888958cc490bd75e44d454896e3c905f51872ec3", + "csharp/src/OneMsg.Sdk.Test/Model/SendFlowRequest1HeaderTests.cs": "4fc4e3ad1b13701b5b4b08a5334424b1b70eab54c581182220938639ac565e41", + "csharp/src/OneMsg.Sdk.Test/Model/SendFlowRequest1Tests.cs": "fde0ea08b33560a0f4ae96e4306a972648ca77c98ad1fc6d3a935d2308238d17", + "csharp/src/OneMsg.Sdk.Test/Model/SendFlowRequestHeaderTests.cs": "ed59a57bd9f67767514e3b804a3066a76c01da6f06fa23669dd24fe77988ca32", + "csharp/src/OneMsg.Sdk.Test/Model/SendListRequestSectionsInnerRowsInnerTests.cs": "9114c8184bc3f23513efeaf6bcb6d8b02f32a0cf7ef80c6fbc0fa9905fac0d40", + "csharp/src/OneMsg.Sdk.Test/Model/SendListRequestSectionsInnerTests.cs": "42e531af99326b0b028f82dd946f6590a879b7470016b328abd508f77803086e", + "csharp/src/OneMsg.Sdk.Test/Model/SendListRequestTests.cs": "ab7416431b10a8cbecd7d7752fb72edb2ac9d3a96365ff9ec8bba565f8acb02d", + "csharp/src/OneMsg.Sdk.Test/Model/SendLocationRequest1Tests.cs": "6ea3a3076f97fcbea49a2a7a895bc7aaf5d121c1aef3ab7101caac87ea8fd178", + "csharp/src/OneMsg.Sdk.Test/Model/SendLocationRequestRequestTests.cs": "2c8136d6d62593f2d5618f345c206bad529fef9b3f72139fa945d32a519bee5c", + "csharp/src/OneMsg.Sdk.Test/Model/SendMessageRequestTests.cs": "16dc3ef9353a22b29439e1efb8d31b8d753416b40327cc94e7ee0e6305b19686", + "csharp/src/OneMsg.Sdk.Test/Model/SendOrderDetailsRequestLanguageTests.cs": "49bd8541747567e07c2423970373e60da3eb4546becbab1c95c894bf9d6d92c4", + "csharp/src/OneMsg.Sdk.Test/Model/SendOrderDetailsRequestOrderItemsInnerAmountTests.cs": "82f05062b81fc0ac58cb7dad5e1810041665364576e01f0450e9234fc9ae13a1", + "csharp/src/OneMsg.Sdk.Test/Model/SendOrderDetailsRequestOrderItemsInnerTests.cs": "ff72c95b315b8ea2baebb77f2d96390205422bfde8f516eb668298e8a612745e", + "csharp/src/OneMsg.Sdk.Test/Model/SendOrderDetailsRequestOrderTests.cs": "f56e674e5f5dba997e3ffd08570b2330bc6909be49f7b33709d0ea23fe75bbc9", + "csharp/src/OneMsg.Sdk.Test/Model/SendOrderDetailsRequestTests.cs": "7945e4c7254dd5e6991e1f8731b81615f002dbe6ef748b937aa87cf9e622bfd8", + "csharp/src/OneMsg.Sdk.Test/Model/SendPaymentRequestRequestTests.cs": "3657ba6681b63452031c315cdd9cac51371dc3dca2cd84d5ada9ef98f08b47ed", + "csharp/src/OneMsg.Sdk.Test/Model/SendReactionRequestTests.cs": "cae6c99b587f6c8015c8f49e6b5e5494e593c4c7e70a0cb66de6b3cda3bcf828", + "csharp/src/OneMsg.Sdk.Test/Model/SendStickerRequestTests.cs": "ff0cc0367545ae9a154c3d05087543dd3c7eeaa8045ffd811ac32fefe13920c2", + "csharp/src/OneMsg.Sdk.Test/Model/SendTemplateRequestLanguageTests.cs": "be3cea6c86dee1e3e73d51a967c5bb67406f0181dcdf7a10b6765eb2e7a0b97e", + "csharp/src/OneMsg.Sdk.Test/Model/SendTemplateRequestTests.cs": "e409774866e48e10e629594f564bb7cce2a4cd5fbab85129c807eb45820e2126", + "csharp/src/OneMsg.Sdk.Test/Model/SetWhatsappBusinessEncryptionRequestTests.cs": "15cc5be6ffa689de6da354d79c45d04d9d6c2426ceec43ba7f4a6c4e2de8a04c", + "csharp/src/OneMsg.Sdk.Test/Model/SuccessResponseTests.cs": "dee08071e31f33ba1db20fef7dec17bdb99bdc50d5e0555b426e1d1538faefd6", + "csharp/src/OneMsg.Sdk.Test/Model/UpdateCallingSettings200ResponseResponseTests.cs": "74c902b7e9d9f4034ea9898217ef90a05c28933a2dd5b9ba66743d281d041638", + "csharp/src/OneMsg.Sdk.Test/Model/UpdateCallingSettings200ResponseTests.cs": "22b03392f4a24a465772817203cde4a5106e64d7e93b328b027e3c74b0f50ea5", + "csharp/src/OneMsg.Sdk.Test/Model/UpdateMeRequestTests.cs": "a49ce0b8956a59dc17bed66ff4666289b06a2c1bf3467e6afeda08ea0b46dc9e", + "csharp/src/OneMsg.Sdk.Test/OneMsg.Sdk.Test.csproj": "05beb5479f1dacf154a34519fbbdfdf64fa9414683ee8fce8ce998ba1ccee901", + "csharp/src/OneMsg.Sdk/Api/CallingApi.cs": "ffcf1d031cd85f9805cbdfc1dc2e44f191237b7def88c54489d61806724970ee", + "csharp/src/OneMsg.Sdk/Api/CatalogApi.cs": "cc60c665891b8172e4d8d0996c8842f55cd2ce45df6cf0508da10a05dee9e488", + "csharp/src/OneMsg.Sdk/Api/ChannelApi.cs": "a220a59af4825a209e173b553caeff436e945efcb6ee8931dcdde70972c128ec", + "csharp/src/OneMsg.Sdk/Api/FlowsApi.cs": "38037bd47a82e9a4714932c9a8faa4a8bb554f3df2751753f677e9e97952c586", + "csharp/src/OneMsg.Sdk/Api/GroupsApi.cs": "4109deded72443dfe2b33d057df7a6f8ff8d8c1cc1cea2c4936baa42b6e3b1c9", + "csharp/src/OneMsg.Sdk/Api/MessagingApi.cs": "94e3d4474b3a3da3b1b6376b2e4a275c40ec379cb57b41ee2f41f67794a8fc1a", + "csharp/src/OneMsg.Sdk/Api/ProfileApi.cs": "247761f2e6c7f82a9a2e3f55dbfe50da07c3c7647ae8be9262a2903f952604d6", + "csharp/src/OneMsg.Sdk/Api/TemplatesApi.cs": "d02a69b264a17586854d6ac67a124bff52387f34171eb0fbb9a4fa562f7d3487", + "csharp/src/OneMsg.Sdk/Api/UsersApi.cs": "15cb4b56af250711f05fc53c11cd819b1b55075a6327a5185e90fc46c89afb16", + "csharp/src/OneMsg.Sdk/Api/WebhooksApi.cs": "36446e354251f1348834c5efec56a2774ca7554e9da8622410cbdc5c051605d2", + "csharp/src/OneMsg.Sdk/Client/ApiClient.cs": "18702e575a40b27438481d5c1a6a7a8aad32068e3045296fb04beb8ed5cfb2fc", + "csharp/src/OneMsg.Sdk/Client/ApiException.cs": "a42437a8bffc28fb0027180b298be6aa3a9a70eedcb7b683e40f3f860e4d3a19", + "csharp/src/OneMsg.Sdk/Client/ApiResponse.cs": "30a169477f8523a6b5a3cae01932505f6d830c6b47c9eb70ba997828cfc98840", + "csharp/src/OneMsg.Sdk/Client/ClientUtils.cs": "ef89398677bb53b6937c6ec1f524bb9788c55146258382f70f16b28ddc2d4d46", + "csharp/src/OneMsg.Sdk/Client/Configuration.cs": "4011935fd62dd0025cc8d57c5ddfa63d920ce439eadd2a1ff7ef9bb05bd52f65", + "csharp/src/OneMsg.Sdk/Client/ExceptionFactory.cs": "45595612eb4947d055df5b8af4c5e6503f37e42d443baf02ba126d82ca5d95c4", + "csharp/src/OneMsg.Sdk/Client/FileParameter.cs": "a8ecc1f957f16b852551a669e5ddadd92b2f62a2bbd7d0077c1f29772b3cb8e4", + "csharp/src/OneMsg.Sdk/Client/GlobalConfiguration.cs": "ff3487c64757ae75ccde70d790636b4897fec3ee23afd286dd65383ac4168a7b", + "csharp/src/OneMsg.Sdk/Client/IApiAccessor.cs": "54f5813ccb2c09a979d3e50b118166c15b5f8783f69889cc6b92553877e73c38", + "csharp/src/OneMsg.Sdk/Client/IAsynchronousClient.cs": "3802e1382473499611207ffb33af9c284e1ae87d45a54f8a02932929f83d9067", + "csharp/src/OneMsg.Sdk/Client/IReadableConfiguration.cs": "48cc4544d305f64f4822db3efce9d0da9b7ba395bff2cc18fdbea69689d174ff", + "csharp/src/OneMsg.Sdk/Client/ISynchronousClient.cs": "a3ac56f079c4f7e3a883fc6d4971d92db364a1f131d32f7b9b763ca2c24c92e0", + "csharp/src/OneMsg.Sdk/Client/Multimap.cs": "968684724a8bfd3db3457f9bac213b79c2c43d98456fe25df1448d52427b961c", + "csharp/src/OneMsg.Sdk/Client/OpenAPIDateConverter.cs": "a6051c7f5f97c01e6a54460023814fd1720f7f5d139acfd1818e62430f470ca2", + "csharp/src/OneMsg.Sdk/Client/RequestOptions.cs": "147c8dea1029ae983e91c488f50e9ddc6dc5c020ebdd75ef8015ae3fa4a2bc3c", + "csharp/src/OneMsg.Sdk/Client/RetryConfiguration.cs": "6667eff98368a3a842d4e14d1572a8489dfd46c93bfc40f5fc1b8321aa7c0ad7", + "csharp/src/OneMsg.Sdk/Client/WebRequestPathBuilder.cs": "68b21b8a40615c0f5dc0480848938a54e4df3c7443a76a5691e62be8cdd794d9", + "csharp/src/OneMsg.Sdk/Model/AbstractOpenAPISchema.cs": "35f30f5a73c1610b1ffe24fe2f0397448aa70500ed5544e08bc80f5a725f097a", + "csharp/src/OneMsg.Sdk/Model/AddTemplateRequest.cs": "7f7f85383d2d72e2bff58d44abb4805b99469d4ab5bd294ebf3c74ccfc40b4b0", + "csharp/src/OneMsg.Sdk/Model/BlockUserRequest.cs": "8bda045eace8246d3ba0b7d05f375521cd6f7e1a481297a673aa486c4e220230", + "csharp/src/OneMsg.Sdk/Model/CallingSettings.cs": "382d84ee96f01bd64d9e2c5ee0f05859857e32d0c6edb87620b6bc7566b81833", + "csharp/src/OneMsg.Sdk/Model/CallingSettingsCalling.cs": "310dd61c03de415c8d7fd9fea67869570e572126d5473ead626a514be9a36ec8", + "csharp/src/OneMsg.Sdk/Model/CallingSettingsCallingAudio.cs": "6db9ed40cb50892847c8ff149268dc13b4cbdcae1298af7658d5e63d835a64f2", + "csharp/src/OneMsg.Sdk/Model/CallingSettingsCallingCallHours.cs": "4588d594326703c2fac7517c89a1cc1db0999635f5bdf26856154c2037c0ef74", + "csharp/src/OneMsg.Sdk/Model/CallingSettingsCallingSip.cs": "f0a0d50d8c8d8b844ba3d8efa4a5dc4e2bf9a4882d259e9a6d5a503deda3c113", + "csharp/src/OneMsg.Sdk/Model/CallingSettingsCallingSipServersInner.cs": "55da33c667de4568b78c10931c4f6e854867d7e19652779e511e0c5bb7ad916a", + "csharp/src/OneMsg.Sdk/Model/CallingSettingsCallingVideo.cs": "731e4765128c9ae31b335aba5a69ab03993735aa27eab56203e5e72cd69c08cb", + "csharp/src/OneMsg.Sdk/Model/ConversationalAutomation.cs": "44c697d2f37887387760570b9bf24b38ab8d75d98cab0d97899794cf4a4e34e6", + "csharp/src/OneMsg.Sdk/Model/ConversationalAutomationCommandsInner.cs": "fc2c892e89cb2e0f2e265f089126ba44e810d539aa688d53f5e36343b36b2afc", + "csharp/src/OneMsg.Sdk/Model/CreateCommerce200Response.cs": "c14723fb51becefd86d256fee53386437273b07a24c035d7cf2afdf74d22dad5", + "csharp/src/OneMsg.Sdk/Model/CreateCommerceRequest.cs": "d106eeedd664c9e2022971d6ccb05930500fb341d29634cb0f02c5733784b67f", + "csharp/src/OneMsg.Sdk/Model/CreateCommerceRequestParams.cs": "5257c42cb5c48fd3142f9b4c2fbee9f28163e2e0b36d06a8130cdd6308b78066", + "csharp/src/OneMsg.Sdk/Model/CreateGroups200Response.cs": "416b91f1de18730572d4422e456013473b46f7a133ab96eff142d29529ef865f", + "csharp/src/OneMsg.Sdk/Model/CreateReadMessage200Response.cs": "4fba867e3b7f81ba160bb1ea3ecd13421931c0d5ec60e1fae09a83d2c3901c2c", + "csharp/src/OneMsg.Sdk/Model/CreateReadMessage401Response.cs": "97a1a3c678ba7975e1b7d9bb77e8683fb01a0efacc89b40b558561df8054b208", + "csharp/src/OneMsg.Sdk/Model/CreateReadMessageRequest.cs": "6a6631ab4bbe85f8ca251b309aa86484a0720ddf27d8b8a19751291cb5a0183b", + "csharp/src/OneMsg.Sdk/Model/DeleteFlowsFlowId200Response.cs": "af4132ace9e7bd504c5825b77270942284d4fb3fee56fa4bbd33dda7d2eec179", + "csharp/src/OneMsg.Sdk/Model/DeleteGroupsGroupId200Response.cs": "91ed8c69af761f7bec3c1f9711b41bf1eced61a64547fa9d3088744a2f14376d", + "csharp/src/OneMsg.Sdk/Model/DeleteMediaLegacyRequest.cs": "03283fece50a24e56364c49e1750ff0806559a537c4d63582e4efe5d40c37c52", + "csharp/src/OneMsg.Sdk/Model/ErrorResponse.cs": "740eb239613a329fde1aa75e21eac27c0e31e5be724aa212050e68b478044f29", + "csharp/src/OneMsg.Sdk/Model/GetCommerce200ResponseInner.cs": "7370ea5539f227e3e70c765ef51fa3600ea54feb7b88bb3ad7e0ebcad42dccc1", + "csharp/src/OneMsg.Sdk/Model/GetMmLiteStatus200Response.cs": "fb24e4c6e73203c992662a8c8b16bed4318589d3e9cfa1ac56b947915faa6297", + "csharp/src/OneMsg.Sdk/Model/GetWebhook200Response.cs": "b63950b4c3bea87e0e64dc9ec279af9ff4fb0a24810a2486f1f016af57384bab", + "csharp/src/OneMsg.Sdk/Model/GetWhatsappBusinessEncryption200Response.cs": "605769cc34421e11dea394699dfda0b2d8ddd2160f5279e9fc0524ffc294d861", + "csharp/src/OneMsg.Sdk/Model/InitiateCallRequest.cs": "92aa906f65c637c47201403b30648857c38e5bc49385a54c80b962ca240e8172", + "csharp/src/OneMsg.Sdk/Model/InitiateCallRequestSession.cs": "d4a152ac406ea739e7ef2565f11662b2545dc3aac17a48663dfda3086f8991cd", + "csharp/src/OneMsg.Sdk/Model/InitiateCallResponse.cs": "c96218c17c38845e417740f89b15dcbacaf05fe06b3cbdc9f08dae92af57c7f0", + "csharp/src/OneMsg.Sdk/Model/InitiateCallResponseCallsInner.cs": "ad419594576a3bbb408ecabfc4d6102b78bd8c6b935f2bfd6a979ca7d0a4ab5a", + "csharp/src/OneMsg.Sdk/Model/InitiateCallResponseResponse.cs": "2ef16a22f979b3138824934069ffc50261834e0a379155e8f85b91bc893f6f8a", + "csharp/src/OneMsg.Sdk/Model/ListBlockedUsers200Response.cs": "991bbfc9733c607fb901e6204aaaa16ccac79f4ee0c2ef3a29ef0069a5295842", + "csharp/src/OneMsg.Sdk/Model/ListFlows200Response.cs": "2268db5dc9d7c66a7959ddcd47579135a83e5c0010c2e22d61a7ba02e6d2dcef", + "csharp/src/OneMsg.Sdk/Model/ListMessages200Response.cs": "5fcf2b298d497bfc6fe1c135d386be5c2450a14ce1f5b8a5f09141d1b5273aa9", + "csharp/src/OneMsg.Sdk/Model/ListTemplates200Response.cs": "781835c25f8f29e07cd9de9ec72224fcb65cc7a36c4339993e71d2beec638aa7", + "csharp/src/OneMsg.Sdk/Model/MessageSentResponse.cs": "042cdd1844e781d6a88f0c59fb7fc735f7274edcdc868ec48e940b4af020fca3", + "csharp/src/OneMsg.Sdk/Model/PatchFlowsFlowIdAssets200Response.cs": "65785276cc13adb37999f195fe785d2ea68d44b0f0d130d182eba374956cbfa6", + "csharp/src/OneMsg.Sdk/Model/ProfileInfo.cs": "fbf7bc475d2dcd3c1116b10d406f6569788a0d1ae8f4c28693932d4f56609896", + "csharp/src/OneMsg.Sdk/Model/RetrieveMedia200Response.cs": "2d95f962423e20bed37c12f6881a660994d89487df53d3468e0cd22c71a36424", + "csharp/src/OneMsg.Sdk/Model/SendAddressMessageRequest.cs": "62ff9bbea0fb1f93a744d601e38f8d06279d6b6796a33df96f7e37d479ebbbed", + "csharp/src/OneMsg.Sdk/Model/SendButtonRequest.cs": "cadc2ab01ecb694756ab510d3a0c0958b232a36aee255a4887d407fa3c17924a", + "csharp/src/OneMsg.Sdk/Model/SendButtonRequestSectionsInner.cs": "12debd172da0e6343fa0076063c08acb9dc6bacfe537b198cd8a7a7d2c253af4", + "csharp/src/OneMsg.Sdk/Model/SendButtonRequestSectionsInnerReply.cs": "37146e3ba29e832c7341df95d9a259e6d3f9016020fd9bada74ffd9b2fcfdd68", + "csharp/src/OneMsg.Sdk/Model/SendCarouselRequest1.cs": "321a0ebf00bb634055d5f9eb28b10e36451cce56d5201daf77695c8189415015", + "csharp/src/OneMsg.Sdk/Model/SendContactRequest.cs": "448b1f710ea5f9d23918b18df4c81f62a5769df5fcebeb44f809e2bfa38189c0", + "csharp/src/OneMsg.Sdk/Model/SendContactRequestContactsInner.cs": "66ff2003340edefa7f6ec764de4bd73034f0ef5f18ac38097823427ba7c68bcd", + "csharp/src/OneMsg.Sdk/Model/SendContactRequestContactsInnerName.cs": "5eeb5755eb3597aa4deb9fbfa7e1d578c187a7073a981b5bd1392a5195ee3fdc", + "csharp/src/OneMsg.Sdk/Model/SendContactRequestContactsInnerOrg.cs": "fc80f967057f05a9ad4d1805939635a8404b684d84bee3071dbdbffbc990553f", + "csharp/src/OneMsg.Sdk/Model/SendContactRequestContactsInnerPhonesInner.cs": "4eab52689075004293edcd9b9ecfbd4b4da5a4c057318f752a0708c16976a80e", + "csharp/src/OneMsg.Sdk/Model/SendCtaUrlRequest.cs": "293a7434e5dfc2169dc63a84cdcb7095eb09098e61001e2c6bc66434db239f4a", + "csharp/src/OneMsg.Sdk/Model/SendFileRequest.cs": "44d0658733b84dd1770903a5fc9fbc4e5afcb3a47ac2191746a42566da0c9a2f", + "csharp/src/OneMsg.Sdk/Model/SendFlowRequest1.cs": "dd16d1c7b629b9ab68526b4e3ec6a36a64bb5c9d22862b5f1065f9d0f9235597", + "csharp/src/OneMsg.Sdk/Model/SendFlowRequest1Header.cs": "3719121306877fe38a0c63376c832dc7393bd54ada7fd00aca954d84b6d00b34", + "csharp/src/OneMsg.Sdk/Model/SendFlowRequestHeader.cs": "b5cba2999911abfe15a7623dae70d427b22a65722d75cb53c92a505fef46ee94", + "csharp/src/OneMsg.Sdk/Model/SendListRequest.cs": "0cbe924dd2e439a983a7355d9d4a3535cc79a21229007cc08fedeb424565f1a3", + "csharp/src/OneMsg.Sdk/Model/SendListRequestSectionsInner.cs": "d5d37f8d95ec9ba6b59190b0aebc9298af07c1eb084ed3f8146b690c41a37a75", + "csharp/src/OneMsg.Sdk/Model/SendListRequestSectionsInnerRowsInner.cs": "3ffe1e232bc6caafbcb359c78f3af6658b2fe738d1d977b29672997db0ecbcfa", + "csharp/src/OneMsg.Sdk/Model/SendLocationRequest1.cs": "4244be3a16bbf4ccc74cf3379f221a90e9dc867e970cdaa4ea195d8d93cd91d9", + "csharp/src/OneMsg.Sdk/Model/SendLocationRequestRequest.cs": "d116a9c6199cddf8f2c7d6b9c4292bdbbb2a9c631bee6363aaeef036b312fdfc", + "csharp/src/OneMsg.Sdk/Model/SendMessageRequest.cs": "dce9d80e5dd1fb9e8bb8f8bdb2f8ab55037d6e43799793e16ec26de93d73ef0f", + "csharp/src/OneMsg.Sdk/Model/SendOrderDetailsRequest.cs": "43a43c1a79d512a9d8ac4aa1152ef1e27edac816af72e2bd21fcc767bd0f512c", + "csharp/src/OneMsg.Sdk/Model/SendOrderDetailsRequestLanguage.cs": "8a5baae9cd87ff5630be7a75ab5e4bbac0993d6b1ee2d933c1c272623be56f48", + "csharp/src/OneMsg.Sdk/Model/SendOrderDetailsRequestOrder.cs": "7d3174ad536ff0e47feca22f06c851b8e59ee6c15aa7c77ec57730572745fc8a", + "csharp/src/OneMsg.Sdk/Model/SendOrderDetailsRequestOrderItemsInner.cs": "0ef6ceddb2b1ea0bba62e9791f731ca16d00851128c012fdb6bd6fe8e9d329b2", + "csharp/src/OneMsg.Sdk/Model/SendOrderDetailsRequestOrderItemsInnerAmount.cs": "16b0cc41218e965d3e1e6b8a1946a4055f4b7824856ea2873c0f3658ff8386ab", + "csharp/src/OneMsg.Sdk/Model/SendPaymentRequestRequest.cs": "b29cff9cf9e6b0320dfe097768ed652884ede68c9b156f89bd01bc23435fcd02", + "csharp/src/OneMsg.Sdk/Model/SendReactionRequest.cs": "4aefc5b9a8ced4eff2c8b998485b3c02d0c256c7c1f01665b325b0e70dce614b", + "csharp/src/OneMsg.Sdk/Model/SendStickerRequest.cs": "23a3b0e01554cdf726f0297d85211d5fa14555b9f1505e5182a0c289dc5b0c54", + "csharp/src/OneMsg.Sdk/Model/SendTemplateRequest.cs": "444a5b973a98c0e9c7ad65f7e22f77f9a5d7d5d58cf0614ed7bddd24bcc2d066", + "csharp/src/OneMsg.Sdk/Model/SendTemplateRequestLanguage.cs": "efafd139bf063949fcd0862137abe21f9e9f9a13f5f8e1bf9792cab0278abc7c", + "csharp/src/OneMsg.Sdk/Model/SetWhatsappBusinessEncryptionRequest.cs": "c84e91d8b508a8970c2d3bff2dafa9133c96e3cd4641c2f4b0a71d892201f1bb", + "csharp/src/OneMsg.Sdk/Model/SuccessResponse.cs": "1464f46f21e9ce171e14d0f07d2094e22dcce41199d48d97aa1c054832432b09", + "csharp/src/OneMsg.Sdk/Model/UpdateCallingSettings200Response.cs": "5b75ec1ddcfe3fc8e4d0526f0bbea610f061105d8ac197fa546dca3345229103", + "csharp/src/OneMsg.Sdk/Model/UpdateCallingSettings200ResponseResponse.cs": "50450f1e87f6b01220d2dd15fc605788d0c03486fcc12749cbce92643c6a2f2e", + "csharp/src/OneMsg.Sdk/Model/UpdateMeRequest.cs": "0c25f85d1894343f1f59457138f3adcadbe766154f76dc791363b152b9e47a08", + "csharp/src/OneMsg.Sdk/OneMsg.Sdk.csproj": "80a06dccec03e44c16afac3d8f782fb39727ed1e207b5d202d2c5af1e7455f5e", + "csharp/src/OneMsg.Sdk/README.md": "4b5b0e298227800df2b69b5ee8a7979435ea9a977c0a4f414869c5972cf960c7" + } + }, + { + "id": "native-python", + "owner": "1MSG SDK maintainers", + "issue": "https://plane.1msg.io/1msg/browse/1MSG-156/", + "expires": "2026-12-11", + "reason": "Native python generation, frozen dependencies, build and offline contract tests have not been verified. Sources remain byte-for-byte frozen until a reviewed language-specific quality profile replaces this exception.", + "requiredWork": [ + "Pin and replay the actual language generator", + "Freeze dependencies and verify native build", + "Add offline required/optional/error serialization and package consumer tests" + ], + "baselineCommit": "802e13a13a3bb11ec25e68258c3bd0518dec8d53", + "roots": ["python"], + "files": { + "python/.gitignore": "b6a41e5e0d0bb0c5eb943284e920c53f1a5bf6b83822a11aaa939c3bdea6ce5a", + "python/.openapi-generator-ignore": "a6ed8f4e275eee926d27e0c52f30f2d1c4d8409465ac1fbc4511f7cc62de51db", + "python/AGENTS.md": "2bc84c6e52869df9f5dcda603b1762f39fce753adba7d4866fd4dd2f835e0f08", + "python/LICENSE": "88170a8e4e7b68f13a057d5b9e1882d4b60c71e0a762b5a95651931a219835ee", + "python/README.md": "d19eae00b9fbf4a1cf73f2ffce6659ad77c55453568799aee4bc482312f76eac", + "python/docs/AddTemplateRequest.md": "53082facc7173324cce0359e688435321cc178298ac0194b0c9f1fb9366294e8", + "python/docs/BlockUserRequest.md": "6940eebcac362a027660002a8c5a5929cf2acb13f6e9b9dbb474ca12bc50d35f", + "python/docs/CallingApi.md": "39baf2fce2b03d805ab078c87179704ec08e4a37924f353bfe6c0e355b09f4df", + "python/docs/CallingSettings.md": "04ac99c717a16113a8657dc70b63022f77cea4e7973ec393ae20564649071747", + "python/docs/CallingSettingsCalling.md": "4fa1535ee509e58b24b1dac9a95f188d5111f1947c3e7474c90bf28a50bafcd7", + "python/docs/CallingSettingsCallingAudio.md": "1b9ff7a678acb4e7192a9e18762c23abe84b4dc141e012d85d8d91dd062059dd", + "python/docs/CallingSettingsCallingCallHours.md": "beee4f25c46a83b51875cfe513bdd69ce32f4e6959e989bf1ac4c7ef47eae617", + "python/docs/CallingSettingsCallingSip.md": "1e0f061c8c35471c746968f258cdeb7ec65656d961b56d9d121ba832a49305cc", + "python/docs/CallingSettingsCallingSipServersInner.md": "e5f1d46bf479f0a141602e73e565e1c7eef1605c2fa20bfc8b8a89a4bb82dafd", + "python/docs/CallingSettingsCallingVideo.md": "d579a09882a6d22ef403a502143023ae80cfb1139cc5649e58e42b24c682a838", + "python/docs/CatalogApi.md": "5602d8ec8a2f4d9c855b5273dac938d28b0429ce343db4a976a949540641abc7", + "python/docs/ChannelApi.md": "3f7973d2f291db1746101c036f2acb6cebabbc4589ec69cbce10953fe3370562", + "python/docs/ConversationalAutomation.md": "0acb73c5362cf03f5922d926654a9f08da8e2ff7d44712505899d2b7bd3dfbe3", + "python/docs/ConversationalAutomationCommandsInner.md": "1c8e85106df3dd7f82f71bfed1df96383674623cbaea34e47337c98025fcf700", + "python/docs/CreateCommerce200Response.md": "44eb03f7d5dcfe4a5846e56b837a44e2c75fb5338e77baa89786a73209d1f8a7", + "python/docs/CreateCommerceRequest.md": "f6bf89252c7a58efbb26b9fac77ad28ddb5b034f6b3815464ab6e09c58073522", + "python/docs/CreateCommerceRequestParams.md": "de7d86b467c8fc4c4ef36bb2ba3af34ab1218eec07a916be892017f6f44512e6", + "python/docs/CreateGroups200Response.md": "39535f6e8fe3ee3892933b6a12085835c7cef9fbc35361af0b54aad1e592d6ad", + "python/docs/CreateReadMessage200Response.md": "abfd49bb0cb31ec8003daeaee14ce6169724fb56419c3dbe55ccf24d1f34c00e", + "python/docs/CreateReadMessage401Response.md": "b632ae37b6b8b51238723a741f478752cdc1558e53cab94fcd55ac89c5ac5905", + "python/docs/CreateReadMessageRequest.md": "f8f6f7d80f2c06824630ecccd6e1ae05bdc401696c14b82db3e87228712ce781", + "python/docs/DeleteFlowsFlowId200Response.md": "bccf99ba534081b07a5166bb6182dd8229dde7b4ce7d6d825805c4982892c7f9", + "python/docs/DeleteGroupsGroupId200Response.md": "c463fb48a8936d2eef9a161476c3a3f9d3e3452d6078492584207607acf2c2d4", + "python/docs/DeleteMediaLegacyRequest.md": "b9ae29f9e85714129413256996b6828177dc34b668218f1e1d2324c2f213e07b", + "python/docs/ErrorResponse.md": "2e8266e4c0eb9c9688dc500f5a93d872211dc1a620906aea883011d8ed915b50", + "python/docs/FlowsApi.md": "80bce04b75dcff54b618ef37a750a942a5bde1b2b5396230fb0570845c447859", + "python/docs/GetCommerce200ResponseInner.md": "fcaa2c853982d9799eafe9e9f79e56bc9d251c65e45bd45b857d031a2da14c89", + "python/docs/GetMmLiteStatus200Response.md": "9918b84d3e6c5981b62fc099021872af6dcf53f7fc3b25d7b662bdf2ce35f0ec", + "python/docs/GetWebhook200Response.md": "d22b8bb4c17dc7e2fecb9ed510884ddf4d647f60e7f008e997d6160891972480", + "python/docs/GetWhatsappBusinessEncryption200Response.md": "0fc533bb1f93e554f1534735e5a359b6a952d1e4f1d49a63bbf11bf22520ade6", + "python/docs/GroupsApi.md": "d3671e9a91560f6c07b562aa5eeb500e777d451aa25c35454617b2c36573247b", + "python/docs/InitiateCallRequest.md": "5d965808edf1b9c69d712089827d2374c25b866a3609d1d8f1484c83ea19877c", + "python/docs/InitiateCallRequestSession.md": "62cd482153aee6a810b150939b5df2a2e1d97ff2a9d9b4b42a3eb993e0a778c7", + "python/docs/InitiateCallResponse.md": "cdf132d40964bf64b11598e1af614c94c09fafa5618efee024209a7792084eda", + "python/docs/InitiateCallResponseCallsInner.md": "a1281ae4807f21b935fb2f73e6816662ad0a77e69d5197ee607e46f685320439", + "python/docs/InitiateCallResponseResponse.md": "629c2eb73faf1c5ba2546e5e1a77bb996f45c2b6e6673082db568558452c0bb0", + "python/docs/ListBlockedUsers200Response.md": "10737e9b1ace1d1538ca3b921b724388a6c8d1501ddb195c77d92134b0dd8620", + "python/docs/ListFlows200Response.md": "10a28830405eada291be9c5ae889ef72fe1cc1dae13ec24b2c3c12b41b92a5f8", + "python/docs/ListMessages200Response.md": "880a32d40e637c517edab478d412bacd2a3b2179f5df53263d010e2307fe7f3d", + "python/docs/ListTemplates200Response.md": "ce862a60c5033ae8a8f955230deceee85c3268406b3162ed2d51a81410f5fa1a", + "python/docs/MessageSentResponse.md": "281b6751b114cfe2aad2e78eac19c22cf6b37fed006e4cab29ba5a1c1af7b63b", + "python/docs/MessagingApi.md": "281436821ad707d9acd3246104d1e1c11fc4606dd72ce31867d6f18f6fb4b137", + "python/docs/PatchFlowsFlowIdAssets200Response.md": "fa4d95477bb77368b92c0dbdb9aef1027e9472e60e83df158c4121817925718a", + "python/docs/ProfileApi.md": "523c441e1c56e5fd668c4c8ce3297a7b64ab47d0af36cac497331e07b60fe06c", + "python/docs/ProfileInfo.md": "81efdc3b98ea14d818c04e86cc17d33b20d5f62719a89e5f70586f00059a86a6", + "python/docs/RetrieveMedia200Response.md": "0a9b8cc9d3ca39b1f06042850d71621e578d06ae495f637d7399a13067d1ca1b", + "python/docs/SendAddressMessageRequest.md": "a9fa428527019fc3d25ffccea09846c1a1c7e4cc4dcecfd4eefebbcceeadca1a", + "python/docs/SendButtonRequest.md": "fc1246ceec26ad9f82785c85c3e140e615b039a6f5d90b177e20b9b94ce4848e", + "python/docs/SendButtonRequestSectionsInner.md": "ffa3b721c8569255b19ab1f39f12cba0261dc68caef6177b946c718967c440a3", + "python/docs/SendButtonRequestSectionsInnerReply.md": "a4bfc8371a9e22d36157f192600cb70af27bd125960cb21bcca39940b6f7475d", + "python/docs/SendCarouselRequest1.md": "db86fa9ffe64f0231c2a83712ec208d8b8f0efea67fcfb13a8438d291b182813", + "python/docs/SendContactRequest.md": "bf1495614233f38f293a5c966e4d4fd70fdf0fbd37e97fd58c49d797ef01b9a6", + "python/docs/SendContactRequestContactsInner.md": "f9794bb4683c89025bf9895ac2429a9398fcc3eb1fce40e8c86192081e1ab139", + "python/docs/SendContactRequestContactsInnerName.md": "bc1f58210b5fb9273287129d3d532ba989543516804d4784bcc95f137ef7f193", + "python/docs/SendContactRequestContactsInnerOrg.md": "2e12032184f4abd0408dcb50fecbbc342bf3c1eb02552954411f43cd486c2568", + "python/docs/SendContactRequestContactsInnerPhonesInner.md": "93c244893a9741083555a2de90011eb3dcd06b48c5f72b195f277fad72e28e43", + "python/docs/SendCtaUrlRequest.md": "55abe6fc967d8289639512c0bc3491f0db3a085d792a6a3291873b54b28f7138", + "python/docs/SendFileRequest.md": "c2e177982cc6a824a602903eaac6b3e372d0adad7ccadea5d0074ca73e7423d0", + "python/docs/SendFlowRequest1.md": "c1793d59a0df04445c17b50d6f31f685c80be11dc1e57bccaaf159f78320e1fa", + "python/docs/SendFlowRequest1Header.md": "3fa0b380df62c7bd872850ca5aba9faa149c397469d5beaa967102a5af4847f5", + "python/docs/SendFlowRequestHeader.md": "eded1c1c8222063ba859a183c394ea355c9486fb5b26ad0a6f516918bcdf51d9", + "python/docs/SendListRequest.md": "b4056897450b7225033bfd9433b80b5053667bd9fa3a4bad0ff07282cad3025a", + "python/docs/SendListRequestSectionsInner.md": "0e04b3812d7dc687af5c9c533131c830793582838ab6488c64b0abda490527ff", + "python/docs/SendListRequestSectionsInnerRowsInner.md": "195c5ebdfba04505eb5f392c7e549b3328780e2ae237c9fef263e39524a9bc28", + "python/docs/SendLocationRequest1.md": "a4f254bfdd34fabf9b46be7abd935e72f34493e227aecd4bb7f7c18e8bebe758", + "python/docs/SendLocationRequestRequest.md": "368e5b1c07473558afb10fd79425cd86c850dc0479fb30bd083dfd37b6bbc5f9", + "python/docs/SendMessageRequest.md": "9efa938ab09b7152b52810fc0f83e94f964923493f500ae2d7f4c01a02712ad4", + "python/docs/SendOrderDetailsRequest.md": "9eb777157f13113f0db2a581024935d9717b93b4be6e08dff894ccc8078552c8", + "python/docs/SendOrderDetailsRequestLanguage.md": "a48b669672092e428f3ca44c5ee4c9509f22a2dc581d5c887f9bfa34ded1022f", + "python/docs/SendOrderDetailsRequestOrder.md": "448aca5c7697ecdefa79855f82aa390e91fa2ef85bbdcaf57c56b7d0b32084c0", + "python/docs/SendOrderDetailsRequestOrderItemsInner.md": "c87bd9bba2bfadab73aca7972ed07a33bc69ebd6b29d3e3eb6f024e3cddc0a24", + "python/docs/SendOrderDetailsRequestOrderItemsInnerAmount.md": "0b488c5b0b5d54a27ac1bb383ee41f7770aba04c46330fbc205217aaea79f1c5", + "python/docs/SendPaymentRequestRequest.md": "324a039ea6152acbcaaecd978d7b20245d033ff7baa11b3be15540ae955f64b5", + "python/docs/SendReactionRequest.md": "9db842265906438f6b7200a7f1128267bb26531f8fa625f88e156c09a77122e1", + "python/docs/SendStickerRequest.md": "0f2ecd4ce3767206e14dab5ccd7b4b8699d5acc4aea79daacfc343c363932e9d", + "python/docs/SendTemplateRequest.md": "08ef41a7cb4a6e8177f4054b9ee425d742f918a2f3a8a670c0aedbe6ea59ae75", + "python/docs/SendTemplateRequestLanguage.md": "5a750ed95554269d395bc6d3481f76e9177231c17f215769f43fdc7df7631e65", + "python/docs/SetWhatsappBusinessEncryptionRequest.md": "db873f709d3df1be4650306720038af954504d6741ae46f0704643579cbf961d", + "python/docs/SuccessResponse.md": "45c0971912c567634531692705572eb616af27cea366f265111ddcf5b532ff47", + "python/docs/TemplatesApi.md": "a72534dbcba7dadd8ea07c48671301c7c323b3418f10470f1ff5e6048f6ba172", + "python/docs/UpdateCallingSettings200Response.md": "751af41e8c2da4cee31c4429bb7bcd374e4d1ef89be8ae20fe13c3597cca2e4c", + "python/docs/UpdateCallingSettings200ResponseResponse.md": "15bc7a126f63aa721547ae867a0bb9a0d6df3bd337cf885e83f372cfaaafe89b", + "python/docs/UpdateMeRequest.md": "a6effd4bdde3174fd32cf70e71516ab1a8723d2e201c1633a5fc2035f3dbb584", + "python/docs/UsersApi.md": "bf804753d07b1ef8a44c4ee466fa94946344fb567e151cb6765399fd88ed42ef", + "python/docs/WebhooksApi.md": "1e3c8940ada99b55d3c527a69a9d055aa8faf8af65f4d262bab21d0a09e65ed4", + "python/one_msg_sdk/__init__.py": "c081014f083e1823591919748b80c1c8656d22da0f0cf65978a4779355068172", + "python/one_msg_sdk/api/__init__.py": "fa698f62db67d4bee0e0456d2ced5f7a741cf0e68f38756eccf0134438df6dbb", + "python/one_msg_sdk/api/calling_api.py": "29af7a233120da95eb5685244eba38ba9de596f827cd96f1198db69312e16a5d", + "python/one_msg_sdk/api/catalog_api.py": "6de6d801a9a9fd032d3b37239eddb269571339935b1338bf32da955fab9c2fee", + "python/one_msg_sdk/api/channel_api.py": "fc3e0a620143ca85f42cb58f23869b6e518cf7f593f375ec39483bcf33ba5200", + "python/one_msg_sdk/api/flows_api.py": "6906fbfcfce5bd0de6c9900abacbd544fc647542740be16e961eb35d4b25ba0d", + "python/one_msg_sdk/api/groups_api.py": "55d6a6a39e0c49ef7a85f5c1d2fb8a0341ee0ef0d435acb0354fe909909f748f", + "python/one_msg_sdk/api/messaging_api.py": "72b4a59afcde3073582aedba33d64535985b1398ebaf9d99421d8bad5f299d4f", + "python/one_msg_sdk/api/profile_api.py": "1d2f83b2f383379f9e23ec6f29071fece8c59e4b8d57f5e8ac2531fabbdc2b69", + "python/one_msg_sdk/api/templates_api.py": "64f1a92ecff949fbe8d1a45665a322961f90b31663f9e0817f8638b3ddd23ee2", + "python/one_msg_sdk/api/users_api.py": "ac6a400475c55f18123b6b5374ebc87572d34bf531f1233335783b0e9b827a96", + "python/one_msg_sdk/api/webhooks_api.py": "8559afb2bb2714e496846ed4a37d2163dc2f29f40740304276a2a46bb9813368", + "python/one_msg_sdk/api_client.py": "46920068176118c93ac5bda5bf4fd6df51964bb6754b8b17f3d40f1113b0ec70", + "python/one_msg_sdk/api_response.py": "78cc70d66a6625ca0667782cf73ea3338a18a19d741a3937df7b3db0ac46bfbb", + "python/one_msg_sdk/configuration.py": "340b229ce09bcac5d1ceb2e494b9104c1394686b462624f8c35f6a808883b2f3", + "python/one_msg_sdk/exceptions.py": "a688651d79d6cb7b9531426fbad83c19917bd89c7dcae0da427a87658178c0c0", + "python/one_msg_sdk/models/__init__.py": "659e82bfb93aa896edbb37b630bdcd409c51c89630d75abbac0d0b1e135d98af", + "python/one_msg_sdk/models/add_template_request.py": "9262e9523f8a094da48d69b294cf7c305a47051bef15c00797c30ec6163563c7", + "python/one_msg_sdk/models/block_user_request.py": "f7c55e9a3b5ce09c2f7b75ce24f5a566dcaf072421934730e59359db1a7d48aa", + "python/one_msg_sdk/models/calling_settings.py": "44b3ce7fd7993887d14c2d6c5e58e4c7d7f6e996104eb0fd49b13306c9763a4e", + "python/one_msg_sdk/models/calling_settings_calling.py": "c8b776ec6108cb2d077ffcfd8b0d772c36c197a5a1e5492c88fd9e01eacfd24a", + "python/one_msg_sdk/models/calling_settings_calling_audio.py": "661506fe35877f0122b7077fa6d6a0aea39bfe539bbe49ac76e65b57a2395288", + "python/one_msg_sdk/models/calling_settings_calling_call_hours.py": "b52b7b7f432f4b984637e984f18cad2d520a4ea39d17136b3180f48cf537c86c", + "python/one_msg_sdk/models/calling_settings_calling_sip.py": "4e8593b2518bdc54a93efabcec4894a69fa4ab92d39faf04fef0e022cbba716e", + "python/one_msg_sdk/models/calling_settings_calling_sip_servers_inner.py": "7f3164f6fbd19d08b48cd602df2a89e7dc196e0ef6398eca7561c914d88cce5b", + "python/one_msg_sdk/models/calling_settings_calling_video.py": "4e53f9902436a3b75446b4f53291698f8e20d8b491d027cb67292a476ba00ee1", + "python/one_msg_sdk/models/conversational_automation.py": "a75eb1cc252b2d3836adeb0fd4982a952755d344b3a3c2ae222adde4451ddc42", + "python/one_msg_sdk/models/conversational_automation_commands_inner.py": "57032f0924b44da90d0bf2717bde12a732f67bb5e2ae96c5c001d7d44ce98d5d", + "python/one_msg_sdk/models/create_commerce200_response.py": "852728dc5e2d267d080b88d8f06fd6f19096ea192c62e641ccd364c0b468c271", + "python/one_msg_sdk/models/create_commerce_request.py": "556c2024a3199450ed4ab0934180f70f8fb754f860522f513a457d8a7dd0203f", + "python/one_msg_sdk/models/create_commerce_request_params.py": "8a78f66917ff7dc60ae9f0d8281c66a2453f8c3a0e44a9809ac7eaf479c7e4e1", + "python/one_msg_sdk/models/create_groups200_response.py": "c781ea6bdfa05e4504d91be2dce35afea7aa123f7f0d4415b34770e6d3f8889a", + "python/one_msg_sdk/models/create_read_message200_response.py": "a53368591322b6d3a11d72686a20e6e78c0098aa5a7e72e37af04803bd24cfdb", + "python/one_msg_sdk/models/create_read_message401_response.py": "4460c06cb39a6231caca2044f756803d1e5133ebcb2e7a41e69941379b0ffb12", + "python/one_msg_sdk/models/create_read_message_request.py": "c9fcb10080067c30aaf15e0be55563e974cd53effbb0ff1ccbf88f6e7ca98da7", + "python/one_msg_sdk/models/delete_flows_flow_id200_response.py": "2a93972fe9d299dda91caa17ce5b6eda07bc7db321fe2f5736c09ec0d9936b14", + "python/one_msg_sdk/models/delete_groups_group_id200_response.py": "964775f5dabc1325bae40341abd003250a7cdad7bf80e93cc5d36e4cc525bcbb", + "python/one_msg_sdk/models/delete_media_legacy_request.py": "2fec0e6423af75fe66b6223bf0e7531b4f29ba53a45e79d1b6bb952d1229f7bd", + "python/one_msg_sdk/models/error_response.py": "afb4b04a104ea2e8119488332a618a08bf8e512b422f43a0f22b600610cb01b4", + "python/one_msg_sdk/models/get_commerce200_response_inner.py": "f6a2df2599985b2de65c12696e0a4754aea298a87f6533445af61647915a32cd", + "python/one_msg_sdk/models/get_mm_lite_status200_response.py": "dad3c5c9c3c6f07cfb64d290355f1d65ebe0672a65b26ab86fda5892722d467b", + "python/one_msg_sdk/models/get_webhook200_response.py": "182b085ada39d79faac363fdb32f5db338729330fdd02d48cf59df3e8bcb6356", + "python/one_msg_sdk/models/get_whatsapp_business_encryption200_response.py": "590e83a1ca9469525feb7b658fe4d7d8aa10231257fae49679c49ac107ba98ce", + "python/one_msg_sdk/models/initiate_call_request.py": "ed028c838765e8baebffe6158354b846f0dff2d3d8b64fba28d78dbd4efefcff", + "python/one_msg_sdk/models/initiate_call_request_session.py": "b66a17fb8e7f53c50dd5e562f1a2f2d65cef23eddaa588994e8759bb69b86128", + "python/one_msg_sdk/models/initiate_call_response.py": "af5b8c64c663b50c05870490cf5c17ade1f7980913b5343db4ce8a6cabec7de0", + "python/one_msg_sdk/models/initiate_call_response_calls_inner.py": "0a5a9b32577465da3d0a6284abd14d5f6ef4bd6979c3697c1c8c4a78af53eeee", + "python/one_msg_sdk/models/initiate_call_response_response.py": "6c6619fd28be664d1bf5c3960ace61d050b06dd5762684e0bfdefeb49aab2801", + "python/one_msg_sdk/models/list_blocked_users200_response.py": "1ead6dbd36d107869264ec5e1d569bebc509283e85c4270b089deb20ceaa9b36", + "python/one_msg_sdk/models/list_flows200_response.py": "c0b2c64742e6794b2db92ce346f71a1f80e541e4e4d38e4c78b9805024e9d7fc", + "python/one_msg_sdk/models/list_messages200_response.py": "a731f96f9574e70c00e8ba3294b536d64dfc12cb765ff0bbeaa1a486967051d0", + "python/one_msg_sdk/models/list_templates200_response.py": "a30f5d1561428204d4b16f46b66773b0497dd3f7eb873fe247653a4c04fd830f", + "python/one_msg_sdk/models/message_sent_response.py": "8afd9d2fc19837fa5d141b6020e1d2e2b417c50b2c55591c8fd6c842548489ea", + "python/one_msg_sdk/models/patch_flows_flow_id_assets200_response.py": "2be8a447c71564314ee6aae960385b166dbfbc98f198911862bbd9c4eae393ea", + "python/one_msg_sdk/models/profile_info.py": "5fc800e34eaed98241ea744ea3a17fb7767805fc5789890dfa6b3675cfaae416", + "python/one_msg_sdk/models/retrieve_media200_response.py": "88d2a64d9cdb45bdc4a6d6b2e3bd4a03f734f2273370a0f49c7882cf26f42635", + "python/one_msg_sdk/models/send_address_message_request.py": "f1d602f288b3bd76dcabf0e617cc6042e02b0716df1130ba6de858a481763c25", + "python/one_msg_sdk/models/send_button_request.py": "cdd4e963474912c2683c21f0210bef9187c86d0180289f346035384cc100dc99", + "python/one_msg_sdk/models/send_button_request_sections_inner.py": "477c293d22be4dcd89fa1246f55c9b9abb40a2d0376bb883c8461f52b34d4fea", + "python/one_msg_sdk/models/send_button_request_sections_inner_reply.py": "913e66ba9b2140f9ddea1e3473714dcc43c7de17f0e59fadc8f568d1bfcb20f7", + "python/one_msg_sdk/models/send_carousel_request1.py": "ca2c600d71e0013ab371c3dafd03b5c6097502cf6c947e392d071a5d3c912886", + "python/one_msg_sdk/models/send_contact_request.py": "925b04bb580bfdf03c99d3bd2b536008bc5ea57763492ccb2eea3a587750c37e", + "python/one_msg_sdk/models/send_contact_request_contacts_inner.py": "3ea616ae2df89db8b364cc51da1dfdde18ad88176a2fcb69e243322e897e7973", + "python/one_msg_sdk/models/send_contact_request_contacts_inner_name.py": "b1835f8e575ba9a72de49b07983bd66cf255ceae3cf8b48fb053884fbc9042c7", + "python/one_msg_sdk/models/send_contact_request_contacts_inner_org.py": "12dcdbc5053ac6003814448fd298c699bf9f945c99b656076841831c5394613e", + "python/one_msg_sdk/models/send_contact_request_contacts_inner_phones_inner.py": "f433787ceee92a97f04498de39aaa12460d8b06afff11415992df60ee61196d1", + "python/one_msg_sdk/models/send_cta_url_request.py": "7366ed337318f6098348f8c07e37f53cc8e2bdf94a74c826f35593a5b0d2fb82", + "python/one_msg_sdk/models/send_file_request.py": "83151adf8cabb34db62520580be849894f9f6616fd378659ab66b834363693e6", + "python/one_msg_sdk/models/send_flow_request1.py": "ae09fc5bd3f1797f4b8e2f3a5aa6ddd44b8b76612e8e1d27f70e3a457ba93c3c", + "python/one_msg_sdk/models/send_flow_request1_header.py": "42f50f690b0374d8f17bf8942ef8351d510bc892d1d3f9eb83619cdc96d5eea9", + "python/one_msg_sdk/models/send_flow_request_header.py": "937f3071ed891458fe4fef8c1e4c85cb3e8551cbc70208d73defce491274d299", + "python/one_msg_sdk/models/send_list_request.py": "bc318051d1f9e0d571d02f7531bd9dd2befaa1553c0ddaa8592a6e37a789e976", + "python/one_msg_sdk/models/send_list_request_sections_inner.py": "70c3b7a1068f1057a05039006749f5ff1c86a77890ab6b70d57f742c00b3a073", + "python/one_msg_sdk/models/send_list_request_sections_inner_rows_inner.py": "27e66bfed1ab0e1abef3de6f0fe15f47d15a7d39158b86f2df6a2a93b2c5f841", + "python/one_msg_sdk/models/send_location_request1.py": "cd35786e60203ad74ea6073061992b6aa8fbaa776c1b2764dc4c9df461b7f898", + "python/one_msg_sdk/models/send_location_request_request.py": "8cc7594503416ee50bac43516c86d340edcbf05846c11bdf8521395a446cebeb", + "python/one_msg_sdk/models/send_message_request.py": "6703a342f6ed47b26f7fc68de7706e10c12f6dfcfff7851c001166b349866be2", + "python/one_msg_sdk/models/send_order_details_request.py": "5e24c9e7780640e18388b573377ae9b62752d018bee4e943bd60c57d94c92168", + "python/one_msg_sdk/models/send_order_details_request_language.py": "f4d37ff2834053d2a8ae811ec0ec504c9084ea596190eb31fbe57642e98ee39c", + "python/one_msg_sdk/models/send_order_details_request_order.py": "6c9b0232d28a12cd23ab3f288250771f5093f5674c3ee87a147adea63bdd79dc", + "python/one_msg_sdk/models/send_order_details_request_order_items_inner.py": "5ab494ebce2d604d6a824f839a1529fafbcb804cc71b08e77307feb0d0006580", + "python/one_msg_sdk/models/send_order_details_request_order_items_inner_amount.py": "367459a43942033900681c08afc8591e88aeac6a5de62463f137af0e7f9cc46d", + "python/one_msg_sdk/models/send_payment_request_request.py": "de4b48c78be0d70f35498ceee73728ea97d3be49cfea8cf442904e790016e664", + "python/one_msg_sdk/models/send_reaction_request.py": "497d5e46db69cdf4d8171d9aac5c6b5ed94a81f1c1a7e37c3bf6f88c27cb6346", + "python/one_msg_sdk/models/send_sticker_request.py": "bef886a7573b6b6b70c6e751fd4c39e81e4476bcd84711e855b60443988ee1b0", + "python/one_msg_sdk/models/send_template_request.py": "f27c8e93c24de6943ef1f98fe8723923d5e2c0d3292a1703803eb9885f513e51", + "python/one_msg_sdk/models/send_template_request_language.py": "9f8ce2da48207c30e3035bc8fb06bc183484c21eba18141e6878e2d8b919c9f6", + "python/one_msg_sdk/models/set_whatsapp_business_encryption_request.py": "1d2916142053149f7f35110e751a40f0fe5386bfc30884ba5507bf00f9fc7e7f", + "python/one_msg_sdk/models/success_response.py": "962e637df6e3580e059753866ea3a11dbfff8a4ce1d2a540267800398faf7711", + "python/one_msg_sdk/models/update_calling_settings200_response.py": "aa14086ed74f9c01a98ecc156f96f48d80ffcdefc76c6ccf2c8be362b600d6e4", + "python/one_msg_sdk/models/update_calling_settings200_response_response.py": "d0711c83ed55b4b027a3427ddc8718da5a56915e46d18cc7e5a5a3d1898662bb", + "python/one_msg_sdk/models/update_me_request.py": "40a31eed4e567b3e10df810b706977e1a563cd5598b04959cc68ae715f590710", + "python/one_msg_sdk/py.typed": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "python/one_msg_sdk/rest.py": "ab5804855fc8b2e76f1103e2cdef52f7a5ef6cc6e80eebf971c7ceb8f340fdae", + "python/pyproject.toml": "340370c7899416a9dc238a99cc4a19cd82fa8f2d883912f68ae2236cdfa2c44b", + "python/requirements.txt": "eae233b5d089dcea887c4ecd88076d4bb0cbf23f46bc7ec21bc9708c9b58aaba", + "python/setup.cfg": "97b6dd29221e75e0618680edba9b01c31d713eb9417f6c987931fb6bc90c81ae", + "python/setup.py": "b0b4625b090908c5bae630ca9eb46b8c06a84563aea15c44e7f76ef004dabff1", + "python/test-requirements.txt": "89cc4a9051f4062b04fb5d6dc01a98f053e7fbbe6d0c54fbf8f73497c0fda556", + "python/test/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "python/test/test_add_template_request.py": "6ada75e7e7266f40411d70a78a3384fabb1b830abdc91206fdbbd21c874e69c0", + "python/test/test_block_user_request.py": "e46f1ebeed9ee9e1fc19ce4ca8055de7978259980292e210c49f1e453a66adaf", + "python/test/test_calling_api.py": "22773a01b3d6c36920e1ba304dea309a68b6f6e41238130f4504ffca0670f1bd", + "python/test/test_calling_settings.py": "532e020cf02cd55d6ed0d1f048e3961d411750ad66a0072552b3b13665fdc716", + "python/test/test_calling_settings_calling.py": "eb811d3f4038d204df9551be059d8ae6ee157089f85a558180e2b794e202aa34", + "python/test/test_calling_settings_calling_audio.py": "80194fd02da36ac1c73ca72eddfcceb2dd4961922a0e1f00470757b8c8490f8a", + "python/test/test_calling_settings_calling_call_hours.py": "67873595aa6c55561ffff043aeebfe7c4f27a85e2e7e01f789b917e241c9d0b9", + "python/test/test_calling_settings_calling_sip.py": "337cf3670186d4d9f8a58a8af9343a37afbfd2d0d27cfafa45e6cdd346dc45e3", + "python/test/test_calling_settings_calling_sip_servers_inner.py": "a1f6b60afaddb7ad56c2c14811894d2032c6318a5c559abc86f0701ce50fa96d", + "python/test/test_calling_settings_calling_video.py": "fd5b1757e69a29bb8f01e3cd1f8f4c54a6db07bd2c3ebec3b97a40c41d9af947", + "python/test/test_catalog_api.py": "6d31fa84759141b3188c683c6723f30261fb1fbc409d832fd48c0b4ab0ba40b2", + "python/test/test_channel_api.py": "49cad49a8c25ed971e47997128550101dfbca7aeb9b4dcf036b161700411a893", + "python/test/test_conversational_automation.py": "b76f725c8a2aa687d2d8a96d75ee5d31a124264b2a90522dc1dd9471e78de26d", + "python/test/test_conversational_automation_commands_inner.py": "e67ecb2b6d9725e9bd232ad10d7824a52417d62ac67416b101fc959d47ebaaee", + "python/test/test_create_commerce200_response.py": "c98d244164a2c2663d3990e2c3d518060e6b064a68db37482214093baa67b1a3", + "python/test/test_create_commerce_request.py": "be50df13420316ca48b946df09beae30f11b3861c3405d0cdf185ef1e732d269", + "python/test/test_create_commerce_request_params.py": "8998f8a11ee58dfbf7b375a7ccbda6d9a258739da1856ca27a0b55a6b84a3549", + "python/test/test_create_groups200_response.py": "1fde79dd809d5b0590e6b497d9173523705b5b30c9055b7688cca39fa7607791", + "python/test/test_create_read_message200_response.py": "9f272309c720f67b258417318213333f895b65800f5d2d2d60fd6375f092608c", + "python/test/test_create_read_message401_response.py": "b11a230bb18d62cc1693a5db09c0be8ca58f111bb89b5b348421f216657deaf4", + "python/test/test_create_read_message_request.py": "a4e8801af84bc581546776ae878d835683a5bb6bc42b572c6576d02372890bf8", + "python/test/test_delete_flows_flow_id200_response.py": "2d8abb92c8463ddc15e262d963b244b3f361e7511f69a7994d1c9cf4e4921e11", + "python/test/test_delete_groups_group_id200_response.py": "7ce89129b828a0a2b6b2c56810b47bcb2f98a58b554bbf6e4eb2f7404c41d3f5", + "python/test/test_delete_media_legacy_request.py": "7dad0a56b23cbbfb6638ecac508ad03756e5c644af1a5fe177f0577988cdcc5d", + "python/test/test_error_response.py": "d79b2fe4de70e63678f8ae108ec7a85e48d119af95a8506f60b5e341f60600be", + "python/test/test_flows_api.py": "72080224956e3b3f590178f702c593d6540f93cdf33d77ae929d2885c1f30ee0", + "python/test/test_get_commerce200_response_inner.py": "790239c031ba3c5e4bae1bc4c623023fef29b98bdc935e43480a041ad6f19fcb", + "python/test/test_get_mm_lite_status200_response.py": "4e4e7d7d7fff9f65d971fffbee6bb58eba55057d33ed87ffa46ee8f07e0096c2", + "python/test/test_get_webhook200_response.py": "ec6ab7a37cf1089c0d013a2e8271d6545c787f770ad7bae9882e2d7dacd0b5be", + "python/test/test_get_whatsapp_business_encryption200_response.py": "d27959a6742d68a3bf2bd589353552d1bb0f97333ffa4f31bda48b3f1fcff3a1", + "python/test/test_groups_api.py": "9ddabe8561d182ba8df4bb61d7841d0b3c87cca344dc584a6ee6871dc69c1eed", + "python/test/test_initiate_call_request.py": "10dc1c582e3cc726b4eee51156710d2078ec6d960407b635c7802d3e81ee79ab", + "python/test/test_initiate_call_request_session.py": "6069c1d55968e7663279f241d57d522cd7c58975dee27580eaaba13b2eeb9875", + "python/test/test_initiate_call_response.py": "8372be82326168aa3a965f767e506f4800ffff25c8880eb18ca7bf20f29bc494", + "python/test/test_initiate_call_response_calls_inner.py": "5f28ed0e9ddbd9e39379e9fa4f472b9ffe1558239fda504217dffe72bea415fb", + "python/test/test_initiate_call_response_response.py": "22ae0c959e96e0e976684468520415d2b0e7aeb10d2a8a689344198e7cb44ece", + "python/test/test_list_blocked_users200_response.py": "e6ee616363e90684ac43dfddf5dee70db0d4dc0f59d28c8607877ea8e65a6e31", + "python/test/test_list_flows200_response.py": "c8e1f92c08118787337575e2713dbba05f154542effd89fcba88bb223557270a", + "python/test/test_list_messages200_response.py": "9a2cd2ce70b593186983ac841c4a1a8f077642cfd54ca2a30d750fe5f1370083", + "python/test/test_list_templates200_response.py": "89a5db872f7de3b266051ffbddaab4fb3495afd07845855ddfedd0106eca9dc8", + "python/test/test_message_sent_response.py": "2de78dedbfe589b6cc3f7ca30b061d08cee086990396f1abe7dec5974c26c643", + "python/test/test_messaging_api.py": "ca7b866ee943801e18ad47a80caf28fb5ed8b7f6771a461b2d4be69ac5a4eb2a", + "python/test/test_patch_flows_flow_id_assets200_response.py": "4090d39514ba7d783939a81bddc428ab8cf4f4d66f186350feb704e40f5694f5", + "python/test/test_profile_api.py": "2571556004ce9e636906abfdb85b99d6c0c9c07c077e6d1d199eef1e1448a645", + "python/test/test_profile_info.py": "bea04ffc6498c9a8964a97e88fcea8aa22d97139f589d99dfaa870ef640d0f82", + "python/test/test_retrieve_media200_response.py": "27456ad675e15c16c4292b9aaab84290dac276a4f45ba44bed46e1b0a66c02cb", + "python/test/test_send_address_message_request.py": "c6fc5744b6e55d352fc3945b7e5544f1842a104a1ac3a81601165f1605564c80", + "python/test/test_send_button_request.py": "c260a4c71a2666372cf3d5bdb637b192a9f8fec0dd6b6f5d705c2691a1ac112e", + "python/test/test_send_button_request_sections_inner.py": "c18353dc37a88f6c69a7992c60edda0d8965ff42ec3a15707170935b786dc8fb", + "python/test/test_send_button_request_sections_inner_reply.py": "8a8c06082eb389137b0966d1e6c1a88118f70efcf34e53f5430a0d0eadbc8a9e", + "python/test/test_send_carousel_request1.py": "6fbb2f32f9ed6bab65cc158ef056d3cee666c6b22b5ee53fb28b275ead6d849b", + "python/test/test_send_contact_request.py": "a5632a54abd03c866ae02b05305adefd2c58a9136f2349e8655b8b519765dff7", + "python/test/test_send_contact_request_contacts_inner.py": "bcc53254cf69c4e3e24332bfcb7dc727c9577ef724b1bd56505af5db2e242ec2", + "python/test/test_send_contact_request_contacts_inner_name.py": "4748d526dc49f1c665db7f982fa3f7432c372d65b33ea04444e862f1be6843e6", + "python/test/test_send_contact_request_contacts_inner_org.py": "c32ee077d81812ef5f58a163d9ffb217ceb59e07964adcac061edf1cca9c7da8", + "python/test/test_send_contact_request_contacts_inner_phones_inner.py": "ab433cf2998af961800699679e4419611a4e89335d4d4d48f3c74b436b24b398", + "python/test/test_send_cta_url_request.py": "a73be4ca1357635b941827da603044343befee8ff3e246ba41e6eb644c45d6d5", + "python/test/test_send_file_request.py": "d2b164ec1b7329c4fb441e7c8ee04823afd9d6ef16740d1709ac00a6c507c731", + "python/test/test_send_flow_request1.py": "c943437e898b4bf5d9f47d7848db7c599d7b17a00006c3c66f03c75bc522a7bf", + "python/test/test_send_flow_request1_header.py": "0b65b66b76bb6b1eaeef63bfd921aa837e925526631ce6ce12e13a15ab368e99", + "python/test/test_send_flow_request_header.py": "e70da4103ab1d0168fc87d5c54ecc83f4c624548bb9d8f0f02e471505270a0ac", + "python/test/test_send_list_request.py": "be84d6abaacb745b68f0386dd6b5c9ba9c8f58e8bd9b366c59202a15b32d1e40", + "python/test/test_send_list_request_sections_inner.py": "4d2ab43fc138558eebb80f08fc0d84054dcdf0544d5f05242555a95084833e80", + "python/test/test_send_list_request_sections_inner_rows_inner.py": "6fbc826b38af0df00467ab7b7cb8c8c5f8a87ddc69d3eb5cff4c08741331cd07", + "python/test/test_send_location_request1.py": "e8eb52c7cae40057f305f8f9596ffaa87bba5714862da92da621dc54bb5ca9c4", + "python/test/test_send_location_request_request.py": "a3713fb01d058a97e70a8adeab05b26a9c85f042919de9baa03c7113c5ebb0c1", + "python/test/test_send_message_request.py": "75d25d3a8456a65dd8cecf4e2bc4e6522dffd12b9c6d91ed1718f5feaa3f8c58", + "python/test/test_send_order_details_request.py": "665e667754664333355b35c90a52a80a9a060fad86f2a5aee40a6763d381abab", + "python/test/test_send_order_details_request_language.py": "07a1353ee9a8aeeb541311fe98a680843f60c20bbfe8d3ae8a5d85fb31f98581", + "python/test/test_send_order_details_request_order.py": "b2b1fbd5133160988c7885972e24305e590e741da2217c15e404aa9a09f21b72", + "python/test/test_send_order_details_request_order_items_inner.py": "14922bf20b7506af62259cb448ba45e40418f5dbe052507b79ed1c1007cb176e", + "python/test/test_send_order_details_request_order_items_inner_amount.py": "b9985ea30a51c4ef626192cc0dc54ed50e77f460f0c3ba47001549fdb19e3d5f", + "python/test/test_send_payment_request_request.py": "baf4db441717079109872acc25e1fcfdcace53a284c60063661e048c35b3b120", + "python/test/test_send_reaction_request.py": "0d2aa516482d046b67e1d2e60061af5756d631ef522b020dafddaef9503c386b", + "python/test/test_send_sticker_request.py": "569c9983d9e1561d1d1a52bad5431a1ca89b63e40f395b0d29d4185e07ca93de", + "python/test/test_send_template_request.py": "c70847836f76bcd19a0f05350d0384ee657872d3837f5616d938d9edc5626a53", + "python/test/test_send_template_request_language.py": "bfabea90ae43d6a9d9de581a53ee0395946c77ce64a046d95e9f272c1b76db4a", + "python/test/test_set_whatsapp_business_encryption_request.py": "6b9560de24c8741a36636a00f6f49b17e09eef550e38801d1b97007e6c653a13", + "python/test/test_success_response.py": "91eef5583e12f56602482d5f37805d3e3111c3a93762df7afc5b38e4349af4f5", + "python/test/test_templates_api.py": "2766a91ca749f4881475faf1db2b05e58dc9f18dff4045e9b35430882d982fde", + "python/test/test_update_calling_settings200_response.py": "3aa33ed7f33ea0d476b61f19b6220efe64b7d0b3fb43bca35a23699af0a643e4", + "python/test/test_update_calling_settings200_response_response.py": "529fe284a9859ced0006d010431b120ee283fd4144b090998f5a7dae348711af", + "python/test/test_update_me_request.py": "e131390b6fe53e20818ca3601d01d0d36c7c68d4ba3356c4e05d5b9fd21ec840", + "python/test/test_users_api.py": "9c10db7b3af70aacab08e1aa871903f72cd1185c13a60ba73f855aeb64abd9cb", + "python/test/test_webhooks_api.py": "84390f09fead9548effb59c41df0af53a63a1993a3de974fb866d86c6fbe78cd", + "python/tox.ini": "f66ea36533aa9cbc05e4b589d5c51419a4216a4e353f4b06fcd05b2c652497d2" + } + }, + { + "id": "native-rust", + "owner": "1MSG SDK maintainers", + "issue": "https://plane.1msg.io/1msg/browse/1MSG-156/", + "expires": "2026-12-11", + "reason": "Native rust generation, frozen dependencies, build and offline contract tests have not been verified. Sources remain byte-for-byte frozen until a reviewed language-specific quality profile replaces this exception.", + "requiredWork": [ + "Pin and replay the actual language generator", + "Freeze dependencies and verify native build", + "Add offline required/optional/error serialization and package consumer tests" + ], + "baselineCommit": "802e13a13a3bb11ec25e68258c3bd0518dec8d53", + "roots": ["rust"], + "files": { + "rust/.gitignore": "3c190dc8bc9f793ca5c8d1e5f01b329ea63b2853bc9e8a3e18da63f7fb10c5b5", + "rust/.openapi-generator-ignore": "a6ed8f4e275eee926d27e0c52f30f2d1c4d8409465ac1fbc4511f7cc62de51db", + "rust/AGENTS.md": "02c4468d846d74beba7f7612e87249e110d89157a67d0f4ccf1b5cfa09b91b58", + "rust/Cargo.toml": "fc21935b710544a56a0b5f9ad158482593e95b644abfbdebc2a33eb7bef01e3b", + "rust/LICENSE": "88170a8e4e7b68f13a057d5b9e1882d4b60c71e0a762b5a95651931a219835ee", + "rust/README.md": "2b28b66abd3581c4eddea85a5ed23cb31287045843316e80efb43736d28a4259", + "rust/docs/AddTemplateRequest.md": "4fd86f839819085446772ab94e93b118667c26c4469d61a2badee2471e846947", + "rust/docs/BlockUserRequest.md": "fae50b2e1438ccb4782da865b91bceaa02c72e1348a0f524ecf7b6470e79200c", + "rust/docs/CallingApi.md": "44105159c946221e06cac9420db02c030d7e2df9c207f9b315aee0416b50104e", + "rust/docs/CallingSettings.md": "dbb02c09c37f60537196589786ef2fe81cc9f4651c46a302676a071aa2507718", + "rust/docs/CallingSettingsCalling.md": "e28f4c99c265581b65588175a71b4bb21fab4945351848f4a1683f5eb873e325", + "rust/docs/CallingSettingsCallingAudio.md": "f15c0d2d2854437d734c832f3a3db01269b4213bf53a45de3eeae0518d565548", + "rust/docs/CallingSettingsCallingCallHours.md": "c27522f8b18644b854f7add78fa0ca8853266bcb78521ba26c3d4f91840e5257", + "rust/docs/CallingSettingsCallingSip.md": "a0ffde6aa2dd0ca313e099232df07da6555023707ac0ec962862383c434d1e70", + "rust/docs/CallingSettingsCallingSipServersInner.md": "8f76e18c7ca12d075146765af952036936f0ed197172225ac0e1398ab7e4e9b2", + "rust/docs/CallingSettingsCallingVideo.md": "4f622f2c509711f9f7db9369eb5abccaacbafd8d4edaa14bb54f34828a2880a9", + "rust/docs/CatalogApi.md": "a3684a86c5a81c68aab5cbb38eeface645e087e871181963642b0e91cedc2e68", + "rust/docs/ChannelApi.md": "3c951ee96683a592b0d3acfabfeb99be6552548e88b2a6fba05b0fdd1449c594", + "rust/docs/ConversationalAutomation.md": "17552c156aef4ef9aaf2f40b8927bba79e7b7753cce7113e08066895c1c9c9b7", + "rust/docs/ConversationalAutomationCommandsInner.md": "4dcfa0b66f5280691c86248d6aeebe8c5bf16d7283c3ba1aa382f36d7406fdf6", + "rust/docs/CreateCommerce200Response.md": "ce704e4fc2ef7f8f18573dc32ded596c0d15a4d272bcc69f762d9e89aa3da3fb", + "rust/docs/CreateCommerceRequest.md": "996eab9c1276fbb6ebae1d7d40a17224b84a64ebf671a0b0f8f4767b0fc5312a", + "rust/docs/CreateCommerceRequestParams.md": "92f71e4838f94ba41a18b6df1cb79f616757da46b3ab91ea5ff019fb3f402e40", + "rust/docs/CreateGroups200Response.md": "539da719b5e50c32da7f2a0b7b21c9aadf0ac20992231c19b8d7c119e9a5348e", + "rust/docs/CreateReadMessage200Response.md": "8d8d2f0c0e7afc77ddc12999eecca37a05a42813a6d3faa6822213eda09ac6ed", + "rust/docs/CreateReadMessage401Response.md": "dfb48bffe164089e933d76c5df39798762dd5ffbcfcb54c7b5a2f46aed7f9d87", + "rust/docs/CreateReadMessageRequest.md": "2fb12ee481faa1c74dfb8e4ca7f05e5a4a05c7ce11ee3a389284e359bd3374ca", + "rust/docs/DeleteFlowsFlowId200Response.md": "6726e8f2a2e03cb6198d82c1982080a8e5606279bbd57956f07c5b2e340ecbb8", + "rust/docs/DeleteGroupsGroupId200Response.md": "cd69385a25bc1f86021e77fc8f5c68430b4c754d55859b2ee7dd10c576a3536c", + "rust/docs/DeleteMediaLegacyRequest.md": "8190b83555a0debc9036dccd80b4031bb62dbe8769c7953c355ce241d055e5a8", + "rust/docs/ErrorResponse.md": "ec1950f4ed7397669f8b35f27ac853de55e9e0fa5b6fe0d9b86dcdedd64ef49e", + "rust/docs/FlowsApi.md": "92ae70482837f4b72e2cbb67df60bfdda7c36097e896b6b9975bf1b55b75f713", + "rust/docs/GetCommerce200ResponseInner.md": "ffe4249a3893249a2bd51f152c7fd5c452b35d97c5a3b97aa76fa26ac5d2a033", + "rust/docs/GetMmLiteStatus200Response.md": "312abb016d4d02f5882032858642a0f5e61ba3ab1ea3a142935febfb88e84af8", + "rust/docs/GetWebhook200Response.md": "9f9d43a023029b733ecc3dec7f329d1aebce6ba1f2c8509517fd2d123895ee28", + "rust/docs/GetWhatsappBusinessEncryption200Response.md": "5e51ea845b6639babb4289645de897511feb6cf3f37927638e0af727b3e9fcf5", + "rust/docs/GroupsApi.md": "45e76bf5f94179713f8480e3495536b3dc306c52da044b4e3b7f99f7f7106bf9", + "rust/docs/InitiateCallRequest.md": "37f88d450a30c1f0dcfeda9e3d50d019d6618e9298b2d9bcc8484c29cce2886f", + "rust/docs/InitiateCallRequestSession.md": "613dfb0ab683b74849a76206c80e32c0e0245fbf824a06a4901d1b371cb9046e", + "rust/docs/InitiateCallResponse.md": "7e43f9a0fea6bcc916f91e203042f667a51db1030e0c6ed6d3088ec20c25e5bc", + "rust/docs/InitiateCallResponseCallsInner.md": "c2def4362019e1c188efb6cd577138a29374c0dd2bfbb66bdf896cd552deae6e", + "rust/docs/InitiateCallResponseResponse.md": "2887737f27ebd04d24712f8ecd12855bba5ab29858757c1fbb66aec5290dcefb", + "rust/docs/ListBlockedUsers200Response.md": "bb9f6b7ca20f7d42fb5b258f0f6266feeb3ebe8e9648743c94fd61acbc6d890b", + "rust/docs/ListFlows200Response.md": "b490cbf5addb58c409f554496bd43e7b5dd00385bc7ff1e81ea8cb59772f0a59", + "rust/docs/ListMessages200Response.md": "0751529b5a94bb1405e90868c0da70df6ac66226c302cce18203facf4002b683", + "rust/docs/ListTemplates200Response.md": "24bacc44dca02e2742325ebb21795f1b288c383fce47b0e2208d021ca92de133", + "rust/docs/MessageSentResponse.md": "30511f16946d1f7e7840cfec2b96f86d807a6a19d3a5fdc430f2b3b94a1c613d", + "rust/docs/MessagingApi.md": "751b798823f1f056ef532d6f5df809a9a15fcb458188b77f232a071df0d0a5e4", + "rust/docs/PatchFlowsFlowIdAssets200Response.md": "94a66dd33f26bf3be519cd9d61741294d7a1bfc37e0937ae811a0cbb829a26d2", + "rust/docs/ProfileApi.md": "fb369a255086f6be71d03faedfab731a69a8c7f61a588ec2e05704b7e63997ca", + "rust/docs/ProfileInfo.md": "e93f6f5bff431954b61de58a0457abc1aa56059de3691367271e1c008ba24d60", + "rust/docs/RetrieveMedia200Response.md": "eabc8934e40787039cec99c28c78ad7b67bfb3d2722a6e909886ab27d419ee38", + "rust/docs/SendAddressMessageRequest.md": "7b8f8864b8733867f8219c39269bf66b2f988e479a2198d195f7873ec8dd00b7", + "rust/docs/SendButtonRequest.md": "5ffb9d831e068e92d005d2f813e044e77d9f4edb56fd7dfe7cf5c9d8fe1786ed", + "rust/docs/SendButtonRequestSectionsInner.md": "e02f43a95c6657a9865a873d0c4208a0fd0eb8c99ded5555b8a2eadc93662e62", + "rust/docs/SendButtonRequestSectionsInnerReply.md": "a2b5475839a70e84ff0f01ce302bb5b2f64478977c7f69be85de9343ec7c9d33", + "rust/docs/SendCarouselRequest1.md": "21f0fcd939c971555dd84177296582f199e0d62bf82f3c59eb873653c8d9c7ec", + "rust/docs/SendContactRequest.md": "6fbb04fbd4e570b4dce242595e43229e23f43f6892a0681a94f4c3b69c1fec07", + "rust/docs/SendContactRequestContactsInner.md": "78a7b10b3837f9ebeceea0dd594a4426a03b94dcc7b6cfa61f58838abd6d2725", + "rust/docs/SendContactRequestContactsInnerName.md": "fab72c312c80f439631723491d757a0d590cca6a765e17e350a64fffbbb0ad69", + "rust/docs/SendContactRequestContactsInnerOrg.md": "a76fba830b148775fb97b490e7ad7bc94589a35176f79b8e9161a71910e3032a", + "rust/docs/SendContactRequestContactsInnerPhonesInner.md": "ef7c6e35e127d78eb4eaa48dd88ebfc3c5abac5da1d13424fd60fbe9b24a5b92", + "rust/docs/SendCtaUrlRequest.md": "34f73dd9d65dbd4d0e358444488f0369adbb58b040c8db3e044f68190e8ad7fa", + "rust/docs/SendFileRequest.md": "bcdfb309979cd263661b07f823caa0721f3377732584ec37eb789e5b0fc70183", + "rust/docs/SendFlowRequest1.md": "cb36901b9f3276e226865cc8a77bd19dc855535ffe5d776cdcd357a50dc825a5", + "rust/docs/SendFlowRequest1Header.md": "631cc405596a21e2b450693162266acfc9185b0a256bd2b3d5cf2e3d365dfeb4", + "rust/docs/SendFlowRequestHeader.md": "dd03adf740666001a7a928da1913ee2ce75367f2e6be76d4f4ede080ec08507e", + "rust/docs/SendListRequest.md": "accbd560345f6d885d42c9c286bc9ab3a26d6da2cb2b6f4f0a54a641ae03f8ce", + "rust/docs/SendListRequestSectionsInner.md": "96f83deebb3242bb1ac2189a36b11a3de7551d7bab6c07c5e987a7f61107e81b", + "rust/docs/SendListRequestSectionsInnerRowsInner.md": "57fa19a82d0466d0612d0593e4d0e54a1e0ecd4972ab3f72b440c1291122b206", + "rust/docs/SendLocationRequest1.md": "f1edb629e0f9daba56dc10fc6f13a86eb5daec86485cf157f30542b3c32ebd00", + "rust/docs/SendLocationRequestRequest.md": "1627eb323387edc4c7dcad0f1fe5bd2fb481631dd5b9816aa96a271472c5b4f1", + "rust/docs/SendMessageRequest.md": "d7dedc88f1e6e36f2d9286fbd62dd4eec36360c5d1b89df1c48d5890334252fe", + "rust/docs/SendOrderDetailsRequest.md": "c9e05f4a3171022cefcff689674b28aac17775bd55d34326d3f48def499049c8", + "rust/docs/SendOrderDetailsRequestLanguage.md": "1e8a203398b04ba9c218642693a3cfbb4aa75f95967932b009a364ecd9fec5d3", + "rust/docs/SendOrderDetailsRequestOrder.md": "760d0ad2aa687ca7e516131246e6f20734c8381f2e3089fb97a14b4c2399886d", + "rust/docs/SendOrderDetailsRequestOrderItemsInner.md": "c2016fe9c535ce304b9c5024b935b27a54992c7a6175d08e573dcef3faeb5096", + "rust/docs/SendOrderDetailsRequestOrderItemsInnerAmount.md": "d6f26beebb62acbfd4270c3532412f23a4335d0a95536ed93cee76b519284f1f", + "rust/docs/SendPaymentRequestRequest.md": "b07267fd6f4ccc2cfe7632a0a8bf0448198542b9f878082d2df037e049014efb", + "rust/docs/SendReactionRequest.md": "40e2b7ea9f83ab4c950bc95adaca4068b1b76a8d08047c8ef4f3f992290cb51c", + "rust/docs/SendStickerRequest.md": "17218f981774480f5f68a2d06dc57109d1e650ab7f9c67bf124578634f625aa3", + "rust/docs/SendTemplateRequest.md": "357a6ee82a179b87775c53dbe3f114803517339931d1242a876725825b17aab3", + "rust/docs/SendTemplateRequestLanguage.md": "b79e242b5085fa604d558b3a93cb799a51eca135f1d2a8b334844d325492970a", + "rust/docs/SetWhatsappBusinessEncryptionRequest.md": "82c81a09a64130599a3852967b2494e7a9b1b14fd9d3a8a98e3cf0c88fbb0c06", + "rust/docs/SuccessResponse.md": "4e9cf673f12cec62ce79387d1414d443cccb48fef951477dfe3e049d2a0fd2a1", + "rust/docs/TemplatesApi.md": "24dfb5f6d5409de1f21467aebc4150c3f0f82eca45c98d806b311cc76b004434", + "rust/docs/UpdateCallingSettings200Response.md": "5c7983285a3afb96a3473b48345bcc758544451b71ce8e1661549495e4e85282", + "rust/docs/UpdateCallingSettings200ResponseResponse.md": "6b2b97b17e52c194dcd0f5113c2ca67a5030e88eca24394b6324826bccfa27b6", + "rust/docs/UpdateMeRequest.md": "1f8cbaf6d97be64c665e7111787ad4efe2205344eb7dca6f5441bd5a52e1f117", + "rust/docs/UsersApi.md": "62e858eb777bd23b330ad61b8f2b92987324a95801e1f6bbafa766ebe9a57501", + "rust/docs/WebhooksApi.md": "7a3302502a5b7e379cf0561f77eddfd7ad2487d6aa336039ae7cae8ff843aec4", + "rust/src/apis/calling_api.rs": "8344e5de1bb241ea785c02dbc9defda1f2f7531e70bcabb3188d51bb6300dbaf", + "rust/src/apis/catalog_api.rs": "9e0a7fd20b2c79d62aef2ce431bc4a33ccfc13be5d1d5ad29d0f8defda296307", + "rust/src/apis/channel_api.rs": "edfd962519398fdf8940ccdcff3f434ce3f3cdba65d38ec1d6e61bff75a59a74", + "rust/src/apis/configuration.rs": "df96e3db14f7c598f6f89a92360b494c988faf1a206bc335cd802f0263c918f8", + "rust/src/apis/flows_api.rs": "dab37ce2e5ab0c4fe296b7e86eb3099a2933a857572b13dfa2f70978459518e9", + "rust/src/apis/groups_api.rs": "93bb5e97a350c361165d5757fac7797dfbed385f878fb3f40718da68d6f02df4", + "rust/src/apis/messaging_api.rs": "f82f45b5f3ce17233d18245607158e5826936b48b9897477aaec60fcd4dc2388", + "rust/src/apis/mod.rs": "8489a35cfb88cb306fba384f0704686f32900425f460ad5146cb1587dac8b5e1", + "rust/src/apis/profile_api.rs": "9f100f9d60b112bfe62485de44b61acb656cb29942e4d70b2aaab832da1686a6", + "rust/src/apis/templates_api.rs": "938df9eac03e08f1a9796e6e5e4a4d0b91b2c09aad3f0779cbc98821b42b2fa4", + "rust/src/apis/users_api.rs": "a51bd51b3cef3f1b26cba484408a1bf41d0dfb3aa3d7cee38101f1c27e8a8ad5", + "rust/src/apis/webhooks_api.rs": "b8421adaa1ab02170cab328b55109c40abc771283d7e0ad08148ee8a0456c6a3", + "rust/src/lib.rs": "590ed4d065b9647efa83aa34b02460309b71bdd141da66af9ebf75600e1e2a71", + "rust/src/models/add_template_request.rs": "8f47a3912ba03b41361b8d484f8d7225dd97581eedaeb59df36f9897bfffda28", + "rust/src/models/block_user_request.rs": "9725c73b7c1d3c9d613862e3e5625f834fd63aebc440f10f0a16f3a378336d96", + "rust/src/models/calling_settings.rs": "bd5c752acef54ed5a54fd242c167531de0b4bcf9b824a1bce61ae15d609b9071", + "rust/src/models/calling_settings_calling.rs": "a71fd9187c71f7939c1fc82a2844bf1a04d92af6affd2cd4ae09ad86a1881c1f", + "rust/src/models/calling_settings_calling_audio.rs": "99aa44c7a0507f7411ae5baecb0e61853432f93280551af0f5903cf58d7228eb", + "rust/src/models/calling_settings_calling_call_hours.rs": "575652b0f07e72142e23830178b336e67c95015ea3586d850b3f6053faecd872", + "rust/src/models/calling_settings_calling_sip.rs": "6752ec080e85085b8c97c49ac827d5c3c0e3b72907543d81d9d34004c2e688ed", + "rust/src/models/calling_settings_calling_sip_servers_inner.rs": "0e17215930a90a4bfff662ed1e36d9aff7527d66241585791327e507f64355a9", + "rust/src/models/calling_settings_calling_video.rs": "dfdd9b7abd6a452d0366e4e049657ab7b658d51627c4affe85a108bbcb2e8b51", + "rust/src/models/conversational_automation.rs": "34415cacd2b31c7c36312386d2316a8fd9ecc2a2f9ee45812b46ca50d1388264", + "rust/src/models/conversational_automation_commands_inner.rs": "6cb5acf3bbb8a7797e8347aa6897dabf1220465e4a4c00284c13dc1a31f9d7f0", + "rust/src/models/create_commerce_200_response.rs": "f9477511ef8c9c19b78fbc9f110077b7a52bdb87b13474dcb6e8c0e97179e851", + "rust/src/models/create_commerce_request.rs": "0a2c372ce86196675aa3a3ff25adfdb9d9e32d550cfc1228e0138116303b555e", + "rust/src/models/create_commerce_request_params.rs": "f4eb08d48511e4d9f2ea0dba2b3b5c791a22430823cf53a5a219e29d9c3b9789", + "rust/src/models/create_groups_200_response.rs": "bbf7095dc2275e5192f2f62194cbe357c98cbcdc800aac55ef44caed14b13bfb", + "rust/src/models/create_read_message_200_response.rs": "ec25b92db0bdb563bb7b67b614edbba7f68ccfdc9f658bda10657ecd58637f05", + "rust/src/models/create_read_message_401_response.rs": "e14c2bff0b04fbba65fda96a0977978b188de3c5780f1dbabd56eeb7a41460d3", + "rust/src/models/create_read_message_request.rs": "2320feaa8c580f00617c5916168f87d6bfb8419eea595d8a8ea75ae515b5b079", + "rust/src/models/delete_flows_flow_id_200_response.rs": "6e055aef5749b24ae2d951df6cf1e3bfe0030747513f1c015419829bc67a08ab", + "rust/src/models/delete_groups_group_id_200_response.rs": "c4a0e40c1f0ddb238f7cc53b42906e0c744ac56663fc41b125b09c34cbc52af7", + "rust/src/models/delete_media_legacy_request.rs": "72fb447556ece955012c9d931ecd67a6e41ed51b9467b47976d7f95aa75b73ff", + "rust/src/models/error_response.rs": "d01f538acfb34371b63d87f3bff38d6da19fdf9dde96f86503a443fe1231c751", + "rust/src/models/get_commerce_200_response_inner.rs": "bb0c766ca735465ea5563dd801402da98385b888c655da6c40711d32433cfb21", + "rust/src/models/get_mm_lite_status_200_response.rs": "20bd5794d2af6c188bce2386bc08ad11ed2e8f5ef4727831bc35c9487e639d03", + "rust/src/models/get_webhook_200_response.rs": "fa4b8abf51081cd546eb0fcf4bad99bf81faa5c8ba58e93de30a4ea41e2c8877", + "rust/src/models/get_whatsapp_business_encryption_200_response.rs": "e44eb21b4bc86e00f8a26af03601006f7512c20b25f24547233161c017133267", + "rust/src/models/initiate_call_request.rs": "0cda42486a4b1e413bd2eeb6dc7b4b055ab07bdc36f7ed42ea7dfdf42664db13", + "rust/src/models/initiate_call_request_session.rs": "c7a70bc11fe3f8815cc65da4eae95afcbb2e7693f6fae8e01af67d07daaaa98d", + "rust/src/models/initiate_call_response.rs": "9280536d9b9b8b03f77b9a560707aa9d3df133c340eab94d5ee0809f736c4f35", + "rust/src/models/initiate_call_response_calls_inner.rs": "dc659baaa4192085c2f5d254719a1d87bb9ec4eb8de041723cd151cd9ad185f0", + "rust/src/models/initiate_call_response_response.rs": "92d08e9943d4c1e4e0967706e949f5106114f62240845f2cb6be39c8bb8a12eb", + "rust/src/models/list_blocked_users_200_response.rs": "70bdc12046e3be6efe79223ac1c7f3ecac19224133d66d019bdd549cb939d699", + "rust/src/models/list_flows_200_response.rs": "513bfdbd1c629d14d96cf53f0abd1316aefa1884723703ccfd2505ada16c5aef", + "rust/src/models/list_messages_200_response.rs": "85f870457a1170ec70f55fd5da792143fe8ebc48270c0a679d7fffe3de159485", + "rust/src/models/list_templates_200_response.rs": "9dd9ad4c5672f81189ea1ba259bc5e95598af6a2dfb51b31ef6e9f476bc79175", + "rust/src/models/message_sent_response.rs": "6fb5cf1c47d50951c341f0478cbe36e98b8d663e5aa4946931578722f5f46ee7", + "rust/src/models/mod.rs": "ceef5f35b69692e9214afd01a99f0ffd2dd394927de5bf99016c33dab92cfcd9", + "rust/src/models/patch_flows_flow_id_assets_200_response.rs": "d61ac400c8581e43dd814bc7f15d4d64119b1d8342057c56ed723a0765ed56fc", + "rust/src/models/profile_info.rs": "6ac49ac7f3572535b61f50d1e07478dadcb9818adf716f67f1f7e06369c0c76b", + "rust/src/models/retrieve_media_200_response.rs": "32c15577e64ce0ed89e45dcdad361a798526eacde03028f475463fe74cefb020", + "rust/src/models/send_address_message_request.rs": "eec6eb08b2b826a2b8974b38baa2461bbd6ab3a5a91e8ef60c233bc8995f8047", + "rust/src/models/send_button_request.rs": "071f8e55d42ed5882fade01e636afa2c0f22994befef97ebff443c2c9ac8a313", + "rust/src/models/send_button_request_sections_inner.rs": "f8f1f62e1f9a7443cc3606cfc623571c1afbf97ffa4e72c5e64947e5b4f88d64", + "rust/src/models/send_button_request_sections_inner_reply.rs": "82acb5054da8632551ad8231ff8d5dce28669cf0460296169135eafbfe770e81", + "rust/src/models/send_carousel_request_1.rs": "03441f022e130ed9440dec8f43bee1cb78e381f4cc0f7ff8cb8dfe7ae72ca056", + "rust/src/models/send_contact_request.rs": "de81c0d41bdb9a119e0dce6e472875e49ea898a6c13ff9ed73ea3d23de953ccf", + "rust/src/models/send_contact_request_contacts_inner.rs": "79038b7e6d049f62c8ecf99e8210c175e88c54f7b54a0be4abc1284657d1f6bc", + "rust/src/models/send_contact_request_contacts_inner_name.rs": "00e2c59cb3643cace82e31946c0b567317169e205bc84b9c98f8861384074208", + "rust/src/models/send_contact_request_contacts_inner_org.rs": "b834030039b4f5a7e26928e49b4a54e41fef7736fa4b0fd73d7382b4501bd3de", + "rust/src/models/send_contact_request_contacts_inner_phones_inner.rs": "35b25a86d0c88c84d0582d409a42091afd2a2a78d5bf96fa34cc609a70028fc4", + "rust/src/models/send_cta_url_request.rs": "e021d1f6b9e27b29c44439d85db87a4b50f91b44864bc713ee6820107406ca2c", + "rust/src/models/send_file_request.rs": "4b81428034970f212dafd32d17e19d3359327df249d6e8632884ee29afcebb4b", + "rust/src/models/send_flow_request_1.rs": "9d9c25dab796db095b36b7880a8b0df20b2327844c45b5d9ecacb21f9ccbbc29", + "rust/src/models/send_flow_request_1_header.rs": "7d66f1f194aa1eccc49a421f5a78668abadb1d9ef457b3ae1f04795232049019", + "rust/src/models/send_flow_request_header.rs": "6d893378e4612930d84db403088d06f22684a1e9242c07bfaa1dde3214261530", + "rust/src/models/send_list_request.rs": "b9073e4dbf32396c17d9b727c89ae33076168c87b46453aacb3026477879e502", + "rust/src/models/send_list_request_sections_inner.rs": "88d43af0f9ef240d99dc3e5b4a117ae5f6290fc2a6b72603a10a5fdc73f8835c", + "rust/src/models/send_list_request_sections_inner_rows_inner.rs": "23961a7ba985911f485c2730414fb6e39077d06a14387194f33c330ecfd43759", + "rust/src/models/send_location_request_1.rs": "1b9c3f476c792f338f1332223f849bc92d0b7994b6fe11920a302ff28b3973a3", + "rust/src/models/send_location_request_request.rs": "6e19f0f70da00cb54ad465236dfcb603321a646a47042208c4f78a7e06b3b31b", + "rust/src/models/send_message_request.rs": "4ef481ad5fbfcb8d07c1c28d4e0b637a26abbb615007ffb165e5f2ca26a69b6d", + "rust/src/models/send_order_details_request.rs": "ebd55feab5ca500c0ebdd47a0c3f9c9364dacacd1f6f361a32d022872efcae45", + "rust/src/models/send_order_details_request_language.rs": "5ab6536a2a2444c261fde4173b3a587c62ccb4633cbac5e1f0ebc442dd9614d0", + "rust/src/models/send_order_details_request_order.rs": "f5d7489aa2e37d7f2f4fdd84fcd981c45cbec9b7cb857d59de05fa117ddea1f5", + "rust/src/models/send_order_details_request_order_items_inner.rs": "7c1c8bc34cca6f2ea5125869ec01be7000a75f868b9236b4b37913df8b27f39a", + "rust/src/models/send_order_details_request_order_items_inner_amount.rs": "5511f46e29618bc9221d8439bf5bdd3e850e97fe5c5ae8227f6540504fca31b2", + "rust/src/models/send_payment_request_request.rs": "01b39fe60f6659235251aabb15675539edd0e57093596ae3e8783b48a11fc946", + "rust/src/models/send_reaction_request.rs": "4b566365cf4a8f5e3398333ce9b59e00a9c0735f23baed69cc5d23527f241c6f", + "rust/src/models/send_sticker_request.rs": "524fd2c0678d20c3a5d5f6548d0e7db84bb89da9f080f1fcad6fe09b3613f3cc", + "rust/src/models/send_template_request.rs": "f0c3d3d6205e66f1d3911e451c70ec8a281c276c74d6b42cb08969cd3ef9d3ed", + "rust/src/models/send_template_request_language.rs": "7e9e79729aea5634cf12e6ec2402c9a8eb1eab0c89dad2577a99d969471cf089", + "rust/src/models/set_whatsapp_business_encryption_request.rs": "f9f066372c98663bec4293d0d635b00f23b6631d6a79027f77b5ccd4d9f992ac", + "rust/src/models/success_response.rs": "e4cd0e8f23bd6987b67babaa1f997daf6b2569f2eb04071a61fb07e3e0f8580e", + "rust/src/models/update_calling_settings_200_response.rs": "9a0c73e9c6f6dd203e75ddd5d455baa1b0997455135b01729500ad40859be9e0", + "rust/src/models/update_calling_settings_200_response_response.rs": "930336f7ded61204a82c4efdfa96e0fb582b76838a046eca1749fca1136213ce", + "rust/src/models/update_me_request.rs": "dc80c9f8d7199408a44993469ec3113c01ec88eda065a89a1340d55b32a9778c" + } + }, + { + "id": "native-ruby", + "owner": "1MSG SDK maintainers", + "issue": "https://plane.1msg.io/1msg/browse/1MSG-156/", + "expires": "2026-12-11", + "reason": "Native ruby generation, frozen dependencies, build and offline contract tests have not been verified. Sources remain byte-for-byte frozen until a reviewed language-specific quality profile replaces this exception.", + "requiredWork": [ + "Pin and replay the actual language generator", + "Freeze dependencies and verify native build", + "Add offline required/optional/error serialization and package consumer tests" + ], + "baselineCommit": "802e13a13a3bb11ec25e68258c3bd0518dec8d53", + "roots": ["ruby"], + "files": { + "ruby/.gitignore": "5e53e2400cee73b7d3a8a16dd9cf0bfcfc873468be87f26ced5e7c3e768cba3f", + "ruby/.gitlab-ci.yml": "ec8818010cb6d4871ae71a9838bbc79d933ca142c75a6b02bb0aaa0c5085912a", + "ruby/.openapi-generator-ignore": "a6ed8f4e275eee926d27e0c52f30f2d1c4d8409465ac1fbc4511f7cc62de51db", + "ruby/.rspec": "e3a05cdf2301e0e7d8be6b1d1137aa310d7d023575bb2f305df3519c6df5cf2b", + "ruby/.rubocop.yml": "d570bdcfdecc0f6f299c4e92b4939468002f3543833946076cb592999206d869", + "ruby/AGENTS.md": "8636336a3406b1ab4240018833d62b640760e68b1bc5aceb561ac3e0a7d6366c", + "ruby/Gemfile": "631eea1aeb59eff826cd4975334d66bdf7ad14d3feacdf35ed5b07f33548981e", + "ruby/LICENSE": "88170a8e4e7b68f13a057d5b9e1882d4b60c71e0a762b5a95651931a219835ee", + "ruby/README.md": "0805dac0e90ca6c196b23a06745e7c825001f7cff1e529420d233fec651c3bc2", + "ruby/Rakefile": "7db29f323928e004b528ce28a05c8cd6f6ef80cafda08ba189650713c496a72b", + "ruby/docs/AddTemplateRequest.md": "d42dc684060fead50b25429b93b771f8a49f2f95e522f9e4723f460793699e95", + "ruby/docs/BlockUserRequest.md": "ba1a4e3df7d0e6dc4b286cce82b829edfa56242689c56efdcd66541fe190fdd8", + "ruby/docs/CallingApi.md": "7d783b944759586da945d18857bbb97da7bab5396352957d1fb871ef2c501783", + "ruby/docs/CallingSettings.md": "e131d1d9fd86af8799614c58ed4008c38eb3fef9fe9a7aca4a7d28da7c1db94d", + "ruby/docs/CallingSettingsCalling.md": "0effb985ab3490cfbc7bb1d6fd49db43dfcf60de42265cff33e562f98995085a", + "ruby/docs/CallingSettingsCallingAudio.md": "dac5cf9620250a7eb5263a317e00e6070b2675437d1831b6deec32a4194433b0", + "ruby/docs/CallingSettingsCallingCallHours.md": "0c951e27c32e53cfa7c3c875f85af2a7dc1d7751442470fa0eebc6fb4a73dc08", + "ruby/docs/CallingSettingsCallingSip.md": "ee8e11c5fc615cda74092a819590711260e75758f67f2b20e1ad657d0413adaa", + "ruby/docs/CallingSettingsCallingSipServersInner.md": "905e52fc5b2c8ba174fbbef8c8e4ce792716b39191c8ccd46c01358c9802c51f", + "ruby/docs/CallingSettingsCallingVideo.md": "cc0c1ed769389228417e49f9c939c1613bc8a0de85d6283307bde8c679845935", + "ruby/docs/CatalogApi.md": "e50567244eca6bb9820b6e747910e18648511477574a485d1faa3ea5c0715d32", + "ruby/docs/ChannelApi.md": "bb9a10edf92fd9c86054f169d99b757f493b761da7f4d6107d68dd3e8be05de2", + "ruby/docs/ConversationalAutomation.md": "ae27f38fdd716f770ceb36e81f894f85cb73975e2c0aaec0189425d3fbd5c87f", + "ruby/docs/ConversationalAutomationCommandsInner.md": "4e4f2caf769f7a46f7f488a0f1a078aac7cb3963ab09f3aa4a35eddc3cdc75aa", + "ruby/docs/CreateCommerce200Response.md": "65ee8eeeddbdbcd0e75d57004ddd0eb19691c6159d8fce731a1220b201185c1b", + "ruby/docs/CreateCommerceRequest.md": "f8d092f8e919c2c108d1c04f83ad9973f26ad7cb4660108aeb3e362ecc87addc", + "ruby/docs/CreateCommerceRequestParams.md": "e8ac1a386d6c3d95f967f58446ab9393cd462221385d2b3b6df1a9db964917ea", + "ruby/docs/CreateGroups200Response.md": "4f49dddf90ba96d3ba6351af3772b16b60e70a13d09840d6f85e5193fed84d10", + "ruby/docs/CreateReadMessage200Response.md": "da26b457035fb03c4b2522cabc9b83f532d5f98d5eda4b6a2d679b300acb1b23", + "ruby/docs/CreateReadMessage401Response.md": "6da375abec95b241ed493256aec42319fcb9da076523b5eb7fa4a512e756bc1e", + "ruby/docs/CreateReadMessageRequest.md": "337ba11fe9e552e3f5fef0e3eb363d4a69d85ba215525bd3944674d3fc52b0ae", + "ruby/docs/DeleteFlowsFlowId200Response.md": "bb313da29501515a6e0727ae788f6b019e7bc3158b836a1393c887e26a15c61b", + "ruby/docs/DeleteGroupsGroupId200Response.md": "8888afe8386f478579fd6e541830ad7fe91482aaac738fe8f2d29938e0ccae6e", + "ruby/docs/DeleteMediaLegacyRequest.md": "a339180d9d2332ae9c79bf299561769def3a33745fc1928d0a37cee73da8f44b", + "ruby/docs/ErrorResponse.md": "08b63ac14acb975f5cb2b63f1e8a6075c267afe04e3ff196cd8c17457a224ca5", + "ruby/docs/FlowsApi.md": "96e286320154ccaaff9357cacec08d2e349724b7444fa8f3b298e4d6a318e3cf", + "ruby/docs/GetCommerce200ResponseInner.md": "18b8dd1d72b533726c5ea300b6804a74f3f3db0a23cdcc4c91ed760a4850f9f5", + "ruby/docs/GetMmLiteStatus200Response.md": "aa3dc4b044387dc38fc551f2ed8aaf0b425449ea6cc5478bc91cf4391c9dfa3e", + "ruby/docs/GetWebhook200Response.md": "9def342afa00b18b30bf3eb52cb1a55854f9554070d346d0aae0feb1de7dc468", + "ruby/docs/GetWhatsappBusinessEncryption200Response.md": "8287446ef369145e8ffc1151daed35a676f6d2fbe284c18357cd5d0f9b0ee163", + "ruby/docs/GroupsApi.md": "6db923544d074aa5815b8d7cd167386c16a6d69eafe8658ec53ea942bf43d2ed", + "ruby/docs/InitiateCallRequest.md": "b2e66eb4fb99e68c603f0d0e9092adca12023eac505c1b261f2efd9a1ceec416", + "ruby/docs/InitiateCallRequestSession.md": "8fb6a675dca251809a925b7467f593aa25ff8358255d5fbf8d7d31c98de4a835", + "ruby/docs/InitiateCallResponse.md": "2eff12c3bf1ebc4b5b20cb02ff56a9b00c7d15b88c5d805ac8b6973ffdf3e605", + "ruby/docs/InitiateCallResponseCallsInner.md": "bedb8744952aa3086ed271c4388d3a65786f5f62793a3df22b00db6e9fa5cc02", + "ruby/docs/InitiateCallResponseResponse.md": "2eb11ec53e97ff8feeaa8460f49f3c56ce6936b1cef131bfa4d353bd5cffe5f6", + "ruby/docs/ListBlockedUsers200Response.md": "97a0b8bc79c3525794044e883a25b164321c443d304d35fe3d15456e2218f44d", + "ruby/docs/ListFlows200Response.md": "c55765fb3401d21088e8084b748b579ba4f9fd6239d184862c1507618ebe87ae", + "ruby/docs/ListMessages200Response.md": "1513e667009f7f0e05af906a1e379e5357476b560a183ba043a06630458acfc6", + "ruby/docs/ListTemplates200Response.md": "90a9cbbaf98be45d834f2e058d376c8531ea05df8d7a115a96f75c8b86b9d0df", + "ruby/docs/MessageSentResponse.md": "ae427dac442d76c3edc0e13eb4fc4fef80e2aac75199b803b039524dcc258e54", + "ruby/docs/MessagingApi.md": "bceb72a0b72adafe1b0de9d7588015e6e2a72b490efd0779ab7348a6bdf5d909", + "ruby/docs/PatchFlowsFlowIdAssets200Response.md": "7fb518f42a23fa608a38f3e4f63f74e1883423976cab6dd98cb7eadadb4d1c97", + "ruby/docs/ProfileApi.md": "99719a9e1d33afd9bc64c7ade9e518cfb2459f327eb7ced4aaa5846d306a80f6", + "ruby/docs/ProfileInfo.md": "c31561c19cb0f115d95c0fad4e07e07bae20167e5aa9f541b8efb6bc30f5d628", + "ruby/docs/RetrieveMedia200Response.md": "e393e0df0b7ef08a12f8c542c9c5ea0755cb465593a47fca4441e888aeb31fba", + "ruby/docs/SendAddressMessageRequest.md": "fd87dbf56311fb106f87a14339f3122a70bb5cc17912fd33f204e8ead60c2b26", + "ruby/docs/SendButtonRequest.md": "68a25579c91adcde50011d8d7c17d0b582a86b4e4a592aed6f9a7564277f29c7", + "ruby/docs/SendButtonRequestSectionsInner.md": "e2fcb3a8259d03508da742ebf70cdbf034c552250970c64f32e49ad5177765df", + "ruby/docs/SendButtonRequestSectionsInnerReply.md": "576dbafba8adeba9d1896895d092108f03cc5a5b71bd2dd655cd4c2d8791ab86", + "ruby/docs/SendCarouselRequest1.md": "ad4d77a86c5e7df7a9e05b63ef36fb3e1a5bead0b151864e7054346164fcf15c", + "ruby/docs/SendContactRequest.md": "b5208de03de0328f31a19736ce9cf9c7a916b3924c988206fe0773abbac2f296", + "ruby/docs/SendContactRequestContactsInner.md": "da2fd9b4d529a4dcfcf29d26196d3f6a9e860eabbb3083bd4e6972601cddd95c", + "ruby/docs/SendContactRequestContactsInnerName.md": "b8ab0095fa702f61c020cb2e8ba755491d3faa79e2cdae2b9553c3d459caed73", + "ruby/docs/SendContactRequestContactsInnerOrg.md": "08f9c0b1454c81791dfb625b01e2e1bfd3e0dc5cbbd1bc9cb0bf1f7cd3ffabff", + "ruby/docs/SendContactRequestContactsInnerPhonesInner.md": "665fbdb4592357340f8f6236b7e405dbd3a466ca6c1f78926d229a59d17c4185", + "ruby/docs/SendCtaUrlRequest.md": "9f550b2f94c1eadf46eab3fabfd5cbc0ecdb77032488d18af0ba2c3248f2177f", + "ruby/docs/SendFileRequest.md": "a73ac911208ea900a96729c1ba9e6c1937b7d9dd28dbcbf47d000f5b63103a41", + "ruby/docs/SendFlowRequest1.md": "032075c7596eebe2e315e4c4a9a5287ff8c84caa366dec13dfc3778efcd7dc07", + "ruby/docs/SendFlowRequest1Header.md": "af6cff8a01a7e3058d9a8b330b89a3fa3eab2f3cbd706c191459740961d043d2", + "ruby/docs/SendFlowRequestHeader.md": "9d3ad20c75e5ae1f04305615bc224570c5d1bf40f4f77cc13c978b4cf6aa764c", + "ruby/docs/SendListRequest.md": "78d0a465388a5e47ce8e6db01979245617c397121841c5c19751fab6c4dc3308", + "ruby/docs/SendListRequestSectionsInner.md": "847123c7fcd871a2354b67f397bc4bbec67c39fe47a60b20f17e992b5963f30c", + "ruby/docs/SendListRequestSectionsInnerRowsInner.md": "84f7a37f410fb4cc93780261158dba98ce6b400cd7d0b96a67b58b2e2aa1bf02", + "ruby/docs/SendLocationRequest1.md": "c2234328673bae378e0f272860f45ac42b1c3574a9226cd313aa3e6a6c3173a1", + "ruby/docs/SendLocationRequestRequest.md": "6bfb15da75c5efbdeeacb6bffb66d9bb535a6636631050b722075f770d952629", + "ruby/docs/SendMessageRequest.md": "8eadbf1e37aed864b7b6b73b47b141b3bbebfaf6ca773ad5bc8d2bc2635980cd", + "ruby/docs/SendOrderDetailsRequest.md": "bb87fbb37d4fac708edb0d4d2ca4394ebc986cca28dc553f85cdd157cc6d836d", + "ruby/docs/SendOrderDetailsRequestLanguage.md": "090273f7424dfad82ab7a0df492a2aa32135d7a5dac94c311f5bd9f49ce1ffca", + "ruby/docs/SendOrderDetailsRequestOrder.md": "704876c1c062b181ff4eba68517182d46bb8a57152f6520b2ebe1046a4fd222c", + "ruby/docs/SendOrderDetailsRequestOrderItemsInner.md": "10cd9c8c0c469be8691571748aa8b8c501b7be3edfbf74dffd56464a8b9f7332", + "ruby/docs/SendOrderDetailsRequestOrderItemsInnerAmount.md": "9448bb8563ab3577351d839493ba1a13edc931e0115f91ca2e4d2513d6edc572", + "ruby/docs/SendPaymentRequestRequest.md": "cc1aedcf452bdd2bee43af3e6abceb18b5e76dd954d8e25fbef21c7791cd4195", + "ruby/docs/SendReactionRequest.md": "0e3b10d848301da682409e3f860d7b1e0aaf65ac9ad67c842ffae0591ca14e50", + "ruby/docs/SendStickerRequest.md": "b8473546f6854a548d0a6635311227ad14ac55100308a66ad2b551c41547e283", + "ruby/docs/SendTemplateRequest.md": "70a8c36a202207e6705d73fecfd8308527953b9db1000e967cc463b270292e68", + "ruby/docs/SendTemplateRequestLanguage.md": "0aed0afa62c7d2b55694a03f43b94ccb1667be117557626a2f882a2e8860ddb4", + "ruby/docs/SetWhatsappBusinessEncryptionRequest.md": "6f20571ca8149ff0963acb9b931619a691b703a23c8bdd2c644c5e2dd3370dff", + "ruby/docs/SuccessResponse.md": "f284a894d795333e0163690ae6a2bf1fcd5cd9b686cd57d5bbdba222bd683d5d", + "ruby/docs/TemplatesApi.md": "3ed40124deba768e4e9290b3edb963daf271cf48c75ef36d5cec77974d19f4fd", + "ruby/docs/UpdateCallingSettings200Response.md": "8e09e6d70c24f45199264cf7ea118240306a2917825f8cc0af2033806e2ffbf8", + "ruby/docs/UpdateCallingSettings200ResponseResponse.md": "eeb201960195ccc4898373b82c007ceefe8317972e2c0838acd49fa716a1d981", + "ruby/docs/UpdateMeRequest.md": "84dbb1fb8c382968ac776aab02c46e13a4f8420ce33ffe0f03460cbcacefb4b7", + "ruby/docs/UsersApi.md": "e257deadc9af232099f07b17874830f46f50cc9179317c4f1ea6300c9bc04edc", + "ruby/docs/WebhooksApi.md": "f6d6559c9a8fa803e4c19939a018c67bc55fbc6a591f838370fe5e216342c09f", + "ruby/lib/one_msg_sdk.rb": "3cab9ebecea316545c60562cf6aa5b940f8129d491d03f759b4f0121dbd8f4c3", + "ruby/lib/one_msg_sdk/api/calling_api.rb": "a4eb62c1b554640347cce19943e655bd0321bf755d14b494fc7c1352da584876", + "ruby/lib/one_msg_sdk/api/catalog_api.rb": "56d4816614dfa303807e391833a24d8b631a16e5fd553dafa2096d11a8eb454d", + "ruby/lib/one_msg_sdk/api/channel_api.rb": "569a2af2f012c7f888f1eac0d0ad02485854ee2ce70139b1a64847e69565658b", + "ruby/lib/one_msg_sdk/api/flows_api.rb": "dba3048f8182379d5a0a2661a84a158fe4d8cbd8a7a70b81c96f0830b816d470", + "ruby/lib/one_msg_sdk/api/groups_api.rb": "5ff3a9afc4ce01a67fcf7b689d4234e948de1848fa401796a575bc7c99400976", + "ruby/lib/one_msg_sdk/api/messaging_api.rb": "e40b0ba21d0d838bb7f99df893f9165327b4903939ac3bf1f65df8b7f6861b36", + "ruby/lib/one_msg_sdk/api/profile_api.rb": "dab170891f74b52d721ced82bd6896240edfe101d08d5ecc0385531812259bf8", + "ruby/lib/one_msg_sdk/api/templates_api.rb": "78fc71804f9f7fc3237db368f687957ed3ddd68249565a5ca8e2112dd51feb21", + "ruby/lib/one_msg_sdk/api/users_api.rb": "1e2fb50580ba4b2ed9f157e3a1c33763ba3aac6ce1de6ff5f757d38c1ea16ddb", + "ruby/lib/one_msg_sdk/api/webhooks_api.rb": "484f5819a213a8bfe72df6f469b174cbb2df05a063e96441c906274658b1ffd2", + "ruby/lib/one_msg_sdk/api_client.rb": "f66098a244d38e7db3fa3e64b7ffd071ad34cba3493f55bd58369053efec7ece", + "ruby/lib/one_msg_sdk/api_error.rb": "79727d98176ff17aff458b5ff767e4f4e5e0a2bad284b6a5e9fe478f7752dc1f", + "ruby/lib/one_msg_sdk/api_model_base.rb": "c3a3cfd7babf91154f318801ff501b8ac0bf1c42d429a9b4699c1f33e2717833", + "ruby/lib/one_msg_sdk/configuration.rb": "f5b26725cfbe38b0f266631b32e905974b020708f040f14748418d4a03f2754e", + "ruby/lib/one_msg_sdk/models/add_template_request.rb": "e7bf13092f242b4679b1501e9202ee270f512b842a1c856b5ecccc2c9919497a", + "ruby/lib/one_msg_sdk/models/block_user_request.rb": "bf0217595caf282c0103223c651a1a3d52f112597ff5d2d00b7f31cab2bf5db9", + "ruby/lib/one_msg_sdk/models/calling_settings.rb": "64655f75cbda06628c6729f01c76ce24422cedbb68f00fdc1459aeb8d493e09f", + "ruby/lib/one_msg_sdk/models/calling_settings_calling.rb": "1a6fd0c7035c77c71b3a9b2dbf64ef64e5a2ad5a1673b3399b29f057859621f1", + "ruby/lib/one_msg_sdk/models/calling_settings_calling_audio.rb": "3a4aa9cd1e70b6510e12267e43d5beab4f6e7e1835625cc4d96a9867ed445267", + "ruby/lib/one_msg_sdk/models/calling_settings_calling_call_hours.rb": "7276fbccc260ef7944c9668c6e3db04a4a5c32f71d5b5d6c3caf46055e54e97a", + "ruby/lib/one_msg_sdk/models/calling_settings_calling_sip.rb": "8e54bb1d41457111c01c7e9cc7f34c4cb7b05dd18329f635092b9a78b1a27399", + "ruby/lib/one_msg_sdk/models/calling_settings_calling_sip_servers_inner.rb": "c7048bf7bc67b4c52f3a8bbe12ce535be1be8328604e9a13879d5d46b5cad4e4", + "ruby/lib/one_msg_sdk/models/calling_settings_calling_video.rb": "3de63366f70f22f1463a38e0bc73e044200010e222670f190527144c7cd6a343", + "ruby/lib/one_msg_sdk/models/conversational_automation.rb": "9b9db1b943b6550e76b573621ecc464bfc6225ba44de1ec3522b746f863bf013", + "ruby/lib/one_msg_sdk/models/conversational_automation_commands_inner.rb": "c19db67c6f05cdbd07e1e3ea9df0356db976f6bcfdadf9992b03dfc663e27ebd", + "ruby/lib/one_msg_sdk/models/create_commerce200_response.rb": "32a5cb48bf1a0bddfbf736507ad1e41d52a4c357d40d889afd579d6d8f99fd49", + "ruby/lib/one_msg_sdk/models/create_commerce_request.rb": "4694fd2510c819c853fca636fbb194bb3916a9c62a4fec69a9753dc7351c89bb", + "ruby/lib/one_msg_sdk/models/create_commerce_request_params.rb": "d66f360022075b4fab3dd6718146d75c985d77b0a06bd7b2206e8fd013e8592c", + "ruby/lib/one_msg_sdk/models/create_groups200_response.rb": "06639a0fec3ece2cf6537108e880c94d0b0eda73705dcd28aba3b6328e85d0c7", + "ruby/lib/one_msg_sdk/models/create_read_message200_response.rb": "62b680e3cd104dc2e0e35dc77c5036f148b2f3fa445c1f5d8a307506b07645b4", + "ruby/lib/one_msg_sdk/models/create_read_message401_response.rb": "121087987123d340f4240ab55aae0e44e1eea1a8870948172e8bf79f27cea075", + "ruby/lib/one_msg_sdk/models/create_read_message_request.rb": "01c23778ea95fcabcd09676284f2fe1086c44ad0ea6bb2b480b5823f5db4880e", + "ruby/lib/one_msg_sdk/models/delete_flows_flow_id200_response.rb": "38231de5907b384e2b9563debbda541a7e116c5bdd71ef50f33b06ff91ae7e53", + "ruby/lib/one_msg_sdk/models/delete_groups_group_id200_response.rb": "1c72987172f493ad202d64943c2cd3749bfd3bd1191cf8509f5d930d04fd726d", + "ruby/lib/one_msg_sdk/models/delete_media_legacy_request.rb": "d3dd346dbe8ff07edc563de8b4cc1a1de9d19baa2c99d7467af322d5c4bb912c", + "ruby/lib/one_msg_sdk/models/error_response.rb": "7930ea441b5bdbf6c9943fe5e1565216a5e915ccf8811e6378f87935b7289d67", + "ruby/lib/one_msg_sdk/models/get_commerce200_response_inner.rb": "58aa25565540227eeeeb2e0395483eba2167d044b17a83d457e37256991b4339", + "ruby/lib/one_msg_sdk/models/get_mm_lite_status200_response.rb": "e5c72a84049b7a3fb8ec77556d401a6b7c0471e67760c44baed4f3629b58a6ef", + "ruby/lib/one_msg_sdk/models/get_webhook200_response.rb": "ed0e757fe13d210619b1468c880304e6d2769d743b69888a2ca9dbf98cb859a2", + "ruby/lib/one_msg_sdk/models/get_whatsapp_business_encryption200_response.rb": "e293c2d1d525f683f001cab41840aab773194857afd6f120329f1dd7f8addf6c", + "ruby/lib/one_msg_sdk/models/initiate_call_request.rb": "41824d67cc4960903f0862384a3fcb8873fa7df49232e6004f5e0de3f5a8b62c", + "ruby/lib/one_msg_sdk/models/initiate_call_request_session.rb": "b087426f7abb19b7cf2b4b9ff2fd1baaef1cec5dca2d13f92413744a5c80f331", + "ruby/lib/one_msg_sdk/models/initiate_call_response.rb": "05459f14e733b8a12b7c822830150c5b8d0d456a283b8343957f3663b022cd28", + "ruby/lib/one_msg_sdk/models/initiate_call_response_calls_inner.rb": "e285a0ef3e9ff4d91ae292364f848ccb2b1c748da5f9f807ac2559b9b42ba544", + "ruby/lib/one_msg_sdk/models/initiate_call_response_response.rb": "f0a63ba98aefa2a9aa7e63f96567d4a42ed30b11da55b1af53e031ca83d281ab", + "ruby/lib/one_msg_sdk/models/list_blocked_users200_response.rb": "846d086e9e4353aed1a376cd9367372fdf5c4ed78578a64be8b9257265550a60", + "ruby/lib/one_msg_sdk/models/list_flows200_response.rb": "e82b99f813af07820d23d0b692b3f2476ee993ecbf83d976eedadde554dc9039", + "ruby/lib/one_msg_sdk/models/list_messages200_response.rb": "e630aa8b15f19ec38deb85329ebb9a675e236e29b491765816668c093561d6b5", + "ruby/lib/one_msg_sdk/models/list_templates200_response.rb": "da8ab3dd441c13e2e6698e4fc2e927a2182351aa175945deb27aef92cd4c6e46", + "ruby/lib/one_msg_sdk/models/message_sent_response.rb": "1a79b514033e078f698e84995c821ebfba2b502bb4ba366be83aad7e8609f0d5", + "ruby/lib/one_msg_sdk/models/patch_flows_flow_id_assets200_response.rb": "5e744871c3e50afb30bfa66c0a2f4ad0c23fcafafe271f56b613b42054e24b31", + "ruby/lib/one_msg_sdk/models/profile_info.rb": "0c35c4a0a32ea45b39929a6d455de3e85e2b6365876b2274e0f3e8dff3770297", + "ruby/lib/one_msg_sdk/models/retrieve_media200_response.rb": "232034093173e6925d5a622130e7d7630a27d84f16a9bee03ca3c8fca1bd6aa0", + "ruby/lib/one_msg_sdk/models/send_address_message_request.rb": "96566cbe4a4a972b85d78f963f91f016ea62a66f85b465cf227622130a797105", + "ruby/lib/one_msg_sdk/models/send_button_request.rb": "be7950787348aafe07c3eefe9685ac4d6d0a82fc393f8ccaf3b971a7962a97e5", + "ruby/lib/one_msg_sdk/models/send_button_request_sections_inner.rb": "5e1758a0415e9400fac378c0da940bf48b9dc3e7dc5701af0d525dde5101a137", + "ruby/lib/one_msg_sdk/models/send_button_request_sections_inner_reply.rb": "2fc002da5f618588f59c0d1b5f302301065857ab2687c323957e5dad6d15a1c6", + "ruby/lib/one_msg_sdk/models/send_carousel_request1.rb": "99473e9b00ffbb3f98868dc98bc7e7326891240df82ebf46a7272c0a12f52cae", + "ruby/lib/one_msg_sdk/models/send_contact_request.rb": "f3455f88ac1fad2937a6afac4451e3eea10e40e28e6604617ec82916255f4d30", + "ruby/lib/one_msg_sdk/models/send_contact_request_contacts_inner.rb": "7407b451a4a396146557d4f0f60f8f051d826f631461d6a950f04b70f624538e", + "ruby/lib/one_msg_sdk/models/send_contact_request_contacts_inner_name.rb": "9aad00bd0e29618210f5516b52e5f42925f55d2deb9f5639834b01d90e8ad293", + "ruby/lib/one_msg_sdk/models/send_contact_request_contacts_inner_org.rb": "3ceb0170773286f90b272f84e9082c8e4feab5cac9ff189ee56a00fd5a22eb88", + "ruby/lib/one_msg_sdk/models/send_contact_request_contacts_inner_phones_inner.rb": "d5e1b31a8cd02beeeea8d096f61346a5d2df6c932d989b5bfa98248a8a6f99d5", + "ruby/lib/one_msg_sdk/models/send_cta_url_request.rb": "4ee1f8e1fb6f94721077cb2fed85fd4b07cea7a00d3d17f09b293b02304bf66e", + "ruby/lib/one_msg_sdk/models/send_file_request.rb": "8eeadbd17ce9db07b81df4cac36cb9a6b5f1771198d33a57aa602d6cdc23779d", + "ruby/lib/one_msg_sdk/models/send_flow_request1.rb": "2e8d2333809677afd3630e2fc3c8b9ac9825745c05e75747f9fa7a1a2e204472", + "ruby/lib/one_msg_sdk/models/send_flow_request1_header.rb": "9faffecc619a854891fc643289bc8d97c32e6e187d0c7e0f3f9c4fa634df6a9c", + "ruby/lib/one_msg_sdk/models/send_flow_request_header.rb": "df01b44f1315f3fefb4c4037cefe37dfba43b3bfb68c1cf1f6ee521242f7cbf6", + "ruby/lib/one_msg_sdk/models/send_list_request.rb": "0f221068dab28c16808426e7031a608f4f467455cc5fc4e3b670a08a08d2c732", + "ruby/lib/one_msg_sdk/models/send_list_request_sections_inner.rb": "8d8dcf72c08f697695e10c9dc8d0bc3183a4a5f62521b6eaeb3370fa1c7a8534", + "ruby/lib/one_msg_sdk/models/send_list_request_sections_inner_rows_inner.rb": "ea9fb261b5c18a84fdffe7db8d13419f48892cf633a3c282e9ffcc8d481ef2f6", + "ruby/lib/one_msg_sdk/models/send_location_request1.rb": "489a591925d40660c62819dc390ec182ce4ddd983f3d7b842664362f2167166a", + "ruby/lib/one_msg_sdk/models/send_location_request_request.rb": "1e9fd6f008256588ebeb505d299de416f4ca39b8eef67493ebe201608bfe37ef", + "ruby/lib/one_msg_sdk/models/send_message_request.rb": "05e50943d9fae37f94bb2f913e425d9e411245fa6f1187a57f868bbd877e573d", + "ruby/lib/one_msg_sdk/models/send_order_details_request.rb": "a6187e6b0bec07129c2d4b8f1a838d7e2ce81e32d7655307cc78d12bfad37832", + "ruby/lib/one_msg_sdk/models/send_order_details_request_language.rb": "3244a02d197261f46ad21a3b3ce8c34ee536129892d6284c8edca544e4092a66", + "ruby/lib/one_msg_sdk/models/send_order_details_request_order.rb": "392f3539b0567f42493743e75279af81642eb653ceeeb91e8f7d47ce2fb71745", + "ruby/lib/one_msg_sdk/models/send_order_details_request_order_items_inner.rb": "4789654e10eb46d3e6989b3f7b8debc641980e3f8132b090f785a6fbb7646f9c", + "ruby/lib/one_msg_sdk/models/send_order_details_request_order_items_inner_amount.rb": "e9342fdd30dfebbba47acefeae753c1f089d46d836d5ca272c910265a4797395", + "ruby/lib/one_msg_sdk/models/send_payment_request_request.rb": "b51494134df83a7f94628ab4522aade29d55e3fa37a2ac260fd84cd27f8fb78d", + "ruby/lib/one_msg_sdk/models/send_reaction_request.rb": "5061043b648ff922a5af04dfac33149b694f237ab09130ba1383a7b2ba262b52", + "ruby/lib/one_msg_sdk/models/send_sticker_request.rb": "4f9bbb933a70649d00242811db9c67cdc8f5e533b15637ab7d51710daa40c299", + "ruby/lib/one_msg_sdk/models/send_template_request.rb": "fa1fbe4a8a3bce8e0b52e098d5d00ebdacd007d130227c229c48d5f7e578274c", + "ruby/lib/one_msg_sdk/models/send_template_request_language.rb": "dad684f5e089ed31f993623810518177adf6b4d6b7feb6f52a957fcb02dca606", + "ruby/lib/one_msg_sdk/models/set_whatsapp_business_encryption_request.rb": "84b1cbe492a29f14023467fcdcb774dbf45e8012b42bb4a84c1e09704c649882", + "ruby/lib/one_msg_sdk/models/success_response.rb": "c085bfe4d36a0c557d03e188b2ef3fcbb78983c1d3cbe6df00c49ed9c16694e8", + "ruby/lib/one_msg_sdk/models/update_calling_settings200_response.rb": "1153fc12d3d0ff6373f29d4090861b0ce16d2453ddba20a4ae4c7bf79986782b", + "ruby/lib/one_msg_sdk/models/update_calling_settings200_response_response.rb": "1322456db4f341581573048f4b859363c8002f8b8f5c1d785ff3340fb0feeada", + "ruby/lib/one_msg_sdk/models/update_me_request.rb": "31da199e90e70eddea815aeeeec6a4a2d0ef243e70b903a1c059c60c0c535c58", + "ruby/lib/one_msg_sdk/version.rb": "7d805e8b5f2aa9069e4dc41cac2e6f75fbdfaa0c6da269ca68c024e56bd4c792", + "ruby/one_msg_sdk.gemspec": "5346bf70cdf14f30581005f65db9c3ccf097b01c69a3a6951668acdb5d4c0fe5", + "ruby/spec/api/calling_api_spec.rb": "343a6f036c9ab902608cc1981a49d6fb10853e60d0dc4addd41bf5f175c1466b", + "ruby/spec/api/catalog_api_spec.rb": "917b16f43d4a24b011f32459826b529804b6108e8cf5caeeb082199a3be5ec1d", + "ruby/spec/api/channel_api_spec.rb": "aed77c72dd62f9a3b5814a89c19f75134994371143829e91793eb7a7b39bb258", + "ruby/spec/api/flows_api_spec.rb": "f2b86f3f44876f75fc7e22533059309dbe5440790abf1a8cacbebb1c665a7203", + "ruby/spec/api/groups_api_spec.rb": "2e5343c25073dcb954a75f9925cf9df92d2f5c09158d02d5018cb11dd4b80925", + "ruby/spec/api/messaging_api_spec.rb": "0ba9f782c3d182e36b1b235f815e82fb58de1caf23ba87a07c135719cbcfbb95", + "ruby/spec/api/profile_api_spec.rb": "8981626cc37f82046c9c95ac20cdce90705a610f276a4e6710c18472564d15ce", + "ruby/spec/api/templates_api_spec.rb": "12fead179201b9ff132953a8940ada7284f81a1cdec6b9158068dc5cee07bf5e", + "ruby/spec/api/users_api_spec.rb": "712df045ac2c0fcf353495aedfb4057e3f927219b6035fa90a7b27afdc85a097", + "ruby/spec/api/webhooks_api_spec.rb": "45ada15a3e6f14044fced90b5328c2ef221b97631558bb1321f7a73b74b16202", + "ruby/spec/models/add_template_request_spec.rb": "72b1b3f3abf6e4c512518ae01d557dd911d8dda2d748cffac557a206cefc2fd4", + "ruby/spec/models/block_user_request_spec.rb": "68bbf3569b94f885cd1a94c3f5d9a2af7acd19c0f6ca5cd01532c941d08123bf", + "ruby/spec/models/calling_settings_calling_audio_spec.rb": "3d3a0abfaa632f3fa84128e8baecde8d9687e68c110735533da27409439fbd88", + "ruby/spec/models/calling_settings_calling_call_hours_spec.rb": "43de8466078f8752fdc266182ca90cde3d42d05c4569e17eb7dbe49649898cd5", + "ruby/spec/models/calling_settings_calling_sip_servers_inner_spec.rb": "096d938099ef5fc3eba55c36e0c2b69a2baae7a01389e2e3f04008e142ab1e5e", + "ruby/spec/models/calling_settings_calling_sip_spec.rb": "b3b132cf7518f28c0b0ca87cdbb2052285fdf98eac0fddd8a09293a44916b31a", + "ruby/spec/models/calling_settings_calling_spec.rb": "77d7dab935deef788d9328d6e52f69b20c6263333c04028fd35358cac4dfc90f", + "ruby/spec/models/calling_settings_calling_video_spec.rb": "cdb3d53454d1221bdc1cc0ba9a2f8e5fdd12fe21e179f9a7af3ee88a08510060", + "ruby/spec/models/calling_settings_spec.rb": "1cb40b1a2753664d460d06e5667eb4f20ac9905008b5a20bb1bd42b764ba1356", + "ruby/spec/models/conversational_automation_commands_inner_spec.rb": "1d5b99ed4183e36bd9b5b0e8d8f16dbf2996c280180ab95b8d7b79bc907fe504", + "ruby/spec/models/conversational_automation_spec.rb": "ded3da2c5574e808ba85db3e9f997c2f89fd343174a26847987a001cf209fd27", + "ruby/spec/models/create_commerce200_response_spec.rb": "84eeb49d98e733c154719829f9ee19fbfb4a0148fca1fd7767f26bd5f23944f4", + "ruby/spec/models/create_commerce_request_params_spec.rb": "e30ff170b86b45ad5d1cea65d21e31840e5f2e0e24591d8c1087fb993bdae4a5", + "ruby/spec/models/create_commerce_request_spec.rb": "229066359eab7ffa035118b88d71f649057245e7826752f43dd4ad166d046a12", + "ruby/spec/models/create_groups200_response_spec.rb": "b7ec3065ad4e47932d89d6d0623e4612504960f7c874d2a9454643e88d4fdde0", + "ruby/spec/models/create_read_message200_response_spec.rb": "53fca9f9d65464371b6ad45b97fa863b64273b7666db1ade2fd3e4b7abb52690", + "ruby/spec/models/create_read_message401_response_spec.rb": "c19acfb56e3bf55ffb3d682033d550009b3d65d77ab9437a75b73a1adc27fbdc", + "ruby/spec/models/create_read_message_request_spec.rb": "eefa7e0cd5c00a49aa22027535e2be98d853af8015e8aca0a1aa4bc9305a6e61", + "ruby/spec/models/delete_flows_flow_id200_response_spec.rb": "7421cca4eb34acad706f977f6ef1943e377aa6e020b69de60cab97cd3cbc5b19", + "ruby/spec/models/delete_groups_group_id200_response_spec.rb": "b6799e4b0ebcba95707e21f34af75e4947db6ef7c2c806d6101a4658c75aaf4e", + "ruby/spec/models/delete_media_legacy_request_spec.rb": "4de179b04f64af12e18a7a72548a0d6dcfd94f3579688c8bd05e8812d44c8e6d", + "ruby/spec/models/error_response_spec.rb": "7d2e3ca22b206b12b87f9b67bf101c4d88df0a0e5c817e43296ef6486089e21a", + "ruby/spec/models/get_commerce200_response_inner_spec.rb": "a33c23697a916ca5fbd272b3a4e869b553ab0022f864a9595da16582c78737a8", + "ruby/spec/models/get_mm_lite_status200_response_spec.rb": "cb2e3b8883d562ed691b657ad847a2374fb0ef90fe459c934a4eaf916b693eae", + "ruby/spec/models/get_webhook200_response_spec.rb": "c91553f983d1764b6560b04310d5d6771c12b69f35262236ee8136cd5d0112bb", + "ruby/spec/models/get_whatsapp_business_encryption200_response_spec.rb": "e8559a0b9dce660fb1543501dd752241e04fc70e22c225a10037b7b3c396201e", + "ruby/spec/models/initiate_call_request_session_spec.rb": "0991538f2fa916bfd76cd79dd895586b4a79472a0eb1d97a80c72f11fb15a757", + "ruby/spec/models/initiate_call_request_spec.rb": "535fd87c3770deffaeba212c123131c4c0fe3b37987b22abda29068727c7eb0a", + "ruby/spec/models/initiate_call_response_calls_inner_spec.rb": "e9c3689c9357b765df506445589fb4e324706fb93117438bb94055bbf09b8c85", + "ruby/spec/models/initiate_call_response_response_spec.rb": "55bedd27a235404b6aa8327ade4423378fde59dcbd695ed17a423e509f91b836", + "ruby/spec/models/initiate_call_response_spec.rb": "059b0e822b1c2042c681772d8df4ebd678a3c044657b2844793db4e093d21cc3", + "ruby/spec/models/list_blocked_users200_response_spec.rb": "85ef60b7c22b649077618f42bcebecd52e3af1664ee92d467301ebb7395ce97a", + "ruby/spec/models/list_flows200_response_spec.rb": "595ea34a27c6c2e34b21052cba912d857c4d4f14c8f437e74f8759ef57a874a5", + "ruby/spec/models/list_messages200_response_spec.rb": "b981b408f4c231d5f7386123b85237024437755a5face029cde565b7986b20cc", + "ruby/spec/models/list_templates200_response_spec.rb": "5e23a9dc4e358a569a384ea4745721116a2f465b4bc9161b94c60d301e253f90", + "ruby/spec/models/message_sent_response_spec.rb": "aa1b288a9dfc4c75f090ca6587911cacf9f2b6b31432709733b09ba108420267", + "ruby/spec/models/patch_flows_flow_id_assets200_response_spec.rb": "a9c2a3735d711ce08885c7c4cbf32610aa01a890be2116b80ee77bdad78b11d5", + "ruby/spec/models/profile_info_spec.rb": "73acd6377a6d67765e8f02a39e7f9c1f36f12dc83b9cdd0f3995de48cfb57789", + "ruby/spec/models/retrieve_media200_response_spec.rb": "71673916f49d1f62476f99d31c0df0ea1b93f62e4c02b843758664203be4485c", + "ruby/spec/models/send_address_message_request_spec.rb": "91512b91381098965876398d6351480810da7422815d6bbadfc6ece8b25b6e24", + "ruby/spec/models/send_button_request_sections_inner_reply_spec.rb": "244ac21f49e286a1e8afd9ceb33c1a50f0350e0598b328be451e8f6f38d920d1", + "ruby/spec/models/send_button_request_sections_inner_spec.rb": "b255cd0f2b2777af47a62fb40a2f0ec0ca9da7235500267f77191fbf88b29d2f", + "ruby/spec/models/send_button_request_spec.rb": "61d2e3e7358540ae8c2ac3cdb12139a282f9b4ee162b38d709f24740dfef946e", + "ruby/spec/models/send_carousel_request1_spec.rb": "c3fe57acb5b3800194cad45a72ac9fc2e9e9083f050bac32acf3f1c09f9685c7", + "ruby/spec/models/send_contact_request_contacts_inner_name_spec.rb": "712dd1aee2e759f97655b6bf4887dab1731601bf02b607db491aef4ae97e5587", + "ruby/spec/models/send_contact_request_contacts_inner_org_spec.rb": "9897ecd528dc18db6f320abcca35ec21f5985876fe8c0707796562c8bb0e6c68", + "ruby/spec/models/send_contact_request_contacts_inner_phones_inner_spec.rb": "2af90058b4c56b3fba92706059715dd50d6c400bff6307da500e5bed82f5f13d", + "ruby/spec/models/send_contact_request_contacts_inner_spec.rb": "3d8e158e323a66d4209edd31f4518a6384bd1be3e3ac4a99e06af1fe4dbf02bf", + "ruby/spec/models/send_contact_request_spec.rb": "d891c677d11daec8d7f4dd7f6804235e1805f155138ca7d4cb545cdc563ba0fb", + "ruby/spec/models/send_cta_url_request_spec.rb": "59e2b80b50a8eddb0f2dc563dc108feb0f37db30796ddbcb0d08f8ade6149d02", + "ruby/spec/models/send_file_request_spec.rb": "cb1ed7348a552cdc5bb59c9bb469f31f7d122d1c1e072dca79444666ab063cb5", + "ruby/spec/models/send_flow_request1_header_spec.rb": "8a7bc624850d9a425d8b8fbe5714415853ccfaa6e948c35a5bd05d54258d2c86", + "ruby/spec/models/send_flow_request1_spec.rb": "fe984f59e41bf681404fc75e676406668177b939722cf2d88995fed27e74efdf", + "ruby/spec/models/send_flow_request_header_spec.rb": "7edf5d2a0ac7f3af62d83080f73c98510ca18c3a3367b7e483d0afdcbbb7a5b3", + "ruby/spec/models/send_list_request_sections_inner_rows_inner_spec.rb": "1caabf5d013ef565381e7e88e52021f37ea3f28aa7bd65e358321ff0327ddd10", + "ruby/spec/models/send_list_request_sections_inner_spec.rb": "86f52341473aa60f0df487ab8effab64c74a9efce39488f21b40d273c655559f", + "ruby/spec/models/send_list_request_spec.rb": "204febca8ddf9fcc1f818d249649adfd3270d84a61cb31cc1b775a3ed7a4c865", + "ruby/spec/models/send_location_request1_spec.rb": "31d1bac0c63ad312b87ff0ef03540dfe7a414b496e3b89d81466fc4916def022", + "ruby/spec/models/send_location_request_request_spec.rb": "34129afa5b8bd991a22b6f353caee5c203268874d8e4fcb5f7c5804a3b83bacf", + "ruby/spec/models/send_message_request_spec.rb": "e06f3c73eeb9b7f178bde7eb6d6bc092f492eefef098ef7ef01f87b230b4964c", + "ruby/spec/models/send_order_details_request_language_spec.rb": "05398e1eef80e9666ea2032be9a6c59763f1876293c4078220aa085f54935d37", + "ruby/spec/models/send_order_details_request_order_items_inner_amount_spec.rb": "0a663c2e66835ab19dfed54421b5742c2ef01666758da929ed328176761e2413", + "ruby/spec/models/send_order_details_request_order_items_inner_spec.rb": "497fe922a0039d5aed3f856e364e19b2fcea2ceeecc7717c73ac7598040a05ee", + "ruby/spec/models/send_order_details_request_order_spec.rb": "ac24101ac4342dc0732b6e5b7474a422998d154b9b315a66789dd56a1bdb7722", + "ruby/spec/models/send_order_details_request_spec.rb": "0c419544eae2b44f08af34b44162ad77786229b7b40661ceae1bf8ccf8944bad", + "ruby/spec/models/send_payment_request_request_spec.rb": "4d408670b19055d52ef79c8031eebca70733c684119d4391ed94558ef4f40919", + "ruby/spec/models/send_reaction_request_spec.rb": "de2e92c1a5921681e17fde01d625f897914e237f6c1ff864211498f58a480eeb", + "ruby/spec/models/send_sticker_request_spec.rb": "5fd168b72474abfbff7cc689b377fd4e5454a82752e1de67052c7a1e126ae296", + "ruby/spec/models/send_template_request_language_spec.rb": "0b05a55953af5ef89cc472351b1bf45228b07a34786de00a7e74e9c17729e70a", + "ruby/spec/models/send_template_request_spec.rb": "66b73f9ca294e4b8995ef036749c3694b0424be1a46c7f40a8c6c46af1c9efd4", + "ruby/spec/models/set_whatsapp_business_encryption_request_spec.rb": "ff7be2c93aa978482b2151372bd7a19f4da1ebafcd0ac410d1fb1e8429cd4a5a", + "ruby/spec/models/success_response_spec.rb": "7f7999a8bcb2fa54e04c69082ae54d77f741cc9b332df20fac34006a323c8821", + "ruby/spec/models/update_calling_settings200_response_response_spec.rb": "2ca73b26ddc60ba66d733f065105c3593321f2c543f302a8835ade71eb974513", + "ruby/spec/models/update_calling_settings200_response_spec.rb": "802f5309f61e7d5c216d2b1630e2b730c2d55bafcf9e6f974bc9b615f5b040e3", + "ruby/spec/models/update_me_request_spec.rb": "d113e2a3da49edfea4aefa328feb4eb32d299881a11c13cfef015c23adba0d5f", + "ruby/spec/spec_helper.rb": "a2369b82afc98976e66ff44ba068d40e5e04e29385a2483ace7b3e4ed576b0f9" + } + } + ] +} diff --git a/quality/exceptions/verify.mjs b/quality/exceptions/verify.mjs new file mode 100644 index 0000000..06222f2 --- /dev/null +++ b/quality/exceptions/verify.mjs @@ -0,0 +1,124 @@ +import { execFileSync, spawnSync } from 'node:child_process'; +import { createHash } from 'node:crypto'; +import { readFile, readdir } from 'node:fs/promises'; +import { resolve } from 'node:path'; +import { pathToFileURL } from 'node:url'; + +/** Read Git metadata without a shell; failures are fatal rather than weakening the frozen scope. */ +function git(root, args) { + return execFileSync('git', args, { cwd: root, encoding: 'utf8' }).trim(); +} + +/** Hash raw bytes, preserving whitespace and comments as part of the deferred source inventory. */ +function hash(bytes) { + return createHash('sha256').update(bytes).digest('hex'); +} + +/** Enumerate tracked and ignored source paths alike; no generated-source or language exemption is implicit. */ +async function diskFiles(root, scope) { + const target = resolve(root, scope); + const entries = await readdir(target, { withFileTypes: true }); + const result = []; + for (const entry of entries) { + const name = `${scope}/${entry.name}`; + if (entry.isSymbolicLink()) throw new Error(`Deferred source symlink is unsupported: ${name}`); + if (entry.isDirectory()) result.push(...(await diskFiles(root, name))); + else result.push(name); + } + return result; +} + +/** Require accountable, unexpired metadata before reading a deferred source tree. */ +function validateMetadata(exception) { + for (const key of ['id', 'owner', 'issue', 'reason', 'expires', 'baselineCommit']) { + if (typeof exception[key] !== 'string' || !exception[key].trim()) + throw new Error(`Missing exception ${key}`); + } + if ( + !/^\d{4}-\d{2}-\d{2}$/.test(exception.expires) || + !Number.isFinite(Date.parse(`${exception.expires}T23:59:59Z`)) || + new Date(`${exception.expires}T23:59:59Z`) < new Date() + ) { + throw new Error(`Expired exception: ${exception.id}`); + } + if (!/^https:\/\//.test(exception.issue)) throw new Error('Exception requires a task URL'); +} + +/** Compare an exception's exact file manifest to both trusted Git history and current on-disk sources. */ +async function verifyScope(root, exception, branch) { + validateMetadata(exception); + git(root, ['merge-base', '--is-ancestor', exception.baselineCommit, `origin/${branch}`]); + const roots = exception.roots; + if ( + !Array.isArray(roots) || + roots.length === 0 || + roots.some((item) => !/^[\w./-]+$/.test(item) || item.includes('..')) + ) + throw new Error('Invalid exception roots'); + const trustedPaths = git(root, [ + 'ls-tree', + '-r', + '--name-only', + exception.baselineCommit, + '--', + ...roots, + ]) + .split('\n') + .filter(Boolean) + .sort(); + const recordedPaths = Object.keys(exception.files).sort(); + if (JSON.stringify(trustedPaths) !== JSON.stringify(recordedPaths)) + throw new Error(`Incomplete exception inventory: ${exception.id}`); + const actualPaths = []; + for (const scope of roots) { + if (recordedPaths.includes(scope)) actualPaths.push(scope); + else actualPaths.push(...(await diskFiles(root, scope))); + } + if (JSON.stringify(actualPaths.sort()) !== JSON.stringify(recordedPaths)) + throw new Error(`Deferred source inventory changed: ${exception.id}`); + for (const name of recordedPaths) { + const trusted = execFileSync('git', ['show', `${exception.baselineCommit}:${name}`], { + cwd: root, + }); + if (hash(trusted) !== exception.files[name]) + throw new Error(`Exception fingerprint not from trusted history: ${name}`); + if (hash(await readFile(resolve(root, name))) !== exception.files[name]) + throw new Error( + `Deferred source changed: ${name}; complete its quality profile before changing it`, + ); + } + return recordedPaths.length; +} + +/** Enforce a dated, owner-assigned exception without presenting deferred compilation or tests as passing. */ +export async function verifyExceptions(root = process.cwd()) { + const configPath = 'quality/exceptions/inventory.json'; + const config = JSON.parse(await readFile(resolve(root, configPath), 'utf8')); + if ( + config.schemaVersion !== 1 || + !Array.isArray(config.exceptions) || + config.exceptions.length === 0 + ) + throw new Error('Invalid exception inventory'); + const base = git(root, ['merge-base', 'HEAD', `origin/${config.defaultBranch}`]); + const previous = spawnSync('git', ['show', `${base}:${configPath}`], { + cwd: root, + encoding: 'utf8', + }); + if (previous.status === 0 && previous.stdout.trim() !== JSON.stringify(config, null, 2).trim()) { + // Once adopted, changing the exception requires replacing this gate with the completed profile. + if (JSON.stringify(JSON.parse(previous.stdout)) !== JSON.stringify(config)) + throw new Error('Existing exception cannot be expanded, renewed or rebased'); + } + let count = 0; + for (const exception of config.exceptions) + count += await verifyScope(root, exception, config.defaultBranch); + console.log( + `Verified ${count} frozen paths under ${config.exceptions.length} temporary exception(s); deferred runtime checks have NOT run.`, + ); + return count; +} + +if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) { + await verifyExceptions(); +} diff --git a/quality/exceptions/verify.test.mjs b/quality/exceptions/verify.test.mjs new file mode 100644 index 0000000..e602567 --- /dev/null +++ b/quality/exceptions/verify.test.mjs @@ -0,0 +1,62 @@ +import assert from 'node:assert/strict'; +import { execFileSync } from 'node:child_process'; +import { createHash } from 'node:crypto'; +import { mkdtemp, mkdir, readFile, writeFile, rm } from 'node:fs/promises'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { test } from 'node:test'; + +import { verifyExceptions } from './verify.mjs'; + +/** Exercise the actual validator against trusted Git history and ignored on-disk source additions. */ +test('temporary exceptions reject changed, missing, extra and expired sources', async () => { + const root = await mkdtemp(join(tmpdir(), '1msg-exception-')); + /** Run isolated fixture Git commands without touching the repository under test. */ + const git = (...args) => execFileSync('git', args, { cwd: root, encoding: 'utf8' }).trim(); + try { + git('init', '-b', 'main'); + git('config', 'user.email', 'fixture@example.invalid'); + git('config', 'user.name', 'Quality fixture'); + await mkdir(join(root, 'legacy')); + await writeFile(join(root, 'legacy/source.ts'), 'export const value = 1;\n'); + await writeFile(join(root, '.gitignore'), 'legacy/ignored.ts\n'); + git('add', '.'); + git('commit', '-m', 'fixture base'); + const baselineCommit = git('rev-parse', 'HEAD'); + git('update-ref', 'refs/remotes/origin/main', baselineCommit); + const source = await readFile(join(root, 'legacy/source.ts')); + const config = { + schemaVersion: 1, + defaultBranch: 'main', + exceptions: [ + { + id: 'legacy', + owner: 'Fixture owner', + issue: 'https://example.invalid/task', + reason: 'Deliberate fixture', + expires: '2099-01-01', + baselineCommit, + roots: ['legacy'], + files: { 'legacy/source.ts': createHash('sha256').update(source).digest('hex') }, + }, + ], + }; + await mkdir(join(root, 'quality/exceptions'), { recursive: true }); + const inventory = join(root, 'quality/exceptions/inventory.json'); + await writeFile(inventory, JSON.stringify(config, null, 2)); + assert.equal(await verifyExceptions(root), 1); + await writeFile(join(root, 'legacy/source.ts'), 'export const value = 2;\n'); + await assert.rejects(verifyExceptions(root), /Deferred source changed/); + await rm(join(root, 'legacy/source.ts')); + await assert.rejects(verifyExceptions(root), /inventory changed/); + await writeFile(join(root, 'legacy/source.ts'), source); + await writeFile(join(root, 'legacy/ignored.ts'), 'export const hidden = true;'); + await assert.rejects(verifyExceptions(root), /inventory changed/); + await rm(join(root, 'legacy/ignored.ts')); + config.exceptions[0].expires = '2000-01-01'; + await writeFile(inventory, JSON.stringify(config, null, 2)); + await assert.rejects(verifyExceptions(root), /Expired exception/); + } finally { + await rm(root, { recursive: true, force: true }); + } +}); diff --git a/quality/generator/exact-optional.mjs b/quality/generator/exact-optional.mjs new file mode 100644 index 0000000..0a05fa6 --- /dev/null +++ b/quality/generator/exact-optional.mjs @@ -0,0 +1,60 @@ +import { readFileSync, readdirSync, writeFileSync } from 'node:fs'; +import { join } from 'node:path'; + +import ts from '../../tools/quality/node_modules/typescript/lib/typescript.js'; + +/** Match generated serializers that materialize missing values as undefined without weakening authored TypeScript checks. */ +function normalizeOptionalProperties(text, filename) { + const source = ts.createSourceFile(filename, text, ts.ScriptTarget.Latest, true); + const edits = []; + /** Locate only optional declarations; runtime expressions, required fields and parameter positions stay unchanged. */ + function visit(node) { + if ( + (ts.isPropertySignature(node) || ts.isPropertyDeclaration(node)) && + node.questionToken && + node.type + ) { + const type = node.type; + const explicitUndefined = + type.kind === ts.SyntaxKind.UndefinedKeyword || + (ts.isUnionTypeNode(type) && + type.types.some((part) => part.kind === ts.SyntaxKind.UndefinedKeyword)); + if (!explicitUndefined) { + edits.push({ start: type.getStart(source), end: type.getStart(source), text: '(' }); + edits.push({ start: type.end, end: type.end, text: ') | undefined' }); + } + } else if (ts.isMethodSignature(node) && node.questionToken && node.type) { + const parameters = node.parameters.map((parameter) => parameter.getText(source)).join(', '); + edits.push({ + start: node.getStart(source), + end: node.end, + text: `${node.name.getText(source)}?: ((${parameters}) => ${node.type.getText(source)}) | undefined;`, + }); + } + ts.forEachChild(node, visit); + } + visit(source); + for (const edit of edits.sort((left, right) => right.start - left.start)) + text = text.slice(0, edit.start) + edit.text + text.slice(edit.end); + return text; +} + +/** Repair exact-optional compatibility in the pinned generator output and omit absent native fetch credentials. */ +export function postProcessExactOptionalSdk(outputDir) { + const sourceDir = join(outputDir, 'src'); + const entries = readdirSync(sourceDir, { recursive: true, withFileTypes: true }); + for (const entry of entries) { + if (!entry.isFile() || !entry.name.endsWith('.ts')) continue; + const file = join(entry.parentPath, entry.name); + const source = readFileSync(file, 'utf8'); + writeFileSync(file, normalizeOptionalProperties(source, file)); + } + const file = join(sourceDir, 'runtime.ts'); + const source = readFileSync(file, 'utf8'); + const anchor = ' credentials: this.configuration.credentials,'; + const replacement = + ' ...(this.configuration.credentials === undefined ? {} : { credentials: this.configuration.credentials }),'; + if (!source.includes(anchor) && !source.includes(replacement)) + throw new Error('Generated fetch credentials layout changed'); + writeFileSync(file, source.replace(anchor, replacement)); +} diff --git a/quality/generator/exact-optional.test.mjs b/quality/generator/exact-optional.test.mjs new file mode 100644 index 0000000..e656fe3 --- /dev/null +++ b/quality/generator/exact-optional.test.mjs @@ -0,0 +1,35 @@ +import assert from 'node:assert/strict'; +import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { test } from 'node:test'; + +import ts from '../../tools/quality/node_modules/typescript/lib/typescript.js'; +import { postProcessExactOptionalSdk } from './exact-optional.mjs'; + +/** Guard AST transform scope and idempotence, including callbacks and nested interface properties. */ +test('optional declarations retain runtime expressions and required contracts', (t) => { + const input = + 'interface Model { required: string; optional?: string; callback?: (value: string) => void; pre?(value: string): Promise; nested?: { value?: number }; existing?: boolean | undefined; }\nconst runtime = { required: "yes" };'; + const directory = mkdtempSync(join(tmpdir(), '1msg-exact-optional-')); + /** This test owns its temporary generator output; always remove it after assertions or failures. */ + t.after(() => rmSync(directory, { recursive: true, force: true })); + mkdirSync(join(directory, 'src')); + const fixture = join(directory, 'src/fixture.ts'); + writeFileSync(fixture, input); + writeFileSync( + join(directory, 'src/runtime.ts'), + ' credentials: this.configuration.credentials,', + ); + postProcessExactOptionalSdk(directory); + const output = readFileSync(fixture, 'utf8'); + assert.match(output, /required: string/); + assert.match(output, /optional\?: \(string\) \| undefined/); + assert.match(output, /callback\?: \(\(value: string\) => void\) \| undefined/); + assert.match(output, /pre\?: \(\(value: string\) => Promise\) \| undefined/); + assert.match(output, /const runtime = \{ required: "yes" \};/); + postProcessExactOptionalSdk(directory); + assert.equal(readFileSync(fixture, 'utf8'), output); + const parsed = ts.createSourceFile('fixture.ts', output, ts.ScriptTarget.Latest, true); + assert.equal(parsed.parseDiagnostics.length, 0); +}); diff --git a/quality/generator/generate.mjs b/quality/generator/generate.mjs new file mode 100644 index 0000000..ace5372 --- /dev/null +++ b/quality/generator/generate.mjs @@ -0,0 +1,94 @@ +import { spawnSync } from 'node:child_process'; +import { createHash } from 'node:crypto'; +import { mkdtemp, readFile, writeFile, mkdir, readdir, rm, cp } from 'node:fs/promises'; +import { tmpdir } from 'node:os'; +import { dirname, join, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import { postProcessExactOptionalSdk } from './exact-optional.mjs'; +import { postProcessGeneratedTypeScriptSdk } from './postprocess.cjs'; + +const directory = dirname(fileURLToPath(import.meta.url)); +const root = resolve(directory, '../..'); +const provenance = JSON.parse(await readFile(join(directory, 'provenance.json'), 'utf8')); +/** Hash producer inputs and output bytes for reproducible regeneration. */ +const hash = (bytes) => createHash('sha256').update(bytes).digest('hex'); +if (hash(await readFile(join(directory, 'postprocess.cjs'))) !== provenance.postprocessorSha256) + throw new Error('Postprocessor checksum mismatch'); +const spec = await readFile(join(directory, 'openapi.yaml')); +if (hash(spec) !== provenance.contractSha256) + throw new Error('Contract differs from pinned provenance'); +const cache = join(tmpdir(), '1msg-openapi-generator'); +await mkdir(cache, { recursive: true }); +const jar = join(cache, `${provenance.generatorVersion}.jar`); +try { + await readFile(jar); +} catch { + const response = await fetch( + `https://repo.maven.apache.org/maven2/org/openapitools/openapi-generator-cli/${provenance.generatorVersion}/openapi-generator-cli-${provenance.generatorVersion}.jar`, + ); + if (!response.ok) throw new Error(`Generator download failed: ${response.status}`); + const bytes = Buffer.from(await response.arrayBuffer()); + if (hash(bytes) !== provenance.generatorSha256) throw new Error('Generator checksum mismatch'); + await writeFile(jar, bytes); +} +if (hash(await readFile(jar)) !== provenance.generatorSha256) + throw new Error('Cached generator checksum mismatch'); + +/** Enumerate every generated path and hash, catching additions/deletions as well as changed files. */ +async function inventory(path, prefix = '') { + const result = {}; + for (const entry of (await readdir(path, { withFileTypes: true })).sort((a, b) => + a.name.localeCompare(b.name), + )) { + const relative = prefix + entry.name; + if (entry.isDirectory()) + Object.assign(result, await inventory(join(path, entry.name), `${relative}/`)); + else result[relative] = hash(await readFile(join(path, entry.name))); + } + return result; +} + +const temporary = await mkdtemp(join(tmpdir(), '1msg-sdk-generation-')); +try { + const result = spawnSync( + 'java', + [ + '-jar', + jar, + 'generate', + '-i', + join(directory, 'openapi.yaml'), + '-g', + 'typescript-fetch', + '-o', + temporary, + '--additional-properties=npmName=@1msg/sdk-generated,supportsES6=true,typescriptThreePlus=true,withInterfaces=true,useSingleRequestParameter=false,hideGenerationTimestamp=true', + ], + { stdio: 'inherit' }, + ); + if (result.status !== 0) throw new Error(`Generation failed: ${result.status}`); + postProcessGeneratedTypeScriptSdk(temporary); + postProcessExactOptionalSdk(temporary); + const expected = await inventory(join(temporary, 'src')); + const output = join(root, 'typescript/src/generated/src'); + const inventoryFile = join(directory, 'inventory.json'); + if (process.argv.includes('--write')) { + await rm(output, { recursive: true, force: true }); + await mkdir(dirname(output), { recursive: true }); + await cp(join(temporary, 'src'), output, { recursive: true }); + await writeFile(inventoryFile, JSON.stringify(expected, null, 2) + '\n'); + } else { + const actual = await inventory(output); + const recorded = JSON.parse(await readFile(inventoryFile, 'utf8')); + for (const candidate of [actual, recorded]) { + if (JSON.stringify(candidate) !== JSON.stringify(expected)) + throw new Error( + 'Generated SDK drift: run node quality/generator/generate.mjs --write and review the contract/producer change', + ); + } + } + console.log(`Verified ${Object.keys(expected).length} generated TypeScript paths`); +} finally { + await rm(temporary, { recursive: true, force: true }); +} diff --git a/quality/generator/inventory.json b/quality/generator/inventory.json new file mode 100644 index 0000000..edd897a --- /dev/null +++ b/quality/generator/inventory.json @@ -0,0 +1,115 @@ +{ + "apis/CallingApi.ts": "129eb7db5b92150022f9da64dae6b85a7db267ae3478e1979f8d71583db458e0", + "apis/CatalogApi.ts": "b85c2c5a0f61f6cfbfca720a1e0c03a5b9abf7b680cec6b420705329337f7fc8", + "apis/ChannelApi.ts": "a969213513f911a04bbce46357591e9c46220d8b474e075303bfd54b3b6123ff", + "apis/FlowsApi.ts": "d1b1ea3d467f99816eb7b888a66d13801a90981419d0f4051b2579c195f8286d", + "apis/GroupsApi.ts": "3e5af239ed0272f900480f5c87bfa86f3ac78676d19eb21f659f166bc92cab6f", + "apis/index.ts": "9dcf1fd9bec551bfd580bb6454406e096c494fd79236b3a46dda2fad38a47080", + "apis/MessagingApi.ts": "df6b1fbf5b75516495270882d1ce0046e0e6e253f25314e3f823f669f95d6c1b", + "apis/ProfileApi.ts": "b11f725dea52f2afe672b2b6413346f529feb315d336d68712b2f50f5403d217", + "apis/TemplatesApi.ts": "9221bc60d79e200c94328a0b175c93d3336050b5154ec8a0d5050a466c385ee8", + "apis/UsersApi.ts": "65cbbf11185465c4e8a0a82faa0e62f61f681a449d78f73c1714b9fa1639a5b6", + "apis/WebhooksApi.ts": "a64d716467e1643463f0d0c1a508938a0cd0ab4a16bd1e1bf0e8adb9a5df4208", + "index.ts": "7fa0f2909685ed2bd45a1d4cded16da3f25b2bd3e41149018c2daf4c3f6cf42b", + "models/AddTemplate200Response.ts": "6f629f0bac01f94f913c09b11501c9767d416c4c67b46045747840deb149bb39", + "models/AddTemplateRequest.ts": "c3fbf1b74d1bfc4e69c803deb3c146bcff32a90e325812b0c9f16397258d22b5", + "models/BlockUserRequest.ts": "3c9808b22e45ca47ee155e184f1bfbb04c19792015fa13a0b3189990be6cb824", + "models/CallingSettings.ts": "10036388c15c78242ca2d6bdbb08e16139a9ecf86f755ed9a75ede6dd54bbe3b", + "models/CallingSettingsCalling.ts": "019486ff5387a2518f2a080e7ef739f9c93e3ae55645b515d5cbc7f536acf11d", + "models/CallingSettingsCallingAudio.ts": "0df13ac2e356a4df104587a46ae0d1389c571891db4675dd1d25166ec7d3bbe5", + "models/CallingSettingsCallingCallHours.ts": "f6a1fe7d0c3d18c0ed5f4be990a531eec36632b44bdb391318b886b6db7aa806", + "models/CallingSettingsCallingSip.ts": "5e36a7fc2528eace43f7cca53bf12b44562b65f323229dc9285bcb82cf3872de", + "models/CallingSettingsCallingSipServersInner.ts": "4e84a14d325edfb239f6740289eb7781aff58e1d0e5ce66a81d6f93eccc7dc5f", + "models/CallingSettingsCallingVideo.ts": "9f6d82339f658911960372d1023ca57be6973ad8deac69103062eccd7d74eb37", + "models/ConversationalAutomation.ts": "73568b112b6de9401dda1ff4482d3f6a073ea95f2df3d0c311d7214e338ad3e5", + "models/ConversationalAutomationCommandsInner.ts": "620e2e9894fbb619a4d55b44f0afe9f0603396acf495245a1b85b382fc9a3a3f", + "models/CreateCommerce200Response.ts": "9f107550a464dd921f05f26bafa7294941653023664d94d7b6eb580aadfc633e", + "models/CreateCommerceRequest.ts": "1b9493eeb7c70922deac70e2f43e7aba6034b118041bc03d10776b9cdff6aedc", + "models/CreateCommerceRequestParams.ts": "3e4d63e02d46d17d9a44d94d4df32a983e3b0cf0c41f04b8d1bd4ebe19d75b47", + "models/CreateFlowsRequest.ts": "20f2358e98a91b7f2575dffa14843dac2c0de9abbaa0c2cc67cd4f024798ebda", + "models/CreateGroups200Response.ts": "d08d320fb027248a4c269126ad0546dacd7b8d99505ceb6b6c8cb6456a191fcb", + "models/CreateGroupsGroupIdRequest.ts": "ecb1846633fd5736889aa6020bceea84924d85c2fa38905717e0a414d9b8dd69", + "models/CreateGroupsRequest.ts": "82a47be29297870726ffdddc4c18b06222de7a36eab2839db5b5eb56ca125284", + "models/CreateReadMessage200Response.ts": "9e36257fe0b0a6bc8f3eae432fdf15b8c3e26288d96f829ee4e4a64181511231", + "models/CreateReadMessage401Response.ts": "cd4c1357cc4bd6fdd732c50156a77fb24a1eaa3869cb56e45a36b21ff7682788", + "models/CreateReadMessageRequest.ts": "ecb6fe02e823f0f9ea3de5233b449e8d10a165f1c6039039862308fc1d2a943e", + "models/CreateSettingsRequest.ts": "71bf960942b7b826e3851b67c324fc12028a0c9eb96f478efc19d7c3bf678bd2", + "models/CreateSettingsRequestWebhookUrl.ts": "a5f6c03b77fc93241d0256bd407d9ac6f959d57e96fd04807ae7ac18cd9c056f", + "models/CreateUploadMedia200Response.ts": "45a745f269050196c0b8decc8c88868104d8dccae4a37069da82bdb0f63a4c34", + "models/CreateUploadMediaRequest.ts": "ced5f543369694fcdfe3a554d49c200647cef869f4c8e86616a99555357d8ef4", + "models/DeleteFlowsFlowId200Response.ts": "7d70cce256f6752b906e3f2ecf764f808e2e15e856191250f1c142ae53cef6f9", + "models/DeleteGroupsGroupId200Response.ts": "5e5c88d7b44ccc4eabe8995e400dfd3c664fec6dcc3f5a5de2bfede7c8f903a2", + "models/DeleteMediaLegacyRequest.ts": "9293ad3772496bab6b5f551781fc600c209c133d8a513043d8d15d7e746856c2", + "models/ErrorResponse.ts": "e5b9c1afdff15a8f521661fd061da5ec45302387dd7f132bba816343a69ff9f2", + "models/GetCommerce200ResponseInner.ts": "943b2f26f99a1ce98f1d93edac1e2ed16daf181dedc77135775516723d47fb79", + "models/GetMmLiteStatus200Response.ts": "3a2aa7575d7be08074ef9a58810cafac1f06fe3f415e2e849d1d9f059fc92461", + "models/GetStatus200Response.ts": "ae915e856819f2dae4fb0dfbb44257287070d948677a440fe4fa7fa664b9800d", + "models/GetWebhook200Response.ts": "37dd83ac02150110aae55e6839c72535f54f9e64078c93b269a3a2a1acbae3d1", + "models/GetWebhook200ResponseWebhookUrl.ts": "cb5ff176cfb4b8cdc99beab7456105c5fa2aaec80537fd82f85d6540ab8384ff", + "models/GetWhatsappBusinessEncryption200Response.ts": "80e594ee1b968f65f6fb488d340c392dd4f6024828934f1e724beabf9e2e27bf", + "models/index.ts": "2dbab93452addd4fb3d1f8eec8dabeefd2190eba241492d1328ff305891ef559", + "models/InitiateCallRequest.ts": "a31e9981a53b4b26c05f8b1c4796e7c0b293f6152778d52c116cafb83eb2cf1a", + "models/InitiateCallRequestSession.ts": "0813ea88e6a0a9126344ae0313db2f5387772f9317b2731ddf51776436eeeb15", + "models/InitiateCallResponse.ts": "384f74d1273a47f1302019e70b90c00b77e93e9c72592bbe1f08132889d727d8", + "models/InitiateCallResponseCallsInner.ts": "e91cb6372a0bb3786e0f56a4074250b2ffc4ef340ea3ac4baa97ea5ac2b94c6b", + "models/InitiateCallResponseResponse.ts": "f2b391d587686651553b038be07912a1f2e33e29e6aa0899f50b76bee64e2c64", + "models/ListBlockedUsers200Response.ts": "2ee77ac56dcde43b1b43ee9d3dbce2ecddc755f23ab5dec1931439c158854888", + "models/ListFlows200Response.ts": "99c381605f9fae51b442ab2e4a2f53c504bc821b5c5966556a68872a66ed3dab", + "models/ListMessages200Response.ts": "cba1ced47e9b2de5e5c872aee5d99f2da77ceb911cc13b1eef61412bf660973c", + "models/ListSettings200Response.ts": "be6069ed0ba0d47dd62e067dc1be3a92507b0066c1a552b6d6cef36a300ee267", + "models/ListSettings200ResponseWebhookUrl.ts": "63aa5d8dd49abba89740a80b4c834aab2814ba0b423573c4a9e72cd5b37b6f30", + "models/ListTemplates200Response.ts": "df236c8739af4414020723d2418d2ca3e92cc81b8585ad7ba312772603f4ac1d", + "models/MessageSentResponse.ts": "698eae2fb85faceaa12b2e458ce7832f142ec6c1d4a641b2c21e19238eec9637", + "models/PatchFlowsFlowIdAssets200Response.ts": "d664242956e0ba40d7d1c44aa41e6c4f73824cdcc0ff4f858be702094dcccf2e", + "models/PatchFlowsFlowIdAssetsRequest.ts": "974961a29771553b8f2d5834c701672d72df7a1aa1ca0640b7293525bce7d42e", + "models/PatchFlowsFlowIdMetadataRequest.ts": "4c81ba7e64500012cf212f0ee5999d305eda724f4665dc5452941b0eadc639eb", + "models/ProfileInfo.ts": "554077e8fb60c7141eea0373ba29bffa25cc1d6d65bf5926e0aa8a967845b9a2", + "models/RemoveTemplateRequest.ts": "39c0508c5b8bc277dccae59e07ad542dde246046af8dfeef12cfbc4ce7ede013", + "models/RetrieveMedia200Response.ts": "50f055a6cf5daeb256deff4ae6dc3d0cb3f275986a12cdb48c93fd42a1bfacd6", + "models/SendAddressMessageRequest.ts": "71f77ffbcaf8b728002c13d5246a83ea22eaf2419e63572bd0ec44d74891db56", + "models/SendButtonRequest.ts": "8e7a8bb571b3535c51affc7375b11082106c09ef8d6b7f883762680d28fa882a", + "models/SendButtonRequestSectionsInner.ts": "d340422e1291e8defe4acde7d614f0a47c9a568fe6ec8a86b0874cc5781de012", + "models/SendButtonRequestSectionsInnerReply.ts": "75ffd6fb06b69fc452ebf54157bd931ffb97a43b79f9e39fa9fb8aeea8b7b898", + "models/SendCarouselRequest1.ts": "1253c235e4b3db31044df26f9e94706d67905030326991fc720cb3338b0c52f3", + "models/SendContactRequest.ts": "fdc235946cde57c1d38cabc32e2ca161994495590c6810680fe66d3d45ac631b", + "models/SendContactRequestContact.ts": "91952b331c03079e64541fad55020d66d05a856ab2dff8314aeb0adabe87d0a4", + "models/SendContactRequestContactName.ts": "7bf8258800f1c7a4391c8176f02f675ed1eab2d1e72c743a628d4f1a426bafa0", + "models/SendContactRequestContactsInner.ts": "fe42fbce017886b4e6e4601235e396135ee020af72670aae644dc55fc203d662", + "models/SendContactRequestContactsInnerName.ts": "0cc11a29344670bf725b68720f64715ff8db77b87405fa8b25397e26ebfc5884", + "models/SendContactRequestContactsInnerOrg.ts": "cd0a66d7a487118cf74c9ce21115eed26c3b3d37a07ca3bacab81e9812687567", + "models/SendContactRequestContactsInnerPhonesInner.ts": "f4537d2d9c0c0827f45e8ff16597ba688e2c6b921df62708cb130aa34fe83a99", + "models/SendCtaUrlRequest.ts": "80c9abc8336ff6d955a9c0d5718cba1d52654a1a80c452e889089109eb6f2243", + "models/SendFileRequest.ts": "0a4be5ca3693cf5175bf237ce4d55fbaf42d34e3a829c3675c6facea2c446375", + "models/SendFlowRequest1.ts": "844925a0d5add4a867c173f2c693b7a1bb51d1973102573a39304302997bc457", + "models/SendFlowRequest1Header.ts": "952c141abc3c8693181f3be19073b9ffe3a1cac8af94a4d8ef66ace19cb249d5", + "models/SendFlowRequestHeader.ts": "8443429192cc785517a763e5f76106bb73c1efca987efe6da983b6f2eadacd66", + "models/SendListRequest.ts": "1f831dfc9503f290b21b62ef584c47f4bf890eab0b4c1856c859d85f2d18f85b", + "models/SendListRequestSectionsInner.ts": "b1e4605c55e291482339c92276261f38ae2e5212ff8f2a420d479485aeee1a04", + "models/SendListRequestSectionsInnerRowsInner.ts": "16bd8ebbef2d0da8798ccfb4f53b8823d1884d3d220b3641095317a8a7b6effc", + "models/SendLocationRequest1.ts": "fb882779a589cb3e85c32d236f6fa2636c8c23ee5582e04973e3caf92c2dbc2e", + "models/SendLocationRequestRequest.ts": "fa0e2e1cf8b9fc7ca584593cb7f7fe5826923d0aec6eae8d1585ca0e918f265a", + "models/SendMessageRequest.ts": "31e4d532e8834215dd6724cb0645dca88c97d4ecea48796618d162f78b6bb5b1", + "models/SendOrderDetailsRequest.ts": "1b84a61ed8003427d14ac13053f048a71802251aa99ce874a1ababfabfdc576a", + "models/SendOrderDetailsRequestLanguage.ts": "9c6237db8f099810d98755b6e719d5ab44b8a894b0802d752bf83cedf4adacc4", + "models/SendOrderDetailsRequestOrder.ts": "9f787157bb690f7e8b7a06d26a38637b62b3896a651c3da2d20ff115002b0229", + "models/SendOrderDetailsRequestOrderItemsInner.ts": "92668bd0184ef69226f9027bc898e8e773d1e89e6134df8c2a95f4e04c5840d4", + "models/SendOrderDetailsRequestOrderItemsInnerAmount.ts": "b2997affd25e89e4e59831243f3a23efb3131b6e006307ca0ee170cdd20c6b31", + "models/SendPaymentRequestRequest.ts": "f4b16c9452dc5db26bec671472bfa79317ba66e8917bdeb77f96df7ca32b780c", + "models/SendProductRequest.ts": "3b4481335a2076adda729cbb188faec79344308d4b5f65c0e53a4a41c019fcad", + "models/SendReactionRequest.ts": "ddd6167aefe7b16e508ef422895dfd4abeafa2ff6a4396c5237d17a417fdf5c0", + "models/SendStickerRequest.ts": "d4c4355fda796aefe246845245f0a8941218ce3c958e1b5b66ce08c696929615", + "models/SendTemplateRequest.ts": "cc5e0cc31be46ec7891806626e9529a85e38e705f7acf1aa8c39b50398ef577d", + "models/SendTemplateRequestLanguage.ts": "4a6975e659db4620935e4c9e6c7ea403b737bf1ec646ebb3420410917ac52138", + "models/SetWebhook200Response.ts": "c37ad359c451db13f9f47c44ddad9f564227fca2d00997bdeda24e0748021cc2", + "models/SetWebhook200ResponseWebhookUrl.ts": "b4bb1f6f7ea618d52fe324e5aca318b86827b9cd239e31c739ce65f469f47849", + "models/SetWebhookRequest.ts": "a20525df595479659336ee86da6167ad770fb742753bfb0bc50f60e1c2cab947", + "models/SetWebhookRequestWebhookUrl.ts": "dcc8679cf3cfeb135c99da2e49144a87e23fb0fd8b58a9672e51001b4f0ee29c", + "models/SetWhatsappBusinessEncryptionRequest.ts": "b645f585750f27944820b245dec1514cd9f875007a9492cf0f1d224cc36ea903", + "models/SuccessResponse.ts": "a1f3747f91cedaca60319587a09b04f656641735aa157dc3f1ac9123dfd48165", + "models/UpdateCallingSettings200Response.ts": "c6105b3919011b8a9e162022dd1076be3078fc115e8a77ce42bb8fc8560cdee9", + "models/UpdateCallingSettings200ResponseResponse.ts": "89f95e8a3af5787e323cfce141b7090aa7e1ccf042c69e9473f3fc1660e09bc7", + "models/UpdateMe200Response.ts": "9dc0f38df817ec66b6406a8d1c32a9e620bc7315950a40efd767cbe86713c329", + "models/UpdateMeRequest.ts": "c2f143150ae49850dd140476dc7be4b94d3d070edb839240b4eb9b717c70a7d6", + "models/WebhookUrlStatus.ts": "eb768c8ec0b41a827bb38cc7d7a68dabbf428e2d148fae8ed6ff3f5fb5f72c55", + "runtime.ts": "55f99bb834cb7817144a6a393e69eadda862cc52bb36aaff731f7ffbd5dbaadd" +} diff --git a/quality/generator/openapi.yaml b/quality/generator/openapi.yaml new file mode 100644 index 0000000..53a43b1 --- /dev/null +++ b/quality/generator/openapi.yaml @@ -0,0 +1,4622 @@ +openapi: 3.0.3 +info: + title: 1MSG WhatsApp Business API (Public) + description: > + Public client API for sending messages, managing groups, flows, and + templates. + + + This is the API exposed to end customers via platform.1msg.io + + + **Authentication:** Pass the channel token in **one** place. The API checks + + JSON body (`token`), then query string (`?token=`), then + + `Authorization: Bearer` header (preferred in production). + + + **Documentation:** + https://help.1msg.io/platform-1msg/getting-start/quick-start + + **API Docs:** https://docs.1msg.io/ + version: 1.0.0 + contact: + name: 1MSG API Support + url: https://help.1msg.io + email: support@1msg.io +servers: + - url: https://api.1msg.io + description: Production + - url: https://api-stage.1msg.io + description: Staging + - url: http://127.0.0.1:3050 + description: Local development +tags: + - name: Messaging + description: Send messages, files, templates, and other content + - name: Users + description: Block, unblock, and list blocked WhatsApp users + - name: Profile + description: Channel profile information (read and update) + - name: Channel + description: Channel status and automation settings + - name: Catalog + description: Catalog and cart commerce settings (`GET`/`POST /commerce`) + - name: Groups + description: Create and manage WhatsApp groups + - name: Flows + description: WhatsApp Flows (interactive forms) + - name: Templates + description: Get and manage message templates + - name: Webhooks + description: > + Client webhook URL configuration (`GET`/`POST /webhook`). + + + Auto-disable is **per URL**, not per channel. Prefer `webhookStatuses` on + + `GET /webhook` / `GET /settings`. Top-level `haveDisabledWebhooks` means + at + + least one configured URL is sticky-disabled; live URLs still receive + events. + - name: Calling + description: > + WhatsApp Calling API (beta) — VoIP **signaling** proxy. + + + 1msg does **not** host media, store call history, or store recordings. + + You need your own WebRTC or SIP stack. + + + ### Prerequisites + + - Meta Calling enabled on the number (Cloud API; not COEX) + + - Paid channel — trial / `subscriptionBlocked` → **403** plain text + + - Webhook URL configured (`POST /webhook`) for `calls` events + + + ### Inbound (user → business) + + 1. Webhook `type=calls`, `event=connect` — take `call_id` + SDP **offer** + + 2. Optional: `POST /initiateCall` `action=pre_accept` + WebRTC **answer** + SDP + + 3. `action=accept` + WebRTC **answer** SDP, or `action=reject` + + 4. Later `event=terminate`, or `action=terminate` to hang up + + + Answer within ~**30–60s** or Meta ends as unanswered. + + + **Critical:** `accept` / `pre_accept` need a **WebRTC-generated SDP + answer**. + + Do **not** echo Meta's offer. Postman/curl alone cannot establish real + media. + + + ### Outbound (business → user) + + 1. Send Call Permission Request (CPR) — template or interactive + + 2. Wait for permission reply on the **messages** webhook + (`call_permission_reply`) + + 3. `POST /initiateCall` `action=connect` + business SDP **offer** + + 4. Apply Meta's SDP **answer** from the `calls` connect webhook + + + Meta limits (summary): permission ~7 days; up to 5 calls / 24h / user; + + max 2 CPR / 7 days; auto-revoke after 4 unanswered. + + + ### Webhooks (`type=calls`) + + Passthrough of Meta `field=calls` plus `type`, `instanceId`. + + Events: connect (offer or answer SDP), statuses (`RINGING` / `ACCEPTED` / + + `REJECTED`), terminate. CPR replies use the messages path, not + `type=calls`. + + + See operations below for request bodies and examples. +paths: + /me: + get: + summary: Get Profile Info + description: > + Return the WhatsApp Business profile for this channel: About, address, + + description, email, phone, websites, industry (`vertical`), and profile + photo URL. + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + description: Profile information + content: + application/json: + schema: + $ref: "#/components/schemas/ProfileInfo" + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Profile + operationId: getMe + post: + summary: Update profile info + description: > + Update WhatsApp Business Account profile fields. At least one of + + about, description, email, photo, address, vertical, websites is + required. + + Blocked when the channel subscription limit is exceeded. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + about: + type: string + description: Profile About section (WhatsApp status text) + example: Available 9–18 + address: + type: string + description: Business address shown on the profile + description: + type: string + description: Business description (max 256 characters) + email: + type: string + description: Business email shown on the profile + example: support@example.com + vertical: + type: string + description: Industry of the business + photo: + type: string + description: HTTPS URL or data:image/...;base64,... payload + websites: + type: array + items: + type: string + description: Business website URLs + additionalProperties: true + example: + about: Available 9–18 + email: support@example.com + responses: + "200": + description: Profile updated + content: + application/json: + schema: + type: object + properties: + result: + type: string + example: success + additionalProperties: true + example: + result: success + "401": + $ref: "#/components/responses/InvalidToken" + "422": + description: Wrong request (no updatable fields) + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Profile + operationId: updateMe + /sendMessage: + post: + summary: Send a Message + description: > + Send a message to an existing chat. (Only if the dialogue has an Open + Session). + + The message will be added to the queue for sending and delivered even if + the phone + + is disconnected from the Internet or authorization is not passed. + + + Only one of two parameters is needed to determine the destination - + chatId or phone. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/x-www-form-urlencoded: + schema: + $ref: "#/components/schemas/SendMessageRequest" + application/json: + schema: + $ref: "#/components/schemas/SendMessageRequest" + example: + body: Hello World + phone: 12020721369 + responses: + "200": + $ref: "#/components/responses/MessageSent" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + operationId: sendMessage + /sendFile: + post: + summary: Send a File + description: > + Send a file to an existing chat. (Only if the dialogue has an Open + Session). + + Only one of two parameters is needed to determine the destination - + chatId or phone. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/x-www-form-urlencoded: + schema: + $ref: "#/components/schemas/SendFileRequest" + application/json: + schema: + $ref: "#/components/schemas/SendFileRequest" + example: + phone: 12020721369 + body: https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf + filename: dummy.pdf + caption: Here is the file + responses: + "200": + $ref: "#/components/responses/MessageSent" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + operationId: sendFile + /sendLocation: + post: + summary: Send a Location + description: > + Send a location to an existing chat. (Only if the dialogue has an Open + Session). + + Only one of two parameters is needed to determine the destination - + chatId or phone. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + content: + application/x-www-form-urlencoded: + schema: + type: object + required: + - lat + - lng + properties: + lat: + type: string + description: "Latitude of the location. Example: 45.018337" + lng: + type: string + description: "Longitude of the location. Example: -73.968285" + address: + type: string + description: "Address of the location. Only displayed if name is present. + Example: 9766 Valley View St., New York, NY 10024" + name: + type: string + description: "Name of the location. Example: Facebook HQ" + quotedMsgId: + type: string + description: Quoted message ID (Cloud API) + chatId: + type: string + description: "Required if phone is not set. Chat ID from the message list. + Examples: 12020721369@c.us or + 120363046942338209@g.us(group)" + phone: + type: integer + description: "Required if chatId is not set. A phone number starting with the + country code. USA example: 12020721369." + application/json: + schema: + type: object + required: + - lat + - lng + properties: + lat: + type: string + lng: + type: string + address: + type: string + name: + type: string + quotedMsgId: + type: string + chatId: + type: string + phone: + type: integer + example: + lat: "45.018337" + lng: "-73.968285" + name: Facebook HQ + address: 9766 Valley View St., New York, NY 10024 + phone: 12020721369 + responses: + "200": + $ref: "#/components/responses/MessageSent" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + operationId: sendLocation + /sendContact: + post: + summary: Send a Contact + description: > + Send a WhatsApp contact card. + + + Preferred simple body (legacy-compatible): + + + ```json + + { + "phone": "79001234567", + "contact": { "name": "Lida", "phone": "+79181976551" } + } + + ``` + + + Cloud API shape also works: `contacts` is an array of objects with + + `name.formatted_name` and `phones[].phone` (E.164 string, **not** a + timestamp). + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + $ref: "#/components/responses/MessageSent" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + requestBody: + content: + application/json: + schema: + type: object + properties: + phone: + type: string + description: Recipient phone with country code. Use phone or chatId. + chatId: + type: string + description: Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). + Use phone or chatId. + quotedMsgId: + type: string + contact: + type: object + description: Simple contact card. Use this or `contacts`. + required: + - name + - phone + properties: + name: + description: Display name (string) or Cloud API name object + oneOf: + - type: string + - type: object + additionalProperties: true + phone: + type: string + description: Contact phone in E.164 (`+79181976551`), not a timestamp + email: + type: string + org: + type: object + additionalProperties: true + url: + type: string + contacts: + type: array + items: + type: object + properties: + name: + type: object + properties: + formatted_name: + type: string + first_name: + type: string + last_name: + type: string + middle_name: + type: string + suffix: + type: string + prefix: + type: string + birthday: + type: string + addresses: + type: array + items: + type: object + additionalProperties: true + emails: + type: array + items: + type: object + additionalProperties: true + org: + type: object + properties: + company: + type: string + department: + type: string + title: + type: string + phones: + type: array + items: + type: object + properties: + phone: + type: string + description: E.164 phone (`+79181976551`). Not a timestamp. + type: + type: string + wa_id: + type: string + urls: + type: array + items: + type: object + additionalProperties: true + example: + phone: "{{testPhone}}" + contact: + name: John Doe + phone: "+1234567890" + operationId: sendContact + /sendList: + post: + summary: Send List Message + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + $ref: "#/components/responses/MessageSent" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + requestBody: + content: + application/json: + schema: + type: object + properties: + phone: + type: string + description: Recipient phone with country code. Use phone or chatId. + chatId: + type: string + description: Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). + Use phone or chatId. + quotedMsgId: + type: string + body: + type: string + buttonText: + type: string + action: + type: string + sections: + type: array + items: + type: object + properties: + title: + type: string + rows: + type: array + items: + type: object + properties: + id: + type: string + format: utc-millisec + title: + type: string + description: + type: string + example: + phone: "{{testPhone}}" + body: This is a list message + buttonText: Click me + action: Action + sections: + - title: Section 1 + rows: + - id: "1" + title: Row 1 + description: Description for Row 1 + operationId: sendList + /sendButton: + post: + summary: Send Reply Buttons Message + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + $ref: "#/components/responses/MessageSent" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + requestBody: + content: + application/json: + schema: + type: object + properties: + phone: + type: string + description: Recipient phone with country code. Use phone or chatId. + chatId: + type: string + description: Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). + Use phone or chatId. + quotedMsgId: + type: string + description: Optional Cloud API wamid to quote + body: + type: string + footer: + type: string + header: + type: object + additionalProperties: true + description: Optional interactive header (text/image/video/document) + buttons: + type: array + items: + type: object + description: Legacy alias for sections (`[{id,title}]`) + sections: + type: array + items: + type: object + properties: + type: + type: string + reply: + type: object + properties: + id: + type: string + format: utc-millisec + title: + type: string + example: + phone: "{{testPhone}}" + body: This is a buttons message + footer: Footer + sections: + - type: reply + reply: + id: "1" + title: Button 1 + operationId: sendButton + /sendLocationRequest: + post: + summary: Send Location Request Message + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + $ref: "#/components/responses/MessageSent" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + requestBody: + content: + application/json: + schema: + type: object + properties: + phone: + type: string + description: Recipient phone with country code. Use phone or chatId. + chatId: + type: string + description: Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). + Use phone or chatId. + quotedMsgId: + type: string + body: + type: string + example: + phone: "{{testPhone}}" + body: Text + operationId: sendLocationRequest + /sendFlow: + post: + summary: Send WhatsApp Flow Message + description: > + Send Interactive WhatsApp Flow message to an existing chat. (Only if the + dialogue has an Open Session). + + Only one of two parameters is needed to determine the destination - + chatId or phone. + + + Use this method to send a published WhatsApp Flow as a service + (interactive) message. + + If the 24-hour window is closed, send a template with a FLOW button via + /sendTemplate. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + content: + application/x-www-form-urlencoded: + schema: + type: object + required: + - body + - flowId + - flowToken + - flowCta + properties: + body: + type: string + description: Flow message body text + header: + oneOf: + - type: string + - type: object + description: Flow header (string or text header object) + footer: + type: string + description: Footer text + flowId: + type: string + description: Published Flow ID + flowToken: + type: string + description: Flow token generated by the business + flowCta: + type: string + description: CTA button text + flowAction: + type: string + enum: + - navigate + - data_exchange + description: Flow action type + flowActionPayload: + type: object + description: Required for flowAction=navigate (screen is required). Ignored for + data_exchange. If data is provided, it must be a non-empty + object. + flowMessageVersion: + type: string + description: Flow message version (default "3") + mode: + type: string + enum: + - draft + - published + description: Flow mode (draft or published). If omitted, provider default + applies + flowActionData: + type: object + description: Shortcut for flowActionPayload.data (optional) + flowActionScreen: + type: string + description: Shortcut for flowActionPayload.screen (optional) + quotedMsgId: + type: string + description: Quoted message ID (Cloud API) + chatId: + type: string + description: "Required if phone is not set. Chat ID from the message list. + Examples: 12020721369@c.us or + 120363046942338209@g.us(group)" + phone: + type: integer + description: "Required if chatId is not set. A phone number starting with the + country code. USA example: 12020721369." + application/json: + schema: + type: object + required: + - body + - flowId + - flowToken + - flowCta + properties: + body: + type: string + header: + oneOf: + - type: string + - type: object + footer: + type: string + flowId: + type: string + flowToken: + type: string + flowCta: + type: string + flowAction: + type: string + enum: + - navigate + - data_exchange + flowActionPayload: + type: object + flowMessageVersion: + type: string + mode: + type: string + enum: + - draft + - published + flowActionData: + type: object + flowActionScreen: + type: string + quotedMsgId: + type: string + chatId: + type: string + phone: + type: integer + responses: + "200": + $ref: "#/components/responses/MessageSent" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + operationId: sendFlow + /sendReaction: + post: + summary: Send Reaction + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + $ref: "#/components/responses/MessageSent" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + requestBody: + content: + application/json: + schema: + type: object + properties: + phone: + type: string + description: Recipient phone with country code. Use phone or chatId. + chatId: + type: string + description: Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). + Use phone or chatId. + body: + type: string + quotedMsgId: + type: string + example: + phone: "{{testPhone}}" + body: 😀 + quotedMsgId: "{{lastMessageId}}" + operationId: sendReaction + /sendCarousel: + post: + summary: Send Carousel + description: > + You can send product cards via Carousel in two ways: + + + Template messages: do not require a 24-hour customer service window + between you and the recipient. Use sendTemplate. + + + Free-form messages: can be sent only when a customer service window is + open between you and the recipient. Use sendCarousel. + + + The message structure in /sendCarousel is largely similar to sending a + template. However, in this case you must + + explicitly specify all elements that are created in advance when working + with templates. This is because the message + + is sent without using a template. + + + In /sendCarousel, for a Catalog Carousel there can be either 1 URL + button or one or more quick reply buttons. + + + Prefer the simple `cards` array (2–10 cards). Each card needs a header + media/product + + plus a CTA URL or quick-reply buttons. Example: + + + ```json + + { + "phone": "79001234567", + "body": "Pick a product", + "cards": [ + { + "header": { "type": "image", "image": { "link": "https://example.com/1.jpg" } }, + "body": { "text": "Card one" }, + "type": "cta_url", + "action": { "name": "cta_url", "parameters": { "url": "https://example.com/p1", "display_text": "Open" } } + }, + { + "header": { "type": "image", "image": { "link": "https://example.com/2.jpg" } }, + "body": { "text": "Card two" }, + "type": "cta_url", + "action": { "name": "cta_url", "parameters": { "url": "https://example.com/p2", "display_text": "Open" } } + } + ] + } + + ``` + + + `params` with a `CAROUSEL` component is the template-like alternative. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + content: + application/x-www-form-urlencoded: + schema: + type: object + properties: + body: + type: string + description: Text shown above the carousel. Optional. If omitted and params + include a body component, the body will be taken from + params. + cards: + type: array + minItems: 2 + maxItems: 10 + description: Preferred. 2–10 carousel cards (header + body + CTA or quick + replies). + items: + type: object + additionalProperties: true + params: + type: array + items: + type: object + description: > + Required. Template-like structure (same as sendTemplate + params). Must include a CAROUSEL component and its cards. + + + Structure: + + - params[] item with type CAROUSEL and cards (2..10) + + - cards[] item: + - components[] items: + - header: parameters[0] with type image/video/product + - image: {"image": {"link": "https://..."}} + - video: {"video": {"link": "https://..."}} + - product: {"product": {"catalog_id": "...", "product_retailer_id": "..."}} + - button: sub_type url or quick_reply + - url: parameters {"text": "Button", "url": "https://..."} + - quick_reply: parameters[] of {"id": "...", "text": "..."} + quotedMsgId: + type: string + description: Quoted message ID (Cloud API) + chatId: + type: string + description: "Required if phone is not set. Chat ID from the message list. + Examples: 12020721369@c.us or + 120363046942338209@g.us(group)" + phone: + type: integer + description: "Required if chatId is not set. A phone number starting with the + country code. USA example: 12020721369." + application/json: + schema: + type: object + properties: + body: + type: string + description: Text shown above the carousel + cards: + type: array + minItems: 2 + maxItems: 10 + description: Preferred. 2–10 carousel cards. + items: + type: object + additionalProperties: true + params: + type: array + items: + type: object + description: Template-like alternative — include a CAROUSEL component with cards + quotedMsgId: + type: string + chatId: + type: string + phone: + type: integer + responses: + "200": + $ref: "#/components/responses/MessageSent" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + operationId: sendCarousel + /sendProduct: + post: + summary: Send a Product + description: > + Send a single catalog product or a product list. + + Destination is `chatId` or `phone`. `action` is required: + + - single product: `{ "catalog_id": "...", "product_retailer_id": "..." + }` + + - product list: `{ "catalog_id": "...", "sections": [{ "title": "...", + "product_items": [{ "product_retailer_id": "..." }] }] }` + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - action + properties: + phone: + type: string + description: Recipient phone with country code. Use phone or chatId. + chatId: + type: string + description: Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). + Use phone or chatId. + quotedMsgId: + type: string + body: + type: string + description: Optional message text shown with the product + footer: + type: string + header: + type: string + description: Text header (product list only) + action: + type: object + additionalProperties: true + description: Catalog action (`catalog_id` + `product_retailer_id`, or `sections` + for a list) + additionalProperties: true + example: + chatId: 12020721369@c.us + body: Have a look + action: + catalog_id: "448008021021719" + product_retailer_id: "0001" + responses: + "200": + $ref: "#/components/responses/MessageSent" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + operationId: sendProduct + /sendTemplate: + post: + summary: Send Template Message + description: > + Send a WhatsApp **template** message (works outside the 24-hour session + window). + + + Use this tool — not `send_message` — when the 24h session is closed. + + + `params` MUST be Cloud API **component objects**, never a flat list of + strings + + and never the old On-Prem `hsm` / `localizable_params` format. + + + Example body variable `{{1}}`: + + + ```json + + { + "type": "body", + "parameters": [{ "type": "text", "text": "Ivan" }] + } + + ``` + + + Do not send `"type": "hsm"` and do not send `params: ["Ivan", "123"]`. + + + Supported `params` button `sub_type` values include: `url`, + `quick_reply`, + + `copy_code` / `coupon_code`, `catalog`, `flow`, `limited_time_offer`, + and + + **`order_details`** (WhatsApp Payments **India only** — requires an + approved + + Utility template with an ORDER_DETAILS button). + + + Convenience wrapper with structured fields: `POST /sendOrderDetails`. + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + additionalProperties: true + tags: + - Templates + requestBody: + content: + application/json: + schema: + type: object + properties: + template: + type: string + description: Approved template name (template `name`, not the old HSM + `element_name`) + language: + type: object + description: Template language. Always set `policy` to `deterministic`. + properties: + policy: + type: string + description: Must be `deterministic` + example: deterministic + default: deterministic + code: + type: string + example: en + namespace: + type: string + description: Template namespace from `list_templates` + params: + type: array + description: > + Template components in WhatsApp Cloud API format. + + Each item is an object with `type` (`body`, `header`, + `button`) + + and `parameters` (objects with `type` + `text` / media / + action). + + Never a list of strings. Never HSM `localizable_params`. + items: + type: object + additionalProperties: true + description: | + Component object, e.g. {"type":"body","parameters":[{"type":"text","text":"Ivan"}]} or a header/button/carousel component. Not a string. + phone: + type: string + description: Recipient phone with country code (use phone or chatId) + chatId: + type: string + description: Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). + Use phone or chatId. + quotedMsgId: + type: string + description: Optional Cloud API wamid to quote + useMMlite: + type: boolean + description: > + Force Marketing Messages API (POST marketing_messages). + + If omitted: auto for MARKETING category when channel has + mm_lite_enabled + + and mm_lite_available service settings. + messageActivitySharing: + type: boolean + description: > + Sets message_activity_sharing on WABA payload. Enables click + tracking webhooks. + + Requires MM Lite path. Ignored on Cloud API fallback. + messageSendTtlSeconds: + type: integer + description: > + Template message TTL in seconds (message_send_ttl_seconds). + + MARKETING via MM Lite: 43200–2592000. AUTHENTICATION: + 30–900. + + UTILITY: 30–43200. AUTH/UTILITY also accept -1 (30-day + custom TTL). + example: + template: test_buttons_2 + language: + policy: deterministic + code: ru + namespace: 41123797_e45e_4f06_a2fa_443b27c6f5ec + phone: "{{testPhone}}" + params: + - type: body + parameters: + - type: text + text: Ivan + operationId: sendTemplate + /messages: + get: + summary: Get messages list + description: | + List stored chat history for this channel (requires history storage). + Filter with `chatId`, `limit`, `last`, message numbers, or time bounds. + parameters: + - $ref: "#/components/parameters/token" + - name: chatId + in: query + schema: + type: string + description: Filter messages for one chat (`phone@c.us`, group `@g.us`, or BSUID + `@lid`) + - name: limit + in: query + schema: + type: integer + description: Max rows to return (default 100) + - name: last + in: query + schema: + type: boolean + description: If true, return the latest messages (DESC). Default false. + - name: lastMessageNumber + in: query + schema: + type: integer + - name: firstMessageNumber + in: query + schema: + type: integer + - name: min_time + in: query + schema: + type: integer + description: Unix timestamp lower bound + - name: max_time + in: query + schema: + type: integer + description: Unix timestamp upper bound + - name: msgId + in: query + schema: + type: string + description: Filter by stored message id + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + properties: + notice: + type: string + messages: + type: array + items: + type: object + additionalProperties: true + additionalProperties: true + examples: + ok: + value: + messages: [] + historyDisabled: + value: + notice: saving history disabled + tags: + - Messaging + operationId: listMessages + /readMessage: + post: + summary: Mark message as read + parameters: + - $ref: "#/components/parameters/token" + requestBody: + content: + application/x-www-form-urlencoded: + schema: + type: object + properties: + messageId: + type: string + msgId: + type: string + typingIndicator: + type: boolean + default: false + description: Show WhatsApp typing indicator (max 25s or until reply) + application/json: + schema: + type: object + properties: + messageId: + type: string + msgId: + type: string + typingIndicator: + type: boolean + default: false + description: Show WhatsApp typing indicator (max 25s or until reply) + responses: + "200": + description: Server response example + content: + application/json: + schema: + type: object + properties: + result: + type: string + additionalProperties: true + example: + result: success + "401": + description: Invalid token + content: + application/json: + schema: + type: object + properties: + error: + type: string + tags: + - Messaging + operationId: createReadMessage + /uploadMedia: + post: + summary: Upload media + description: > + Upload a file to WhatsApp media storage and get a numeric `mediaId` + + for later use with `send_file` / `send_sticker` (`mediaId` field, not + `body`). + + + Pass the file as `body` **or** `url` — an HTTP(S) URL or a base64 data + URI. + + The `mediaId` in the response is a numeric string (keep it as a string). + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + body: + type: string + description: File HTTP(S) URL or base64 data URI (`data:;base64,...`) + url: + type: string + description: Alias for `body` — public HTTP(S) URL of the file to upload + example: + body: https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + properties: + mediaId: + type: string + additionalProperties: true + tags: + - Messaging + operationId: createUploadMedia + /sendSticker: + post: + summary: Send sticker message + description: Send a WhatsApp sticker by mediaId or link URL. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + phone: + type: integer + chatId: + type: string + mediaId: + type: string + description: WABA media id from uploadMedia + link: + type: string + description: Public URL to webp sticker + quotedMsgId: + type: string + additionalProperties: true + responses: + "200": + $ref: "#/components/responses/MessageSent" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + operationId: sendSticker + /sendCtaUrl: + post: + summary: Send CTA URL interactive message + description: Send an interactive message with a single call-to-action URL button. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - body + - displayText + - url + properties: + phone: + type: integer + chatId: + type: string + body: + type: string + displayText: + type: string + description: Button label + url: + type: string + format: uri + header: + type: object + additionalProperties: true + footer: + type: string + quotedMsgId: + type: string + additionalProperties: true + responses: + "200": + $ref: "#/components/responses/MessageSent" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + operationId: sendCtaUrl + /sendAddressMessage: + post: + summary: Send address request message + description: > + Request shipping address from the user (WhatsApp interactive + `address_message`). + + + **India and Singapore only.** Requires: + + - Business WhatsApp number registered in that country + + - Recipient phone matching the country (`+91` ↔ `IN`, `+65` ↔ `SG`) + + + Pass `country: "IN"` or `country: "SG"`. Eligibility is validated + upstream; + + mismatches (e.g. Singapore phone with `country: "IN"`) return errors + such as + + `Unsupported Interactive Message type` (HTTP 200 with `sent: false`). + + + Optional action parameters: `values`, `saved_addresses`, + `validation_errors`. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - body + properties: + phone: + type: integer + description: Recipient phone (E.164 digits, no +). Must match country. + chatId: + type: string + body: + type: string + description: Body text shown with the address request + country: + type: string + enum: + - IN + - SG + description: Address form country. Defaults to IN if omitted. + example: SG + values: + type: object + description: Optional prefilled address fields + additionalProperties: true + saved_addresses: + type: array + description: Optional previously saved addresses for the user + items: + type: object + additionalProperties: true + validation_errors: + type: object + description: Optional field validation errors when re-prompting + additionalProperties: true + quotedMsgId: + type: string + additionalProperties: true + examples: + singapore: + summary: Singapore + value: + phone: 6531650115 + body: Thanks for your order! Tell us what address you’d like this delivered to. + country: SG + india: + summary: India + value: + phone: 919876543210 + body: Thanks for your order! Tell us what address you’d like this delivered to. + country: IN + responses: + "200": + $ref: "#/components/responses/MessageSent" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + operationId: sendAddressMessage + /sendOrderDetails: + post: + summary: Send order details (India payments template) + description: > + Send a WhatsApp **order details** payment / invoice message using a + + pre-approved **Utility** template that has an `ORDER_DETAILS` button. + + + **India only** (WhatsApp Payments India). Requires: + + - India WhatsApp Business number + + - Commerce enabled on the channel (`GET`/`POST /commerce`) + + - Approved template with an `ORDER_DETAILS` button + + + Use this method when you need structured fields (`order`, `referenceId`, + + `currency`, `paymentSettings`). The API appends a template button + + `sub_type: order_details` and sends via the same path as `POST + /sendTemplate`. + + + Works **outside the 24-hour session window** (template message). + + + You can also send the same payload yourself with `POST /sendTemplate` by + + including a button component in `params`: + + + ```json + + { + "type": "button", + "sub_type": "order_details", + "index": 0, + "parameters": [{ + "type": "action", + "action": { + "order_details": { + "reference_id": "order-123", + "currency": "INR", + "order": { "status": "pending", "items": [], "subtotal": { "offset": 100, "value": 50000 } } + } + } + }] + } + + ``` + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - template + - namespace + - language + - order + properties: + phone: + type: integer + description: Recipient phone (India E.164 digits, no +). Use phone or chatId. + example: 919876543210 + chatId: + type: string + description: Recipient chatId (e.g. phone@c.us). Use phone or chatId. + template: + type: string + description: Approved Utility template name that includes an ORDER_DETAILS + button + example: order_details_utility + namespace: + type: string + description: Template namespace from the channel / template list + example: your_namespace_uuid + language: + type: object + description: Template language + required: + - code + properties: + code: + type: string + description: Language code + example: en + policy: + type: string + description: Optional language policy + example: deterministic + additionalProperties: true + params: + type: array + description: > + Extra template components (HEADER / BODY / etc.). If an + order_details button is missing, the API appends one from + order / referenceId / currency / paymentSettings. + items: + type: object + additionalProperties: true + referenceId: + type: string + description: Unique order / payment reference id (maps to reference_id) + example: order-123 + currency: + type: string + description: Currency code for India payments + example: INR + paymentSettings: + type: object + description: > + Optional payment settings (UPI / payment gateway / payment + link). Forwarded as payment_settings on the order_details + action. + additionalProperties: true + order: + type: object + description: > + Order payload for the ORDER_DETAILS button. Typical fields: + status, items[], subtotal, tax, shipping, discount. Amount + objects use `{ "offset": 100, "value": }` + (e.g. value 50000 with offset 100 = ₹500.00). + required: + - items + properties: + status: + type: string + description: Order status + example: pending + items: + type: array + description: Line items + items: + type: object + properties: + retailer_id: + type: string + example: SKU-1 + name: + type: string + example: Item + quantity: + type: integer + example: 1 + amount: + type: object + properties: + offset: + type: integer + example: 100 + value: + type: integer + example: 50000 + additionalProperties: true + additionalProperties: true + subtotal: + type: object + properties: + offset: + type: integer + example: 100 + value: + type: integer + example: 50000 + additionalProperties: true + tax: + type: object + additionalProperties: true + shipping: + type: object + additionalProperties: true + discount: + type: object + additionalProperties: true + additionalProperties: true + additionalProperties: true + example: + phone: 919876543210 + template: order_details_utility + namespace: your_namespace_uuid + language: + code: en + referenceId: order-123 + currency: INR + order: + status: pending + items: + - retailer_id: SKU-1 + name: Item + amount: + offset: 100 + value: 50000 + quantity: 1 + subtotal: + offset: 100 + value: 50000 + responses: + "200": + $ref: "#/components/responses/MessageSent" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + operationId: sendOrderDetails + /sendPaymentRequest: + post: + summary: Send payment request (regional) + description: > + Send a regional payment request interactive message (beta scaffold). + + `region` must be IN, SG, or BR. Payload shape follows Meta regional + payments docs; + + verify on stage before production use. Full regional builders are not + implemented yet. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - phone + - region + properties: + phone: + type: integer + region: + type: string + enum: + - IN + - SG + - BR + body: + type: string + interactive: + type: object + additionalProperties: true + action: + type: object + additionalProperties: true + additionalProperties: true + responses: + "200": + $ref: "#/components/responses/MessageSent" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + operationId: sendPaymentRequest + /retrieveMedia: + get: + summary: Retrieve uploaded media metadata + description: | + Get WABA media URL and metadata by mediaId (from uploadMedia). + The returned `url` is temporary and typically expires within ~5 minutes. + parameters: + - $ref: "#/components/parameters/token" + - name: mediaId + in: query + required: true + schema: + type: string + responses: + "200": + description: Media metadata + content: + application/json: + schema: + type: object + properties: + url: + type: string + mimeType: + type: string + sha256: + type: string + fileSize: + type: integer + id: + type: string + additionalProperties: true + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + operationId: retrieveMedia + /media/{mediaId}: + delete: + summary: Delete media from WABA storage + description: > + Delete previously uploaded media by numeric `mediaId` (from + `/uploadMedia`). + + + This is the canonical deletion endpoint and uses the REST `DELETE` verb + on the + + media resource path. The older `POST /deleteMedia` is a deprecated + alias. + parameters: + - $ref: "#/components/parameters/token" + - name: mediaId + in: path + required: true + description: Numeric WABA media id + schema: + type: string + responses: + "200": + $ref: "#/components/responses/Success" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + operationId: deleteMedia + /deleteMedia: + post: + summary: Delete media from WABA storage (deprecated alias) + deprecated: true + description: > + **Deprecated.** Use `DELETE /media/{mediaId}` instead. + + + This POST alias is kept for backward compatibility with earlier + integrations. + + New integrations should call `DELETE /media/{mediaId}`: 1msg follows + REST + + conventions for resource deletion going forward (delete a resource with + the + + `DELETE` verb on its resource path). + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - mediaId + properties: + mediaId: + type: string + description: Numeric WABA media id + additionalProperties: true + responses: + "200": + $ref: "#/components/responses/Success" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + operationId: deleteMediaLegacy + /blockUser: + post: + summary: Block WhatsApp user + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - phone + properties: + phone: + type: integer + additionalProperties: true + responses: + "200": + $ref: "#/components/responses/Success" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Users + operationId: blockUser + /unblockUser: + post: + summary: Unblock WhatsApp user + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - phone + properties: + phone: + type: integer + additionalProperties: true + responses: + "200": + $ref: "#/components/responses/Success" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Users + operationId: unblockUser + /blockedUsers: + get: + summary: List blocked WhatsApp users + description: > + Returns users currently blocked on this WhatsApp channel (WABA `GET + /block_users`). + + Same channel token auth as `blockUser` / `unblockUser`. + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + description: Blocked users list + content: + application/json: + schema: + type: object + properties: + blockedUsers: + type: array + items: + type: object + additionalProperties: true + additionalProperties: true + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Users + operationId: listBlockedUsers + /mmLiteStatus: + get: + summary: Get MM Lite availability and status + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + description: MM Lite status for the channel + content: + application/json: + schema: + type: object + properties: + available: + type: boolean + status: + type: string + message: + type: string + additionalProperties: true + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Messaging + operationId: getMmLiteStatus + /status: + get: + summary: Get channel status + description: > + Return WhatsApp Cloud API connection status for this channel + (`connected` + + when the number can send). May include `accountStatus`, messaging limit, + + and MM Lite availability. + + + Optional `health_status_warning` appears only when Meta Graph health + could + + not be loaded and a soft `connected` response is returned. Omitted on + the + + normal path and when health details are not applicable for the channel — + + never an internal provider/transport name. + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + description: Channel status + content: + application/json: + schema: + type: object + properties: + isCloud: + type: boolean + example: true + status: + type: string + description: typically `connected` when the number can send + example: connected + accountStatus: + type: string + example: authenticated + mm_lite_available: + type: boolean + health_status_warning: + type: string + description: Optional soft-fail warning when Meta Graph health_status could not + be loaded. Never includes internal provider names. + additionalProperties: true + example: + isCloud: true + status: connected + accountStatus: authenticated + mm_lite_available: false + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Channel + operationId: getStatus + /settings: + get: + summary: Get channel settings + description: > + Return channel settings: webhook URL(s), delivery flags, and analytics + toggles. + + + Auto-disable / circuit state matches `GET /webhook`. **Prefer + `webhookStatuses`** + + (one row per configured URL). The breaker is per URL, not per channel. + + + Channel-level `haveDisabledWebhooks` is `true` when **at least one** URL + in + + `webhookUrl` is sticky auto-disabled — not "the channel is dead". Live + URLs + + still receive events. Top-level `circuitState` / `reason` / `fails` / + `trips` + + are a compatibility summary of one URL (first sticky-disabled, else + first + + configured). + + + This is the same `GET /settings` endpoint as the REST API (previously + missing from MCP). + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + description: Current settings + content: + application/json: + schema: + type: object + properties: + webhookUrl: + oneOf: + - type: string + - type: array + items: + type: string + description: One URL, or several if multiple webhooks are configured + guaranteedHooks: + type: boolean + description: Retry webhooks until acknowledged + ackNotificationsOn: + type: boolean + description: Include message ACK / status events in webhooks + rawHooks: + type: boolean + description: Forward raw provider webhook payloads + mm_lite_enabled: + type: boolean + template_analytics_enabled: + type: boolean + cta_url_link_tracking_opted_out: + type: boolean + haveDisabledWebhooks: + type: boolean + description: > + `true` when at least one URL in `webhookUrl` is sticky + auto-disabled. + + Not "the channel is dead": other configured URLs still + receive events. + circuitState: + type: string + description: > + Compatibility scalar for **one** URL (first + sticky-disabled, else first + + configured). Prefer `webhookStatuses[].circuitState`. + enum: + - ok + - degraded + - open + - half_open + - disabled + reason: + type: string + description: Last qualifying fail reason of the summary URL + fails: + type: integer + description: > + Diagnostic only (summary URL). Qualifying failures in the + rolling + + ~10 minute breaker window — not lifetime. Prefer + `webhookStatuses`. + trips: + type: integer + description: > + Diagnostic only (summary URL). Failed recovery probes (≈15 + min → + + 1 h → 6 h). Sticky disable after 3. Not a blind unblock + timer. + disabledAt: + type: integer + description: Epoch milliseconds when the summary URL became sticky-disabled + firstFailAt: + type: integer + description: > + Diagnostic only (summary URL). Epoch ms of the first fail + in the + + current ~10 minute window (pairs with `fails`). + lastStatus: + type: integer + description: Last HTTP status from the summary URL, when known + nextProbeAt: + type: integer + description: Epoch milliseconds of the next half-open probe for the summary URL, + if any + disabledWebhooks: + type: array + description: Currently configured URLs that are sticky auto-disabled (subset of + `webhookUrl`) + items: + type: object + additionalProperties: true + webhookStatuses: + type: array + description: One entry per currently configured URL. Prefer this over top-level + `haveDisabledWebhooks` / `circuitState`. + items: + $ref: "#/components/schemas/WebhookUrlStatus" + additionalProperties: true + example: + webhookUrl: https://example.com/webhook + guaranteedHooks: false + ackNotificationsOn: true + rawHooks: false + haveDisabledWebhooks: false + circuitState: ok + disabledWebhooks: [] + webhookStatuses: + - url: https://example.com/webhook + circuitState: ok + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Channel + operationId: listSettings + post: + summary: Update channel settings + description: > + Update channel settings. Only send fields you want to change. + + + `webhookUrl` **replaces** the stored list (one URL string, or up to 5 + URLs as an array). + + Passing an empty value clears webhooks. Repeating the same URL(s) also + clears a + + sticky auto-disable. With several URLs, send the complete array to + re-enable one + + of them — omitting a URL removes it from the channel. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + webhookUrl: + oneOf: + - type: string + - type: array + items: + type: string + description: Replacement webhook URL, or array of URLs (max 5) + guaranteedHooks: + type: boolean + ackNotificationsOn: + type: boolean + rawHooks: + type: boolean + template_analytics_enabled: + type: boolean + cta_url_link_tracking_opted_out: + type: boolean + additionalProperties: true + example: + webhookUrl: https://example.com/webhook + ackNotificationsOn: true + responses: + "200": + description: Updated settings + content: + application/json: + schema: + type: object + additionalProperties: true + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Channel + operationId: createSettings + /commerce: + get: + summary: Get Commerce Settings + description: > + Returns catalog/cart commerce settings for the channel. + + + Fails with a provider error when the WABA has no catalog linked — that + is an + + API/account limitation, not an MCP schema bug. + + + - `is_catalog_visible` — show catalog storefront icon (`true`) or hide + it (`false`). + + - `is_cart_enabled` — enable cart (`true`) or disable it (`false`). + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + description: Commerce settings + content: + application/json: + schema: + type: array + items: + type: object + properties: + id: + type: string + description: Catalog id + is_cart_enabled: + type: boolean + description: Whether the cart is enabled + is_catalog_visible: + type: boolean + description: Whether the catalog storefront icon is shown + additionalProperties: true + example: + - id: "789887292550821" + is_cart_enabled: true + is_catalog_visible: true + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Catalog + operationId: getCommerce + post: + summary: Set Commerce Settings + description: > + Update catalog/cart commerce settings via the `params` object. + + + - `params.is_catalog_visible` — show catalog storefront icon (`true`) or + hide it (`false`). + + - `params.is_cart_enabled` — enable cart (`true`) or disable it + (`false`). + + + Blocked when the channel subscription limit is exceeded. + + Requires a commerce-capable channel (Cloud Functions `/commerceWAV2`). + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - params + properties: + params: + type: object + required: + - is_cart_enabled + - is_catalog_visible + properties: + is_cart_enabled: + type: boolean + description: Enable cart + is_catalog_visible: + type: boolean + description: Show catalog storefront icon + additionalProperties: true + additionalProperties: true + example: + params: + is_cart_enabled: true + is_catalog_visible: true + responses: + "200": + description: Commerce updated + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + additionalProperties: true + example: + success: true + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Catalog + operationId: createCommerce + /conversationalAutomation: + get: + summary: Get conversational automation settings + description: > + Get WhatsApp conversational components for the channel (welcome message, + + ice-breaker prompts, and slash commands). + + + Proxies Meta/360dialog `GET /conversational_automation`. + + + When `enable_welcome_message` is true and a user opens chat for the + first + + time, Meta delivers a webhook message with `type: request_welcome`. The + + inbound formatter exposes that as `type: "request_welcome"` and + + `meta.request_welcome: true` so your webhook can send a custom welcome + reply. + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + description: Conversational automation settings + content: + application/json: + schema: + $ref: "#/components/schemas/ConversationalAutomation" + example: + enable_welcome_message: true + prompts: + - How can I help? + commands: + - command_name: help + command_description: Get support options + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Channel + operationId: getConversationalAutomation + post: + summary: Set conversational automation settings + description: | + Update WhatsApp conversational components. + + Allowed body fields (others are ignored): + - `enable_welcome_message` (boolean) + - `prompts` (string[], max 4, each ≤ 80 chars) + - `commands` (`{ command_name, command_description }[]`) + + Proxies Meta/360dialog `POST /conversational_automation`. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/ConversationalAutomation" + example: + enable_welcome_message: true + prompts: + - How can I help? + commands: + - command_name: help + command_description: Get support options + responses: + "200": + description: > + Updated settings from WABA, or legacy response.error wrapper on + upstream failure. + content: + application/json: + schema: + type: object + additionalProperties: true + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Channel + operationId: setConversationalAutomation + /webhook: + get: + summary: Get webhook URL + description: > + Return the webhook URL(s) currently configured for this channel, plus + delivery + + status for each URL. + + + `webhookUrl` is a string when a single URL is set, an array of strings + when + + multiple URLs are configured, or `null` if none is set. + + + **Prefer `webhookStatuses`.** The circuit breaker is per URL, not per + channel. + + If 1 of 4 URLs is sticky-disabled, that URL is skipped; the other three + still + + receive events. Send/receive are not affected. + + + Channel-level `haveDisabledWebhooks`, `circuitState`, `reason`, `fails`, + + `trips`, and timestamps are a compatibility summary of **one** URL (the + first + + sticky-disabled URL, else the first configured URL). They are not "the + channel + + is dead". + + + - `haveDisabledWebhooks` — `true` when **at least one** URL in + `webhookUrl` is + sticky auto-disabled. Live URLs still get events. + - `circuitState` — compressed scalar for that same primary URL: + `ok` | `degraded` | `open` | `half_open` | `disabled`. + - `disabledWebhooks` — currently configured URLs that are + sticky-disabled + (subset of `webhookUrl`). + - `webhookStatuses` — one row per currently configured URL. Use this + array + to see which endpoints are live vs skipped. + - `fails` / `trips` / `firstFailAt` — **diagnostics for support**, not + product + UI. `fails` = failures in a rolling ~10 minute window (not lifetime). + `trips` = failed recovery probes on the 15 min → 1 h → 6 h schedule (sticky + disable after 3). Clients can ignore these and use `webhookStatuses` + + `disabledWebhooks` only. + + Sticky disable skips delivery; it does not unconfigure the URL (it stays + in + + `webhookUrl`). Re-enable with `POST /webhook` or `POST /settings`. Those + + endpoints **replace** the whole list — with multiple URLs, send the full + array. + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + description: Current webhook URL and per-URL circuit status + content: + application/json: + schema: + type: object + properties: + webhookUrl: + nullable: true + oneOf: + - type: string + nullable: true + format: uri + - type: array + items: + type: string + format: uri + description: Configured webhook URL, array of URLs, or null when none is set + haveDisabledWebhooks: + type: boolean + description: > + `true` when at least one URL in `webhookUrl` is sticky + auto-disabled. + + Not "the channel is dead": other configured URLs still + receive events. + + Send/receive are unaffected. + circuitState: + type: string + description: > + Compatibility scalar for **one** URL (first + sticky-disabled, else first + + configured). Not the channel as a whole. Prefer + `webhookStatuses[].circuitState`. + enum: + - ok + - degraded + - open + - half_open + - disabled + reason: + type: string + description: Last qualifying fail reason of the summary URL (same URL as + `circuitState`) + fails: + type: integer + description: > + Diagnostic only (summary URL). Qualifying failures in the + rolling + + ~10 minute breaker window — not lifetime and not customer + retries. + + Prefer `webhookStatuses` / `disabledWebhooks`. + trips: + type: integer + description: > + Diagnostic only (summary URL). Failed recovery probes (≈15 + min → + + 1 h → 6 h). Sticky disable after 3. Not a blind unblock + timer. + disabledAt: + type: integer + description: Epoch milliseconds when the summary URL became sticky-disabled + firstFailAt: + type: integer + description: > + Diagnostic only (summary URL). Epoch ms of the first fail + in the + + current ~10 minute window (pairs with `fails`). + lastStatus: + type: integer + description: Last HTTP status from the summary URL, when known + nextProbeAt: + type: integer + description: Epoch milliseconds of the next half-open probe for the summary URL, + if any + disabledWebhooks: + type: array + description: > + Currently configured URLs that are sticky auto-disabled + (subset of `webhookUrl`). + + Does not include leftover URLs that are no longer + configured. + items: + type: object + additionalProperties: true + webhookStatuses: + type: array + description: > + One entry per currently configured URL. Prefer this over + top-level + + `haveDisabledWebhooks` / `circuitState` when more than one + webhook is set. + items: + $ref: "#/components/schemas/WebhookUrlStatus" + additionalProperties: true + examples: + healthy: + summary: Single URL delivering + value: + webhookUrl: https://example.com/webhook + haveDisabledWebhooks: false + circuitState: ok + disabledWebhooks: [] + webhookStatuses: + - url: https://example.com/webhook + circuitState: ok + mixed: + summary: One of several URLs sticky-disabled + value: + webhookUrl: + - https://live.example.com/webhook + - https://down.example.com/webhook + haveDisabledWebhooks: true + circuitState: disabled + reason: http_404 + fails: 1 + trips: 3 + disabledWebhooks: + - url: https://down.example.com/webhook + reason: http_404 + state: disabled + fails: 1 + trips: 3 + webhookStatuses: + - url: https://live.example.com/webhook + circuitState: ok + - url: https://down.example.com/webhook + circuitState: disabled + reason: http_404 + fails: 1 + trips: 3 + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Webhooks + operationId: getWebhook + post: + summary: Set webhook URL + description: > + Set the client webhook URL that receives inbound events for this + channel. + + + **Replaces** the stored webhook list (it does not append). To deliver + the same + + events to several endpoints, pass an array in `webhookUrl` (max 5) or + use + + `POST /settings`. With several URLs already configured, posting only the + + disabled URL **drops the others** — send the complete array to re-enable + one + + of many. + + + Incoming payloads include messages, delivery ACKs, group updates, + coexistence + + echoes, and calling events. WhatsApp Calling payloads (`type: "calls"`) + are + + documented under the **Calling** tag. Call permission replies arrive on + the + + normal messages path (`call_permission_reply`). + + + Repeating `POST /webhook` with the same URL(s) clears an auto-disable + (self-serve + + re-enable). Send/receive are not affected by webhook auto-disable. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - webhookUrl + properties: + webhookUrl: + oneOf: + - type: string + format: uri + - type: array + items: + type: string + format: uri + maxItems: 5 + description: > + HTTP or HTTPS URL, or array of URLs (max 5). Replaces the + stored list. + + Empty values are rejected — clear webhooks with `POST + /settings`. + additionalProperties: true + examples: + single: + summary: Single URL + value: + webhookUrl: https://example.com/webhook + multiple: + summary: Several URLs (replaces the list) + value: + webhookUrl: + - https://example.com/webhook + - https://backup.example.com/webhook + responses: + "200": + description: Webhook configured + content: + application/json: + schema: + type: object + properties: + set: + type: boolean + description: True when the stored webhook URL(s) match the request + webhookUrl: + oneOf: + - type: string + - type: array + items: + type: string + description: Currently stored webhook URL or list + additionalProperties: true + example: + set: true + webhookUrl: https://example.com/webhook + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Webhooks + operationId: setWebhook + /callingSettings: + get: + summary: Get calling settings + description: > + Return WhatsApp Calling API settings for this channel (beta). + + + Proxies upstream `GET /calling/settings`. + + + **Prerequisites** + + - Number must be eligible for Meta Calling (Cloud API; not COEX) + + - Trial / `subscriptionBlocked` channels receive **403** plain text + + - You need your own WebRTC or SIP stack; 1msg is a **signaling proxy** + only + and does **not** store call history or recordings + + See the **Calling** tag overview for inbound/outbound flows and + webhooks. + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + description: Calling settings (and possibly other Cloud API settings Meta returns) + content: + application/json: + schema: + $ref: "#/components/schemas/CallingSettings" + example: + calling: + status: ENABLED + call_icon_visibility: DEFAULT + callback_permission_status: ENABLED + sip: + status: DISABLED + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Calling + operationId: getCallingSettings + post: + summary: Update calling settings + description: > + Enable, disable, or update WhatsApp Calling settings (beta). + + + Proxies upstream `POST /calling/settings`. + + Body is forwarded as-is (1msg does not validate fields). + + + **Common fields under `calling`** + + - `status` (`ENABLED` | `DISABLED`) — required to turn calling on/off + + - `call_icon_visibility` (`DEFAULT` | `DISABLE_ALL`) — optional + + - `callback_permission_status` (`ENABLED` | `DISABLED`) — optional; + when enabled, inbound user calls grant callback permission + - `call_hours` — optional hours / timezone object + + - `sip` — optional SIP trunk; when SIP is ENABLED, Graph call actions + and + calling webhooks are not used + - `srtp_key_exchange_protocol` (`DTLS` | `SDES`) — SDES only with SIP + + - `video.status` — optional + + + Meta may accept only one feature group per request — prefer focused + updates + + (e.g. enable status first, then SIP). + + + Trial / `subscriptionBlocked` → **403** plain text. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/CallingSettings" + examples: + enable: + summary: Enable calling + value: + calling: + status: ENABLED + call_icon_visibility: DEFAULT + callback_permission_status: ENABLED + disable: + summary: Disable calling + value: + calling: + status: DISABLED + enableSip: + summary: Enable SIP (disables Graph call webhooks) + value: + calling: + status: ENABLED + sip: + status: ENABLED + servers: + - hostname: sip.example.com + port: 5061 + responses: + "200": + description: | + Usually `{ "success": true }` from upstream, or legacy + `{ "result": "success" }` / `{ "response": { "error": "..." } }`. + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + result: + type: string + example: success + response: + type: object + properties: + error: + type: string + additionalProperties: true + additionalProperties: true + example: + success: true + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Calling + operationId: updateCallingSettings + /initiateCall: + post: + summary: Call action (connect / pre_accept / accept / reject / terminate) + description: > + Perform a WhatsApp Calling action (beta). + + + Proxies upstream `POST /calling/calls`. Despite the historical path + + name `/initiateCall`, this endpoint handles **all** call actions: + + + | action | Use | Required | + + |--------|-----|----------| + + | `connect` | Outbound business → user | `to` + `session` (`sdp_type: + offer`) | + + | `pre_accept` | Inbound (optional, reduces audio clipping) | `call_id` + + `session` (`sdp_type: answer`) | + + | `accept` | Inbound answer | `call_id` + `session` (`sdp_type: answer`) + | + + | `reject` | Decline inbound | `call_id` | + + | `terminate` | Hang up | `call_id` | + + + **SDP / media (critical)** + + - `accept` / `pre_accept` require a **WebRTC-generated SDP answer**. + + - Do **not** send Meta's offer SDP back as the answer. + + - Postman (or curl) alone **cannot** establish real media — you need a + WebRTC or SIP stack. 1msg only proxies signaling. + + Answer within ~**30–60 seconds** of an inbound `connect` webhook or Meta + + terminates as unanswered. Common Meta errors include Calling not enabled + + (`138000`), no permission (`138006`), SDP validation failures. + + + **Outbound** requires a prior Call Permission Request (CPR) acceptance. + + See the **Calling** tag overview for the full outbound flow and CPR + limits. + + + Trial / `subscriptionBlocked` → **403** plain text. + + Upstream failures often return HTTP 200 with `{ "response": { "error": + "" } }`. + + `Invalid API KEY` is used only when Meta/360 body actually indicates an + + invalid API key or token. Other upstream 401s (notably call permission + + `138006`) pass through `error.message` / `error_user_msg`. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/InitiateCallRequest" + examples: + outboundConnect: + summary: Outbound connect (business SDP offer) + value: + messaging_product: whatsapp + to: "12185552828" + action: connect + biz_opaque_callback_data: order-123 + session: + sdp_type: offer + sdp: "[REPLACE_WITH_WEBRTC_SDP]" + preAccept: + summary: Inbound pre_accept (WebRTC answer SDP) + value: + messaging_product: whatsapp + call_id: wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh + action: pre_accept + session: + sdp_type: answer + sdp: "[REPLACE_WITH_WEBRTC_SDP]" + accept: + summary: Inbound accept (WebRTC answer SDP) + value: + messaging_product: whatsapp + call_id: wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh + action: accept + session: + sdp_type: answer + sdp: "[REPLACE_WITH_WEBRTC_SDP]" + reject: + summary: Reject inbound call + value: + messaging_product: whatsapp + call_id: wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh + action: reject + terminate: + summary: Terminate active call + value: + messaging_product: whatsapp + call_id: wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh + action: terminate + responses: + "200": + description: Call action result from upstream, or legacy error wrapper + content: + application/json: + schema: + $ref: "#/components/schemas/InitiateCallResponse" + examples: + success: + summary: Accept / pre_accept / reject / terminate success + value: + messaging_product: whatsapp + success: true + connectSuccess: + summary: Outbound connect success (includes call id) + value: + messaging_product: whatsapp + calls: + - id: wacid.HBgLMTIxODU1NTI4MjgVAgARGCAyODRQIAFRoA + upstreamError: + summary: Upstream error wrapped by 1msg + value: + response: + error: Calling not enabled + callPermissionDenied: + summary: Meta 138006 (upstream 401, not Invalid API KEY) + value: + response: + error: No approved call permission from the recipient + invalidApiKey: + summary: Real invalid D360/Meta token + value: + response: + error: Invalid API KEY + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Calling + operationId: initiateCall + /groups: + post: + summary: Create Group + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - groupName + properties: + groupName: + type: string + description: Group subject / name + description: + type: string + description: Optional group description + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + properties: + error: + description: Error details returned by the provider. May be a string or a JSON + object. + additionalProperties: true + tags: + - Groups + operationId: createGroups + get: + summary: Get Groups List + description: List WhatsApp groups for this channel. Paginate with `limit`, + `before`, and `after`. + parameters: + - $ref: "#/components/parameters/token" + - name: limit + in: query + schema: + type: integer + description: Max groups to return + - name: before + in: query + schema: + type: string + description: Cursor for the previous page + - name: after + in: query + schema: + type: string + description: Cursor for the next page + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + additionalProperties: true + tags: + - Groups + operationId: listGroups + /groups/{groupId}: + get: + summary: Get Group Info + parameters: + - $ref: "#/components/parameters/token" + - name: fields + in: query + schema: + type: string + description: Comma-separated group fields to return + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + additionalProperties: true + tags: + - Groups + operationId: getGroupsGroupId + parameters: + - name: groupId + in: path + required: true + schema: + type: string + example: "{{createdGroupId}}" + post: + summary: Update Group Info + description: | + Update group subject, description, and/or profile picture. + Path `groupId` is the WABA group id (without `@g.us`). + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + subject: + type: string + description: New group subject / name + description: + type: string + description: New group description + profile_picture_file: + type: string + description: Image URL or base64 data URI for the group profile picture + example: + subject: Support team + description: Customer support + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + additionalProperties: true + tags: + - Groups + operationId: createGroupsGroupId + delete: + summary: Delete Group + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + response: + type: object + additionalProperties: true + additionalProperties: true + tags: + - Groups + operationId: deleteGroupsGroupId + /groups/{groupId}/inviteLink: + get: + summary: Get Invite Link + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + additionalProperties: true + tags: + - Groups + operationId: getGroupsGroupIdInvitelink + parameters: + - name: groupId + in: path + required: true + schema: + type: string + example: "{{createdGroupId}}" + post: + summary: Reset Invite Link + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + additionalProperties: true + tags: + - Groups + operationId: createGroupsGroupIdInvitelink + /whatsapp_business_encryption: + get: + summary: Get business encryption public key + description: > + Retrieve the WhatsApp business public key and signature status for this + channel's + + phone number. Required before publishing or sending Flows that use data + encryption. + parameters: + - $ref: "#/components/parameters/token" + responses: + "200": + description: Business encryption key status + content: + application/json: + schema: + type: object + properties: + business_public_key: + type: string + description: Stored 2048-bit RSA public key (PEM) + business_public_key_signature_status: + type: string + enum: + - VALID + - MISMATCH + data: + type: array + items: + type: object + additionalProperties: true + additionalProperties: true + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Flows + operationId: getWhatsappBusinessEncryption + post: + summary: Set business encryption public key + description: > + Upload and sign a 2048-bit RSA business public key (PEM) for this + channel's phone number. + + Meta requires a signed key before Flow publish/send. Only one active key + per number; + + a new upload replaces the previous key. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - business_public_key + properties: + business_public_key: + type: string + description: 2048-bit RSA public key in PEM format + example: | + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA... + -----END PUBLIC KEY----- + responses: + "200": + description: Public key uploaded and signed + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + additionalProperties: true + "400": + description: Missing or invalid PEM key + content: + application/json: + schema: + type: object + properties: + error: + type: string + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Flows + operationId: setWhatsappBusinessEncryption + /flows: + post: + summary: Create Flow + description: > + Create a WhatsApp Flow (`name` + `categories` required). + + Currently returns HTTP 501 until the Meta Graph Flows rewrite is + available. + parameters: + - $ref: "#/components/parameters/token" + - name: wabaAccountId + in: query + schema: + type: string + example: "{{wabaAccountId}}" + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - name + - categories + properties: + name: + type: string + description: Flow name + categories: + type: array + items: + type: string + enum: + - SIGN_UP + - SIGN_IN + - APPOINTMENT_BOOKING + - LEAD_GENERATION + - CONTACT_US + - CUSTOMER_SUPPORT + - SURVEY + - OTHER + description: One or more Flow categories + endpointUri: + type: string + description: HTTPS endpoint for the Flow data channel + publish: + type: boolean + description: Publish immediately after create + flowJson: + type: object + additionalProperties: true + description: Optional Flow JSON document + example: + name: lead_form + categories: + - LEAD_GENERATION + publish: false + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + properties: + error: + description: Error details returned by the provider. May be a string or a JSON + object. + additionalProperties: true + "501": + description: WhatsApp Flows are not available on this channel yet + tags: + - Flows + operationId: createFlows + get: + summary: List Flows + description: > + List WhatsApp Flows for the WABA. + + Currently returns HTTP 501 until the Meta Graph Flows rewrite is + available. + parameters: + - $ref: "#/components/parameters/token" + - name: wabaAccountId + in: query + schema: + type: string + example: "{{wabaAccountId}}" + - name: fields + in: query + schema: + type: string + description: Comma-separated Flow fields to return + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + properties: + items: + type: array + items: + type: object + additionalProperties: true + paging: + type: object + additionalProperties: true + count: + type: integer + total: + type: integer + error: + description: Error details returned by the provider. May be a string or a JSON + object. + additionalProperties: true + "501": + description: WhatsApp Flows are not available on this channel yet + tags: + - Flows + operationId: listFlows + /flows/{flowId}: + get: + summary: Get Flow Details + parameters: + - $ref: "#/components/parameters/token" + - name: wabaAccountId + in: query + schema: + type: string + example: "{{wabaAccountId}}" + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + properties: + error: + description: Error details returned by the provider. May be a string or a JSON + object. + additionalProperties: true + tags: + - Flows + operationId: getFlowsFlowId + parameters: + - $ref: "#/components/parameters/flowId" + example: "{{flowId}}" + delete: + summary: Delete Flow + parameters: + - $ref: "#/components/parameters/token" + - name: wabaAccountId + in: query + schema: + type: string + example: "{{wabaAccountId}}" + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + error: + description: Error details returned by the provider. May be a string or a JSON + object. + additionalProperties: true + tags: + - Flows + operationId: deleteFlowsFlowId + /flows/{flowId}/metadata: + patch: + summary: Update Flow Metadata + description: > + Update Flow `name`, `categories`, and/or `endpointUri`. + + Currently returns HTTP 501 until the Meta Graph Flows rewrite is + available. + parameters: + - $ref: "#/components/parameters/token" + - name: wabaAccountId + in: query + schema: + type: string + example: "{{wabaAccountId}}" + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + categories: + type: array + items: + type: string + enum: + - SIGN_UP + - SIGN_IN + - APPOINTMENT_BOOKING + - LEAD_GENERATION + - CONTACT_US + - CUSTOMER_SUPPORT + - SURVEY + - OTHER + endpointUri: + type: string + description: HTTPS endpoint for the Flow data channel + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + additionalProperties: true + "501": + description: WhatsApp Flows are not available on this channel yet + tags: + - Flows + operationId: patchFlowsFlowIdMetadata + parameters: + - $ref: "#/components/parameters/flowId" + example: "{{flowId}}" + /flows/{flowId}/assets: + patch: + summary: Update Flow Structure + description: > + Replace the Flow JSON document (`flowJson`). + + Currently returns HTTP 501 until the Meta Graph Flows rewrite is + available. + parameters: + - $ref: "#/components/parameters/token" + - name: wabaAccountId + in: query + schema: + type: string + example: "{{wabaAccountId}}" + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - flowJson + properties: + flowJson: + type: object + additionalProperties: true + description: WhatsApp Flow JSON document + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + validationErrors: + type: array + items: + type: object + additionalProperties: true + error: + description: Error details returned by the provider. May be a string or a JSON + object. + additionalProperties: true + "501": + description: WhatsApp Flows are not available on this channel yet + tags: + - Flows + operationId: patchFlowsFlowIdAssets + parameters: + - $ref: "#/components/parameters/flowId" + example: "{{flowId}}" + /flows/{flowId}/preview: + get: + summary: Preview Flow + parameters: + - $ref: "#/components/parameters/token" + - name: wabaAccountId + in: query + schema: + type: string + example: "{{wabaAccountId}}" + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + additionalProperties: true + tags: + - Flows + operationId: getFlowsFlowIdPreview + parameters: + - $ref: "#/components/parameters/flowId" + example: "{{flowId}}" + /flows/{flowId}/publish: + post: + summary: Publish Flow + parameters: + - $ref: "#/components/parameters/token" + - name: wabaAccountId + in: query + schema: + type: string + example: "{{wabaAccountId}}" + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + additionalProperties: true + tags: + - Flows + operationId: createFlowsFlowIdPublish + parameters: + - $ref: "#/components/parameters/flowId" + example: "{{flowId}}" + /flows/{flowId}/deprecate: + post: + summary: Deprecate Flow + parameters: + - $ref: "#/components/parameters/token" + - name: wabaAccountId + in: query + schema: + type: string + example: "{{wabaAccountId}}" + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + additionalProperties: true + tags: + - Flows + operationId: createFlowsFlowIdDeprecate + parameters: + - $ref: "#/components/parameters/flowId" + example: "{{flowId}}" + /templates: + get: + summary: Get templates list + description: List message templates. Paginate with `limit` / `offset`; sort by + `id`, `name`, or `status`. + parameters: + - $ref: "#/components/parameters/token" + - name: limit + in: query + schema: + type: integer + - name: offset + in: query + schema: + type: integer + - name: sort + in: query + schema: + type: string + enum: + - id + - name + - status + description: Sort field (`id`, `name`, or `status`) + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + properties: + total: + type: integer + templates: + type: array + items: + type: object + additionalProperties: true + error: + type: object + additionalProperties: true + additionalProperties: true + tags: + - Templates + operationId: listTemplates + /addTemplate: + post: + summary: Create message template + description: > + Create a WABA message template (`name`, `category`, `language`, + `components`). + + After create, Meta reviews the template; list it with `GET /templates`. + parameters: + - $ref: "#/components/parameters/token" + requestBody: + content: + application/json: + schema: + type: object + properties: + name: + type: string + description: Template name + example: hello_world + category: + type: string + description: MARKETING, UTILITY, or AUTHENTICATION + example: UTILITY + language: + type: string + description: Template language code (e.g. en_US) + example: en_US + components: + type: array + items: + type: object + additionalProperties: true + description: Template components (HEADER, BODY, FOOTER, BUTTONS, CAROUSEL) + additionalProperties: true + example: + name: hello_world + category: UTILITY + language: en_US + components: + - type: BODY + text: Hello {{1}} + responses: + "200": + description: Template created. Provider payload is wrapped in `response`. + content: + application/json: + schema: + type: object + properties: + response: + type: object + description: Upstream create-template payload + additionalProperties: true + additionalProperties: true + example: + response: + id: "123456789" + status: PENDING + category: MARKETING + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Templates + operationId: addTemplate + /removeTemplate: + post: + summary: Remove message template + description: Delete a message template by `name` (all language versions of that name). + parameters: + - $ref: "#/components/parameters/token" + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - name + properties: + name: + type: string + description: Template name to delete + example: + name: hello_world + responses: + "200": + description: Template removed + content: + application/json: + schema: + type: object + additionalProperties: true + "401": + $ref: "#/components/responses/InvalidToken" + "500": + $ref: "#/components/responses/InternalError" + tags: + - Templates + operationId: removeTemplate +components: + parameters: + flowId: + name: flowId + in: path + required: true + schema: + type: string + description: Flow ID + token: + name: token + in: query + required: true + schema: + type: string + description: JWT token or API key for authorization + date: + name: date + in: query + required: false + schema: + type: string + format: date + description: Filter by date (YYYY-MM-DD) + groupId: + name: groupId + in: path + required: true + schema: + type: string + description: Group ID (phone number with country code) + schemas: + ErrorResponse: + type: object + properties: + error: + type: string + description: Error message + description: Standard error response + MessageSentResponse: + type: object + properties: + sent: + type: boolean + description: Whether the message was successfully queued for sending + id: + type: string + description: Message ID + message: + type: string + description: Status message + description: + type: string + description: Detailed description + additionalProperties: true + description: Response for successfully sent message + SuccessResponse: + type: object + properties: + result: + type: string + description: Operation result + additionalProperties: true + description: Generic success response + ProfileInfo: + type: object + properties: + about: + type: string + description: Profile's About section + address: + type: string + description: Address of the business + description: + type: string + description: Description of the business + email: + type: string + description: Business email + phone: + type: string + description: Linked phone number + vertical: + type: string + enum: + - Automotive + - Beauty, Spa and Salon + - Clothing and Apparel + - Education + - Entertainment + - Event Planning and Service + - Finance and Banking + - Food and Grocery + - Public Service + - Hotel and Lodging + - Medical and Health + - Non-profit + - Professional Services + - Shopping and Retail + - Travel and Transportation + - Restaurant + - Other + description: Industry of the business + photo: + type: string + description: Profile photo URL + websites: + type: array + items: + type: string + additionalProperties: true + description: WhatsApp Business profile information + ConversationalAutomation: + type: object + properties: + enable_welcome_message: + type: boolean + description: Enable the automatic welcome message for new conversations + prompts: + type: array + maxItems: 4 + description: Ice-breaker prompt strings (max 4, each ≤ 80 characters) + items: + type: string + maxLength: 80 + commands: + type: array + maxItems: 30 + description: Slash commands shown in WhatsApp + items: + type: object + required: + - command_name + - command_description + properties: + command_name: + type: string + maxLength: 32 + command_description: + type: string + maxLength: 256 + additionalProperties: true + additionalProperties: true + CallingSettings: + type: object + description: > + Calling settings payload for GET/POST `/callingSettings`. + + Proxies upstream `GET|POST /calling/settings`. + + Extra Meta fields may appear on GET responses; document core fields + below. + properties: + calling: + type: object + description: Calling feature configuration for the business phone number + properties: + status: + type: string + description: Enable or disable Calling API on this number + enum: + - ENABLED + - DISABLED + example: ENABLED + call_icon_visibility: + type: string + description: Controls call icon visibility in the WhatsApp client + enum: + - DEFAULT + - DISABLE_ALL + example: DEFAULT + callback_permission_status: + type: string + description: > + When ENABLED, a user who calls your business automatically + grants + + call permission for business-initiated callbacks (subject to + Meta rules). + enum: + - ENABLED + - DISABLED + example: ENABLED + srtp_key_exchange_protocol: + type: string + description: | + SRTP key exchange. DTLS is default/recommended. + SDES is only valid when SIP signaling is enabled. + enum: + - DTLS + - SDES + example: DTLS + call_hours: + type: object + description: Optional call hours / timezone configuration (Meta shape) + additionalProperties: true + properties: + status: + type: string + example: ENABLED + timezone: + type: string + example: America/Los_Angeles + day_of_week_start: + type: string + example: MONDAY + sip: + type: object + description: > + SIP trunk settings. When SIP is ENABLED, Graph call actions and + + calling webhooks are not used — Meta dials your SIP server + directly. + properties: + status: + type: string + enum: + - ENABLED + - DISABLED + example: DISABLED + servers: + type: array + items: + type: object + properties: + hostname: + type: string + example: sip.example.com + port: + type: integer + example: 5061 + request_uri_user_params: + type: object + additionalProperties: + type: string + sip_user_password: + type: string + description: Present on GET when SIP credentials are returned by Meta + password: + type: string + description: Alternate password field name from some Meta responses + app_id: + type: string + additionalProperties: true + additionalProperties: true + video: + type: object + description: Video calling toggle when supported + properties: + status: + type: string + enum: + - ENABLED + - DISABLED + additionalProperties: true + audio: + type: object + description: Audio settings (typically response-only) + properties: + status: + type: string + additionalProperties: true + restrictions: + type: object + description: Calling restrictions (response-only) + additionalProperties: true + ip_addresses: + type: object + description: Meta media IP ranges (response-only) + additionalProperties: true + call_icons: + type: object + description: Call icon country restrictions (response-only) + additionalProperties: true + additionalProperties: true + additionalProperties: true + InitiateCallRequest: + type: object + description: > + Call action payload for `POST /initiateCall` (proxies upstream `POST + /calling/calls`). + + + Despite the path name, this endpoint handles **all** call actions — not + only + + outbound connect. + + + ## Required fields by `action` + + + | action | Required | `session` | + + |--------|----------|-----------| + + | `connect` (outbound) | `messaging_product`, `to`, `action` | + `sdp_type: offer` + business WebRTC SDP | + + | `pre_accept` | `messaging_product`, `call_id`, `action` | `sdp_type: + answer` (WebRTC-generated) | + + | `accept` | `messaging_product`, `call_id`, `action` | `sdp_type: + answer` (WebRTC-generated) | + + | `reject` | `messaging_product`, `call_id`, `action` | none | + + | `terminate` | `messaging_product`, `call_id`, `action` | none | + + + **Critical:** For `pre_accept` / `accept`, `session.sdp` must be a + + **WebRTC-generated SDP answer**. Do not echo Meta's offer SDP back. + + Postman alone cannot establish real media — you need a WebRTC (or SIP) + stack. + required: + - messaging_product + - action + properties: + messaging_product: + type: string + description: Must be `whatsapp` + enum: + - whatsapp + example: whatsapp + action: + type: string + description: Call control action + enum: + - connect + - pre_accept + - accept + - reject + - terminate + example: connect + call_id: + type: string + description: > + WhatsApp call id from the inbound/outbound calls webhook + (`calls[].id`). + + Required for `pre_accept`, `accept`, `reject`, `terminate`. + example: wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh + to: + type: string + description: | + Recipient WhatsApp user phone (digits, country code, no +). + Required for outbound `connect`. + example: "12185552828" + biz_opaque_callback_data: + type: string + description: Optional opaque string echoed on later call webhooks for correlation + maxLength: 512 + example: order-123-callback + session: + type: object + description: WebRTC SDP session (required for connect / pre_accept / accept) + required: + - sdp_type + - sdp + properties: + sdp_type: + type: string + description: offer for outbound connect; answer for pre_accept/accept + enum: + - offer + - answer + example: offer + sdp: + type: string + description: > + Full SDP (RFC 8866). Replace placeholders with SDP from your + WebRTC stack. + + Must negotiate ICE, DTLS-SRTP, and OPUS for WhatsApp media. + example: "[REPLACE_WITH_WEBRTC_SDP]" + additionalProperties: true + additionalProperties: true + InitiateCallResponse: + type: object + description: > + Successful call action response from upstream, returned as-is. + + On empty upstream body, 1msg may return `{ "result": "success" }`. + + Upstream failures are often wrapped as HTTP 200 `{ "response": { + "error": "..." } }`. + properties: + messaging_product: + type: string + example: whatsapp + success: + type: boolean + example: true + calls: + type: array + description: Present on outbound `connect` — contains the new call id + items: + type: object + properties: + id: + type: string + example: wacid.HBgLMTIxODU1NTI4MjgVAgARGCAyODRQIAFRoA + additionalProperties: true + result: + type: string + description: Legacy success marker when upstream returns an empty body + example: success + response: + type: object + description: Present when 1msg wraps an upstream error + properties: + error: + type: string + additionalProperties: true + additionalProperties: true + WebhookUrlStatus: + type: object + description: | + Circuit / auto-disable status for one configured webhook URL. + The breaker is per URL (`instanceId` + URL hash), not per channel. + required: + - url + - circuitState + properties: + url: + type: string + format: uri + description: This webhook URL (same string as in `webhookUrl`) + circuitState: + type: string + description: > + Delivery state for this URL only. `ok` delivering; `degraded` recent + qualifying fails (still delivering, warning email on the 2nd fail); + `open` skipping most deliveries pending a probe; `half_open` probe + in flight (resume only on HTTP 2xx); `disabled` sticky auto-disabled + until self-serve re-enable (`POST /webhook` / `POST /settings` with + this URL) or a successful probe before sticky disable. + enum: + - ok + - degraded + - open + - half_open + - disabled + reason: + type: string + description: Last qualifying fail reason, e.g. `http_404` or `timeout_or_network` + fails: + type: integer + description: > + Diagnostic only — safe for clients to ignore. Number of qualifying + delivery + + failures in the rolling ~10 minute breaker window (not lifetime, not + "how many + + times the customer retried"). Prefer `circuitState` / + `disabledWebhooks`. + trips: + type: integer + description: > + Diagnostic only — safe for clients to ignore. How many recovery + probes already + + failed for this URL. Probes run on a schedule (≈15 min → 1 h → 6 h); + sticky + + disable after 3 failed probes. The 6 h step is the last probe, not a + blind + + "unblock in 6 hours" timer. + disabledAt: + type: integer + description: Epoch milliseconds when this URL became sticky-disabled + firstFailAt: + type: integer + description: > + Diagnostic only. Epoch ms of the first fail in the current ~10 + minute window + + (pairs with `fails`; not a customer-facing period). + lastStatus: + type: integer + description: Last HTTP status from this URL, when known + nextProbeAt: + type: integer + description: Epoch milliseconds of the next half-open probe, if any + additionalProperties: true + SendMessageRequest: + type: object + required: + - body + properties: + body: + type: string + description: Message text, UTF-8 or UTF-16 string with emoji + minLength: 1 + maxLength: 4096 + example: Hello World 🌍 + quotedMsgId: + type: string + description: Message ID to quote/reply to (Cloud API wamid) + pattern: ^wamid\..+$ + example: wamid.HBgNMTIwMjA3MjEzNjkVAgARGBI5RTBCNUY0QUE2RjZBQzhGNDkA + chatId: + type: string + description: "Recipient chat ID: phone@c.us, group@g.us, or BSUID@lid" + example: 12020721369@c.us + phone: + type: integer + description: Phone number starting with country code (alternative to chatId) + minimum: 1000000000 + maximum: 999999999999999 + example: 12020721369 + additionalProperties: false + description: Request body for sending a text message + SendFileRequest: + type: object + properties: + body: + type: string + description: | + File source (required unless mediaId is set): + - HTTP/HTTPS URL + - Base64 data URI + filename: + type: string + description: File name with extension (required with body, not with mediaId) + mediaId: + type: string + description: WABA media id from uploadMedia (alternative to body) + mediaType: + type: string + enum: + - image + - video + - audio + - document + description: Required when using mediaId + voice: + type: boolean + description: Native WhatsApp voice note (audio/ogg only) + caption: + type: string + maxLength: 1024 + quotedMsgId: + type: string + chatId: + type: string + phone: + type: integer + additionalProperties: true + description: Send file by URL/base64 or by mediaId + responses: + InvalidToken: + description: Invalid or missing authentication token + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + InternalError: + description: Internal server error + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + MessageSent: + description: Message sent successfully + content: + application/json: + schema: + $ref: "#/components/schemas/MessageSentResponse" + BadRequest: + description: Invalid request parameters + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + TooManyRequests: + description: Rate limit exceeded + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + Success: + description: Operation successful + content: + application/json: + schema: + $ref: "#/components/schemas/SuccessResponse" + securitySchemes: + tokenAuth: + type: apiKey + in: query + name: token + description: JWT token or API key + requestBodies: {} +security: + - tokenAuth: [] diff --git a/quality/generator/postprocess.cjs b/quality/generator/postprocess.cjs new file mode 100644 index 0000000..1d1cd3f --- /dev/null +++ b/quality/generator/postprocess.cjs @@ -0,0 +1,133 @@ +// Vendored compatibility transforms; provenance.json identifies the source commit. +const fs = require("node:fs"); +const path = require("node:path"); + +function postProcessGeneratedTypeScriptSdk(outputDir) { + const srcDir = path.join(outputDir, 'src'); + const runtimePath = path.join(srcDir, 'runtime.ts'); + const apisIndexPath = path.join(srcDir, 'apis', 'index.ts'); + const generatedIndexPath = path.join(srcDir, 'index.ts'); + const profileInfoPath = path.join(srcDir, 'models', 'ProfileInfo.ts'); + const modelsIndexPath = path.join(srcDir, 'models', 'index.ts'); + + if (fs.existsSync(runtimePath)) { + const runtime = fs.readFileSync(runtimePath, 'utf8'); + if (!runtime.includes('export function objectToJSON')) { + fs.appendFileSync( + runtimePath, + '\nexport function objectToJSON(value: unknown): unknown {\n return value;\n}\n', + ); + } + } + + const messagingApiPath = path.join(srcDir, 'apis', 'MessagingApi.ts'); + if (fs.existsSync(messagingApiPath)) { + let messagingApi = fs.readFileSync(messagingApiPath, 'utf8'); + if (messagingApi.includes('objectToJSON(') && !messagingApi.includes('objectToJSON,')) { + messagingApi = messagingApi.replace( + "import * as runtime from '../runtime';", + "import * as runtime from '../runtime';\nimport { objectToJSON } from '../runtime';", + ); + fs.writeFileSync(messagingApiPath, messagingApi); + } + } + + if (!fs.existsSync(profileInfoPath)) { + fs.writeFileSync( + profileInfoPath, + `/* tslint:disable */ +/* eslint-disable */ +import { mapValues } from '../runtime'; + +export interface ProfileInfo { + about?: string; + address?: string; + description?: string; + email?: string; + phone?: string; + vertical?: ProfileInfoVerticalEnum; + photo?: string; + websites?: Array; + [key: string]: unknown; +} + +export const ProfileInfoVerticalEnum = { + Automotive: 'Automotive', + BeautySpaAndSalon: 'Beauty, Spa and Salon', + ClothingAndApparel: 'Clothing and Apparel', + Education: 'Education', + Entertainment: 'Entertainment', + EventPlanningAndService: 'Event Planning and Service', + FinanceAndBanking: 'Finance and Banking', + FoodAndGrocery: 'Food and Grocery', + PublicService: 'Public Service', + HotelAndLodging: 'Hotel and Lodging', + MedicalAndHealth: 'Medical and Health', + NonProfit: 'Non-profit', + ProfessionalServices: 'Professional Services', + ShoppingAndRetail: 'Shopping and Retail', + TravelAndTransportation: 'Travel and Transportation', + Restaurant: 'Restaurant', + Other: 'Other', +} as const; +export type ProfileInfoVerticalEnum = typeof ProfileInfoVerticalEnum[keyof typeof ProfileInfoVerticalEnum]; + +export function ProfileInfoFromJSON(json: unknown): ProfileInfo { + return ProfileInfoFromJSONTyped(json, false); +} + +export function ProfileInfoFromJSONTyped(json: unknown, _ignoreDiscriminator: boolean): ProfileInfo { + if (json == null || typeof json !== 'object') { + return json as ProfileInfo; + } + return mapValues(json as Record, (value) => value) as ProfileInfo; +} + +export function ProfileInfoToJSON(value?: ProfileInfo | null): unknown { + return value ?? null; +} +`, + ); + + if (fs.existsSync(modelsIndexPath)) { + const modelsIndex = fs.readFileSync(modelsIndexPath, 'utf8'); + if (!modelsIndex.includes('./ProfileInfo')) { + fs.appendFileSync(modelsIndexPath, "export * from './ProfileInfo';\n"); + } + } + } + + if (fs.existsSync(apisIndexPath)) { + const apisDir = path.dirname(apisIndexPath); + const apiExports = fs + .readdirSync(apisDir) + .filter((f) => f.endsWith('Api.ts')) + .sort() + .map((f) => { + const name = f.replace(/\.ts$/, ''); + return `export { ${name} } from './${name}';`; + }) + .join('\n'); + fs.writeFileSync( + apisIndexPath, + `/* tslint:disable */ +/* eslint-disable */ +${apiExports} +`, + ); + } + + if (fs.existsSync(generatedIndexPath)) { + fs.writeFileSync( + generatedIndexPath, + `/* tslint:disable */ +/* eslint-disable */ +export * from './runtime'; +export * from './apis/index'; +export * from './models/index'; +`, + ); + } + +} +module.exports = { postProcessGeneratedTypeScriptSdk }; diff --git a/quality/generator/provenance.json b/quality/generator/provenance.json new file mode 100644 index 0000000..4af3e7b --- /dev/null +++ b/quality/generator/provenance.json @@ -0,0 +1,116 @@ +{ + "sourceRepository": "https://github.com/1msg/1msg-api", + "sourceCommit": "929c4526d3c914984be5a9bab561890a5c610433", + "generatorVersion": "7.22.0", + "generatorSha256": "3f1e6ce5c6ad4f15242c6170ab43aad4bad771622617eeece4a7d4f72ffaf329", + "contractSha256": "8f3153f944c6d0dc3cff048ba491a954a79c9c64f8b8d47ca8989dbd8c622dce", + "sourceFiles": { + "gen/bump-sdk-version.js": "f68b5a877b6bc26eef6cdd5df4766ef8fa967f9eba09c88c14304aabe05ba79c", + "gen/bundle-public.js": "503a286bf4b73cc636fb5dff19ce63e2756fbda9214ff5b3dc6a6ac79433c374", + "gen/generate-sdk-docs.js": "cd6e9b79992fb44db28c0a99a7995fa268e92bc8007b356b8f509cfa53e87d51", + "gen/generate-sdk.js": "e5ee3e533d734c608e736574e4a125a6c5182f9955ded63fe075cb1f8fceffb3", + "gen/openapi-local-cli.cjs": "a9b82fc15523979cd058050ddf35b84da6037d0b22168d0ecfaded7c22cfc733", + "gen/sdk-doc-schema.cjs": "7097fdcec8f8c48776413b655e9780de2b20be04d1aea5d6ef14cab786af021a", + "gen/sdk-exact-optional.cjs": "f574aa1c01ebf294d72698a273bb48051c8bef81b494c1591ae24b9db76e12b4", + "gen/sdk-openapi-generator.json": "381512004372deb54bc534592d1b9be262a8409b5e7190ef489927f2638231c5", + "openapitools.json": "b7658c68d73bb8fd9d92f6ea45cf6d2be303ceca01d991681800bf8088465d57", + "package-lock.json": "bdfeb550255495678477c34d25450322e451c4f3e4ea4cbe7a35e6955f67adb3", + "packages/sdk/package.json": "ad2d1ad03d8d91dfd1711256a5ecd03903c9c507cec65810afa73a8a59b98aeb", + "packages/sdk/src/client-config.ts": "009294617e2216ce71b8537ad7db129b4dd25544b6c19b5c3cd5c8a4db3fa293", + "packages/sdk/src/client.ts": "5e4a2b9009aaa58eea30a046384f8208f8f910c49df0e5dd6bb39a9002c138fc", + "packages/sdk/src/index.ts": "bf511c5f2729823a0dd2705ad85f4de5fb6e71fe5308f5bb29e3f3a53718c37a", + "packages/sdk/src/version.ts": "59cb84c7afd9012ea621044a58075ea6bf0fc4113067375fd8c7d839a403116a", + "public/openapi.yaml": "5010623f5ab269355b2b6dc11d9b4d47d1e392d9cb366cef66cbbd8239c3ab2b", + "public/paths/calling/callingSettings.yaml": "8f1ff6184a953c190d025f43bdd5ecc85fea2d8e30423b3cf0d381d539c41cf7", + "public/paths/calling/initiateCall.yaml": "82febe8ab1ff895e78a522ef23f943507fa6978a3867f4f7d2b4cdfa07109b77", + "public/paths/channel/commerce.yaml": "6b43175a6d9ba928c4cc65033a5933d4d2f2a7f65471dafa07112d058dbb2e1f", + "public/paths/channel/conversationalAutomation.yaml": "2509e0ae34e8d19bc83dc47bb4da584a4a3653f7c7391c17a372e09fe1a68d4c", + "public/paths/channel/mmLiteStatus.yaml": "3cb8b6f1dfbc8b028408cf792268af1984ee38e4362e71d809e3ec438cb26d38", + "public/paths/channel/settings.yaml": "e2893c6ce65399cb1b2f260dc9c67b062b3cc1af50213af3cd9deab77205f261", + "public/paths/channel/status.yaml": "9670a21034685cdd79fb28b92dbec38feb74f8255df5bbf76a02d23ea0834841", + "public/paths/channel/whatsappBusinessEncryption.yaml": "62bd8c98b8a3970d9b2a8afbde9a24197cf3e3ab3d075c633330e67c58480fd1", + "public/paths/flows/flows.yaml": "9e5a75c523d7c149412c9e9d4863b7f5dfc3240eb443c1498e420c02eaef2e7f", + "public/paths/flows/flows_flowId.yaml": "d6a84944203deb528081980f8213291d694a42944e21e6df889dbd9158f8ff8e", + "public/paths/flows/flows_flowId_assets.yaml": "637f3d977b840dc2c804585234f173fb917735fc77f879f785011cbc06c81cf1", + "public/paths/flows/flows_flowId_deprecate.yaml": "f2242d190723ee11ed540d962c82b3e7ad9f3d017f75f5bdbd4d02dc9cb7b65e", + "public/paths/flows/flows_flowId_metadata.yaml": "297b8c9059f17b2a5a61c4bab80b112f51304e0659956ba04fc29565e97cb3ef", + "public/paths/flows/flows_flowId_preview.yaml": "a838105c68ffaa7b93c2d78d0ddeba7c5a325fef5fe2e7699b115139bd4e422c", + "public/paths/flows/flows_flowId_publish.yaml": "b39e31eafb8a64c4ae74bd3de0aa915ece2f854fa654dc2810cc29ea51586af8", + "public/paths/groups/groups.yaml": "f595e2f5e147f44a7278fe928154e9a8401a8e28d4760963ae5c2b8e197bf6f4", + "public/paths/groups/groups_groupId.yaml": "48f002f2b8f64e5dca4abfd634c5eb9e2cde2498fe32e44ca1dbc3e3f4fc19f5", + "public/paths/groups/groups_groupId_invite_link.yaml": "8ddcc592bbb8f47e099e11f4d7cc75b91ff79296eaa35130308a1e29c1794836", + "public/paths/messaging/deleteMedia.yaml": "00c09f041df7aa0a49ccdd60122cb6855a89386594676d4fe523bec442c0b4ca", + "public/paths/messaging/media-id.yaml": "5afa9603d73d4771348544c80638c46785cc75aa1388808b84fdeb90051e8172", + "public/paths/messaging/messages.yaml": "d99ba398d05acca8ecb817d9b9806b497dea9bbdb079e280c0bcda1bad966b0d", + "public/paths/messaging/readMessage.yaml": "f35a04e3e6a8b115b208f0699ff67503a996284f417cea42efe8d51fc323cb36", + "public/paths/messaging/retrieveMedia.yaml": "4c73b3992f4653a4b3155be742b6d6720d79a454a17f0f3fbdc9e20d83cc5d01", + "public/paths/messaging/sendAddressMessage.yaml": "e759d10dbe389068ff3a0d06e03d93e1616cdbfdc6c2c1c6767270bd31bb6265", + "public/paths/messaging/sendButton.yaml": "5fc74240b27f216c65b45da4975b47e675c6ca4e3da7b204c27d67242566dcc3", + "public/paths/messaging/sendCarousel.yaml": "f188681458f3afdfc9846863a79d5ea28b6756cb1a5a00641bb9a29a332aad70", + "public/paths/messaging/sendContact.yaml": "509e1535bc405bce49a2efaf0fc812293042f338e8c42e26376c06b06e2cf194", + "public/paths/messaging/sendCtaUrl.yaml": "2935101dab612c8289aed85fed0e4900e6eb7a67ef1404000d115ecfefdc23f2", + "public/paths/messaging/sendFile.yaml": "6c07d60b36c8a415cab43c61a706aed4a73a53e52a114d50d8fbebc733296530", + "public/paths/messaging/sendFlow.yaml": "6add518a4650aa1d507aebe2053cfb53559d6c313fea0f2e1f7c04d4582ebd76", + "public/paths/messaging/sendList.yaml": "16cfc200444319d4280a801926d31d0acabbe917bea986460f54ad129f91fcd6", + "public/paths/messaging/sendLocation.yaml": "1f34da40ea89af2a693affffec822fc59663f4efe1554136817dd83fda3ae2ff", + "public/paths/messaging/sendLocationRequest.yaml": "b207ed18f773276c39c7bd854ee2c853071bcba244762d5a678e361b7d706446", + "public/paths/messaging/sendMessage.yaml": "5599e639be4dd34414649a7d5faf0d647599cb203d0e95a14f7ae660d6ade6ec", + "public/paths/messaging/sendOrderDetails.yaml": "7e27336c33ca83b575ef6e02445a5196664455f48a55d1755179bb2e36ffc4d9", + "public/paths/messaging/sendPaymentRequest.yaml": "2c83ccf1b20bc0dbae956e2fc445f981cdeac2be742c80b7b4db472f539d8afe", + "public/paths/messaging/sendProduct.yaml": "1871d3e9e4686e76a3ed30f111ea7619cb8c22665e679b6266390014fbb10b9d", + "public/paths/messaging/sendReaction.yaml": "65abf2bde681ca8e32b49ec273125f3e4aa41deb3d09873fa87b17e621da946f", + "public/paths/messaging/sendSticker.yaml": "ff7f7b7df63ec75fd5098e3616fd903e92d2ac86bdf3ce6bd08c78450ffabf1b", + "public/paths/messaging/uploadMedia.yaml": "4d7899c88220fcf712667ee3584f93006bd0dcc0de663a54de53409a46f3a9b5", + "public/paths/profile/me.yaml": "c1dc83a56b3d843cd0cced9345904bea65413c3a6b50445baa5d0c7efe2958c2", + "public/paths/templates/addTemplate.yaml": "a242c132f53885418dba9d718be2690473d3da88955acd705da27b689773e419", + "public/paths/templates/removeTemplate.yaml": "9c5cfe2f8d51e488cfc957c4bc7c4fb9a8599caf0ec37c53e61891f8eccfc303", + "public/paths/templates/sendTemplate.yaml": "29b4bb0e3793f1f05ec259fb465ceadd942b683da7d09e80faf4156110d2e253", + "public/paths/templates/templates.yaml": "f6e41fb5b90dca2a80c4eac4d052c51e6846919b95eee37f401b35a642cdfda6", + "public/paths/users/blockUser.yaml": "334c133da8bac1f3c1ce2c1642b526ad1bd44b2cbd0a91430a36cc0cc57dbdfb", + "public/paths/users/blockedUsers.yaml": "6f86fa8a90fac5e423cb0e267b13503466c42d669c5d77c1f2b0dd43920ab201", + "public/paths/users/unblockUser.yaml": "84fa3721451121872fee2ee7505c94b603a3af2045ca6f774208d25f151c28d1", + "public/paths/webhooks/webhook.yaml": "7aec81ccce6469de78b36749821286e8d322b82b15a88bc010d741513f350239", + "shared/parameters/date.yaml": "9db4dd8c143a365d139971a4208745646284da7c59f30320cd1958e27685b32a", + "shared/parameters/flowId.yaml": "5553440629ce9916e4191be9d67c5b115914cf7bc53eba5f9753fe2233e459c5", + "shared/parameters/group_id.yaml": "72da018aeabdf5e1f02c07405b98ece7b59f01152dfff38d026bd565c62486ee", + "shared/parameters/template_external_id.yaml": "2f3d2bf4340c7e47e171e28068ed0a9cf956c48f3b84ca79b6f6fa23f1cfe76b", + "shared/responses/BadRequest.yaml": "ef65a9cde8edb7870bf4bf28b6595b1e37f0dd3520faa877f71b6d3d732865d4", + "shared/responses/InternalError.yaml": "0b7bee775301c9c6aca8f8c665214a08b3e856b5c5eeeb57c036ef22b48f2407", + "shared/responses/InvalidToken.yaml": "be7e20df9dfa90f128897053856f768a676acc685906a37445bfc625df0854af", + "shared/responses/MessageSent.yaml": "0aca0872bb784a7039ff8be7ef57fc13c91638240624831249eeda7aa95704be", + "shared/responses/Success.yaml": "8c4363edb30103d41fbf7bcb8c9bc97782c76611a2bfcd2dbdd48081a2f4b813", + "shared/responses/TooManyRequests.yaml": "330a80e797769b544ed5c434623ba658d9d68bb66a554c560339d12e4266ce7c", + "shared/schemas/CallingSettings.yaml": "def3877472b9ed0bacfe9666d22c9bce30bc6b29d7433528ed4bffd471a9c5f5", + "shared/schemas/ChannelStatus.yaml": "7a95f1b01d56390f14005349b59c76d576f179b581587628f057ff5d6e60bb35", + "shared/schemas/ChannelStatusDetailed.yaml": "63cf817f0ae8bda5850b64e2ca24a3cf5867e5e1fe1383ca30ad16cc1d0fe385", + "shared/schemas/ConversationalAutomation.yaml": "b918c15cdb9cebb64075fd93c680c6dec48e713245d36535c0c5b423e1522602", + "shared/schemas/ErrorResponse.yaml": "2e2745599a88a23228168b585743e25c6a04f971e4aa319198539a9af0006503", + "shared/schemas/FlowInfo.yaml": "9a9f9d8b67420768fdb95170af04eea56f86a729fe6e4b8e55ffe6bb866a7ebb", + "shared/schemas/InitiateCallRequest.yaml": "f3300ec43cd4074afaf38f4e9d3695251ae1e1c1855fe5babb0253b23cb8b30b", + "shared/schemas/InitiateCallResponse.yaml": "eeb204a62e2b611327a510cc9f714b5fcdf4914bf96f44a7691d050bba48b5aa", + "shared/schemas/MessageSentResponse.yaml": "2dfb0257aafe1d9a7a3697088323909ebd74ac3f61520770e227e5f7b34aad43", + "shared/schemas/ProfileInfo.yaml": "4efee312cd1a86f6bfd06655d800cb156fad93d038f3b49fc52d296be2995207", + "shared/schemas/StatisticsResponse.yaml": "bd908f2527dc7bfcb41bda15a5748b26210f2bc09a9fa0f24fea7498c9342715", + "shared/schemas/SuccessResponse.yaml": "7dbb8695c11212213b86d6b8ddd0d6453e5630891735db447273014b3ae0b53c", + "shared/schemas/WebhookInfo.yaml": "22a6eecc886d3212ff55c7fb36e5a2f7ae7084666b0e7df79ebb308189afe3b8", + "shared/schemas/WebhookUrlStatus.yaml": "3e52f8356f7795966f9ef68d36c0b7c3d88ee00ad7abac58f9e4b85a46ddc766", + "shared/schemas/requests/ReadMessageRequest.yaml": "e1cbb41a16912c5f0c857af5046708804e7efb0b460b09df22b41c0959dd7666", + "shared/schemas/requests/SendButtonRequest.yaml": "d23b38055c5d512bb892706ae323ffeb7454c60d6ad0e78692908bf8c4b38702", + "shared/schemas/requests/SendCarouselRequest.yaml": "ddaa58dbb472eea48d291add1354a47e8fce4fc2d6a92641cf5175889cf5eb03", + "shared/schemas/requests/SendContactRequest.yaml": "02b7a66eb96273183d73ff8934d5a7ae3fdcda891bb7868b1f4b5473c8cae569", + "shared/schemas/requests/SendFileRequest.yaml": "c47eca1d90b15997ce9b1e955694e8437ca66a141df62dce997921bdf84c2b00", + "shared/schemas/requests/SendListRequest.yaml": "5de384d53c241635aa22fbd397db4b2007d2fb2ad04ed32f53cc845117d46b83", + "shared/schemas/requests/SendLocationRequest.yaml": "9a3a90dd091093680a45dc5ee0b260f48f8b2822e7c74cbc3a6007135bdd05e2", + "shared/schemas/requests/SendMessageRequest.yaml": "ee9cd3b8fa8392cabba39ed7307aa9fa93b9485350549f66695560c39eea4b16", + "shared/schemas/requests/SendProductRequest.yaml": "f6748ab368cf809b4ce9d0fe253466e46a2501390fe4fbc129fe235a1b51fc66", + "shared/schemas/requests/SendReactionRequest.yaml": "d06f0d5f96b9d7d2b6f7ad36ccf5288d0933458ffcf9ba711e02246108f8f9fc", + "shared/schemas/requests/UploadMediaRequest.yaml": "ad2639c9bb58140b3b8bc7e05324aa9fb6f661ebada33a327ffc1b856b64dec3" + }, + "postprocessorSha256": "22b45d7c425a5012875d6a0aae05e7baa787036085ed0021fffb2099218e4046", + "release": { + "version": "1.0.4", + "runId": "offline-1msg-156-final", + "artifactSha256": "a68783cd7214e853d9a2bfc3a01836f9657bea4594a474971bb19656ea07c480", + "versionDerivation": "gen/bump-sdk-version.js applied to sourceCommit before generation" + } +} diff --git a/quality/generator/verify-negative.mjs b/quality/generator/verify-negative.mjs new file mode 100644 index 0000000..958d4c3 --- /dev/null +++ b/quality/generator/verify-negative.mjs @@ -0,0 +1,30 @@ +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; +import { readFileSync, writeFileSync, rmSync, existsSync } from 'node:fs'; + +const sample = 'typescript/src/generated/src/runtime.ts'; +const original = readFileSync(sample); +const extra = 'typescript/src/generated/src/__untracked_quality_fixture__.ts'; +if (existsSync(extra)) throw new Error('Refusing to overwrite existing drift fixture'); +/** Require the actual pinned regeneration check to reject an output inventory mutation. */ +function rejects() { + const result = spawnSync(process.execPath, ['quality/generator/generate.mjs'], { + encoding: 'utf8', + timeout: 120000, + }); + assert.notEqual(result.status, 0, 'Generated drift unexpectedly passed'); + assert.match(result.stdout + result.stderr, /Generated SDK drift/); +} +try { + writeFileSync(sample, Buffer.concat([original, Buffer.from('\n// Unexpected generated edit\n')])); + rejects(); + rmSync(sample); + rejects(); + writeFileSync(sample, original); + writeFileSync(extra, '// Unexpected generated addition\n'); + rejects(); +} finally { + writeFileSync(sample, original); + rmSync(extra, { force: true }); +} +console.log('Actual regeneration rejects modified, deleted and untracked output'); diff --git a/scripts/pack-smoke.mjs b/scripts/pack-smoke.mjs new file mode 100644 index 0000000..2756248 --- /dev/null +++ b/scripts/pack-smoke.mjs @@ -0,0 +1,38 @@ +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; +import { mkdtempSync, rmSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join, resolve } from 'node:path'; + +/** Execute the packed SDK consumer and reject hangs or command failures. */ +function run(command, args, cwd) { + const result = spawnSync(command, args, { cwd, encoding: 'utf8', timeout: 30000 }); + if (result.status !== 0) + throw new Error(`${command}: ${result.stderr || result.stdout || result.error}`); + return result.stdout; +} +const directory = mkdtempSync(join(tmpdir(), '1msg-sdk-pack-')); +try { + const [packed] = JSON.parse( + run( + 'npm', + ['pack', '--json', '--ignore-scripts', '--pack-destination', directory], + resolve('typescript'), + ), + ); + assert.ok(packed.files.some((file) => file.path === 'dist/generated/src/runtime.js')); + run('tar', ['-xzf', join(directory, packed.filename), '-C', directory], directory); + run( + process.execPath, + [ + '-e', + `const assert = require('node:assert/strict'); const sdk = require('./package'); const client = sdk.createClient({baseUrl:'https://fixture.invalid/', instanceId:'instance', token:'fixture'}); assert.equal(client.config.buildRequestUrl('/sendMessage'), 'https://fixture.invalid/instance/sendMessage?token=fixture'); assert.equal(typeof client.messaging.sendMessage,'function'); assert.equal(typeof sdk.SendMessageRequestFromJSON,'function');`, + ], + directory, + ); + console.log( + 'Packed SDK imports without source files or workspace dependencies and exposes its public client/model API', + ); +} finally { + rmSync(directory, { recursive: true, force: true }); +} diff --git a/scripts/quality-extensions.test.mjs b/scripts/quality-extensions.test.mjs new file mode 100644 index 0000000..cc7b940 --- /dev/null +++ b/scripts/quality-extensions.test.mjs @@ -0,0 +1,101 @@ +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; +import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs'; +import { dirname, join, relative } from 'node:path'; +import test from 'node:test'; + +const sourceRoot = 'typescript/src'; +const runtimeFile = 'typescript/src/__quality_extension_runtime.ts'; +const testFile = 'typescript/src/__tests__/__quality_extension_runtime.test.ts'; + +/** Read actual Knip file diagnostics; a malformed report or tool failure cannot masquerade as coverage. */ +function unusedFiles(production) { + const result = spawnSync( + process.execPath, + [ + 'tools/quality/node_modules/knip/bin/knip.js', + '--config', + 'knip.config.mjs', + '--reporter', + 'json', + '--no-config-hints', + '--no-progress', + '--include', + 'files', + ...(production ? ['--production'] : []), + ], + { encoding: 'utf8', timeout: 60_000, maxBuffer: 16 * 1024 * 1024 }, + ); + assert.equal(result.signal, null, String(result.error ?? result.stderr)); + assert.equal( + result.status, + 1, + `Unused probes must fail Knip: ${result.stdout}\n${result.stderr}`, + ); + const report = JSON.parse(result.stdout); + assert.ok(Array.isArray(report.issues), result.stdout); + const files = new Set(); + for (const issue of report.issues) for (const entry of issue.files ?? []) files.add(entry.name); + return files; +} + +/** Create an isolated test dependency without changing existing entry files or executing the candidate modules. */ +function createTestDependency() { + for (const file of [runtimeFile, testFile]) { + assert.equal(existsSync(file), false, `Refusing to overwrite ${file}`); + mkdirSync(dirname(file), { recursive: true }); + } + const target = './' + relative(dirname(testFile), runtimeFile).replaceAll('\\', '/'); + if (runtimeFile.endsWith('.cjs')) { + writeFileSync(runtimeFile, 'module.exports = { onlyInTests: 1 };\n'); + writeFileSync( + testFile, + `const { onlyInTests } = require('${target}');\nconsole.log(onlyInTests);\n`, + ); + } else { + writeFileSync(runtimeFile, 'export const onlyInTests = 1;\n'); + writeFileSync( + testFile, + `import { onlyInTests } from '${target}';\nconsole.log(onlyInTests);\n`, + ); + } +} + +/** New extensions enter both inventories, while a runtime module reachable only from a test remains unused in production. */ +test('Knip inventories authored extensions without treating tests as production entries', () => { + const directory = join(sourceRoot, '__quality_extension_inventory__'); + assert.equal(existsSync(directory), false, `Refusing to overwrite ${directory}`); + assert.equal(existsSync(runtimeFile), false, `Refusing to overwrite ${runtimeFile}`); + assert.equal(existsSync(testFile), false, `Refusing to overwrite ${testFile}`); + mkdirSync(directory); + const files = ['js', 'jsx', 'mjs', 'cjs', 'ts', 'tsx', 'mts', 'cts'].map((extension) => + join(directory, `unused-${extension}.${extension}`), + ); + try { + for (const file of files) + writeFileSync( + file, + file.endsWith('.cjs') + ? 'module.exports = { unusedExtensionProbe: 1 };\n' + : 'export const unusedExtensionProbe = 1;\n', + ); + createTestDependency(); + for (const production of [false, true]) { + const reported = unusedFiles(production); + for (const file of files) + assert.ok( + reported.has(file.replaceAll('\\', '/')), + `${production ? 'production' : 'full'} omitted ${file}`, + ); + assert.equal( + reported.has(runtimeFile), + production, + `Test-only runtime dependency ${runtimeFile} must be reachable only in the full graph`, + ); + } + } finally { + rmSync(directory, { recursive: true, force: true }); + rmSync(runtimeFile, { force: true }); + rmSync(testFile, { force: true }); + } +}); diff --git a/scripts/quality-hook.test.mjs b/scripts/quality-hook.test.mjs new file mode 100644 index 0000000..cede201 --- /dev/null +++ b/scripts/quality-hook.test.mjs @@ -0,0 +1,208 @@ +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; +import { + chmodSync, + statSync, + copyFileSync, + existsSync, + mkdirSync, + mkdtempSync, + readFileSync, + rmSync, + symlinkSync, + writeFileSync, +} from 'node:fs'; +import { tmpdir } from 'node:os'; +import { dirname, join, resolve } from 'node:path'; +import test from 'node:test'; + +const repository = resolve('.'); +const configuration = { + source: 'typescript/src', + tooling: 'scripts', + typed: true, + files: [ + 'package.json', + 'quality.config.mjs', + '.husky/pre-commit', + 'eslint.config.mjs', + 'eslint.static.config.mjs', + 'eslint.typed.config.mjs', + 'eslint.hook.config.mjs', + 'tsconfig.json', + 'tsconfig.quality.json', + 'prettier.config.mjs', + '.prettierrc', + '.prettierrc.json', + '.prettierrc.js', + '.prettierignore', + 'typescript/tsconfig.json', + 'typescript/tsconfig.quality.json', + ], + links: ['node_modules', 'tools/quality'], +}; + +/** Run the real hook tools with an isolated Git identity and bounded child lifetime. */ +function command(root, program, args) { + const env = { + ...process.env, + HUSKY: '1', + GIT_CONFIG_NOSYSTEM: '1', + GIT_CONFIG_GLOBAL: process.platform === 'win32' ? 'NUL' : '/dev/null', + }; + for (const key of Object.keys(env)) + if (key.startsWith('GIT_') && !['GIT_CONFIG_NOSYSTEM', 'GIT_CONFIG_GLOBAL'].includes(key)) + delete env[key]; + const result = spawnSync(program, args, { + cwd: root, + env, + encoding: 'utf8', + timeout: 60_000, + maxBuffer: 8 * 1024 * 1024, + }); + assert.equal( + result.signal, + null, + `Fixture must finish by diagnostics: ${result.error ?? result.stderr}`, + ); + return result; +} + +/** Preserve full diagnostics when setup or a corrected commit unexpectedly fails. */ +function successful(root, program, args) { + const result = command(root, program, args); + assert.equal( + result.status, + 0, + `${program} ${args.join(' ')}\n${result.stdout}\n${result.stderr}`, + ); + return result.stdout.trim(); +} + +/** Copy production configuration and install the actual executable hook without borrowing the user's Git settings. */ +function fixture(t) { + const root = mkdtempSync(join(tmpdir(), '1msg-hook-extensions-')); + /** Remove only this disposable checkout after all real commit attempts finish. */ + t.after(() => rmSync(root, { recursive: true, force: true })); + for (const file of configuration.files) { + if (!existsSync(join(repository, file))) continue; + mkdirSync(dirname(join(root, file)), { recursive: true }); + copyFileSync(join(repository, file), join(root, file)); + } + for (const directory of configuration.links) { + mkdirSync(dirname(join(root, directory)), { recursive: true }); + symlinkSync(join(repository, directory), join(root, directory), 'dir'); + } + const actualPackage = JSON.parse(readFileSync(join(repository, 'package.json'), 'utf8')); + writeFileSync(join(root, 'package.json'), JSON.stringify(actualPackage)); + successful(root, 'git', ['init', '--quiet']); + successful(root, 'git', ['config', 'user.name', 'Quality fixture']); + successful(root, 'git', ['config', 'user.email', 'quality-fixture@example.invalid']); + successful(root, 'git', [ + '-c', + 'commit.gpgsign=false', + 'commit', + '--quiet', + '--allow-empty', + '-m', + 'fixture setup', + ]); + chmodSync(join(root, '.husky/pre-commit'), 0o755); + successful(root, process.execPath, ['tools/quality/node_modules/husky/bin.js']); + assert.equal(successful(root, 'git', ['config', '--local', 'core.hooksPath']), '.husky/_'); + assert.ok(statSync(join(root, '.husky/_/pre-commit')).mode & 0o111); + return root; +} + +/** Stage normalized fixture text so the intended lint rule, rather than unrelated formatting, refuses the commit. */ +function stage(root, files, source) { + for (const file of files) { + mkdirSync(dirname(join(root, file)), { recursive: true }); + writeFileSync(join(root, file), source); + } + successful(root, process.execPath, [ + 'tools/quality/node_modules/prettier/bin/prettier.cjs', + '--write', + ...files, + ]); + successful(root, 'git', ['add', '--', ...files]); +} + +/** A rejected commit must retain HEAD and identify every tested extension, preventing one covered file from masking an ignored peer. */ +function rejected(root, files, diagnostic) { + const head = successful(root, 'git', ['rev-parse', 'HEAD']); + const result = command(root, 'git', [ + '-c', + 'commit.gpgsign=false', + 'commit', + '--quiet', + '-m', + 'reject invalid authored extensions', + ]); + const output = `${result.stdout}\n${result.stderr}`.replaceAll('\\', '/'); + assert.notEqual(result.status, 0, output); + assert.match(output, diagnostic); + for (const file of files) { + const sections = output.split(/\n\s*\n/).filter((section) => section.includes(file)); + assert.ok( + sections.some((section) => diagnostic.test(section)), + `Missing intended diagnostic for ${file}:\n${output}`, + ); + } + assert.equal(successful(root, 'git', ['rev-parse', 'HEAD']), head); + successful(root, 'git', ['reset', '--quiet', 'HEAD', '--', ...files]); + for (const file of files) rmSync(join(root, file)); +} + +/** Exercise actual commits for all authored extensions; strict TS boundaries additionally require their configured program. */ +test('installed pre-commit covers JavaScript and TypeScript extensions', (t) => { + const root = fixture(t); + /** Keep fixture paths inside the actual source program and give each extension its own diagnostic. */ + const paths = (extensions) => + extensions.map((extension) => `${configuration.source}/hook-${extension}.${extension}`); + const javascript = paths(['js', 'jsx', 'mjs', 'cjs']); + const typescript = paths(['ts', 'tsx', 'mts', 'cts']); + stage( + root, + javascript, + 'const value = process.env.HOOK_FIXTURE_VALUE;\nconsole.log(value == 1);\n', + ); + rejected(root, javascript, /eqeqeq/); + stage( + root, + typescript, + '/** Preserve the supplied untrusted value. */\nexport function same(value: any) { return value; }\n', + ); + rejected( + root, + typescript, + configuration.typed ? /no-explicit-any/ : /TypeScript requires a configured strict program/, + ); + if (configuration.typed) { + const boundaries = [...typescript, `${configuration.tooling}/hook-tooling.mts`]; + stage( + root, + boundaries, + '/** Decode external text without trusting its shape. */\nexport function decode(text: string): string { return JSON.parse(text); }\n', + ); + rejected(root, boundaries, /no-unsafe-return/); + stage( + root, + boundaries, + '/** Return the supplied typed value unchanged. */\nexport function identity(value: string): string { return value; }\n', + ); + } + stage( + root, + javascript, + 'const value = process.env.HOOK_FIXTURE_VALUE;\nconsole.log(value === 1);\n', + ); + successful(root, 'git', [ + '-c', + 'commit.gpgsign=false', + 'commit', + '--quiet', + '-m', + 'accept corrected authored extensions', + ]); +}); diff --git a/scripts/quality-negative.mjs b/scripts/quality-negative.mjs new file mode 100644 index 0000000..e9392eb --- /dev/null +++ b/scripts/quality-negative.mjs @@ -0,0 +1,58 @@ +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; +import { existsSync, mkdirSync, writeFileSync, rmSync } from 'node:fs'; +import { join } from 'node:path'; + +const root = process.argv[2] ?? 'src'; +const directory = join(root, '__quality_negative_fixtures__'); +if (existsSync(directory)) throw new Error(`Refusing to overwrite ${directory}`); +mkdirSync(directory); + +/** Run the repository's actual analyzer and require the intended diagnostic, not an unrelated setup failure. */ +function rejects(command, args, expected) { + const result = spawnSync(process.execPath, [command, ...args], { + encoding: 'utf8', + env: { ...process.env, CI: 'true', ESLINT_SKIP_TYPE_AWARE: 'true' }, + }); + const output = result.stdout + result.stderr; + assert.notEqual(result.status, 0, 'negative fixture unexpectedly passed'); + assert.match(output, expected, `wrong failure: ${output}`); +} + +try { + const fixture = join(directory, 'unsafe.ts'); + writeFileSync( + fixture, + '/** Negative fixture: checks that typed lint cannot be disabled by environment flags. */\nexport function unsafe(value: any) { Promise.resolve(1); return value.field; }\n', + ); + rejects( + 'tools/quality/node_modules/eslint/bin/eslint.js', + ['-c', 'eslint.typed.config.mjs', fixture], + /no-floating-promises/, + ); + rejects( + 'tools/quality/node_modules/eslint/bin/eslint.js', + ['-c', 'eslint.typed.config.mjs', fixture], + /no-unsafe-member-access/, + ); + for (const [name, next] of [ + ['a', 'b'], + ['b', 'c'], + ['c', 'a'], + ]) { + writeFileSync( + join(directory, `${name}.ts`), + `import { ${next} } from './${next}.js';\nexport const ${name} = () => ${next}();\n`, + ); + } + rejects( + 'tools/quality/node_modules/dependency-cruiser/bin/dependency-cruiser.mjs', + ['--config', '.dependency-cruiser.cjs', directory], + /no-runtime-cycles/, + ); + console.log( + 'Negative fixtures reject floating promises, unsafe access, skip flags and a three-edge runtime cycle', + ); +} finally { + rmSync(directory, { recursive: true, force: true }); +} diff --git a/tools/quality/README.md b/tools/quality/README.md new file mode 100644 index 0000000..750bd5c --- /dev/null +++ b/tools/quality/README.md @@ -0,0 +1,172 @@ +# 1MSG quality template 1.0.11 + +Vendored, private template for 1MSG-156. Install its exact tools with +`npm --prefix tools/quality ci` on Node 24.19.0. The lockfile and +`template-manifest.json` identify the reviewed version. This package is not +published to npm. Each consumer commits a full copy, its manifest, and its own +`quality.config.mjs` inventory. A version update requires policy review and +real negative fixtures; do not edit/reseal one consumer to hide a violation. + +## Profiles and commands + +A (Node runtime) and B (UI) require full static and typed ESLint, strict production, +test and tooling typechecks, architecture, debt gates, tests, and production build. +D applies these to authored TypeScript/tooling while each generated language uses +reproducible generation and native build/offline contract tests. C runs formatting +and static lint on every changed/new authored file and ratchets existing debt. +Compiler presets are provided for NodeNext, Next bundler and Svelte bundler; +consumers must include real sources/tests/tooling and the framework's generated types. + +Exported `staticConfig`, `typedConfig`, `maintainabilityConfig` compose with the +actual framework preset. Next uses its compatible core-web-vitals + TypeScript +presets and React Hooks; Svelte uses its parser/plugin and `svelte-check` on real +components. Browser globals and Node runtime checks have separate scopes. + +`node tools/quality/run.mjs guards` checks source inventory, suppressions, vendored +integrity and documentation for changed functions/private methods/substantive +callbacks plus full pilot roots. Comments explain purpose, effects and constraints; +AST coverage is mechanical, usefulness and accuracy require review. Formatting-only +changes do not create a method change. Meaningless boilerplate does not satisfy review. + +Mandatory graph/debt commands: `unused-production`, `unused-full`, `duplicates`. +`duplicates-full` saves the extended tests/fixtures report and fails analyzer errors; +it is a report, not the runtime clone gate. Configure `duplicatePaths`, +`duplicateFullPaths`, exact generated ignores, explicit formats, and an inventoried +numeric `duplicateMaxPercentage`. Detection uses minLines=5, minTokens=50, mild mode. +Clone groups cannot grow even if the overall duplicate percentage falls. + +Wrap actual JSON analyzer output with: + +- `report --kind eslint --name complexity -- node tools/quality/node_modules/eslint/bin/eslint.js . -c eslint.complexity.config.mjs -f json` +- `report --kind depcruiser --name architecture -- node tools/quality/node_modules/dependency-cruiser/bin/dependency-cruiser.mjs src --config dependency-cruiser.config.cjs --output-type json` + +Only maintainability metrics and existing runtime cycles are baselinable through +those report commands. Other static/typed/architecture diagnostics remain fatal. +Knip keeps separate production and full graphs; missing resolvers, empty graphs, +stale exclusions and malformed output are failures. Configure public exports and +dynamic entrypoints explicitly, never declare all source as entrypoints. + +## Historical debt + +Initial bootstrap is local only and requires owner, expiry, reason and issue: +`--bootstrap --owner TEAM --expires YYYY-MM-DD --reason TEXT --issue URL`. +It reruns the actual analyzer against the trusted Git base using the adopted +configuration. New files, disconnected imports and increased findings cannot be +blessed as historical debt. Replay removes only newly added entry/project patterns +that have no historical source; existing source always comes from Git archive. +Dependencies are shared read-only with the current installation for resolution. + +CI supplies the trusted PR base SHA through `QUALITY_BASE` and fetches full history. +After adoption, allowances cannot grow or renew their expiry; reductions and removed +findings must retire allowances. Reports include head/base SHAs and gate outcome. +Never describe a nonempty baseline as a clean codebase. + +## CI and local hooks + +Run `npm --prefix tools/quality test` as a mandatory independent check. Fixtures +execute actual Knip, jscpd and dependency-cruiser CLIs and verify ratchet growth, +coverage, documentation and malformed reports. Consumers add real typed/framework, +public API, native I/O, SQL, compatibility and generated-drift fixtures as applicable. +`Quality` / `quality-required` must aggregate all applicable checks and fail on any +missing, failed or cancelled required job. Configure this actual job context in +branch protection without removing existing requirements. CI never runs `--fix`. + +The pinned Husky/lint-staged dependencies support committed `.husky/pre-commit` and +an explicit repository `hooks:install` command. Keep hooks quick; CI is authoritative. +Do not change shared Git hook configuration of another worktree during verification. + +## Updating this template + +Change the template at its source, update its version, test actual consumers, +run `node seal.mjs`, copy the complete template, and commit lockfiles and inventory. +Integrity verification prevents hiding authored code under the vendor exemption. +No analyzer flag may depend on CI or a skip-type-aware environment variable. + +Version 1.0.2 resolves Svelte embedded clone paths to their physical source while retaining fragment identity. Initial Knip replay omits only the exact current-only sealed vendor ignore; authored stale ignores remain errors. + +## Canonical maintainability measurement (1.0.3) + +For adoption that includes formatting, run `node tools/quality/complexity.mjs --config eslint.complexity.config.mjs` as the analyzer inside the existing `report --kind eslint --name complexity` gate. Both trusted historical source and current source are independently formatted in memory with the pinned Prettier version and sealed policy before the same ESLint rules execute. Files on disk are never rewritten. This gives line metrics the same unit of measurement; AST complexity and the per-finding ratchet remain enforced. The original Git source hash remains adoption evidence. The JSON report includes canonical source so diagnostic locations identify the correct function after formatting. Formatter/parse failures are fatal. This does not replace `Prettier --check` on the actual checkout. + +Existing consumers pinned to 1.0.2 do not need a policy change; 1.0.3 adds the explicit canonical measurement command. + +For JS/TS formatting migrations, `duplicateCanonicalFormat: true` measures both trusted base and current source after the same pinned formatter in disposable copies. Declare the supported `duplicateFormats` (`javascript`, `typescript`, `jsx`, `tsx`) and exact ignored dependency/generated paths. Source files stay unchanged. New/grown clone groups still fail even if the aggregate percentage falls. Unsupported framework source, unexpected symlinks, empty coverage or failed formatting are analyzer failures. Report line numbers refer to canonical source fragments. + +Version 1.0.6 runs canonical complexity with inline ESLint configuration disabled on both sides. Legacy directives for unrelated framework plugins cannot corrupt metric coverage, and a source comment cannot suppress complexity debt. The separate source suppression guard still enforces the current-code policy. Trusted replay also copies exact Jest config filenames as analyzer inputs, allowing Knip to load current test-runner configuration against historical application and test source. Ordinary source files continue to come exclusively from the trusted Git archive. + +Version 1.0.7 parses JS/TS/JSX/TSX with the pinned TypeScript compiler and prints an in-memory, comment-free metric input before pinned Prettier formatting. Comments inside JSX callbacks otherwise change indentation and wrap executable lines, inflating line debt despite `skipComments`. Both current and trusted historical sources use the same normalization; recompute both sides when adopting this version. No rule limits or baseline allowances change. The original files are not rewritten, and strings, regular expressions, template literals and rendered JSX content remain data rather than comment matches. Unsupported source extensions and syntax errors fail closed before recovered syntax can become a metric report. + +The 31-test suite includes actual CLI fixtures proving that JSX documentation leaves file/function line metrics unchanged, an added statement still increases those metrics, malformed JS/TSX fails, and canonical string/tagged-template/regular-expression, JSX rendering and automatic-semicolon behavior is preserved. JSX assertions compare rendered text and element order because formatting may split adjacent text nodes. Formatting and documentation guards still inspect the actual checkout. Consumers remaining on sealed 1.0.2 are unchanged by this release. + +## Version 1.0.8 + +Complexity findings use complete lexical ownership (class, function, binding, +property and call argument), independent of emitted diagnostic order. Fixing an +older callback therefore cannot renumber a different callback's allowance. +Ambiguous sibling scopes are tied to ordered, comment-free AST evidence; changed +or indistinguishable groups fail closed. The real CLI fixtures verify both +legitimate debt reduction and rejection of transferred/increased allowances. +Existing consumers must replay historical source with this version when adopting +the new key schema; old diagnostic ordinals are never silently migrated. + +## 1.0.9 migration + +Complexity identities now retain lexical `for`, `for-in` and `for-of` headers +(binding, source/condition/increment and `await` mode). Identical statements in +different loops no longer collide. Loop bodies, source lines and diagnostic +ordinals do not identify allowances; indistinguishable sibling loops still fail +closed. Consumers must replay their original trusted adoption base with the +updated analyzer, preserving debt owners, deadlines and reasons. Do not translate +baseline keys manually or renew historical debt as part of the version update. + +## 1.0.10 migration + +Otherwise identical sibling scopes use the nearest distinguishing parsed branch or +block context, including then/else, loop, switch and try/catch/finally roles. This +fallback leaves already unambiguous identities unchanged. The complete ordered +peer evidence remains part of an ambiguous group's identity; swaps, new peers, +growth and fully indistinguishable ancestry cannot borrow another allowance. +ESLint object-property diagnostics resolve the exact property name to its direct +callable initializer. Previously misattributed nested callback metrics now belong +to that callback, rather than its enclosing function. Consumers must replay their +original trusted adoption base; preserve owners, expiry and reasons and never +translate baseline keys manually. + +For function documentation only, a syntax error in trusted historical source +removes all inherited function signatures: every current function in that file +must have documentation. Current syntax errors and historical/current I/O, +configuration or Git failures remain fatal. This conservative documentation +fallback does not alter metric analysis, source coverage or debt baselines. + +## 1.0.11 migration + +Test repositories now initialize their default branch with `git init` followed by +`git symbolic-ref HEAD refs/heads/main`. This works on the older Git installation +used by the self-hosted runner, which does not support `git init -b`. A regression +fixture rejects that unsupported option and replays both actual Git-backed test +families through a subprocess-only Node preload shim; all other Git operations +remain real. The fixture uses no Unix executable or shebang assumptions and does +not modify the runtime Git driver or skip checks on Windows. +Only fixture setup changes: analysis rules, historical identities and baseline +records are unchanged. Copy the complete sealed version without changing debt +owners, reasons, issue links, expiry dates or baseline entries. + +## 1.0.12 migration + +Suppression detection now scans trivia between parsed TypeScript tokens. A plain +scanner loses context after a template interpolation: it can mistake generated +directive text for a source comment and overlook a real directive after the +template. Parsed template segments, regex bodies and JSX text remain data; +comments inside interpolations/JSX expressions and at EOF remain enforceable. +Positive and negative syntax fixtures and the real guard CLI cover both failure +modes, including scoped exception requirements and Svelte script blocks. +Copy the complete sealed version. Metric identities, source coverage and debt +allowances do not change; rerun guards to detect any previously missed comments. + +The staged-file coverage preflight (`staged.mjs --config -- +`) permits ignored files only when the repository inventory explicitly +declares them or they belong to the verified sealed preset. Run it before ESLint +with `--no-warn-ignored`: this supports preset updates and generated files while +still rejecting an accidentally ignored authored file. An added or altered +unsealed vendor file fails integrity validation; an arbitrary ESLint ignore alone +never grants an exemption. diff --git a/tools/quality/canonical-duplicates.mjs b/tools/quality/canonical-duplicates.mjs new file mode 100644 index 0000000..c706926 --- /dev/null +++ b/tools/quality/canonical-duplicates.mjs @@ -0,0 +1,128 @@ +import { spawnSync } from 'node:child_process'; +import { + lstat, + mkdir, + mkdtemp, + readFile, + readdir, + rm, + writeFile, + realpath, +} from 'node:fs/promises'; +import { tmpdir } from 'node:os'; +import { dirname, join, resolve } from 'node:path'; +import { format } from 'prettier'; +import picomatch from 'picomatch'; +import policy from './prettier.config.mjs'; +const config = JSON.parse(process.argv[2]); +const root = process.cwd(); +if (!Array.isArray(config.duplicatePaths) || !config.duplicatePaths.length) + throw new Error('Canonical clone roots are required'); +for (const file of config.duplicatePaths) + if ( + typeof file !== 'string' || + file.startsWith('/') || + file.split(/[\\/]/).includes('..') + ) + throw new Error('Clone root must remain inside the repository'); +const formats = config.duplicateFormats ?? [ + 'javascript', + 'typescript', + 'jsx', + 'tsx', +]; +if ( + !formats.length || + formats.some( + (value) => !['javascript', 'typescript', 'jsx', 'tsx'].includes(value), + ) +) + throw new Error( + 'Canonical clone measurement supports only declared JavaScript and TypeScript formats', + ); +const temporary = await realpath( + await mkdtemp(join(tmpdir(), 'canonical-clones-')), +); +const ignored = picomatch(config.duplicateIgnore ?? [], { dot: true }); +let files = 0; +/** Inventory declared roots without following symlinks and format each authored source with the same sealed policy. */ +async function copy(file) { + if (ignored(file)) return; + const info = await lstat(join(root, file)); + if (info.isSymbolicLink()) throw Error(`Unreviewed source symlink: ${file}`); + if (info.isDirectory()) { + for (const entry of await readdir(join(root, file))) + await copy(join(file, entry)); + return; + } + if (/\.(svelte|vue)$/.test(file)) + throw new Error( + `Canonical clone measurement needs a framework formatter for ${file}`, + ); + if (!/\.[cm]?[jt]sx?$/.test(file)) return; + const canonical = await format(await readFile(join(root, file), 'utf8'), { + ...policy, + filepath: file, + }); + const target = join(temporary, file); + await mkdir(dirname(target), { recursive: true }); + await writeFile(target, canonical); + files++; +} +/** Restore portable source identities after analyzing the temporary canonical copy; fragments retain their measured text. */ +function originalPaths(value) { + if (typeof value === 'string' && value.startsWith(temporary + '/')) + return join(root, value.slice(temporary.length + 1)); + if (Array.isArray(value)) return value.map(originalPaths); + if (value && typeof value === 'object') + return Object.fromEntries( + Object.entries(value).map(([key, item]) => [ + originalPaths(key), + originalPaths(item), + ]), + ); + return value; +} +try { + for (const file of config.duplicatePaths) await copy(file); + if (!files) throw Error('Canonical clone inventory is empty'); + const tool = new URL('./node_modules/jscpd/run-jscpd.js', import.meta.url) + .pathname; + const result = spawnSync( + process.execPath, + [ + tool, + ...config.duplicatePaths, + '--reporters', + 'json', + '--output', + 'reports', + '--mode', + 'mild', + '--min-lines', + '5', + '--min-tokens', + '50', + '--silent', + '--absolute', + '--format', + formats.join(','), + ], + { + cwd: temporary, + encoding: 'utf8', + timeout: 180000, + maxBuffer: 50 * 1024 * 1024, + }, + ); + if (result.status !== 0 || result.error || result.signal) + throw Error(result.stderr || result.stdout || String(result.error)); + const report = JSON.parse( + await readFile(join(temporary, 'reports/jscpd-report.json'), 'utf8'), + ); + if (report.duplicates.some((clone) => typeof clone.fragment !== 'string')) + throw Error('Missing canonical clone fragment'); + process.stdout.write(JSON.stringify(originalPaths(report))); +} finally { + await rm(temporary, { recursive: true, force: true }); +} diff --git a/tools/quality/complexity.mjs b/tools/quality/complexity.mjs new file mode 100644 index 0000000..fb0b27a --- /dev/null +++ b/tools/quality/complexity.mjs @@ -0,0 +1,83 @@ +#!/usr/bin/env node +import { realpathSync } from 'node:fs'; +import { readFile } from 'node:fs/promises'; +import { extname } from 'node:path'; +import { pathToFileURL } from 'node:url'; + +import { ESLint } from 'eslint'; +import { format } from 'prettier'; +import ts from 'typescript'; + +import policy from './prettier.config.mjs'; + +/** Remove only parsed comments before formatting so documentation cannot inflate wrapped code lines; reject unsupported or invalid syntax. */ +function metricSource(source, filePath) { + if (!/^[.](?:[cm]?[jt]s|[jt]sx)$/.test(extname(filePath))) + throw new Error(`Unsupported complexity source: ${filePath}`); + const syntax = ts.createSourceFile( + filePath, + source, + ts.ScriptTarget.Latest, + true, + ); + if (syntax.parseDiagnostics.length) { + const diagnostic = syntax.parseDiagnostics[0]; + throw new Error( + `Complexity parse failed: ${filePath}: ${ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`, + ); + } + return ts + .createPrinter({ removeComments: true, newLine: ts.NewLineKind.LineFeed }) + .printFile(syntax); +} + +/** Measure comment-free source with the same pinned formatting policy, retaining canonical text for diagnostic scope identities. */ +export async function measureComplexity(config, targets) { + const eslint = new ESLint({ + overrideConfigFile: config, + allowInlineConfig: false, + }); + const inventory = await eslint.lintFiles(targets); + if (!inventory.length) + throw new Error('Complexity source inventory is empty'); + const reports = []; + for (const file of inventory) { + if (file.fatalErrorCount) + throw new Error(`Complexity parse failed: ${file.filePath}`); + const source = await readFile(file.filePath, 'utf8'); + const canonical = await format(metricSource(source, file.filePath), { + ...policy, + filepath: file.filePath, + }); + const [report] = await eslint.lintText(canonical, { + filePath: file.filePath, + }); + if (!report || report.fatalErrorCount) + throw new Error(`Complexity parse failed: ${file.filePath}`); + reports.push({ ...report, source: canonical }); + } + return reports; +} + +/** Keep formatter, parser and inventory failures distinct from ordinary maintainability diagnostics. */ +async function main() { + const args = process.argv.slice(2); + const position = args.indexOf('--config'); + if (position < 0 || !args[position + 1]) + throw new Error('Complexity measurement requires --config'); + const [config] = args.splice(position, 2).slice(1); + const reports = await measureComplexity(config, args.length ? args : ['.']); + process.stdout.write(JSON.stringify(reports)); + if (reports.some((report) => report.errorCount || report.warningCount)) + process.exitCode = 1; +} + +if ( + process.argv[1] && + import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href +) { + main().catch((error) => { + console.error(error instanceof Error ? error.message : String(error)); + process.exitCode = 2; + }); +} diff --git a/tools/quality/eslint.mjs b/tools/quality/eslint.mjs new file mode 100644 index 0000000..142b9f1 --- /dev/null +++ b/tools/quality/eslint.mjs @@ -0,0 +1,137 @@ +import js from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import imports from 'eslint-plugin-import'; +import node from 'eslint-plugin-n'; +import unicorn from 'eslint-plugin-unicorn'; +import perfectionist from 'eslint-plugin-perfectionist'; +import sonarjs from 'eslint-plugin-sonarjs'; +import globals from 'globals'; +import { createRequire } from 'node:module'; + +const require = createRequire(import.meta.url); +export { + tseslint, + imports as importPlugin, + node as nodePlugin, + sonarjs, + unicorn, + perfectionist, + globals, +}; + +export const sourceFiles = ['**/*.{js,jsx,cjs,mjs,ts,tsx,cts,mts}']; +export const testFiles = [ + '**/*.{test,spec,stories}.{js,jsx,ts,tsx}', + '**/{test,tests,__tests__,fixtures,mocks}/**', +]; + +/** Return the shared correctness/style layer; callers provide explicit browser/Node globals and generated paths. */ +export function staticConfig({ files = sourceFiles, globals = {} } = {}) { + return [ + { + files, + languageOptions: { globals }, + linterOptions: { reportUnusedDisableDirectives: 'error' }, + plugins: { import: imports, n: node, unicorn, perfectionist, sonarjs }, + settings: { + 'import/resolver': { + [require.resolve('eslint-import-resolver-typescript')]: { + alwaysTryTypes: true, + }, + node: { extensions: ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs'] }, + }, + }, + rules: { + ...js.configs.recommended.rules, + eqeqeq: ['error', 'always'], + 'no-var': 'error', + 'prefer-const': 'error', + 'import/no-unresolved': 'error', + 'import/no-duplicates': 'error', + 'n/no-unsupported-features/node-builtins': [ + 'error', + { version: '>=24.0.0 <25.0.0' }, + ], + 'unicorn/prefer-node-protocol': 'error', + 'unicorn/prefer-type-error': 'error', + 'perfectionist/sort-imports': [ + 'error', + { type: 'natural', order: 'asc', sortSideEffects: false }, + ], + 'perfectionist/sort-exports': [ + 'error', + { type: 'natural', order: 'asc' }, + ], + 'sonarjs/no-identical-functions': 'error', + 'sonarjs/no-all-duplicated-branches': 'error', + }, + }, + ...tseslint.configs.recommended.map((config) => ({ + ...config, + files: ['**/*.{ts,tsx,cts,mts}'], + })), + ]; +} + +/** Apply mandatory type-aware Promise and unknown-boundary checks using actual repository tsconfigs. */ +export function typedConfig({ + files = ['**/*.{ts,tsx,cts,mts}'], + project, + tsconfigRootDir, +} = {}) { + return [ + { + files, + languageOptions: { + parser: tseslint.parser, + parserOptions: { project, tsconfigRootDir }, + }, + plugins: { '@typescript-eslint': tseslint.plugin }, + rules: { + '@typescript-eslint/no-floating-promises': 'error', + '@typescript-eslint/no-misused-promises': 'error', + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-unsafe-assignment': 'error', + '@typescript-eslint/no-unsafe-argument': 'error', + '@typescript-eslint/no-unsafe-call': 'error', + '@typescript-eslint/no-unsafe-member-access': 'error', + '@typescript-eslint/no-unsafe-return': 'error', + }, + }, + ]; +} + +/** Keep complexity diagnostics separate so only measured maintainability debt can use a ratchet. */ +export function maintainabilityConfig({ files = sourceFiles } = {}) { + return [ + { + files, + ignores: testFiles, + plugins: { sonarjs }, + rules: { + 'max-lines': [ + 'error', + { max: 500, skipBlankLines: true, skipComments: true }, + ], + 'max-lines-per-function': [ + 'error', + { max: 80, skipBlankLines: true, skipComments: true }, + ], + complexity: ['error', { max: 20, variant: 'classic' }], + 'sonarjs/cognitive-complexity': ['error', 15], + 'max-depth': ['error', 4], + 'max-params': ['error', 5], + }, + }, + { + files: ['**/*.{jsx,tsx}'], + ignores: testFiles, + rules: { + 'max-lines-per-function': [ + 'error', + { max: 150, skipBlankLines: true, skipComments: true }, + ], + }, + }, + ]; +} diff --git a/tools/quality/lib/baseline.mjs b/tools/quality/lib/baseline.mjs new file mode 100644 index 0000000..b4e11a4 --- /dev/null +++ b/tools/quality/lib/baseline.mjs @@ -0,0 +1,82 @@ +import { createHash } from 'node:crypto'; + +/** Hash normalized evidence so line moves cannot grant new duplicate allowances. */ +export function digest(text) { + return createHash('sha256').update(text).digest('hex'); +} + +/** Keep a stable identifier for each independent finding, rather than a global failure count. */ +export function record(key, value = 1, details = {}) { + if (!key || !Number.isFinite(value) || value < 0) + throw new Error('Invalid analyzer finding'); + return { key, value, ...details }; +} + +/** Reject duplicate diagnostic identities because collapsing them could hide growing debt. */ +export function index(records) { + const result = new Map(); + for (const entry of records) { + if (result.has(entry.key)) + throw new Error(`Duplicate finding identity: ${entry.key}`); + result.set(entry.key, entry); + } + return result; +} + +/** Compare current findings with allowances and the trusted base's allowances, including stale debt. */ +export function assess( + findings, + baseline, + previous, + today = new Date().toISOString().slice(0, 10), +) { + const errors = []; + if (baseline.schemaVersion !== 1 || !Array.isArray(baseline.entries)) { + throw new Error('Unsupported or missing baseline schema'); + } + const current = index(findings); + const allowances = index(baseline.entries); + const older = previous ? index(previous.entries) : null; + for (const [key, allowance] of allowances) { + if ( + !allowance.owner || + !allowance.reason || + !allowance.issue || + !allowance.expires + ) { + errors.push(`Unowned/unexplained allowance: ${key}`); + } + if ( + !/^\d{4}-\d{2}-\d{2}$/.test(allowance.expires ?? '') || + allowance.expires < today + ) { + errors.push(`Expired or invalid allowance: ${key}`); + } + const finding = current.get(key); + if (!finding) errors.push(`Remove stale allowance: ${key}`); + else if (finding.value < allowance.value) + errors.push(`Reduce allowance to ${finding.value}: ${key}`); + if (older) { + const old = older.get(key); + if (!old || allowance.value > old.value) + errors.push(`Baseline expanded relative to trusted base: ${key}`); + if (old && allowance.expires > old.expires) + errors.push(`Allowance expiry extended: ${key}`); + } + } + for (const [key, finding] of current) { + if (!allowances.has(key) || finding.value > allowances.get(key).value) { + errors.push(`New or increased violation (${finding.value}): ${key}`); + } + } + return errors; +} + +/** Parse machine-readable output only; a missing report or unexpected schema is an analysis failure. */ +export function parseJson(stdout, analyzer) { + try { + return JSON.parse(stdout); + } catch { + throw new Error(`${analyzer} did not return a complete JSON report`); + } +} diff --git a/tools/quality/lib/git.mjs b/tools/quality/lib/git.mjs new file mode 100644 index 0000000..2aa6dcb --- /dev/null +++ b/tools/quality/lib/git.mjs @@ -0,0 +1,86 @@ +import { spawnSync } from 'node:child_process'; +import { readFileSync } from 'node:fs'; + +/** Run a bounded, non-shell child process; preserve failures instead of returning an empty analysis. */ +export function execute(command, args = [], options = {}) { + const result = spawnSync(command, args, { + encoding: 'utf8', + maxBuffer: 128 * 1024 * 1024, + timeout: 600_000, + ...options, + }); + if (result.error || result.signal || result.status === null) { + throw new Error( + `${command} did not complete: ${result.error?.message ?? result.signal}`, + ); + } + return result; +} + +/** Execute read-only Git operations and reject a missing ref or failed comparison. */ +export function git(args) { + const result = execute('git', args); + if (result.status !== 0) + throw new Error(`git ${args[0]} failed: ${result.stderr.trim()}`); + return result.stdout; +} + +/** Resolve one trusted comparison commit; CI explicitly supplies its PR base SHA. */ +export function baseRef( + defaultBranch = 'main', + explicit = process.env.QUALITY_BASE, +) { + if (explicit) + return git(['rev-parse', '--verify', `${explicit}^{commit}`]).trim(); + return git(['merge-base', 'HEAD', `origin/${defaultBranch}`]).trim(); +} + +/** Return tracked paths, including staged additions, with unambiguous NUL delimiters. */ +export function trackedFiles() { + return git(['ls-files', '-z']).split('\0').filter(Boolean); +} + +/** Include committed, staged, unstaged and untracked additions in local changed-file checks. */ +export function changedFiles(base) { + return [ + ...new Set( + [ + ...git([ + 'diff', + '--name-only', + '--diff-filter=ACMR', + '-z', + base, + '--', + ]).split('\0'), + ...git(['ls-files', '--others', '--exclude-standard', '-z']).split( + '\0', + ), + ].filter(Boolean), + ), + ].sort(); +} + +/** Read an optional file at the verified base; missing files mean additions, not failed Git. */ +export function baseFile(base, path) { + const paths = git([ + 'ls-tree', + '-r', + '--name-only', + '-z', + base, + '--', + path, + ]).split('\0'); + return paths.includes(path) ? git(['show', `${base}:${path}`]) : null; +} + +/** Read current bytes only when the path exists; deleted files have no current diagnostics. */ +export function currentFile(path) { + try { + return readFileSync(path, 'utf8'); + } catch (error) { + if (error.code === 'ENOENT') return null; + throw error; + } +} diff --git a/tools/quality/lib/guards.mjs b/tools/quality/lib/guards.mjs new file mode 100644 index 0000000..0e3fddb --- /dev/null +++ b/tools/quality/lib/guards.mjs @@ -0,0 +1,427 @@ +import ts from 'typescript'; +import picomatch from 'picomatch'; +import { existsSync } from 'node:fs'; +import { baseFile, changedFiles, currentFile, trackedFiles } from './git.mjs'; +import { digest } from './baseline.mjs'; +import { verifyTemplate } from './template.mjs'; + +const sourcePattern = /\.(?:[cm]?[jt]sx?|svelte)$/; + +/** Match repo-relative paths consistently; generated and exception paths stay explicit. */ +export function matches(path, patterns = []) { + return patterns.some((pattern) => picomatch(pattern, { dot: true })(path)); +} + +/** Validate manifest entries before they can remove any source from a mandatory check. */ +export function validateConfig( + config, + today = new Date().toISOString().slice(0, 10), +) { + if ( + config.schemaVersion !== 1 || + !['A', 'B', 'C', 'D'].includes(config.profile) + ) { + throw new Error( + 'quality.config.mjs requires schemaVersion=1 and a concrete profile', + ); + } + if (!Array.isArray(config.sourceRoots) || config.sourceRoots.length === 0) { + throw new Error( + 'sourceRoots must inventory the authored source and tooling', + ); + } + if ( + config.duplicateCanonicalFormat !== undefined && + typeof config.duplicateCanonicalFormat !== 'boolean' + ) + throw new Error('duplicateCanonicalFormat must be an explicit boolean'); + for (const root of config.sourceRoots) { + if (!existsSync(root)) throw new Error(`Missing source root: ${root}`); + } + for (const entry of config.generated ?? []) { + if ( + !entry.producer || + !entry.pattern || + ['**', '**/*', '**/*.ts', '**/*.js'].includes(entry.pattern) + ) { + throw new Error( + 'Generated exclusions require a narrow path and actual producer', + ); + } + } + for (const entry of [ + ...(config.excluded ?? []), + ...(config.comments?.exclude ?? []), + ]) { + if ( + !entry.pattern || + !entry.owner || + !entry.reason || + !entry.expires || + entry.expires < today + ) { + throw new Error(`Unowned or expired source exception: ${entry.pattern}`); + } + } +} + +/** Parse script content with its actual syntax kind; Svelte markup is handled by framework checks. */ +export function parseUnits(path, text) { + if (path.endsWith('.svelte')) { + return [...text.matchAll(/]*)>([\s\S]*?)<\/script\s*>/g)].map( + (match, index) => ({ + suffix: `script${index}`, + ast: ts.createSourceFile( + path, + match[2], + ts.ScriptTarget.Latest, + true, + /lang\s*=\s*["']ts["']/.test(match[1]) + ? ts.ScriptKind.TS + : ts.ScriptKind.JS, + ), + }), + ); + } + const kind = path.endsWith('.tsx') + ? ts.ScriptKind.TSX + : path.endsWith('.jsx') + ? ts.ScriptKind.JSX + : /\.[cm]?ts$/.test(path) + ? ts.ScriptKind.TS + : ts.ScriptKind.JS; + return [ + { + suffix: '', + ast: ts.createSourceFile(path, text, ts.ScriptTarget.Latest, true, kind), + }, + ]; +} + +/** Compare parsed semantic tokens, including template segments, without treating comments or optional trailing commas as method edits. */ +function functionFingerprint(node, ast) { + const tokens = []; + /** Traverse lexical tokens rather than rescanning text, so template-expression context remains accurate. */ + function visit(current) { + if ( + current.kind >= ts.SyntaxKind.FirstJSDocNode && + current.kind <= ts.SyntaxKind.LastJSDocNode + ) + return; + const children = current.getChildren(ast); + if (children.length) { + for (const child of children) visit(child); + return; + } + if (current.kind === ts.SyntaxKind.SyntaxList) return; + const value = + ts.isStringLiteralLike(current) || + ts.isTemplateHead(current) || + ts.isTemplateMiddle(current) || + ts.isTemplateTail(current) + ? current.text + : current.getText(ast); + tokens.push([current.kind, value]); + } + visit(node); + const meaningful = tokens.filter(([kind], index) => { + if (kind !== ts.SyntaxKind.CommaToken) return true; + const next = tokens[index + 1]?.[0]; + if (next === ts.SyntaxKind.CloseBracketToken) { + // Array elisions change length and must never be treated as formatting. + const previous = tokens[index - 1]?.[0]; + return [ + ts.SyntaxKind.CommaToken, + ts.SyntaxKind.OpenBracketToken, + ].includes(previous); + } + return ![ + ts.SyntaxKind.CloseParenToken, + ts.SyntaxKind.CloseBraceToken, + ].includes(next); + }); + return digest(JSON.stringify(meaningful)); +} + +/** Identify a call chain without embedding mutable arguments or comments into callback ownership. */ +function lexicalCall(node, ast) { + if ( + ts.isParenthesizedExpression(node) || + ts.isAsExpression(node) || + ts.isNonNullExpression(node) + ) + return lexicalCall(node.expression, ast); + if (ts.isCallExpression(node) || ts.isNewExpression(node)) + return `${lexicalCall(node.expression, ast)}()`; + if (ts.isPropertyAccessExpression(node)) + return `${lexicalCall(node.expression, ast)}.${node.name.text}`; + if (ts.isElementAccessExpression(node)) { + const key = ts.isStringLiteralLike(node.argumentExpression) + ? node.argumentExpression.text + : ''; + return `${lexicalCall(node.expression, ast)}[${key}]`; + } + return ts.isIdentifier(node) ? node.text : ''; +} + +/** Identify callbacks by their lexical owner, not their position among unrelated functions. */ +function lexicalScope(node, ast) { + const owners = []; + for (let current = node.parent; current; current = current.parent) { + if (ts.isFunctionLike(current) || ts.isClassLike(current)) { + const name = current.name ?? current.parent?.name; + if (name) owners.push(name.getText(ast)); + } else if (ts.isCallExpression(current)) { + owners.push(lexicalCall(current.expression, ast)); + } + } + return owners.reverse().join('/'); +} + +/** Resolve a function's meaningful enclosing declaration for stable identity and adjacent documentation. */ +function declaration(node) { + let owner = node; + if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) { + if (ts.isVariableDeclaration(node.parent)) { + owner = node.parent.parent.parent; + } else if ( + ts.isPropertyAssignment(node.parent) || + ts.isPropertyDeclaration(node.parent) + ) { + owner = node.parent; + } + } + return owner; +} + +/** Read adjacent callback docs through casts/assignments, stopping at its own statement or enclosing function. */ +function callbackComments(node, ast) { + const comments = []; + let current = node; + while (current) { + if (current !== node && ts.isFunctionLike(current)) break; + const trivia = ast.text.slice( + current.getFullStart(), + current.getStart(ast), + ); + comments.push(...(trivia.match(/\/\*[\s\S]*?\*\/|\/\/[^\r\n]*/g) ?? [])); + if (ts.isStatement(current)) break; + current = current.parent; + } + return comments; +} + +/** Identify source syntax failures without conflating analyzer, configuration or I/O errors. */ +class SourceParseError extends SyntaxError {} + +/** Extract all implemented functions, including private methods, factories and substantive callbacks. */ +export function functionsIn(path, text) { + const functions = []; + for (const { suffix, ast } of parseUnits(path, text)) { + if (ast.parseDiagnostics.length) + throw new SourceParseError( + `Cannot parse ${path}: ${ast.parseDiagnostics[0].messageText}`, + ); + const visit = (node) => { + if (ts.isFunctionLike(node) && node.body) { + const owner = declaration(node); + const name = + node.name?.getText(ast) ?? + node.parent.name?.getText(ast) ?? + ''; + const ranges = + ts.getLeadingCommentRanges(ast.text, owner.getFullStart()) ?? []; + const comments = ranges.map((range) => + ast.text.slice(range.pos, range.end), + ); + const parentComments = + node.parent && ts.isCallExpression(node.parent) + ? ( + ts.getLeadingCommentRanges( + ast.text, + node.parent.parent.getFullStart(), + ) ?? [] + ).map((range) => ast.text.slice(range.pos, range.end)) + : []; + functions.push({ + key: `${suffix}:${lexicalScope(node, ast)}:${name}`, + signature: functionFingerprint(node, ast), + name, + comments: [ + ...comments, + ...parentComments, + ...(name === '' ? callbackComments(node, ast) : []), + ], + line: ast.getLineAndCharacterOfPosition(node.getStart(ast)).line + 1, + callback: name === '', + // An expression-only projection has no independent scenario; its enclosing function is documented. + trivialCallback: + name === '' && + !ts.isBlock(node.body) && + node.body.getText(ast).length < 80 && + !/await|throw|fetch|\bnew\b/.test(node.body.getText(ast)), + }); + } + ts.forEachChild(node, visit); + }; + visit(ast); + } + return functions; +} + +/** Invalid historical syntax earns no unchanged-function allowance; every current function must satisfy the documentation contract. */ +function historicalFunctions(path, text) { + if (text === null) return []; + try { + return functionsIn(path, text); + } catch (error) { + if (error instanceof SourceParseError) return []; + throw error; + } +} + +/** Yield parsed lexical leaves without descending into documentation or splitting literal/JSX content. */ +function* syntaxTokens(node, ast) { + if ( + (node.kind >= ts.SyntaxKind.FirstJSDocNode && + node.kind <= ts.SyntaxKind.LastJSDocNode) || + node.kind === ts.SyntaxKind.JSDocComment + ) + return; + const children = node.getChildren(ast); + if (children.length) { + for (const child of children) yield* syntaxTokens(child, ast); + } else if (node.kind !== ts.SyntaxKind.SyntaxList) { + yield node; + } +} + +/** Scan only trivia between parsed tokens; interpolation expressions retain comments while template/regex/JSX bodies stay opaque. */ +function* sourceComments(ast) { + let end = 0; + for (const token of syntaxTokens(ast, ast)) { + const start = token.getStart(ast); + const scanner = ts.createScanner( + ts.ScriptTarget.Latest, + false, + ts.LanguageVariant.Standard, + ast.text.slice(end, start), + ); + for ( + let trivia = scanner.scan(); + trivia !== ts.SyntaxKind.EndOfFileToken; + trivia = scanner.scan() + ) { + if ( + ![ + ts.SyntaxKind.SingleLineCommentTrivia, + ts.SyntaxKind.MultiLineCommentTrivia, + ].includes(trivia) + ) + continue; + yield scanner.getTokenText(); + } + end = token.end; + } +} + +/** Identify suppression directives in comments only, never in strings or generated documentation examples. */ +export function suppressionErrors(path, text, config) { + const errors = []; + for (const { ast } of parseUnits(path, text)) { + for (const comment of sourceComments(ast)) { + if ( + /@ts-(?:ignore|nocheck)\b/.test(comment) || + /eslint-disable(?!-next-line|-line)\b/.test(comment) + ) { + errors.push(`${path}: broad lint/type suppression is forbidden`); + } + if ( + /eslint-disable(?:-next-line|-line)\b/.test(comment) && + !/eslint-disable(?:-next-line|-line)\s+[\w@/-]+(?:\s*,\s*[\w@/-]+)*\s+--\s+.{12,}/.test( + comment, + ) + ) { + errors.push( + `${path}: suppression must name rules and explain the scoped exception`, + ); + } + if ( + /@ts-expect-error\b/.test(comment) && + (!/@ts-expect-error\s*:?\s+.{12,}/.test(comment) || + !matches(path, config.negativeTypeTests ?? [])) + ) { + errors.push( + `${path}: @ts-expect-error requires an explained negative type-test scope`, + ); + } + } + } + return errors; +} + +/** Enforce complete authored-file coverage plus documentation on changed functions and pilot trees. */ +export function runGuards(config, base) { + validateConfig(config); + verifyTemplate(base); + const changed = new Set(changedFiles(base)); + const allFiles = [...new Set([...trackedFiles(), ...changed])]; + const generated = (config.generated ?? []).map((entry) => entry.pattern); + const excluded = (config.excluded ?? []).map((entry) => entry.pattern); + const errors = []; + let checked = 0; + for (const path of allFiles.filter((path) => sourcePattern.test(path))) { + if (path.startsWith('tools/quality/')) continue; // Versioned template has its own tests and documented API. + if (matches(path, [...generated, ...excluded])) continue; + if ( + !config.sourceRoots.some( + (root) => + root === '.' || + path === root || + path.startsWith(`${root.replace(/\/$/, '')}/`), + ) + ) { + errors.push(`${path}: authored file has no declared source root`); + continue; + } + const text = currentFile(path); + if (text === null) continue; + checked++; + const full = matches(path, config.comments?.full); + if (!changed.has(path) && !full) continue; + errors.push(...suppressionErrors(path, text, config)); + if ( + matches( + path, + (config.comments?.exclude ?? []).map((entry) => entry.pattern), + ) + ) + continue; + const before = baseFile(base, path); + const previous = new Map(); + for (const fn of historicalFunctions(path, before)) { + const identity = `${fn.key}:${fn.signature}`; + previous.set(identity, (previous.get(identity) ?? 0) + 1); + } + for (const fn of functionsIn(path, text)) { + const identity = `${fn.key}:${fn.signature}`; + const remaining = previous.get(identity) ?? 0; + if (remaining > 0) previous.set(identity, remaining - 1); + if ((!full && remaining > 0) || fn.trivialCallback) continue; + const docs = fn.comments + .filter((comment) => fn.callback || comment.startsWith('/**')) + .join('\n'); + const words = docs + .replace(/\{@[^}]+\}|\{[^}]+\}|\*|\//g, ' ') + .trim() + .split(/\s+/); + if (words.length < 3 || docs.length < 18) + errors.push( + `${path}:${fn.line}: document ${fn.name}'s purpose and contract`, + ); + } + } + if (checked === 0 && config.profile !== 'D') + errors.push('No authored JS/TS/Svelte files were checked'); + return { checked, errors }; +} diff --git a/tools/quality/lib/historical.mjs b/tools/quality/lib/historical.mjs new file mode 100644 index 0000000..29ba0a2 --- /dev/null +++ b/tools/quality/lib/historical.mjs @@ -0,0 +1,139 @@ +import { + cpSync, + existsSync, + mkdirSync, + mkdtempSync, + readFileSync, + rmSync, + symlinkSync, + writeFileSync, +} from 'node:fs'; +import { dirname, join, resolve } from 'node:path'; +import { tmpdir } from 'node:os'; +import { execute, git } from './git.mjs'; +import picomatch from 'picomatch'; + +/** Omit only new entry/project targets that cannot exist in the historical source being measured. */ +function historicalPatterns(value, prefix, currentPaths, basePaths) { + const patterns = typeof value === 'string' ? [value] : value; + if (!Array.isArray(patterns)) return value; + return patterns.filter((pattern) => { + if (typeof pattern !== 'string' || pattern.startsWith('!')) return true; + const match = picomatch( + join(prefix, pattern.replace(/!$/, '')).replaceAll('\\', '/'), + { dot: true }, + ); + return ( + basePaths.some((path) => match(path)) || + !currentPaths.some((path) => match(path)) + ); + }); +} + +/** Keep current Knip policy but remove newly introduced tooling-only roots from historical coverage. */ +function prepareHistoricalKnip(path, currentPaths, basePaths) { + if (!path.endsWith('.json') || !existsSync(path)) return; + const config = JSON.parse(readFileSync(path, 'utf8')); + // The sealed vendor snapshot is new during initial adoption. Its current-only + // import roots are removed below, so this exact exemption would otherwise be stale. + if ( + !basePaths.some((path) => path.startsWith('tools/quality/')) && + Array.isArray(config.ignore) + ) { + config.ignore = config.ignore.filter( + (pattern) => pattern !== 'tools/quality/**', + ); + } + const scopes = [['.', config], ...Object.entries(config.workspaces ?? {})]; + for (const [prefix, scope] of scopes) { + if (!scope || typeof scope !== 'object') continue; + for (const key of ['entry', 'project']) { + if (scope[key]) + scope[key] = historicalPatterns( + scope[key], + prefix, + currentPaths, + basePaths, + ); + } + } + writeFileSync(path, `${JSON.stringify(config, null, 2)}\n`); +} + +/** Re-run the same analyzer against trusted source with the newly adopted analysis configuration. */ +export function historicalAnalysis(base, config, templateDirectory, analyze) { + const current = process.cwd(); + const snapshot = mkdtempSync(join(tmpdir(), '1msg-quality-base-')); + const archiveDirectory = mkdtempSync(join(tmpdir(), '1msg-quality-archive-')); + try { + const archivePath = join(archiveDirectory, 'source.tar'); + const archive = execute('git', [ + 'archive', + '--format=tar', + '--output', + archivePath, + base, + ]); + if (archive.status !== 0) + throw new Error(`Cannot read trusted source: ${archive.stderr}`); + const extract = execute('tar', ['-xf', archivePath, '-C', snapshot]); + if (extract.status !== 0) + throw new Error(`Cannot unpack trusted source: ${extract.stderr}`); + const paths = git(['ls-files', '-co', '--exclude-standard', '-z']) + .split('\0') + .filter(Boolean); + const basePaths = git(['ls-tree', '-r', '--name-only', '-z', base]) + .split('\0') + .filter(Boolean); + // Some legacy multi-package repos adopt their first root manifest with the quality tooling. + // Findings on this new manifest still cannot become debt: initialEvidence requires a base file. + if ( + !existsSync(join(snapshot, 'package.json')) && + existsSync('package.json') + ) { + cpSync('package.json', join(snapshot, 'package.json')); + } + const configuration = paths.filter((path) => + /(?:^|\/)(?:eslint(?:\.[\w-]+)?\.config\.[cm]?js|dependency-cruiser(?:\.[\w-]+)?\.config\.[cm]?js|jest(?:\.[\w-]+)?\.config\.[cm]?[jt]s|tsconfig(?:\.[\w-]+)?\.json|quality\.config\.mjs)$/.test( + path, + ), + ); + configuration.push(config.knipConfig ?? 'knip.json'); + for (const path of new Set(configuration)) { + if (!existsSync(path)) continue; + mkdirSync(dirname(join(snapshot, path)), { recursive: true }); + cpSync(path, join(snapshot, path)); + } + prepareHistoricalKnip( + join(snapshot, config.knipConfig ?? 'knip.json'), + paths, + basePaths, + ); + // Dependencies are analyzer inputs; historical application source always comes from Git above. + const packages = new Set([ + '.', + ...paths.filter((path) => path.endsWith('/package.json')).map(dirname), + ]); + for (const path of packages) { + const modules = resolve(current, path, 'node_modules'); + const destination = join(snapshot, path, 'node_modules'); + if (!existsSync(modules) || existsSync(destination)) continue; + mkdirSync(dirname(destination), { recursive: true }); + symlinkSync(modules, destination, 'dir'); + } + const destination = join(snapshot, 'tools/quality'); + rmSync(destination, { recursive: true, force: true }); + mkdirSync(dirname(destination), { recursive: true }); + symlinkSync(templateDirectory, destination, 'dir'); + process.chdir(snapshot); + const historicalConfig = { + ...config, + duplicatePaths: config.duplicatePaths?.filter((path) => existsSync(path)), + }; + return analyze(historicalConfig); + } finally { + process.chdir(current); + rmSync(snapshot, { recursive: true, force: true }); + rmSync(archiveDirectory, { recursive: true, force: true }); + } +} diff --git a/tools/quality/lib/knip-reporter.mjs b/tools/quality/lib/knip-reporter.mjs new file mode 100644 index 0000000..87999ef --- /dev/null +++ b/tools/quality/lib/knip-reporter.mjs @@ -0,0 +1,42 @@ +import jsonReporter from '../node_modules/knip/dist/reporters/json.js'; + +/** Reject incomplete Knip graphs before emitting the pinned version's standard JSON report. */ +export default async function qualityReporter(options) { + if (options.hasConfigLoadErrors || options.counters.processed === 0) { + throw new Error( + 'Knip failed to load configuration or analyzed an empty graph', + ); + } + for (const required of [ + 'files', + 'exports', + 'dependencies', + 'unlisted', + 'unresolved', + ]) { + if (!options.report[required]) + throw new Error(`Mandatory Knip issue type disabled: ${required}`); + } + const incomplete = options.configurationHints.filter((hint) => + [ + 'entry-empty', + 'project-empty', + 'project-extension-unregistered', + 'project-extension-excluded', + 'workspace-unconfigured', + 'top-level-unconfigured', + 'ignore', + 'ignoreFiles', + 'ignoreBinaries', + 'ignoreDependencies', + 'ignoreUnresolved', + 'ignoreWorkspaces', + ].includes(hint.type), + ); + if (incomplete.length) { + throw new Error( + `Knip coverage/stale exclusion failure: ${incomplete.map((hint) => `${hint.type}:${hint.identifier}`).join(', ')}`, + ); + } + await jsonReporter(options); +} diff --git a/tools/quality/lib/reports.mjs b/tools/quality/lib/reports.mjs new file mode 100644 index 0000000..4cec53b --- /dev/null +++ b/tools/quality/lib/reports.mjs @@ -0,0 +1,581 @@ +import { relative, isAbsolute } from 'node:path'; +import { existsSync } from 'node:fs'; +import ts from 'typescript'; +import { currentFile } from './git.mjs'; +import { digest, record } from './baseline.mjs'; + +/** Convert report paths to portable repository paths; external paths are not silently accepted. */ +export function repoPath(path) { + if (typeof path !== 'string' || !path) + throw new Error('Analyzer returned a missing file path'); + const normalized = (isAbsolute(path) ? relative(process.cwd(), path) : path) + .replaceAll('\\', '/') + .replace(/^\.\//, ''); + if (normalized === '..' || normalized.startsWith('../')) + throw new Error(`Analyzer escaped repository: ${path}`); + return normalized; +} + +/** Preserve all enabled Knip issue categories and distinguish separate symbols in the same file. */ +export function knipRecords(report) { + if (!report || !Array.isArray(report.issues)) + throw new Error('Invalid Knip JSON schema'); + const results = []; + for (const row of report.issues) { + const path = repoPath(row.file); + for (const [type, issues] of Object.entries(row)) { + if (['file', 'owners'].includes(type)) continue; + if (!Array.isArray(issues)) + throw new Error(`Invalid Knip category: ${type}`); + const grouped = new Map(); + for (const issue of issues) { + const symbols = (Array.isArray(issue) ? issue : [issue]).map( + (item) => item.name ?? item.symbol, + ); + if (symbols.some((symbol) => typeof symbol !== 'string')) + throw new Error(`Invalid Knip symbol: ${path}/${type}`); + const symbol = symbols.sort().join(','); + grouped.set(symbol, (grouped.get(symbol) ?? 0) + 1); + } + for (const [symbol, count] of grouped) + results.push( + record(`${path}|${type}|${symbol}`, count, { + path, + rule: type, + symbol, + }), + ); + } + } + return results.sort((a, b) => a.key.localeCompare(b.key)); +} + +/** Normalize token evidence without stripping string values or treating comments as meaningful duplicates. */ +export function tokenFingerprint(fragment) { + const scanner = ts.createScanner( + ts.ScriptTarget.Latest, + true, + ts.LanguageVariant.JSX, + fragment, + ); + const tokens = []; + for ( + let token = scanner.scan(); + token !== ts.SyntaxKind.EndOfFileToken; + token = scanner.scan() + ) { + tokens.push([token, scanner.getTokenText()]); + } + return digest(JSON.stringify(tokens)); +} + +/** Parse actual dependency-cruiser output; only pre-existing runtime cycles may be tracked as debt. */ +export function architectureRecords(report) { + if ( + !Array.isArray(report?.modules) || + !report.modules.length || + !report.summary?.totalCruised || + !Array.isArray(report.summary.violations) + ) + throw new Error('dependency-cruiser returned invalid/empty coverage'); + const cycles = new Map(); + for (const violation of report.summary.violations) { + if ( + violation.type !== 'cycle' || + violation.rule?.name !== 'no-runtime-cycles' || + !Array.isArray(violation.cycle) || + !violation.cycle.length + ) { + throw new Error( + `Non-baselinable architecture violation: ${violation.rule?.name}: ${violation.from} -> ${violation.to}`, + ); + } + const members = violation.cycle.map((member) => repoPath(member.name)); + const rotations = members.map((_, index) => + [...members.slice(index), ...members.slice(0, index)].join(' -> '), + ); + const key = `no-runtime-cycles|${rotations.sort()[0]}`; + cycles.set( + key, + record(key, 1, { + rule: 'no-runtime-cycles', + paths: [...new Set(members)].sort(), + }), + ); + } + return [...cycles.values()].sort((a, b) => a.key.localeCompare(b.key)); +} + +/** Resolve jscpd's embedded Svelte fragments to an existing source while retaining their language identity. */ +function duplicateSource(path) { + const participant = repoPath(path); + const embedded = + /^(.*\.svelte):(html|css|scss|sass|less|stylus|javascript|typescript|jsx|tsx)$/.exec( + participant, + ); + if (!embedded) { + if (/\.svelte:/.test(participant)) + throw new Error(`Unknown Svelte clone fragment: ${participant}`); + return { path: participant, participant, embedded: false }; + } + const source = embedded[1]; + if (!existsSync(source)) + throw new Error(`Missing Svelte clone source: ${source}`); + return { path: source, participant, embedded: true }; +} + +/** Identify clone groups by normalized code and participants, so unrelated unique code cannot dilute violations. */ +export function duplicateRecords(report) { + if ( + !report || + !Array.isArray(report.duplicates) || + !report.statistics?.total?.sources + ) { + throw new Error('jscpd report is missing or has empty source coverage'); + } + const grouped = new Map(); + for (const clone of report.duplicates) { + const first = duplicateSource(clone.firstFile?.name); + const second = duplicateSource(clone.secondFile?.name); + let fragment = clone.fragment; + if (typeof fragment !== 'string') { + if (first.embedded || second.embedded) + throw new Error('jscpd omitted embedded fragment evidence'); + const source = currentFile(first.path); + if ( + source === null || + !Number.isInteger(clone.firstFile.start) || + !Number.isInteger(clone.firstFile.end) + ) { + throw new Error('jscpd omitted clone evidence'); + } + fragment = source + .split(/\r?\n/) + .slice(clone.firstFile.start - 1, clone.firstFile.end) + .join('\n'); + } + const fingerprint = `${clone.format}|${tokenFingerprint(fragment)}`; + const group = grouped.get(fingerprint) ?? { + paths: new Set(), + participants: new Set(), + pairs: 0, + tokens: 0, + }; + group.paths.add(first.path); + group.paths.add(second.path); + group.participants.add(first.participant); + group.participants.add(second.participant); + group.pairs++; + group.tokens = Math.max(group.tokens, clone.tokens ?? 0); + grouped.set(fingerprint, group); + } + return [...grouped] + .map(([fingerprint, group]) => { + const paths = [...group.paths].sort(); + const participants = [...group.participants].sort(); + return record(`${fingerprint}|${participants.join('|')}`, group.pairs, { + paths, + ...(participants.some((path) => /\.svelte:/.test(path)) + ? { participants } + : {}), + tokens: group.tokens, + }); + }) + .sort((a, b) => a.key.localeCompare(b.key)); +} + +/** Fingerprint parsed syntax without comments, retaining literal and template text that can change callback behavior. */ +function syntaxFingerprint(node, source) { + const tokens = []; + /** Preserve parser token boundaries, including template substitutions, instead of rescanning a context-free fragment. */ + function visit(current) { + if ( + current.kind >= ts.SyntaxKind.FirstJSDocNode && + current.kind <= ts.SyntaxKind.LastJSDocNode + ) + return; + const children = current.getChildren(source); + if (children.length) { + for (const child of children) visit(child); + } else if (current.kind !== ts.SyntaxKind.SyntaxList) { + tokens.push([current.kind, current.getText(source)]); + } + } + visit(node); + return digest(JSON.stringify(tokens)); +} + +/** Identify a callable expression without incorporating the bodies or mutable arguments of other callbacks in its chain. */ +function callTarget(node, source) { + if ( + ts.isParenthesizedExpression(node) || + ts.isAsExpression(node) || + ts.isTypeAssertionExpression(node) || + ts.isNonNullExpression(node) || + ts.isSatisfiesExpression(node) + ) + return callTarget(node.expression, source); + if (ts.isIdentifier(node)) return ['identifier', node.text]; + if (node.kind === ts.SyntaxKind.ThisKeyword) return ['this']; + if (node.kind === ts.SyntaxKind.SuperKeyword) return ['super']; + if (ts.isPropertyAccessExpression(node)) + return ['member', callTarget(node.expression, source), node.name.text]; + if (ts.isElementAccessExpression(node)) + return [ + 'element', + callTarget(node.expression, source), + syntaxFingerprint(node.argumentExpression, source), + ]; + if (ts.isCallExpression(node) || ts.isNewExpression(node)) + return [ts.SyntaxKind[node.kind], callTarget(node.expression, source)]; + if (ts.isFunctionLike(node)) + return [ + ts.SyntaxKind[node.kind], + node.name?.getText(source) ?? '', + ]; + return ['expression', syntaxFingerprint(node, source)]; +} + +/** Keep ordinary binding names readable while preserving computed and destructured names without formatting-sensitive text. */ +function ownerName(node, source) { + if (ts.isIdentifier(node) || ts.isPrivateIdentifier(node)) return node.text; + if (ts.isStringLiteralLike(node) || ts.isNumericLiteral(node)) + return ['literal', node.text]; + return ['computed', syntaxFingerprint(node, source)]; +} + +/** Include named owners, lexical loop bindings and call argument positions without source lines or diagnostic order. */ +function lexicalOwners(node, source) { + const owners = []; + let child; + for ( + let current = node; + current && !ts.isSourceFile(current); + current = current.parent + ) { + if (ts.isForOfStatement(current) || ts.isForInStatement(current)) { + owners.push([ + ts.SyntaxKind[current.kind], + syntaxFingerprint(current.initializer, source), + syntaxFingerprint(current.expression, source), + ts.isForOfStatement(current) && current.awaitModifier + ? 'await' + : 'sync', + child === current.statement ? 'body' : 'header', + ]); + } else if (ts.isForStatement(current)) { + owners.push([ + ts.SyntaxKind[current.kind], + current.initializer + ? syntaxFingerprint(current.initializer, source) + : null, + current.condition ? syntaxFingerprint(current.condition, source) : null, + current.incrementor + ? syntaxFingerprint(current.incrementor, source) + : null, + child === current.statement ? 'body' : 'header', + ]); + } else if (ts.isCallExpression(current) || ts.isNewExpression(current)) { + const argument = current.arguments?.indexOf(child) ?? -1; + owners.push([ + ts.SyntaxKind[current.kind], + callTarget(current.expression, source), + argument < 0 ? 'callee' : argument, + ]); + } else if ( + ts.isBinaryExpression(current) && + current.operatorToken.kind >= ts.SyntaxKind.FirstAssignment && + current.operatorToken.kind <= ts.SyntaxKind.LastAssignment + ) { + owners.push(['assignment', callTarget(current.left, source)]); + } else if (ts.isFunctionLike(current) || ts.isClassLike(current)) { + owners.push([ + ts.SyntaxKind[current.kind], + current.name ? ownerName(current.name, source) : '', + current.modifiers?.some( + (modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword, + ) + ? 'static' + : 'instance', + ]); + } else if (current.name) { + owners.push([ + ts.SyntaxKind[current.kind], + ownerName(current.name, source), + ]); + } else if ( + ts.isJsxOpeningElement(current) || + ts.isJsxSelfClosingElement(current) + ) { + owners.push(['jsx', current.tagName.getText(source)]); + } + child = current; + } + return owners.reverse(); +} + +/** Recognize independently reported nesting nodes; sibling blocks must not share a function's depth allowance. */ +function isDepthScope(node) { + return [ + ts.SyntaxKind.IfStatement, + ts.SyntaxKind.ForStatement, + ts.SyntaxKind.ForInStatement, + ts.SyntaxKind.ForOfStatement, + ts.SyntaxKind.WhileStatement, + ts.SyntaxKind.DoStatement, + ts.SyntaxKind.SwitchStatement, + ts.SyntaxKind.TryStatement, + ts.SyntaxKind.WithStatement, + ].includes(node.kind); +} + +/** Identify a control-flow child by its semantic role, never its position among statements. */ +function branchRole(parent, child) { + if (ts.isIfStatement(parent) || ts.isConditionalExpression(parent)) { + if (child === (parent.thenStatement ?? parent.whenTrue)) return 'then'; + if (child === (parent.elseStatement ?? parent.whenFalse)) return 'else'; + return 'condition'; + } + if (ts.isTryStatement(parent)) { + if (child === parent.tryBlock) return 'try'; + if (child === parent.catchClause) return 'catch'; + return 'finally'; + } + if (ts.isCatchClause(parent)) + return child === parent.block ? 'body' : 'binding'; + if (ts.isCaseClause(parent)) + return child === parent.expression ? 'case-value' : 'case-body'; + if (ts.isDefaultClause(parent)) return 'default-body'; + if (ts.isSwitchStatement(parent)) + return child === parent.caseBlock ? 'cases' : 'expression'; + if (isDepthScope(parent)) + return child === parent.statement ? 'body' : 'header'; + return 'block'; +} + +/** Collect parsed enclosing branches only for otherwise indistinguishable peers; literal values and then/else roles remain evidence. */ +function structuralContext(node, source) { + const contexts = []; + let child = node; + for ( + let parent = node.parent; + parent && !ts.isSourceFile(parent); + parent = parent.parent + ) { + if ( + ts.isBlock(parent) || + isDepthScope(parent) || + ts.isConditionalExpression(parent) || + ts.isCatchClause(parent) || + ts.isCaseClause(parent) || + ts.isDefaultClause(parent) + ) { + contexts.push([ + ts.SyntaxKind[parent.kind], + branchRole(parent, child), + syntaxFingerprint(parent, source), + ]); + } + child = parent; + } + return contexts; +} + +/** Find the shortest unique ancestor prefix among equal bodies; completely equal ancestry still has no safe correspondence. */ +function distinctContexts(nodes, fingerprints, source) { + const contexts = nodes.map( + /** Avoid introducing contextual identities for a body already distinguished by its own syntax. */ + (node, index) => + fingerprints.indexOf(fingerprints[index]) === + fingerprints.lastIndexOf(fingerprints[index]) + ? [] + : structuralContext(node, source), + ); + return contexts.map( + /** Select the shortest semantic ancestor evidence that separates this body from its equal peers. */ ( + context, + index, + ) => { + const peers = fingerprints.flatMap((fingerprint, peer) => + fingerprint === fingerprints[index] && peer !== index ? [peer] : [], + ); + if (!peers.length) return null; + for (let length = 1; length <= context.length; length++) { + const candidate = JSON.stringify(context.slice(0, length)); + if ( + peers.every( + (peer) => + JSON.stringify(contexts[peer].slice(0, length)) !== candidate, + ) + ) + return candidate; + } + return null; + }, + ); +} + +/** Index all lexical scopes, including functions below lint thresholds, so disappearing diagnostics cannot renumber another allowance. */ +function scopeIdentities(source, depth = false) { + const groups = new Map(); + /** Inventory complete syntax before resolving any diagnostic, keeping below-threshold siblings in ambiguity decisions. */ + function visit(node) { + const included = depth + ? isDepthScope(node) + : (ts.isFunctionLike(node) && node.body) || + ts.isClassStaticBlockDeclaration(node) || + (ts.isPropertyDeclaration(node) && node.initializer); + if (included) { + const owners = lexicalOwners(node, source); + if (depth) owners.push(['nesting', ts.SyntaxKind[node.kind]]); + if (ts.isClassStaticBlockDeclaration(node)) owners.push(['static-block']); + const owner = JSON.stringify(owners); + const group = groups.get(owner) ?? []; + group.push(node); + groups.set(owner, group); + } + ts.forEachChild(node, visit); + } + visit(source); + const identities = new Map(); + for (const [owner, nodes] of groups) { + if (nodes.length === 1) { + identities.set(nodes[0], owner); + continue; + } + const fingerprints = nodes.map((node) => syntaxFingerprint(node, source)); + // Preserve source order in ambiguous groups: swapping a large and small body must not transfer the large allowance. + const group = digest(JSON.stringify(fingerprints)); + const contexts = distinctContexts(nodes, fingerprints, source); + const contextualGroup = digest( + JSON.stringify( + fingerprints.map((fingerprint, index) => [ + fingerprint, + contexts[index], + ]), + ), + ); + for (const [index, node] of nodes.entries()) { + const fingerprint = fingerprints[index]; + // A changed ambiguous group loses every old allowance; even matching another old body cannot borrow its budget. + identities.set( + node, + fingerprints.indexOf(fingerprint) === + fingerprints.lastIndexOf(fingerprint) + ? `${owner}|group:${group}|member:${fingerprint}` + : contexts[index] === null + ? null + : `${owner}|context-group:${contextualGroup}|member:${fingerprint}|context:${digest(contexts[index])}`, + ); + } + } + return identities; +} + +/** Resolve a diagnostic to its innermost inventoried owner; indistinguishable siblings and missing locations fail closed. */ +function scopeAt(source, identities, line, column) { + const offset = source.getPositionOfLineAndCharacter( + Math.max(0, line - 1), + Math.max(0, column - 1), + ); + let matched; + /** Select the innermost scope containing the reported token, never an unrelated neighboring declaration. */ + function visit(node) { + if (node.getStart(source) <= offset && node.end > offset) { + if (identities.has(node)) matched = node; + // ESLint complexity locates a named object property before its arrow/function initializer. + // Resolve only that direct callable initializer, never an unrelated neighboring function. + if ( + ts.isPropertyAssignment(node) && + ts.isFunctionLike(node.initializer) && + identities.has(node.initializer) && + offset >= node.name.getStart(source) && + offset < node.name.end + ) { + matched = node.initializer; + } + ts.forEachChild(node, visit); + } + } + visit(source); + if (!matched) + throw new Error( + `No lexical scope for ESLint diagnostic: ${source.fileName}:${line}:${column}`, + ); + const identity = identities.get(matched); + if (identity === null) + throw new Error( + `Ambiguous lexical scope for ESLint diagnostic: ${source.fileName}:${line}:${column}`, + ); + return identity; +} + +/** Only complexity diagnostics may use a debt baseline; parser, typed and correctness errors remain fatal. */ +export function eslintRecords(report) { + if (!Array.isArray(report) || report.length === 0) + throw new Error('ESLint returned empty source coverage'); + const allowed = new Set([ + 'complexity', + 'max-depth', + 'max-params', + 'max-lines', + 'max-lines-per-function', + 'sonarjs/cognitive-complexity', + ]); + const results = []; + for (const file of report) { + const path = repoPath(file.filePath); + if (!Array.isArray(file.messages)) throw new Error('Invalid ESLint report'); + if (file.messages.length === 0) continue; + const source = ts.createSourceFile( + path, + file.source ?? currentFile(path) ?? '', + ts.ScriptTarget.Latest, + true, + ); + if (source.parseDiagnostics.length) + throw new Error(`Invalid syntax in ESLint scope evidence: ${path}`); + const functions = scopeIdentities(source); + const depths = scopeIdentities(source, true); + const identities = new Set(); + for (const message of file.messages) { + if (message.fatal || !allowed.has(message.ruleId)) { + throw new Error( + `${path}: non-baselinable ${message.ruleId ?? 'parser'}: ${message.message}`, + ); + } + const metricPatterns = { + complexity: /complexity of (\d+)/i, + 'max-depth': /(?:nested too deeply|maximum allowed).*?\((\d+)\)/i, + 'max-params': /too many parameters \((\d+)\)/i, + 'max-lines': /too many lines \((\d+)\)/i, + 'max-lines-per-function': /too many lines \((\d+)\)/i, + 'sonarjs/cognitive-complexity': /complexity from (\d+)/i, + }; + const values = metricPatterns[message.ruleId].exec(message.message); + if (!values) + throw new Error(`No metric in ESLint diagnostic: ${message.message}`); + const scope = + message.ruleId === 'max-lines' + ? '' + : scopeAt( + source, + message.ruleId === 'max-depth' ? depths : functions, + message.line ?? 1, + message.column ?? 1, + ); + const identity = `${path}|${message.ruleId}|${scope}`; + if (identities.has(identity)) + throw new Error(`Duplicate ESLint diagnostic identity: ${identity}`); + identities.add(identity); + results.push( + record(identity, Number(values[1]), { + path, + rule: message.ruleId, + scope, + }), + ); + } + } + return results.sort((a, b) => a.key.localeCompare(b.key)); +} diff --git a/tools/quality/lib/template.mjs b/tools/quality/lib/template.mjs new file mode 100644 index 0000000..0a31562 --- /dev/null +++ b/tools/quality/lib/template.mjs @@ -0,0 +1,56 @@ +import { existsSync, readFileSync, readdirSync } from 'node:fs'; +import { join } from 'node:path'; +import { baseFile } from './git.mjs'; +import { digest } from './baseline.mjs'; + +/** Inventory all vendored files except installed dependencies; unexpected symlinks cannot hide source. */ +export function templateFiles(root, relative = '') { + return readdirSync(join(root, relative), { withFileTypes: true }) + .flatMap((entry) => { + const path = join(relative, entry.name).replaceAll('\\', '/'); + if (path === 'node_modules' || path === 'template-manifest.json') + return []; + if (entry.isSymbolicLink()) + throw new Error(`Untracked template symlink: ${path}`); + return entry.isDirectory() ? templateFiles(root, path) : [path]; + }) + .sort(); +} + +/** Keep the vendored exemption exact and require a new template version for changed preset contents. */ +export function verifyTemplate(base) { + const root = 'tools/quality'; + if (!existsSync(root)) return; // Standalone CLI fixtures exercise the runner outside a vendored checkout. + const manifestPath = `${root}/template-manifest.json`; + if (!existsSync(manifestPath)) + throw new Error( + 'Vendored quality template is missing its versioned inventory', + ); + const manifest = JSON.parse(readFileSync(manifestPath, 'utf8')); + const packageInfo = JSON.parse(readFileSync(`${root}/package.json`, 'utf8')); + if (manifest.schemaVersion !== 1 || manifest.version !== packageInfo.version) + throw new Error('Template version mismatch'); + const files = templateFiles(root); + if ( + JSON.stringify(files) !== JSON.stringify(Object.keys(manifest.files).sort()) + ) + throw new Error('Quality template has undeclared/missing files'); + for (const path of files) { + if ( + digest(readFileSync(`${root}/${path}`, 'utf8')) !== manifest.files[path] + ) + throw new Error(`Quality template integrity mismatch: ${path}`); + } + const previousText = baseFile(base, manifestPath); + if (previousText) { + const previous = JSON.parse(previousText); + if ( + previous.version === manifest.version && + JSON.stringify(previous.files) !== JSON.stringify(manifest.files) + ) { + throw new Error( + 'Quality template changed without an explicit version update', + ); + } + } +} diff --git a/tools/quality/package-lock.json b/tools/quality/package-lock.json new file mode 100644 index 0000000..bf75285 --- /dev/null +++ b/tools/quality/package-lock.json @@ -0,0 +1,6852 @@ +{ + "name": "@1msg/quality-template", + "version": "1.0.12", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@1msg/quality-template", + "version": "1.0.12", + "dependencies": { + "@eslint/js": "9.39.5", + "dependency-cruiser": "18.6.0", + "eslint": "9.39.5", + "eslint-import-resolver-typescript": "4.4.5", + "eslint-plugin-import": "2.32.0", + "eslint-plugin-n": "18.4.1", + "eslint-plugin-perfectionist": "5.12.1", + "eslint-plugin-react": "7.37.5", + "eslint-plugin-react-hooks": "7.1.1", + "eslint-plugin-sonarjs": "3.0.7", + "eslint-plugin-unicorn": "62.0.0", + "globals": "17.13.0", + "husky": "9.1.7", + "jscpd": "5.4.1", + "knip": "6.41.0", + "lint-staged": "16.2.7", + "picomatch": "4.0.7", + "prettier": "3.9.10", + "typescript": "5.9.3", + "typescript-eslint": "8.71.1" + }, + "engines": { + "node": "24.x" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.10.tgz", + "integrity": "sha512-EMCx3AGZ3WfAl6ht7AyQoPm2Lh+BGYEMdc4Q6Hf7uSCDOZFuLq44qNwL+iaim8VlyYhRAo4X43+weadK8ZB4Yg==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.9.tgz", + "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.10.tgz", + "integrity": "sha512-B3lYAs2nkKskbgQ1nfy8Ma9ao9Q1rntTAQHrzzyDuj+TSO+X3le6PfWwqDvodsb+OumE10eMFfuMCTQSQ5iuIQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.9", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.2.tgz", + "integrity": "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz", + "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.7.tgz", + "integrity": "sha512-F42g89Qd5oAWtp0k0nnSrjziAKza7w8SVT4mStc18LZMaRb4J1HQAHLCalEtDCxrTuksx7NU9qsmeLwpOfPqWw==", + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.3.2", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", + "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz", + "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==", + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.5.tgz", + "integrity": "sha512-HshSvXzmBxNzqejd3k/KemgQ3hdREUYFRRrgxOZ+gPljDIsO2SDZrVZMd4Z/HsxudQbE62OVyVFE8z9BCurfjA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4", + "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4" + } + }, + "node_modules/@oxc-parser/binding-android-arm-eabi": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.153.0.tgz", + "integrity": "sha512-BcWu25dMwMjHpaDCEidmpAi7rGg1qZoihJeUUH9bD55pVZ0z4Wa5CQgqSTo0R41H81oozisQKW3WqvAN2m77IQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-android-arm64": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.153.0.tgz", + "integrity": "sha512-9l5rdp2DhRqVriBHsNpu5cEf+hizZ4B58rt93HzyQEBUgZiC6qe2oFpaAAnXGCxHGnQExI1s7S2G0QhFacUZ6w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-darwin-arm64": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.153.0.tgz", + "integrity": "sha512-EcpsyRXHhENDpekpG4QNaSZj2F/BAz4Gh4o89zZwNss86R8KyRSQ6sXbAj74Xyeb4z3j/yBZZ6joQZhraIWyfw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-darwin-x64": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.153.0.tgz", + "integrity": "sha512-hlj80HUQy07/2lYp6rmxH+3u+H2ik3rjLR52CUdPApxmZCNxASDUf/+ykTzAHS/fehftmVMATKvPaWmuLHuasg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-freebsd-x64": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.153.0.tgz", + "integrity": "sha512-fWRcv2pMSh1qtez46MOu8vuUJ5fiaQZPHSphbWulbL7SHBMKfRgZl2PzjXZYQJbq7NEXyXbgIuIuUm+/Rmkv8w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-arm-gnueabihf": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.153.0.tgz", + "integrity": "sha512-paZeUK1GXShl/bOJQET1/8AQxayFeuN4SIWAkgTRxE7ZQwv9uYSB2n0648smygP22N7jcI3zxAm0Z+ALNiIKxg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-arm-musleabihf": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.153.0.tgz", + "integrity": "sha512-qFPp5NwMf4K1C0O+DCVGmcbOaYyYAq98Rvv9p4VSfb777iUwlJCqMUxf6QG9N5f5ls4TEX6LitOZHi+6GL6rYQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-arm64-gnu": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.153.0.tgz", + "integrity": "sha512-oufEhZCX7saeo27Logra8cvBR1jQ/yw2zUI2hHmWw3qA/XYqEW31FOvLQBv7DWN32NjVdlcaP11WBBZTJo4k9g==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-arm64-musl": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.153.0.tgz", + "integrity": "sha512-zXYzuAqng85h6+LI3iRm0zeMLX1/K2z41ZAMWxVRgt0D10VvZUaV5q+TEB46KDhoKBpdexoTLC6QoB/EiP2oqQ==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-ppc64-gnu": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.153.0.tgz", + "integrity": "sha512-J7+NLwLEzdkKM9cKyPHH/AjXXstWOs98KYgLrPPnO4N9MO8EZRBfPNnBcS3S67uMOBkRpUmCl2FhRnWdQ5CbBA==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-riscv64-gnu": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.153.0.tgz", + "integrity": "sha512-sD0K11GQTLWylln54nPMMTtgmBbQrR5It/vMpZpy/fogiw8O2AvIE+9LuWUXddrWk9zvFIHGRcSgFn4IHOfoYg==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-riscv64-musl": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.153.0.tgz", + "integrity": "sha512-7L66uql2BhvSz51LwfExjOdn6et/ydTiQxl23VApdKzJhTc3TczA1Qt6VR/UcvlQrL2ZbytIJb447vh7p5wmUw==", + "cpu": [ + "riscv64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-s390x-gnu": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.153.0.tgz", + "integrity": "sha512-hXV3T7mNyrPR19rbPYkglkQJtoM/UNo/xwbZeeqdAxEg8PXgb4LXXuxPpGgI4bzRRCWwLUxdDSS58xIyC2u1TA==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-x64-gnu": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.153.0.tgz", + "integrity": "sha512-Da8Vqs1xdtoDYtEjmozD7wGgJeLBQkMbR0WUBECOSxodyX5DXy8ySlvJWbukyO2Q0+TM9EK+4LT6tbq0jCg4hQ==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-linux-x64-musl": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.153.0.tgz", + "integrity": "sha512-zGAPxNTIIw6X5WyTRscIFE/oDjpdNtrrl32ing6NOXdGjzRucadnxBilexLdeYQ9YxixF93GujpXyQ0jw7ddSg==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-openharmony-arm64": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-openharmony-arm64/-/binding-openharmony-arm64-0.153.0.tgz", + "integrity": "sha512-GoHzpqP5XyPIp9DHokoEdCp+K4UPl/h1neFj1uXnUB3pJYyOQ7NOhFVOttNUgCGcj2eywAvu5cRivTOSq4S10g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-win32-arm64-msvc": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.153.0.tgz", + "integrity": "sha512-xGcy12tO9k7zFbeyQzEuilfWfQpyRq23/fLPfN3wjSWuWv58k46fQT1hsO1KFNykZuVGW9xSJE/z592TmAoSDA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-win32-ia32-msvc": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.153.0.tgz", + "integrity": "sha512-o1ykUjWncvXX6N5a4KebgLjtD8zRui+f1llMhSGoSC9oP2KOqapRpdwmZ3NcNG0axFouwVKmhGBjd+IhA8BksA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-win32-x64-msvc": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.153.0.tgz", + "integrity": "sha512-gxQz7G96Up136fd+2zWrP+o6FYGs9NO4Dyv55IoeJFJUDwLFHcLYY11hhA5wQKs0HoM57Q8esQ3nEVhnCdsjAQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.153.0.tgz", + "integrity": "sha512-jSNrRIyvPVLL5E1z/tS5zLAprosGz/FuI1PWwEOz59j3E4TTTzSpqKb/RDGqJhhW0QHYISGXxq582wGx6T11Tw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/oxc-project" + } + }, + "node_modules/@oxc-resolver/binding-android-arm-eabi": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-android-arm-eabi/-/binding-android-arm-eabi-11.24.2.tgz", + "integrity": "sha512-y09e0L0SRI2OA2tUIrjBgoV3eH5hvUKXNkJqXmNo5V2WxIjyC7I7aJfRLMEVpA8yi95f90gFDvO0VMgrDw+vwA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@oxc-resolver/binding-android-arm64": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-android-arm64/-/binding-android-arm64-11.24.2.tgz", + "integrity": "sha512-cl4icWaZFnLdg8m6qtnh5rBMuGbxc/ptStFHLeCNwr+2cZjkjNwQu/jYRS0CHlnPecOJMpuS5M6/BH+0J/YkEg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@oxc-resolver/binding-darwin-arm64": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-arm64/-/binding-darwin-arm64-11.24.2.tgz", + "integrity": "sha512-At29QEMF6HajbQvgY8K6OXnHD1x9rad74xBEfmCB6ZqCGsdq75aK7tOYcTbOanMy8qdIBrfL3SMr3p/lfSlb9w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oxc-resolver/binding-darwin-x64": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-x64/-/binding-darwin-x64-11.24.2.tgz", + "integrity": "sha512-A5Kqr1EUj4oIL5CF4WRssq/o5P0Y11cwoFouMRmQ7YnC/A8V93nv1nb7aSU8HwcgmXropjLNkVTl4MN87cu28Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oxc-resolver/binding-freebsd-x64": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-freebsd-x64/-/binding-freebsd-x64-11.24.2.tgz", + "integrity": "sha512-R5xkRBRRz7ceH/P5Jrc6G7FmdUdgpLYyESFAUDVTNQ9K0sGPxcp4ljiwEwEqsvNcQ4sYbMRrWcHHBCu7ksAJVw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@oxc-resolver/binding-linux-arm-gnueabihf": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-11.24.2.tgz", + "integrity": "sha512-k/RuYL4L/R58IBn3wT5ma3Wh4k62bp1eYCFRWCmMsasUOqL+H6sW0VGFadEzKWXFFlz+2uIMoeMk9ySSZJHgbg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-arm-musleabihf": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-11.24.2.tgz", + "integrity": "sha512-bnHAak3ujYfH5pKk4NieFNbvYvernfoQDgwLddbZ3OtMYrem87/qjlA+u+aKG0oZcqSLGCful/6/CEA+aeAgaA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-arm64-gnu": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-11.24.2.tgz", + "integrity": "sha512-vDT3KHgzYp47gmtNOqL2VNhCyl5Zv643eyxm//A68J8DeUGXrvD1pZFiaT4jSfe+RInfnn1R2yVHye4enx6RnA==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-arm64-musl": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-musl/-/binding-linux-arm64-musl-11.24.2.tgz", + "integrity": "sha512-+kMlQvbzfyEYtu5FcjE4p+ttBLpKW4d/AsAsuE69BxV6V4twZJeIQZFfD8gh/wqglY0MkPSezWXQH0jBV13MUw==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-ppc64-gnu": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-11.24.2.tgz", + "integrity": "sha512-shjfMhmZ3gq9fv/w7bi3PnZlgOPG+2QAOFf0BJF0EgBSIGZ6PMLN2zbGEblTUYB/NKVDRyYhE2ff3dJ1QqNPkA==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-riscv64-gnu": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-11.24.2.tgz", + "integrity": "sha512-zGelwFR5oRo+b69k8Lrzun86DyUHzfKN6cnjbR9l7Z7NIRznOE/2ZvPa1IUKqAL2PzAXOdwkfVqNvO1H2RlpAw==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-riscv64-musl": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-11.24.2.tgz", + "integrity": "sha512-qxZ1SWCXJY0eyhAlP6Lmo9F2Nrtx7EkYj9oCgL8apDPCwXwCEDA2U697bbT81JIc2IrVjxO4KX6WU2N+oN9Z4w==", + "cpu": [ + "riscv64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-s390x-gnu": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-11.24.2.tgz", + "integrity": "sha512-sGCecF3cx2DFlH4t/z7ApnOnXqN48p5p5mlHDEnHTAukQa2P+qMVE4CwyWE9W+q/m3QJ7kKfGrIjax31f44oFQ==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-x64-gnu": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-gnu/-/binding-linux-x64-gnu-11.24.2.tgz", + "integrity": "sha512-k/VlMMcSzMlahb3/fENM4rTlsJ0s3fFROA0KXPBmKggqmTSaE383sl8F3KCOXPLmVsYfW6hCitMhXCEtNeZxxg==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-x64-musl": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-musl/-/binding-linux-x64-musl-11.24.2.tgz", + "integrity": "sha512-8hbnZyNi97b/8wapYaIF9+t9GmZKBW2vunaOc3h9HGJptH7b7XpvZqOTBSm/MpTjr7H497BlgOaSfLUdhmy2bw==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-openharmony-arm64": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-openharmony-arm64/-/binding-openharmony-arm64-11.24.2.tgz", + "integrity": "sha512-MvyGik3a6pVgZ0t/kWlbmFxFLmXQJwgLsY2eYFHLpy0wGwRbfzeIGgDwQ3kXqE30z+kSXennRkCrT7TUvkptNg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@oxc-resolver/binding-wasm32-wasi": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-wasm32-wasi/-/binding-wasm32-wasi-11.24.2.tgz", + "integrity": "sha512-vHcssMPwO08RTvj/c0iOBz90attxyG3wQJ0dTcyEQK43LRpcdLWZlV5feBhv6Isn6ahbQIzHbCgfa81+RiML0Q==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.11.2", + "@emnapi/runtime": "1.11.2", + "@napi-rs/wasm-runtime": "^1.1.6" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-resolver/binding-win32-arm64-msvc": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-11.24.2.tgz", + "integrity": "sha512-uokJqro2iBqkFvJdKQLP7d8/BUmFwESQFVmIJUQKj1Xn1a/LysJoe1vmeECLF5b3jsV8CAL5sEMJXX6SdK9Nhg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@oxc-resolver/binding-win32-x64-msvc": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-x64-msvc/-/binding-win32-x64-msvc-11.24.2.tgz", + "integrity": "sha512-UqGPmo56KDfLlfXFAFIrNflHT8tFxWGEivWg3Zeyp4Uy2NlKN1FGPr6/BxcLGG3+kZ6Wp14g5Uj+n71boqZfiw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "license": "MIT" + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.4.tgz", + "integrity": "sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.71.1.tgz", + "integrity": "sha512-nNlBf6HuotqMgZvSkWD5hNdemiBIxQ2NmrlgfcUIeZRs+BbakjscCQRq/Hb74EFVnFiSWWdL12JruqwBy3ERDw==", + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.71.1", + "@typescript-eslint/type-utils": "8.71.1", + "@typescript-eslint/utils": "8.71.1", + "@typescript-eslint/visitor-keys": "8.71.1", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.71.1", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.71.1.tgz", + "integrity": "sha512-oM/5sAqz/l1v/zYK1qTOPrn2+JIrBGC1V6uNYucRO5gh6eT9vWJ/RhPbGE59byvZEUQ4VP6XkLBaS5Jti5jpvw==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.71.1", + "@typescript-eslint/types": "8.71.1", + "@typescript-eslint/typescript-estree": "8.71.1", + "@typescript-eslint/visitor-keys": "8.71.1", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.71.1.tgz", + "integrity": "sha512-Oijc9RUsohHjncg6iGi7gCtjnEjYt9FWv9u6ygK8uKcHK5eLjLAkqERQ9BaytbpceOFdk6kifPCS/zAZE+A99g==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.71.1", + "@typescript-eslint/types": "^8.71.1", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.71.1.tgz", + "integrity": "sha512-1YUDZXdTnXLlob03SFHBipdyMBsDVm7zoSz0ytTJ39dk5J1TgsTK03VlR/dLXG/RLLUrPcYbD4rp23BmHxHP0w==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.71.1", + "@typescript-eslint/visitor-keys": "8.71.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.71.1.tgz", + "integrity": "sha512-oTvkml5SxXhgg+WWKhod5qWQICDXtOB+/Hi9VdPKFAANJ2b7YOgMffgvzXuqog7R6A/JtrzRf128dsxummyWhg==", + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.71.1.tgz", + "integrity": "sha512-kH3t3jZCYv2PZSBEWPKTariLrCaoF1CLoPitYFBJOhAGEwWnSRAtGEifrfrpBa4K9JlwWNZotgA5w3/wLSk/FQ==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.71.1", + "@typescript-eslint/typescript-estree": "8.71.1", + "@typescript-eslint/utils": "8.71.1", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.71.1.tgz", + "integrity": "sha512-ybYnPTUwg3VQQOFEiBPLs8Jxl1ry2vXdn1kVKguomBbvxpetdu3MKTNDqFNUrlG8ylP9MpZosmXMFYlGQHk1oQ==", + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.71.1.tgz", + "integrity": "sha512-pSKSEK1JJpHs6KiKVtABCE4iJK5d7FLFzDXQNBQ2oRY7LEd3UwOt3TZemTgu9syTIf56dJWlTn/pdmrO9oKUXQ==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.71.1", + "@typescript-eslint/tsconfig-utils": "8.71.1", + "@typescript-eslint/types": "8.71.1", + "@typescript-eslint/visitor-keys": "8.71.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.8" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.71.1.tgz", + "integrity": "sha512-CBjT6gfAz3DW2j9Q4moFnqt208Aq+506sVGXfpRcyAeqn0EpayL0mjdWoCO2t3RC7GewNrFxdeehuEaPg6DMzQ==", + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.71.1", + "@typescript-eslint/types": "8.71.1", + "@typescript-eslint/typescript-estree": "8.71.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.71.1.tgz", + "integrity": "sha512-0GxiUGqMU0qXJt58cBsiG3DP8lUmBaFo2vChtUX+CT7PnR3v/VGLLrzVP4K9r1lNiZXjHYefMBbPunplr09v6w==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.71.1", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz", + "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz", + "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz", + "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz", + "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz", + "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz", + "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz", + "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz", + "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz", + "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz", + "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==", + "cpu": [ + "loong64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz", + "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==", + "cpu": [ + "loong64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz", + "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz", + "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz", + "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==", + "cpu": [ + "riscv64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz", + "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz", + "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz", + "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-openharmony-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz", + "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz", + "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", + "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz", + "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz", + "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/acorn": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz", + "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-jsx-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/acorn-jsx-walk/-/acorn-jsx-walk-2.0.0.tgz", + "integrity": "sha512-uuo6iJj4D4ygkdzd6jPtcxs8vZgDX9YFIkqczGImoypX2fQ4dVImmu3UzA4ynixCIMTrEOWW+95M2HuBaCEOVA==", + "license": "MIT" + }, + "node_modules/acorn-loose": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/acorn-loose/-/acorn-loose-8.5.2.tgz", + "integrity": "sha512-PPvV6g8UGMGgjrMu+n/f9E/tCSkNQ2Y97eFvuVdJfG11+xdIeDcLyNdC8SHcrHbRqkfwLASdplyR6B6sKM1U4A==", + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.4.0.tgz", + "integrity": "sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "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==", + "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-includes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.2.0.tgz", + "integrity": "sha512-VXY5eFRarnXcYxwBjJzPmEhH55+rmP79/+ueDhi0F+TuqfHCItagIHqxeUZrmgrOPa31QTh9H85DjX3FfJ0FTg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-object-atoms": "^1.1.2", + "es-shim-unscopables": "^1.1.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "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/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.28", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.28.tgz", + "integrity": "sha512-br0LOmjJqr6Rt4AEkadbcNf67Zpo7EPwKsWbjnRrJIa1QYFHQBqM4C7F2WTbV8ahTEcg1Eo+Y0aWjjORInYFyA==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz", + "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==", + "license": "MIT", + "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==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.29.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.3.tgz", + "integrity": "sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==", + "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" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.11.26", + "caniuse-lite": "^1.0.30001813", + "electron-to-chromium": "^1.5.439", + "node-releases": "^2.0.57", + "update-browserslist-db": "^1.3.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001815", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001815.tgz", + "integrity": "sha512-uDybUEyfgbyJJ93J1vikTylBX31AkdVYeVPeffMQpf8XN7hSfr0oZOn4VFOIMNvtU5+rHvC5Udg2TgtJKHm23Q==", + "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" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", + "license": "MIT" + }, + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/clean-regexp/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==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", + "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", + "license": "MIT", + "dependencies": { + "slice-ansi": "^8.0.0", + "string-width": "^8.2.0" + }, + "engines": { + "node": ">=20" + }, + "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==", + "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/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz", + "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==", + "license": "MIT", + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.50.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.50.0.tgz", + "integrity": "sha512-XGpFGbMLHwSt74YLTKho7Ib242qi6O8MSX+sRokV4oz7iKXvQWGYZthjIhjRGMxjzVkAubBO512dKGYcefmX3Q==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.7" + }, + "engines": { + "node": ">=6.4.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "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==", + "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==", + "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/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dependency-cruiser": { + "version": "18.6.0", + "resolved": "https://registry.npmjs.org/dependency-cruiser/-/dependency-cruiser-18.6.0.tgz", + "integrity": "sha512-It7NW5AmCDBCLMq7I91Nfu8VRKzrIE6S+M/FMQzALDceJ0B1PWRHo77q9YJg/HwyBBEWHVtOuTptIQki+xecOw==", + "license": "MIT", + "dependencies": { + "acorn": "8.19.0", + "acorn-jsx": "5.3.2", + "acorn-jsx-walk": "2.0.0", + "acorn-loose": "8.5.2", + "acorn-walk": "8.3.5", + "commander": "15.0.0", + "enhanced-resolve": "5.26.0", + "ignore": "7.0.12", + "interpret": "3.1.1", + "is-installed-globally": "1.0.1", + "json5": "2.2.3", + "picomatch": "4.0.7", + "prompts": "2.4.2", + "rechoir": "0.8.0", + "safe-regex": "2.1.1", + "semver": "7.8.5", + "tsconfig-paths-webpack-plugin": "4.2.0", + "watskeburt": "6.0.0" + }, + "bin": { + "depcruise": "bin/dependency-cruiser.mjs", + "depcruise-baseline": "bin/depcruise-baseline.mjs", + "depcruise-fmt": "bin/depcruise-fmt.mjs", + "depcruise-wrap-stream-in-html": "bin/wrap-stream-in-html.mjs", + "dependency-cruise": "bin/dependency-cruiser.mjs", + "dependency-cruiser": "bin/dependency-cruiser.mjs" + }, + "engines": { + "node": "^22||^24||>=26" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.452", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.452.tgz", + "integrity": "sha512-cVvk1YBSj6571VmV6hdJTqj94Y79xSu8cj6Y9t6ae4Y4431z8/7EJFvu3rVp90xhfuv9BpPKUmaLfTo4+FOGBg==", + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.26.0.tgz", + "integrity": "sha512-9vhedylFonb2YGogzUKX6+Ja72gOJbN1QHAqdrvqLwhdl/QWbKopzoUC9EbQNVsAns/bx/4uyqalrQAoy1IByw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/es-abstract": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", + "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-abstract-get": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-abstract-get/-/es-abstract-get-1.0.0.tgz", + "integrity": "sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.2", + "is-callable": "^1.2.7", + "object-inspect": "^1.13.4" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.4.0.tgz", + "integrity": "sha512-c/A0P0oxkACDc+cKWw8evLXK83oBKgn0qPOqCYT4x9uolpCIJAcYvJC9QYKNDRPsTeGyCrQ326jrvgZWdCdK5Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.1.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.3.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", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.5", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "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==", + "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-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.4.tgz", + "integrity": "sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==", + "license": "MIT", + "dependencies": { + "es-abstract-get": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "is-callable": "^1.2.7", + "is-date-object": "^1.1.0", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", + "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.6", + "@eslint/js": "9.39.5", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-compat-utils": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", + "license": "MIT", + "dependencies": { + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-import-context": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", + "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", + "license": "MIT", + "dependencies": { + "get-tsconfig": "^4.10.1", + "stable-hash-x": "^0.2.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-context" + }, + "peerDependencies": { + "unrs-resolver": "^1.0.0" + }, + "peerDependenciesMeta": { + "unrs-resolver": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz", + "integrity": "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==", + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.16.1", + "resolve": "^2.0.0-next.6" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-4.4.5.tgz", + "integrity": "sha512-nbE5XLph6TLtGYcu/U6e6ZVXyKBhbDWK5cLGk76eJ7NdZpwf1P9EFkpt1Z01mNZNrrilsAYWKH6zUkL4reoXbw==", + "license": "ISC", + "dependencies": { + "debug": "^4.4.1", + "eslint-import-context": "^0.1.8", + "get-tsconfig": "^4.10.1", + "is-bun-module": "^2.0.0", + "stable-hash-x": "^0.2.0", + "tinyglobby": "^0.2.14", + "unrs-resolver": "^1.7.11" + }, + "engines": { + "node": "^16.17.0 || >=18.6.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.14.0.tgz", + "integrity": "sha512-W2WCRZ9Dqntd+2u8jJcVMV2PKulc6RdLgUUoh/yQr3uB6lo/ZOeGx11sv60/8S4QFFKNslAlWhr9u0Ef7ZW6Ig==", + "license": "MIT", + "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==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-es-x": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", + "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": ">=8" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "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==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-n": { + "version": "18.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-18.4.1.tgz", + "integrity": "sha512-2sBReWOvCbzgkPri9M5SFmD5EbIwZLa1xz6B5RZsrI19WSFKpyx1sOMr+pdk8puCiXuEgCbErEHy1PuaUrc/4w==", + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.5.0", + "enhanced-resolve": "^5.17.1", + "eslint-plugin-es-x": "^7.8.0", + "get-tsconfig": "^4.8.1", + "globals": "^15.11.0", + "globrex": "^0.1.2", + "ignore": "^5.3.2", + "js-yaml": "^5.4.1", + "semver": "^7.6.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": ">=8.57.1", + "ts-declaration-location": "^1.0.6", + "typescript": ">=5.0.0" + }, + "peerDependenciesMeta": { + "ts-declaration-location": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-n/node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-n/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint-plugin-n/node_modules/js-yaml": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.4.3.tgz", + "integrity": "sha512-yzzNtgczwgoVHNigCyKTXcQJU4Y8t/ikU4UxXW0BvrLfHTGWZhsNcOT2s/a7vn81/4KqVnNmHjaUEPlvWnNwVw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.mjs" + } + }, + "node_modules/eslint-plugin-perfectionist": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-5.12.1.tgz", + "integrity": "sha512-krdSE7Dz+TCtcVr2+rfNhlOIFFBJcUdoRvjaN7JQnsaVnxJw+BZh9wMkY3MSLCJat+yW+UPTQLKS82Epc7MGZA==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "^8.70.0", + "@typescript-eslint/utils": "^8.70.0", + "natural-orderby": "^5.0.0" + }, + "engines": { + "node": "^20.0.0 || >=22.0.0" + }, + "peerDependencies": { + "eslint": "^8.45.0 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz", + "integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-sonarjs": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-3.0.7.tgz", + "integrity": "sha512-62jB20krIPvcwBLAyG3VVKa2ce2j2lL1yCb8Y0ylMRR/dLvCCTiQx8gQbXb+G81k1alPZ2/I3muZinqWQdBbzw==", + "license": "LGPL-3.0-only", + "dependencies": { + "@eslint-community/regexpp": "4.12.2", + "builtin-modules": "3.3.0", + "bytes": "3.1.2", + "functional-red-black-tree": "1.0.1", + "jsx-ast-utils-x": "0.1.0", + "lodash.merge": "4.6.2", + "minimatch": "10.1.2", + "scslre": "0.3.0", + "semver": "7.7.4", + "typescript": ">=5" + }, + "peerDependencies": { + "eslint": "^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/minimatch": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.2.tgz", + "integrity": "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-unicorn": { + "version": "62.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-62.0.0.tgz", + "integrity": "sha512-HIlIkGLkvf29YEiS/ImuDZQbP12gWyx5i3C6XrRxMvVdqMroCI9qoVYCoIl17ChN+U89pn9sVwLxhIWj5nEc7g==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "@eslint-community/eslint-utils": "^4.9.0", + "@eslint/plugin-kit": "^0.4.0", + "change-case": "^5.4.4", + "ci-info": "^4.3.1", + "clean-regexp": "^1.0.0", + "core-js-compat": "^3.46.0", + "esquery": "^1.6.0", + "find-up-simple": "^1.0.1", + "globals": "^16.4.0", + "indent-string": "^5.0.0", + "is-builtin-module": "^5.0.0", + "jsesc": "^3.1.0", + "pluralize": "^8.0.0", + "regexp-tree": "^0.1.27", + "regjsparser": "^0.13.0", + "semver": "^7.7.3", + "strip-indent": "^4.1.1" + }, + "engines": { + "node": "^20.10.0 || >=21.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=9.38.0" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/globals": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", + "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "license": "MIT" + }, + "node_modules/fd-package-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fd-package-json/-/fd-package-json-2.0.0.tgz", + "integrity": "sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==", + "license": "MIT", + "dependencies": { + "walk-up-path": "^4.0.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.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==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up-simple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", + "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/formatly": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/formatly/-/formatly-0.11.4.tgz", + "integrity": "sha512-TeCC10lP8KCgoX+Fe5lryILIT0/Dy+nP0OSVnsuB5CwXoLuOdqxCYlPFF1inR8S/zTy1ec7TjhS2TeRKWzzImA==", + "license": "MIT", + "dependencies": { + "fd-package-json": "^2.0.0", + "package-manager-detector": "^1.8.0" + }, + "bin": { + "formatly": "bin/index.mjs" + }, + "engines": { + "node": ">=18.14.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==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.2.0.tgz", + "integrity": "sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2", + "hasown": "^2.0.4", + "is-callable": "^1.2.7", + "is-document.all": "^1.0.0" + }, + "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==", + "license": "MIT" + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.7.0.tgz", + "integrity": "sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "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==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.3.tgz", + "integrity": "sha512-++QEw4DIY7WGoukz+/+A/8dGYPT9l9yIadnmSgZ8Rjr3YVSVDipQSO9CdnJo9ePqFqUUqh+wk9uIaoiAwsiPkA==", + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "license": "MIT", + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals": { + "version": "17.13.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.13.0.tgz", + "integrity": "sha512-RwMTC61u7hrG3ZJMkZQOK4JLJrKS8QtoTii63EmWvFXHqycY9FObBJQCbsLxSO8kjKhWE5kV1GC+Vb1g3RI0Zg==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "license": "MIT" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "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==", + "license": "ISC" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "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==", + "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==", + "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==", + "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.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/ignore": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.12.tgz", + "integrity": "sha512-/8UvqAPU9DGTI9k4mxtf49U37Isfwr8Uts96+SBHIkFxPJnHS0Ew4f00sM4Scd8V8EjM0jUNtVDdv1kPdt35lg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "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==", + "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==", + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-builtin-module": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-5.0.0.tgz", + "integrity": "sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==", + "license": "MIT", + "dependencies": { + "builtin-modules": "^5.0.0" + }, + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-builtin-module/node_modules/builtin-modules": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.4.0.tgz", + "integrity": "sha512-JCWSCdun+4Ovd9BhM/Vtlmwb7oD6Wl4YiPRXXwhAuwlPhW1un/MKgXn7GZoFm53ginnoNzus69V8JWx0K393jg==", + "license": "MIT", + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-bun-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.17.0.tgz", + "integrity": "sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.4" + }, + "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==", + "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==", + "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-document.all": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-document.all/-/is-document.all-1.0.0.tgz", + "integrity": "sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4" + }, + "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==", + "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==", + "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": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "license": "MIT", + "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==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-installed-globally": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-1.0.1.tgz", + "integrity": "sha512-li88H4QGRoNMX27jEmY8nR515oJVspAgC/WFMlhHfFV8RJ4QyGpHhXnwAe9gH5RIgKmdYRUmrOhQobcgEjIdSw==", + "license": "MIT", + "dependencies": { + "global-directory": "^4.0.1", + "is-path-inside": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "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==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "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==", + "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==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "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==", + "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==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "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==", + "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==", + "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/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jscpd": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/jscpd/-/jscpd-5.4.1.tgz", + "integrity": "sha512-afUt+LSQMmzSPYrWZlNGTwj8X4tmwVJbMNmr92qxPf4uUF/naLwG7SQyMPEZtrHqGgzGxmAzNjiwlVdjls2MyQ==", + "license": "MIT", + "bin": { + "jscpd": "run-jscpd.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://opencollective.com/jscpd" + }, + "optionalDependencies": { + "jscpd-darwin-arm64": "5.4.1", + "jscpd-darwin-x64": "5.4.1", + "jscpd-linux-arm64-gnu": "5.4.1", + "jscpd-linux-arm64-musl": "5.4.1", + "jscpd-linux-x64-gnu": "5.4.1", + "jscpd-linux-x64-musl": "5.4.1", + "jscpd-windows-arm64-msvc": "5.4.1", + "jscpd-windows-x64-msvc": "5.4.1" + } + }, + "node_modules/jscpd-darwin-arm64": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/jscpd-darwin-arm64/-/jscpd-darwin-arm64-5.4.1.tgz", + "integrity": "sha512-LXHVeH60C9BsozcVIMPmXWvj97KqFKbCJYmYG4hDwfwIwS1kz+uF7yiObckP6h2xo12pD88nI4XjWTB5frjZUw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/jscpd-darwin-x64": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/jscpd-darwin-x64/-/jscpd-darwin-x64-5.4.1.tgz", + "integrity": "sha512-Gqck4tcMZjv4IvYHU2Vcikb885zTADo5T/YfEqeu1i5W5tfFpLdViiTYrh5wbrW+uxBqC33gHpG1hy0xbGYknQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/jscpd-linux-arm64-gnu": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/jscpd-linux-arm64-gnu/-/jscpd-linux-arm64-gnu-5.4.1.tgz", + "integrity": "sha512-XUYZJZVxSY7JIBEoyOOMTgvJwmymkns4wG55tu6I/vRKXnS5QtaTESQfRLt6xj1+62aflAvr01FAhPAy+du6tA==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/jscpd-linux-arm64-musl": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/jscpd-linux-arm64-musl/-/jscpd-linux-arm64-musl-5.4.1.tgz", + "integrity": "sha512-h2sH8Bk++yBxWqq2QAy4fvPzXkw1vecDSyOmzLwPfnRQoQ2Q/EWxCNOrgJSb+SNMLWoHLLzfqx8m9wt2GG6a8w==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/jscpd-linux-x64-gnu": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/jscpd-linux-x64-gnu/-/jscpd-linux-x64-gnu-5.4.1.tgz", + "integrity": "sha512-UiC4YoGAVVLy6hPVz8A6cndo7W5br4FAO2hADnFeinhBPnXPu0QFh1q/s/8B3ldeQHQkpYd/l5cjqNBMrbm78w==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/jscpd-linux-x64-musl": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/jscpd-linux-x64-musl/-/jscpd-linux-x64-musl-5.4.1.tgz", + "integrity": "sha512-toAafl5roqfFotPrDJNMY9noNVZ9dReBqcO/nT5pJ8+7aq+opbscaLUcV4+8jxTq5btUD6CiO72+Fu+TyUZv3Q==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/jscpd-windows-arm64-msvc": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/jscpd-windows-arm64-msvc/-/jscpd-windows-arm64-msvc-5.4.1.tgz", + "integrity": "sha512-JLMga/NIwv/OPurPsXA2/d5OdWfdwrsBk2D4NhyKnrV/uNjo1BIi2zXztzDyTQVKMK/TEK6GPgLD143GG1fZ0A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/jscpd-windows-x64-msvc": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/jscpd-windows-x64-msvc/-/jscpd-windows-x64-msvc-5.4.1.tgz", + "integrity": "sha512-sN57Y9YP3ijrqc1IsWDceOFHUwbukg9/mU2NSDHTryKKc5CUvWz+o9GId8uKTiJIhkKfR/Ce5GKkCepTwB6kaw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/jsx-ast-utils-x": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils-x/-/jsx-ast-utils-x-0.1.0.tgz", + "integrity": "sha512-eQQBjBnsVtGacsG9uJNB8qOr3yA8rga4wAaGG1qRcBzSIvfhERLrWxMAM1hp5fcS6Abo8M4+bUBTekYR0qTPQw==", + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/knip": { + "version": "6.41.0", + "resolved": "https://registry.npmjs.org/knip/-/knip-6.41.0.tgz", + "integrity": "sha512-DrhQlIuV6xScd5Q+WTF1znd1w41QzxFGCtAHXCajsH/ndGMotHoNYbdXbuFtzW3mIOmniHtZ7zCtvnQkUmJtQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/webpro" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/knip" + } + ], + "license": "ISC", + "dependencies": { + "formatly": "^0.11.4", + "get-tsconfig": "4.14.3", + "jiti": "^2.7.0", + "oxc-parser": "^0.153.0", + "oxc-resolver": "11.24.2", + "picomatch": "^4.0.7", + "smol-toml": "^1.9.0", + "strip-json-comments": "5.0.3", + "tinyglobby": "^0.2.17", + "unbash": "^5.0.0", + "yaml": "^2.9.1", + "zod": "^4.6.5" + }, + "bin": { + "knip": "bin/knip.js", + "knip-bun": "bin/knip-bun.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/knip/node_modules/strip-json-comments": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.3.tgz", + "integrity": "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lint-staged": { + "version": "16.2.7", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.2.7.tgz", + "integrity": "sha512-lDIj4RnYmK7/kXMya+qJsmkRFkGolciXjrsZ6PC25GdTfWOAWetR0ZbsNXRAj1EHHImRSalc+whZFg56F5DVow==", + "license": "MIT", + "dependencies": { + "commander": "^14.0.2", + "listr2": "^9.0.5", + "micromatch": "^4.0.8", + "nano-spawn": "^2.0.0", + "pidtree": "^0.6.0", + "string-argv": "^0.3.2", + "yaml": "^2.8.1" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=20.17" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/listr2": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", + "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", + "license": "MIT", + "dependencies": { + "cli-truncate": "^5.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "license": "MIT" + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/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==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "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==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "license": "ISC", + "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==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nano-spawn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-2.1.0.tgz", + "integrity": "sha512-yTW+2okrElHiH4fsiz/+/zc0EDo9BDDoC3iKk8dpv1GeRc9nUWzUZHx6TofMWErchhUQR8hY9/Eu1Uja9x1nqA==", + "license": "MIT", + "engines": { + "node": ">=20.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/nano-spawn?sponsor=1" + } + }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "license": "MIT" + }, + "node_modules/natural-orderby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/natural-orderby/-/natural-orderby-5.0.0.tgz", + "integrity": "sha512-kKHJhxwpR/Okycz4HhQKKlhWe4ASEfPgkSWNmKFHd7+ezuQlxkA5cM3+XkBPvm1gmHen3w53qsYAv+8GwRrBlg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/node-exports-info": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.2.tgz", + "integrity": "sha512-kXs9Go0cah0qHVV2v389IXQLdLCeE1xfFtjOAF+iobu0OIoG1pje8At2vMHyaPMiPMnG/LWP50twML21eMcAag==", + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/node-exports-info/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/node-releases": { + "version": "2.0.58", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.58.tgz", + "integrity": "sha512-BdiKAgbfRlvfMq/XzO/AF9NPmaA8a+YpLAyAFTVFBj3gARrAIfWvNq7Q7NE4se3KgFu0KkrvQMxTS0XVnsGzHg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "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==", + "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==", + "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/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.2.tgz", + "integrity": "sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/oxc-parser": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.153.0.tgz", + "integrity": "sha512-cEnpyyV1OJRXv++SFNw0z8i+2o/cr88rVLaOYJafELDoHM5yHvCAbwGRLvxuany6SNLcbblSMUyZaGzH+quSYg==", + "license": "MIT", + "dependencies": { + "@oxc-project/types": "^0.153.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/oxc-project" + }, + "optionalDependencies": { + "@oxc-parser/binding-android-arm-eabi": "0.153.0", + "@oxc-parser/binding-android-arm64": "0.153.0", + "@oxc-parser/binding-darwin-arm64": "0.153.0", + "@oxc-parser/binding-darwin-x64": "0.153.0", + "@oxc-parser/binding-freebsd-x64": "0.153.0", + "@oxc-parser/binding-linux-arm-gnueabihf": "0.153.0", + "@oxc-parser/binding-linux-arm-musleabihf": "0.153.0", + "@oxc-parser/binding-linux-arm64-gnu": "0.153.0", + "@oxc-parser/binding-linux-arm64-musl": "0.153.0", + "@oxc-parser/binding-linux-ppc64-gnu": "0.153.0", + "@oxc-parser/binding-linux-riscv64-gnu": "0.153.0", + "@oxc-parser/binding-linux-riscv64-musl": "0.153.0", + "@oxc-parser/binding-linux-s390x-gnu": "0.153.0", + "@oxc-parser/binding-linux-x64-gnu": "0.153.0", + "@oxc-parser/binding-linux-x64-musl": "0.153.0", + "@oxc-parser/binding-openharmony-arm64": "0.153.0", + "@oxc-parser/binding-win32-arm64-msvc": "0.153.0", + "@oxc-parser/binding-win32-ia32-msvc": "0.153.0", + "@oxc-parser/binding-win32-x64-msvc": "0.153.0" + } + }, + "node_modules/oxc-resolver": { + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/oxc-resolver/-/oxc-resolver-11.24.2.tgz", + "integrity": "sha512-FY91FiDBj7ls5MsFS9jN3tjz2o0/zsdSsymlakySaBwVJZorHhkWyICLZMKxlu1R9vYo+sd3z1jwb4J8x7bNDw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxc-resolver/binding-android-arm-eabi": "11.24.2", + "@oxc-resolver/binding-android-arm64": "11.24.2", + "@oxc-resolver/binding-darwin-arm64": "11.24.2", + "@oxc-resolver/binding-darwin-x64": "11.24.2", + "@oxc-resolver/binding-freebsd-x64": "11.24.2", + "@oxc-resolver/binding-linux-arm-gnueabihf": "11.24.2", + "@oxc-resolver/binding-linux-arm-musleabihf": "11.24.2", + "@oxc-resolver/binding-linux-arm64-gnu": "11.24.2", + "@oxc-resolver/binding-linux-arm64-musl": "11.24.2", + "@oxc-resolver/binding-linux-ppc64-gnu": "11.24.2", + "@oxc-resolver/binding-linux-riscv64-gnu": "11.24.2", + "@oxc-resolver/binding-linux-riscv64-musl": "11.24.2", + "@oxc-resolver/binding-linux-s390x-gnu": "11.24.2", + "@oxc-resolver/binding-linux-x64-gnu": "11.24.2", + "@oxc-resolver/binding-linux-x64-musl": "11.24.2", + "@oxc-resolver/binding-openharmony-arm64": "11.24.2", + "@oxc-resolver/binding-wasm32-wasi": "11.24.2", + "@oxc-resolver/binding-win32-arm64-msvc": "11.24.2", + "@oxc-resolver/binding-win32-x64-msvc": "11.24.2" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-manager-detector": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.9.0.tgz", + "integrity": "sha512-zAMfbta9nPA8AKkA4WdmNAT8R8s6Dk0/xwPsqNnRidMFcLo1YkLuPDTgs2f64XdzS8vbLNnoJ+uUIkgbz7oRHA==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "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==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.1.tgz", + "integrity": "sha512-e0F9AOF1JMrCfBsyJOwU9lNvQ0WtXTq0j/4jk0BQ5JSI9VAybPXmDpPRw/2FQ3e5d3ZFN1mLh7jW99m/jjaptw==", + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.10.tgz", + "integrity": "sha512-skGHTH1Yb9QvaTC4hWnRTzEYtCpApF0UMBPz+t/0ZPzP8ihefo/btKd+QA7pUE0fEwA1SbS/NmhyEcstdXOIdA==", + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.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==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "license": "MIT", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/rechoir/node_modules/resolve": { + "version": "1.22.13", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.13.tgz", + "integrity": "sha512-Dj/cW9zBV2aRj6XzCxuGIs3ESZKv02jixne3q6jFZYZ3/Tg09gHHviSMDL4kObh9pqSahdRHEnDoaP2gn8YLhA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.17.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/refa": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/refa/-/refa-0.12.1.tgz", + "integrity": "sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==", + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.8.0" + }, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.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==", + "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-ast-analysis": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.7.1.tgz", + "integrity": "sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==", + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.8.0", + "refa": "^0.12.1" + }, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "license": "MIT", + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "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/regjsparser": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.4.tgz", + "integrity": "sha512-EWV80YgFaVgFrjGCAsV7oybp4GOxbls5RzBg8OB0nKEVXsBJR1JlV8Di1JhCROg3MzTfe1RI8yitIm1eOs68iA==", + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/resolve": { + "version": "2.0.0-next.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz", + "integrity": "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.2", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, + "node_modules/safe-array-concat": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", + "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "license": "MIT", + "dependencies": { + "regexp-tree": "~0.1.1" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scslre": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/scslre/-/scslre-0.3.0.tgz", + "integrity": "sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==", + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.8.0", + "refa": "^0.12.0", + "regexp-ast-analysis": "^0.7.0" + }, + "engines": { + "node": "^14.0.0 || >=16.0.0" + } + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "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==", + "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==", + "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==", + "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/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==", + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", + "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.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "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==", + "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==", + "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==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/slice-ansi": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz", + "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.3", + "is-fullwidth-code-point": "^5.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/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==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/smol-toml": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.9.1.tgz", + "integrity": "sha512-j7WyPdf0CJoutMzMoPLF/bVXHtKZIT9Rb4eGeEbWw8X2t5oirjPgpL+OpaENZrILYaXqYwnVH+qgUwVbl+pUJQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, + "node_modules/stable-hash-x": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", + "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.3.0.tgz", + "integrity": "sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.1.0.tgz", + "integrity": "sha512-tHNHTxInrYLCga9O9YGxWA3G9/nnzQw8UGAyqGx3Ar1pSTTzIuM4woFSq4SowkXCjJIwq5sIiQvEfRI9tCH1qQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.2", + "get-intrinsic": "^1.3.0", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.4", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.11.tgz", + "integrity": "sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-object-atoms": "^1.1.2", + "has-property-descriptors": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.10.tgz", + "integrity": "sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.2" + }, + "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==", + "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.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-indent": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.1.1.tgz", + "integrity": "sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths-webpack-plugin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.2.0.tgz", + "integrity": "sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.7.0", + "tapable": "^2.2.1", + "tsconfig-paths": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/tsconfig-paths-webpack-plugin/node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "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", + "optional": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "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==", + "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.5", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.5.tgz", + "integrity": "sha512-0FHJvLPqZ7KJzp17O13jfsAjsqazgrxBu2zEK95PmUz8lv2+GjRuxUInCr2Rk9Dms3ihN21zJ929ZO43yJ95QQ==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.9", + "for-each": "^0.3.5", + "gopd": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.8.tgz", + "integrity": "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "for-each": "^0.3.5", + "gopd": "^1.2.0", + "is-typed-array": "^1.1.15", + "possible-typed-array-names": "^1.1.0", + "reflect.getprototypeof": "^1.0.10" + }, + "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==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.71.1.tgz", + "integrity": "sha512-oiNVPC3/NbV1FpaHU07l8O6ynqG9v4PAiW2WvTrAmZdR0f2HI/gE668ElMLCK7Xbsu5k2fK5C4fXNiq05j7/nQ==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.71.1", + "@typescript-eslint/parser": "8.71.1", + "@typescript-eslint/typescript-estree": "8.71.1", + "@typescript-eslint/utils": "8.71.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/unbash": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unbash/-/unbash-5.0.0.tgz", + "integrity": "sha512-RYNm/ISFtflWpIcXTPHHLJZ0mqzInav+L9ke9PcL+hHsSf9+Fd/syPb614Mlqs/O3AYgjnvxDOFl0a+zVqi1/w==", + "license": "ISC", + "engines": { + "node": ">=14" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "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/unrs-resolver": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", + "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.4" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.12.2", + "@unrs/resolver-binding-android-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-x64": "1.12.2", + "@unrs/resolver-binding-freebsd-x64": "1.12.2", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", + "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", + "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-musl": "1.12.2", + "@unrs/resolver-binding-openharmony-arm64": "1.12.2", + "@unrs/resolver-binding-wasm32-wasi": "1.12.2", + "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", + "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", + "@unrs/resolver-binding-win32-x64-msvc": "1.12.2" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz", + "integrity": "sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==", + "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" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/walk-up-path": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-4.0.0.tgz", + "integrity": "sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==", + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/watskeburt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/watskeburt/-/watskeburt-6.0.0.tgz", + "integrity": "sha512-jfiuDABaxSkC71T6oZ3vCS99roYkSHm/+As+G0Dz8taAHQb+SJBvLEm5RlsgG71XdfAj3rv7eudUBTgwcQUPlQ==", + "license": "MIT", + "bin": { + "watskeburt": "dist/run-cli.js" + }, + "engines": { + "node": "^22.13||^24||>=26" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "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==", + "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==", + "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==", + "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.24", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.24.tgz", + "integrity": "sha512-wk4Mf4pR5mRP7eYuuTBCIQ9d0ud2Fv2jRLQpfgnRjbOxAFHmjKFValgTpitVKzJJS8ajnYQV2Du1SZ8j6b/EUQ==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.9", + "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/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/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==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz", + "integrity": "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.6.tgz", + "integrity": "sha512-4UmzQUF5fxvfcYHlbjBmejU+w+hbDnWFx4aS8kBx7nPBHcO2SqPbpAG8snbdg+Xse4pRefR98hgjFgIMCI/UhA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + } + } +} diff --git a/tools/quality/package.json b/tools/quality/package.json new file mode 100644 index 0000000..f6bbd11 --- /dev/null +++ b/tools/quality/package.json @@ -0,0 +1,34 @@ +{ + "name": "@1msg/quality-template", + "version": "1.0.12", + "private": true, + "type": "module", + "engines": { + "node": "24.x" + }, + "scripts": { + "test": "node --test test/*.test.mjs" + }, + "dependencies": { + "@eslint/js": "9.39.5", + "dependency-cruiser": "18.6.0", + "eslint": "9.39.5", + "eslint-import-resolver-typescript": "4.4.5", + "eslint-plugin-import": "2.32.0", + "eslint-plugin-n": "18.4.1", + "eslint-plugin-perfectionist": "5.12.1", + "eslint-plugin-react": "7.37.5", + "eslint-plugin-react-hooks": "7.1.1", + "eslint-plugin-sonarjs": "3.0.7", + "eslint-plugin-unicorn": "62.0.0", + "globals": "17.13.0", + "husky": "9.1.7", + "jscpd": "5.4.1", + "knip": "6.41.0", + "lint-staged": "16.2.7", + "picomatch": "4.0.7", + "prettier": "3.9.10", + "typescript": "5.9.3", + "typescript-eslint": "8.71.1" + } +} diff --git a/tools/quality/prettier.config.mjs b/tools/quality/prettier.config.mjs new file mode 100644 index 0000000..9d0c3e3 --- /dev/null +++ b/tools/quality/prettier.config.mjs @@ -0,0 +1,2 @@ +/** One formatting policy shared by authored code and the quality template itself. */ +export default { singleQuote: true, trailingComma: 'all' }; diff --git a/tools/quality/run.mjs b/tools/quality/run.mjs new file mode 100644 index 0000000..17e3c74 --- /dev/null +++ b/tools/quality/run.mjs @@ -0,0 +1,368 @@ +#!/usr/bin/env node +import { + readFileSync, + writeFileSync, + mkdirSync, + mkdtempSync, + rmSync, +} from 'node:fs'; +import { dirname, resolve, join } from 'node:path'; +import { tmpdir } from 'node:os'; +import { fileURLToPath, pathToFileURL } from 'node:url'; +import { + execute, + baseRef, + baseFile, + currentFile, + git, + changedFiles, +} from './lib/git.mjs'; +import { assess, parseJson } from './lib/baseline.mjs'; +import { runGuards, validateConfig } from './lib/guards.mjs'; +import { + knipRecords, + duplicateRecords, + eslintRecords, + architectureRecords, + tokenFingerprint, +} from './lib/reports.mjs'; +import { historicalAnalysis } from './lib/historical.mjs'; + +const directory = dirname(fileURLToPath(import.meta.url)); +const args = process.argv.slice(2); +const action = args[0]; + +/** Read an option without treating subsequent flags as values. */ +function option(name, fallback) { + const position = args.indexOf(name); + if (position < 0) return fallback; + const value = args[position + 1]; + if (!value || value.startsWith('--')) + throw new Error(`Missing value for ${name}`); + return value; +} + +/** Record analyzer exit state together with the report; non-diagnostic exits always fail. */ +function analyze(command, argv, name) { + const result = execute(command, argv); + if (![0, 1].includes(result.status)) + throw new Error(`${name} failed (${result.status}): ${result.stderr}`); + if (result.stderr.trim()) process.stderr.write(result.stderr); + return { status: result.status, report: parseJson(result.stdout, name) }; +} + +/** Run Knip's actual production or full graph with its independent config and JSON reporter. */ +function unused(config, production) { + const argv = [ + join(directory, 'node_modules/knip/bin/knip.js'), + '--config', + config.knipConfig ?? 'knip.json', + '--reporter', + join(directory, 'lib/knip-reporter.mjs'), + ]; + if (production) argv.push('--production'); + const { report } = analyze(process.execPath, argv, 'Knip'); + return { findings: knipRecords(report), report }; +} + +/** Run duplicate analysis into a fresh temporary directory, rejecting empty or missing output. */ +function duplicates(config) { + if (!config.duplicatePaths?.length) + throw new Error('duplicatePaths must list authored runtime/tooling roots'); + if (config.duplicateCanonicalFormat) { + const { report } = analyze( + process.execPath, + [join(directory, 'canonical-duplicates.mjs'), JSON.stringify(config)], + 'Canonical jscpd', + ); + return { findings: duplicateRecords(report), report }; + } + const output = mkdtempSync(join(tmpdir(), '1msg-jscpd-')); + try { + const argv = [ + join(directory, 'node_modules/jscpd/run-jscpd.js'), + ...config.duplicatePaths, + '--reporters', + 'json', + '--output', + output, + '--mode', + 'mild', + '--min-lines', + '5', + '--min-tokens', + '50', + '--silent', + '--absolute', + '--format', + ( + config.duplicateFormats ?? [ + 'javascript', + 'typescript', + 'jsx', + 'tsx', + 'svelte', + ] + ).join(','), + ]; + if (config.duplicateIgnore?.length) + argv.push('--ignore', config.duplicateIgnore.join(',')); + const result = execute(process.execPath, argv); + if (result.status !== 0) + throw new Error( + `jscpd failed (${result.status}): ${result.stderr || result.stdout}`, + ); + const report = parseJson( + readFileSync(join(output, 'jscpd-report.json'), 'utf8'), + 'jscpd', + ); + return { findings: duplicateRecords(report), report }; + } finally { + rmSync(output, { recursive: true, force: true }); + } +} + +/** Confirm initial allowances describe existing source; freshly introduced problems cannot be bootstrapped. */ +function initialEvidence(finding, base, historical) { + const prior = historical.find((item) => item.key === finding.key); + if (!prior || finding.value > prior.value) + throw new Error(`Cannot baseline a new/increased finding: ${finding.key}`); + const evidence = {}; + for (const path of finding.paths ?? [finding.path]) { + if (!path) throw new Error(`Finding lacks source evidence: ${finding.key}`); + const before = baseFile(base, path); + const current = currentFile(path); + if (before === null || current === null) + throw new Error(`Cannot baseline a new/missing file: ${path}`); + if (path.endsWith('package.json') && finding.symbol) { + const old = JSON.parse(before); + const dependencies = { + ...old.dependencies, + ...old.devDependencies, + ...old.optionalDependencies, + }; + evidence[path] = + finding.symbol in dependencies + ? `dependency:${finding.symbol}:${dependencies[finding.symbol]}` + : tokenFingerprint(before); + } else { + evidence[path] = tokenFingerprint(before); + } + } + return evidence; +} + +/** Write explicit historical allowances locally, then validate the same artifact as CI. */ +function bootstrap(findings, path, base, historical) { + if (process.env.CI) throw new Error('Baseline bootstrap is forbidden in CI'); + const owner = option('--owner'); + const expires = option('--expires'); + const reason = option('--reason'); + const issue = option('--issue'); + if (!owner || !expires || !reason || !issue) + throw new Error( + 'Bootstrap requires --owner, --expires, --reason and --issue', + ); + const entries = findings.map((finding) => ({ + ...finding, + owner, + expires, + reason, + issue, + evidence: initialEvidence(finding, base, historical), + })); + const baseline = { schemaVersion: 1, adoptionBase: base, entries }; + mkdirSync(dirname(path), { recursive: true }); + writeFileSync(path, `${JSON.stringify(baseline, null, 2)}\n`); + return baseline; +} + +/** Ratchet individual debt against trusted Git history, including reductions and expired allowances. */ +function gate(config, name, result, base, analyzeBase) { + if (!/^[a-z][a-z0-9-]*$/.test(name)) throw new Error('Invalid gate name'); + const path = `${config.baselineDir ?? 'quality/baselines'}/${name}.json`; + const raw = currentFile(path); + const old = baseFile(base, path); + const previous = old === null ? null : parseJson(old, 'trusted baseline'); + const historical = + previous || result.findings.length === 0 + ? [] + : historicalAnalysis(base, config, directory, analyzeBase).findings; + const baseline = args.includes('--bootstrap') + ? bootstrap(result.findings, path, base, historical) + : raw === null + ? { schemaVersion: 1, entries: [] } + : parseJson(raw, 'baseline'); + if (!previous && baseline.entries.length) { + if (baseline.adoptionBase !== base) + throw new Error('Initial baseline is not tied to the trusted base SHA'); + for (const entry of baseline.entries) { + if ( + JSON.stringify(entry.evidence) !== + JSON.stringify(initialEvidence(entry, base, historical)) + ) { + throw new Error(`Initial baseline evidence changed: ${entry.key}`); + } + } + } + const errors = assess(result.findings, baseline, previous); + if (name === 'duplicates') { + if ( + !Number.isFinite(config.duplicateMaxPercentage) || + config.duplicateMaxPercentage < 0 || + config.duplicateMaxPercentage > 100 + ) { + throw new Error( + 'duplicateMaxPercentage must specify the inventoried numeric ceiling (0–100)', + ); + } + const percentage = result.report.statistics.total.percentage; + if (!Number.isFinite(percentage)) + throw new Error('jscpd omitted its numeric duplicate percentage'); + if (percentage > config.duplicateMaxPercentage) + errors.push( + `Duplicate percentage ${percentage} exceeds ${config.duplicateMaxPercentage}`, + ); + } + mkdirSync('quality/reports', { recursive: true }); + writeFileSync( + `quality/reports/${name}.json`, + `${JSON.stringify( + { + schemaVersion: 1, + head: git(['rev-parse', 'HEAD']).trim(), + base, + result: errors.length ? 'FAIL' : 'PASS', + findings: result.findings, + errors, + analyzer: result.report, + }, + null, + 2, + )}\n`, + ); + if (errors.length) throw new Error(errors.join('\n')); + console.log( + `${name}: PASS (${result.findings.length} existing, individually tracked violations)`, + ); +} + +/** Dispatch one mandatory check; unsupported actions or missing configuration never count as success. */ +async function main() { + const config = ( + await import(pathToFileURL(resolve('quality.config.mjs')).href) + ).default; + validateConfig(config); + const base = baseRef( + config.defaultBranch, + option('--base', process.env.QUALITY_BASE), + ); + if (action === 'changed-files') { + console.log(JSON.stringify(changedFiles(base))); + return; + } + if (action === 'guards') { + const result = runGuards(config, base); + if (result.errors.length) throw new Error(result.errors.join('\n')); + console.log( + `guards: PASS (${result.checked} authored source files inventoried)`, + ); + return; + } + if (['unused-production', 'unused-full'].includes(action)) { + const analyzeBase = (sourceConfig) => + unused(sourceConfig, action === 'unused-production'); + gate(config, action, analyzeBase(config), base, analyzeBase); + return; + } + if (action === 'duplicates') { + gate(config, action, duplicates(config), base, duplicates); + return; + } + if (action === 'duplicates-full') { + if (!config.duplicateFullPaths?.length) + throw new Error( + 'duplicateFullPaths must inventory runtime, tests and tooling', + ); + const result = duplicates({ + ...config, + duplicatePaths: config.duplicateFullPaths, + duplicateIgnore: + config.duplicateFullIgnore ?? + (config.generated ?? []).map((entry) => entry.pattern), + }); + mkdirSync('quality/reports', { recursive: true }); + writeFileSync( + 'quality/reports/duplicates-full.json', + `${JSON.stringify( + { + schemaVersion: 1, + head: git(['rev-parse', 'HEAD']).trim(), + base, + result: 'REPORT', + ...result, + }, + null, + 2, + )}\n`, + ); + console.log( + `duplicates-full: analyzed ${result.report.statistics.total.sources} files; report saved`, + ); + return; + } + if (action === 'report' && option('--kind') === 'eslint') { + const split = args.indexOf('--'); + if (split < 0 || !args[split + 1]) + throw new Error('report requires -- '); + const analyzeBase = () => { + const { report } = analyze( + args[split + 1], + args.slice(split + 2), + 'ESLint', + ); + return { findings: eslintRecords(report), report }; + }; + gate( + config, + option('--name', 'complexity'), + analyzeBase(), + base, + analyzeBase, + ); + return; + } + if (action === 'report' && option('--kind') === 'depcruiser') { + const split = args.indexOf('--'); + if (split < 0 || !args[split + 1]) + throw new Error('report requires -- '); + const analyzeBase = () => { + const result = execute(args[split + 1], args.slice(split + 2)); + const report = parseJson(result.stdout, 'dependency-cruiser'); + if ( + !Number.isInteger(report.summary?.advisedExitCode) || + (result.status !== 0 && + result.status !== report.summary.advisedExitCode % 256) + ) { + throw new Error( + `dependency-cruiser exit/report mismatch (${result.status}): ${result.stderr}`, + ); + } + return { findings: architectureRecords(report), report }; + }; + gate( + config, + option('--name', 'architecture'), + analyzeBase(), + base, + analyzeBase, + ); + return; + } + throw new Error(`Unknown quality action: ${action}`); +} + +main().catch((error) => { + console.error(error.message); + process.exitCode = 1; +}); diff --git a/tools/quality/seal.mjs b/tools/quality/seal.mjs new file mode 100644 index 0000000..8e2c5b9 --- /dev/null +++ b/tools/quality/seal.mjs @@ -0,0 +1,19 @@ +import { readFileSync, writeFileSync } from 'node:fs'; +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { digest } from './lib/baseline.mjs'; +import { templateFiles } from './lib/template.mjs'; + +// Maintainers seal a reviewed template version before copying it into consumer repositories. +const root = dirname(fileURLToPath(import.meta.url)); +const { version } = JSON.parse(readFileSync(`${root}/package.json`, 'utf8')); +const files = Object.fromEntries( + templateFiles(root).map((path) => [ + path, + digest(readFileSync(`${root}/${path}`, 'utf8')), + ]), +); +writeFileSync( + `${root}/template-manifest.json`, + `${JSON.stringify({ schemaVersion: 1, version, files }, null, 2)}\n`, +); diff --git a/tools/quality/staged.mjs b/tools/quality/staged.mjs new file mode 100644 index 0000000..bbfa798 --- /dev/null +++ b/tools/quality/staged.mjs @@ -0,0 +1,43 @@ +import { ESLint } from 'eslint'; +import { readFileSync, existsSync } from 'node:fs'; +import { relative, resolve } from 'node:path'; +import { pathToFileURL } from 'node:url'; +import { matches } from './lib/guards.mjs'; +import { verifyTemplate } from './lib/template.mjs'; + +const [, , flag, configuration, separator, ...files] = process.argv; +if (flag !== '--config' || !configuration || separator !== '--') + throw new Error('Usage: staged.mjs --config -- '); + +const { default: inventory } = await import( + pathToFileURL(resolve('quality.config.mjs')).href +); +const approved = [ + ...(inventory.generated ?? []), + ...(inventory.excluded ?? []), +].map((entry) => entry.pattern); +const manifestPath = 'tools/quality/template-manifest.json'; +let vendorFiles = new Set(); +if (existsSync(manifestPath)) { + verifyTemplate('HEAD'); + const manifest = JSON.parse(readFileSync(manifestPath, 'utf8')); + vendorFiles = new Set([ + manifestPath, + ...Object.keys(manifest.files).map((path) => `tools/quality/${path}`), + ]); +} +const eslint = new ESLint({ overrideConfigFile: configuration }); +const uncovered = []; +for (const file of files) { + const path = relative(process.cwd(), resolve(file)).replaceAll('\\', '/'); + if ( + (await eslint.isPathIgnored(file)) && + !vendorFiles.has(path) && + !matches(path, approved) + ) + uncovered.push(path); +} +if (uncovered.length) + throw new Error( + `Staged authored files have no ESLint coverage:\n${uncovered.join('\n')}`, + ); diff --git a/tools/quality/template-manifest.json b/tools/quality/template-manifest.json new file mode 100644 index 0000000..4e79096 --- /dev/null +++ b/tools/quality/template-manifest.json @@ -0,0 +1,33 @@ +{ + "schemaVersion": 1, + "version": "1.0.12", + "files": { + "README.md": "80380757947a33100e4f43f7808b129f2c3cdc81c380614fc2e55153ef5f124a", + "canonical-duplicates.mjs": "a3583fdc3e344af448ea8d2543c2398daaa03fa10a0739da486afb04e35425ba", + "complexity.mjs": "4ed5553c392621e0615a48c12e12300c8602ed2a28cfbaff67002acf82e49cac", + "eslint.mjs": "607ddfaac3d365fedd7dbc5e21c781d448347b1c36662f3492e4364ff9f22ded", + "lib/baseline.mjs": "7876ba90b80448d9c9003c21e348095ed22630c41fc26ed944984742020549dd", + "lib/git.mjs": "b7c26871526d864bf8d12f01c613d3bfa0adb2da9d072544d8f09407ef598758", + "lib/guards.mjs": "fe95129ef78aa5354446d8b37769ac27deb95d2b8bc978c5d3bafad538bd7836", + "lib/historical.mjs": "43b46395828daa3f19d8692e9bd22ea6cfc1d0dbac83814d727894f672a0ddd2", + "lib/knip-reporter.mjs": "175d7d96e2913e8f6de04b6c706172258d9d7654a26ba7f9ed7edff79d3fc8ca", + "lib/reports.mjs": "361e38ae981238db91f7b9a31af963ccbb89e3ae6745d1582b2086e6c64f0c9e", + "lib/template.mjs": "c2a14b715f0c9dbe8b8243b142f4c6628967400fb8f92767537169e1b7bfd8f4", + "package-lock.json": "238e6a8ff9303c66968b8e83ef028dfa49b7bb6a5ca485c0a7e65520d4c54365", + "package.json": "91adacf496715638a7e765035ca16d27e7a3c40ad3abbdd4bb4fc8c9574113eb", + "prettier.config.mjs": "7576563a9a30aff8eb3177f9cc2e4bc7a0f6b825042eadb9a619b86f519c5e5e", + "run.mjs": "7cf26128cdf63f3a7ccab7341a0a274a352fd9bda0521ba41e37216bb9cc249f", + "seal.mjs": "fb38c8e08ea3cf9f4dcd95e45ffc931aea3b7a54181fed88d7379f8aad4c050d", + "staged.mjs": "17db5c61a1369e6e740fd233887eca0033b64f2114dd3871b96108afb6123d49", + "test/cli.test.mjs": "a8e066e20790fc0d915b6a6d7ba11ca8d2af2a59ca6d51f4da232e7efb511f39", + "test/complexity.test.mjs": "ba1f702ba94de3fcad93cb5e43a49bc2456be1426c81754149420d210f2b3952", + "test/git-portability.test.mjs": "0e65759ff3a1aa87c20d20ae147154d980381c2e8075f57f341ef3c53c3b3f62", + "test/guard-history.test.mjs": "00b17403b3ef17cc5d83c681c990ca98b6a0ad4857a95d501d2cf8f390aa7b1e", + "test/ratchet.test.mjs": "324a932c5a52d1b037e111042e1b41e5686f8d4dbfd0307faf86cee649ebc27a", + "test/reports.test.mjs": "521a13da2f16628b4a30de7040529e0b7b7e25e7db79d19de8004945d49c5e0c", + "test/suppression-syntax.test.mjs": "1b3dfc3a66ee9978491402e3683511c2d3a6d42203b283cd4a74578551a197b0", + "tsconfig.next.json": "d900a35fcb0852376b06854df5be2f8f178e26cb5383b93b07ebeb6220e30faf", + "tsconfig.node.json": "627661abcb7e992c4bfaf98d6e68a12678573b5d4f6e821ea0fa43fa6e233f28", + "tsconfig.svelte.json": "5777247ea98aaf2d886b87cd12206a641377edcdd086ce5fd5b58adc6f0bc771" + } +} diff --git a/tools/quality/test/cli.test.mjs b/tools/quality/test/cli.test.mjs new file mode 100644 index 0000000..88b6aa6 --- /dev/null +++ b/tools/quality/test/cli.test.mjs @@ -0,0 +1,980 @@ +import { templateFiles } from '../lib/template.mjs'; +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { + mkdtempSync, + mkdirSync, + writeFileSync, + rmSync, + cpSync, + readFileSync, +} from 'node:fs'; +import { tmpdir } from 'node:os'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { spawnSync } from 'node:child_process'; + +const runner = fileURLToPath(new URL('../run.mjs', import.meta.url)); + +/** Create a real Git fixture so CLI tests exercise trusted base and working-tree changes together. */ +function fixture() { + const cwd = mkdtempSync(join(tmpdir(), '1msg-quality-test-')); + mkdirSync(join(cwd, 'src')); + writeFileSync( + join(cwd, 'package.json'), + '{"name":"quality-fixture","private":true,"type":"module"}\n', + ); + writeFileSync( + join(cwd, 'quality.config.mjs'), + `export default { + schemaVersion:1,profile:'A',defaultBranch:'main',sourceRoots:['src','quality.config.mjs'], + knipConfig:'knip.json',duplicatePaths:['src'],duplicateMaxPercentage:100 + };\n`, + ); + writeFileSync( + join(cwd, 'knip.json'), + JSON.stringify({ entry: ['src/index.js!'], project: ['src/**/*.js!'] }), + ); + const git = (...args) => { + const result = spawnSync('git', args, { cwd, encoding: 'utf8' }); + assert.equal(result.status, 0, result.stderr); + return result.stdout.trim(); + }; + git('init'); + git('symbolic-ref', 'HEAD', 'refs/heads/main'); + git('config', 'user.email', 'quality@example.invalid'); + git('config', 'user.name', 'Quality fixture'); + const commit = () => { + git('add', '.'); + git('commit', '-m', 'test: fixture'); + return git('rev-parse', 'HEAD'); + }; + const run = (...args) => + spawnSync(process.execPath, [runner, ...args], { + cwd, + encoding: 'utf8', + env: { ...process.env, CI: '', QUALITY_BASE: undefined }, + timeout: 60_000, + maxBuffer: 16 * 1024 * 1024, + }); + return { + cwd, + git, + commit, + run, + write: (path, text) => writeFileSync(join(cwd, path), text), + close: () => rmSync(cwd, { recursive: true, force: true }), + }; +} + +test('real CLI blocks undocumented new functions, broad suppression and uncovered files', () => { + const f = fixture(); + try { + f.write('src/index.js', 'console.log("app");\n'); + const base = f.commit(); + assert.equal(f.run('guards', '--base', base).status, 0); + f.write( + 'src/index.js', + 'function createWidget() { return 2; }\nconsole.log(createWidget());\n', + ); + assert.match( + f.run('guards', '--base', base).stderr, + /document createWidget/, + ); + f.write( + 'src/index.js', + '/** Construct the default widget. */\nfunction createWidget() { return 2; }\nconsole.log(createWidget());\n', + ); + assert.equal(f.run('guards', '--base', base).status, 0); + f.write('src/index.js', '// @ts-nocheck\nconsole.log("app");\n'); + assert.match(f.run('guards', '--base', base).stderr, /broad lint/); + f.write('rogue.js', 'console.log("forgotten");\n'); + assert.match( + f.run('guards', '--base', base).stderr, + /no declared source root/, + ); + assert.notEqual(f.run('guards', '--base', 'missing-ref').status, 0); + } finally { + f.close(); + } +}); + +/** The real guard CLI distinguishes generated directive text from actual suppressions in and after interpolations. */ +test('actual guards CLI enforces comments around interpolated template data', () => { + const f = fixture(); + try { + f.write('src/index.js', 'console.log("app");\n'); + const base = f.commit(); + f.write( + 'src/index.js', + 'const generated = `a ${name} /* eslint-disable */`;\nconsole.log(generated);\n', + ); + const valid = f.run('guards', '--base', base); + assert.equal(valid.status, 0, valid.stderr); + for (const source of [ + 'const generated = `a ${ /* eslint-disable */ name } z`;\n', + 'const generated = `a ${name} z`; // @ts-nocheck\n', + ]) { + f.write('src/index.js', source); + const invalid = f.run('guards', '--base', base); + assert.equal(invalid.status, 1, invalid.stderr); + assert.match(invalid.stderr, /broad lint\/type suppression/); + } + } finally { + f.close(); + } +}); + +/** The actual staged preflight permits declared generated sources while rejecting ordinary ESLint ignores. */ +test('staged coverage rejects unowned ignores and validates sealed vendor files', () => { + const f = fixture(); + try { + f.write('src/index.js', 'console.log("app");\n'); + f.commit(); + f.write( + 'eslint.config.mjs', + 'export default [{ignores:["src/ignored.js","src/generated.js","tools/quality/**"]}];\n', + ); + f.write( + 'quality.config.mjs', + 'export default {generated:[{pattern:"src/generated.js",producer:"fixture"}]};\n', + ); + f.write('src/ignored.js', 'export const forgotten = 1;\n'); + f.write('src/generated.js', 'export const generated = 1;\n'); + const staged = fileURLToPath(new URL('../staged.mjs', import.meta.url)); + /** Invoke the installed ESLint resolver and real sealed inventory with only disposable files. */ + const check = (path) => + spawnSync( + process.execPath, + [staged, '--config', 'eslint.config.mjs', '--', path], + { cwd: f.cwd, encoding: 'utf8' }, + ); + assert.equal(check('src/index.js').status, 0); + assert.equal(check('src/generated.js').status, 0); + const ignored = check('src/ignored.js'); + assert.equal(ignored.status, 1); + assert.match( + ignored.stderr, + /Staged authored files have no ESLint coverage/, + ); + const template = fileURLToPath(new URL('..', import.meta.url)); + for (const path of [...templateFiles(template), 'template-manifest.json']) { + const destination = join(f.cwd, 'tools/quality', path); + mkdirSync(dirname(destination), { recursive: true }); + cpSync(join(template, path), destination); + } + assert.equal(check('tools/quality/lib/guards.mjs').status, 0); + f.write('tools/quality/rogue.js', 'export const bypass = 1;\n'); + const rogue = check('tools/quality/rogue.js'); + assert.equal(rogue.status, 1); + assert.match(rogue.stderr, /undeclared\/missing files/); + } finally { + f.close(); + } +}); + +test('actual Knip CLI blocks an unused file and unresolved import', () => { + const f = fixture(); + try { + f.write('src/index.js', 'console.log("app");\n'); + const base = f.commit(); + assert.equal(f.run('unused-full', '--base', base).status, 0); + f.write('src/forgotten.js', 'export const value = 42;\n'); + const unused = f.run('unused-full', '--base', base); + assert.equal(unused.status, 1, unused.stderr); + assert.match(unused.stderr, /forgotten/); + f.write( + 'src/index.js', + 'import value from "./missing.js"; console.log(value);\n', + ); + assert.match( + f.run('unused-production', '--base', base).stderr, + /unresolved/, + ); + } finally { + f.close(); + } +}); + +test('documentation survives formatting and unrelated callback removal, but new copies still require docs', () => { + const f = fixture(); + try { + f.write( + 'src/index.js', + ` + run(() => { return {name: "removed"}; }); + run(() => { return {name: "retained"}; }); + function load(value) { return request(value, {name: "widget"}); } + `, + ); + const base = f.commit(); + f.write( + 'src/index.js', + ` + run(() => { return {name: 'retained',}; }); + function load(value,) { return request(value, {name: 'widget',},); } + `, + ); + const formatted = f.run('guards', '--base', base); + assert.equal(formatted.status, 0, formatted.stderr); + f.write( + 'src/index.js', + ` + run(() => { return {name: 'retained',}; }); + run(() => { return {name: 'retained',}; }); + function load(value,) { return request(value, {name: 'widget',},); } + `, + ); + const duplicated = f.run('guards', '--base', base); + assert.equal(duplicated.status, 1, duplicated.stderr); + assert.match(duplicated.stderr, /document /); + } finally { + f.close(); + } +}); + +test('actual jscpd CLI blocks a new clone even with unrelated unique lines', () => { + const f = fixture(); + try { + const source = `export function summarize(values) { + const result = []; + for (const value of values) { + const normalized = String(value).trim(); + if (normalized.length > 0) { + result.push({ value: normalized, length: normalized.length }); + } + } + return result.sort((left, right) => left.length - right.length); + }\n`; + f.write('src/index.js', source); + const base = f.commit(); + const clean = f.run('duplicates', '--base', base); + assert.equal(clean.status, 0, clean.stderr); + f.write( + 'src/copy.js', + source + '\nexport const unrelated = "extra unique content";\n', + ); + const duplicated = f.run('duplicates', '--base', base); + assert.equal(duplicated.status, 1, duplicated.stderr); + assert.match(duplicated.stderr, /New or increased/); + } finally { + f.close(); + } +}); + +test('Knip production rejects runtime code referenced only from tests while full accepts it', () => { + const f = fixture(); + try { + f.write( + 'knip.json', + JSON.stringify({ + entry: ['src/index.js!', 'test.js'], + project: ['src/**/*.js!', 'test.js'], + }), + ); + f.write('src/index.js', 'console.log("app");\n'); + f.write('src/helper.js', 'export const value = 42;\n'); + f.write( + 'test.js', + 'import { value } from "./src/helper.js"; console.log(value);\n', + ); + const base = f.commit(); + const full = f.run('unused-full', '--base', base); + assert.equal(full.status, 0, full.stderr); + const production = f.run('unused-production', '--base', base); + assert.equal(production.status, 1, production.stderr); + assert.match(production.stderr, /helper/); + } finally { + f.close(); + } +}); + +test('initial debt is replayed against trusted source, including edited files and newly disconnected imports', () => { + const f = fixture(); + const bootstrap = [ + '--bootstrap', + '--owner', + 'quality', + '--expires', + '2099-01-01', + '--reason', + 'historical fixture debt', + '--issue', + 'TEST-1', + ]; + try { + f.write( + 'src/index.js', + 'import { value } from "./helper.js"; console.log(value);\n', + ); + f.write('src/helper.js', 'export const value = 42;\n'); + f.write('src/forgotten.js', 'export const oldDebt = 1;\n'); + const base = f.commit(); + f.write('src/forgotten.js', 'export const oldDebt = 2;\n'); + f.write('new-tool.mjs', 'console.log(123);'); + f.write( + 'knip.json', + JSON.stringify({ + entry: ['src/index.js!', 'new-tool.mjs'], + project: ['src/**/*.js!', 'new-tool.mjs'], + }), + ); + const historical = f.run('unused-full', '--base', base, ...bootstrap); + assert.equal(historical.status, 0, historical.stderr); + f.write('src/index.js', 'console.log("now disconnected");\n'); + const newDebt = f.run('unused-full', '--base', base, ...bootstrap); + assert.equal(newDebt.status, 1, newDebt.stderr); + assert.match( + newDebt.stderr, + /Cannot baseline a new\/increased finding.*helper/, + ); + } finally { + f.close(); + } +}); + +test('jscpd preserves multiple source roots and enforces its numeric ceiling', () => { + const f = fixture(); + try { + mkdirSync(join(f.cwd, 'runtime')); + const source = `export function summarize(values) { + const result = []; + for (const value of values) { + const normalized = String(value).trim(); + if (normalized.length > 0) result.push({ value: normalized, length: normalized.length }); + } + return result.sort((left, right) => left.length - right.length); + }\n`; + f.write('src/index.js', source); + f.write('runtime/copy.js', source); + f.write( + 'quality.config.mjs', + `export default { schemaVersion:1,profile:'A',sourceRoots:['src','runtime'], + duplicatePaths:['src','runtime'],duplicateMaxPercentage:100 };`, + ); + const base = f.commit(); + const bootstrap = [ + '--bootstrap', + '--owner', + 'quality', + '--expires', + '2099-01-01', + '--reason', + 'historical fixture debt', + '--issue', + 'TEST-1', + ]; + const accepted = f.run('duplicates', '--base', base, ...bootstrap); + assert.equal(accepted.status, 0, accepted.stderr); + f.write( + 'quality.config.mjs', + `export default { schemaVersion:1,profile:'A',sourceRoots:['src','runtime'], + duplicatePaths:['src','runtime'],duplicateMaxPercentage:0 };`, + ); + const percentage = f.run('duplicates', '--base', base); + assert.equal(percentage.status, 1, percentage.stderr); + assert.match(percentage.stderr, /Duplicate percentage/); + } finally { + f.close(); + } +}); + +test('actual dependency-cruiser detects a long runtime cycle and refuses native I/O debt', () => { + const f = fixture(); + const executable = fileURLToPath( + new URL( + '../node_modules/dependency-cruiser/bin/dependency-cruiser.mjs', + import.meta.url, + ), + ); + const command = [ + '--', + process.execPath, + executable, + 'src', + '--config', + 'dependency-cruiser.config.cjs', + '--output-type', + 'json', + ]; + try { + f.write( + 'dependency-cruiser.config.cjs', + `module.exports = { forbidden: [ + {name:'no-runtime-cycles',severity:'error',from:{},to:{circular:true,dependencyTypesNot:['type-only']}}, + {name:'application-no-native-io',severity:'error',from:{path:'src'},to:{dependencyTypes:['core']}}, + ] };`, + ); + f.write('src/index.js', 'import "./second.js"; console.log("one");\n'); + f.write('src/second.js', 'import "./third.js"; console.log("two");\n'); + f.write('src/third.js', 'console.log("three");\n'); + const base = f.commit(); + const clean = f.run( + 'report', + '--kind', + 'depcruiser', + '--base', + base, + ...command, + ); + assert.equal(clean.status, 0, clean.stderr); + f.write('src/third.js', 'import "./index.js"; console.log("three");\n'); + const cycle = f.run( + 'report', + '--kind', + 'depcruiser', + '--base', + base, + ...command, + ); + assert.equal(cycle.status, 1, cycle.stderr); + assert.match(cycle.stderr, /no-runtime-cycles/); + f.write('src/third.js', 'import fs from "node:fs"; console.log(fs);\n'); + const native = f.run( + 'report', + '--kind', + 'depcruiser', + '--base', + base, + '--bootstrap', + '--owner', + 'quality', + '--expires', + '2099-01-01', + '--reason', + 'cannot bless native dependency', + '--issue', + 'TEST-1', + ...command, + ); + assert.equal(native.status, 1, native.stderr); + assert.match(native.stderr, /Non-baselinable architecture/); + } finally { + f.close(); + } +}); + +test('vendored exemption rejects unregistered and modified template files', () => { + const f = fixture(); + try { + f.write('src/index.js', 'console.log("app");\n'); + const base = f.commit(); + const template = fileURLToPath(new URL('..', import.meta.url)); + for (const path of [...templateFiles(template), 'template-manifest.json']) { + const destination = join(f.cwd, 'tools/quality', path); + mkdirSync(dirname(destination), { recursive: true }); + cpSync(join(template, path), destination); + } + const clean = f.run('guards', '--base', base); + assert.equal(clean.status, 0, clean.stderr); + f.write('tools/quality/hidden.js', 'export const hidden = 1;'); + assert.match(f.run('guards', '--base', base).stderr, /undeclared/); + rmSync(join(f.cwd, 'tools/quality/hidden.js')); + f.write('tools/quality/README.md', 'unreviewed mutation'); + assert.match(f.run('guards', '--base', base).stderr, /integrity mismatch/); + } finally { + f.close(); + } +}); + +/** Real embedded Svelte clones keep language identity but historical evidence belongs to their physical component. */ +test('jscpd Svelte fragments bootstrap existing clones and reject another participant', () => { + const f = fixture(); + try { + const component = ` +

Summary

\n`; + f.write('src/First.svelte', component); + f.write('src/Second.svelte', component); + const base = f.commit(); + const accepted = f.run( + 'duplicates', + '--base', + base, + '--bootstrap', + '--owner', + 'quality', + '--expires', + '2099-01-01', + '--reason', + 'historical Svelte fixture debt', + '--issue', + 'TEST-1', + ); + assert.equal(accepted.status, 0, accepted.stderr); + const report = JSON.parse( + readFileSync(join(f.cwd, 'quality/reports/duplicates.json'), 'utf8'), + ); + assert.ok( + report.findings.some((finding) => + finding.participants?.some((path) => + path.endsWith('.svelte:javascript'), + ), + ), + ); + assert.ok( + report.findings.every((finding) => + finding.paths.every((path) => path.endsWith('.svelte')), + ), + ); + f.write('src/Third.svelte', component); + const expanded = f.run('duplicates', '--base', base); + assert.equal(expanded.status, 1, expanded.stderr); + assert.match(expanded.stderr, /New or increased/); + } finally { + f.close(); + } +}); + +/** Only the new sealed vendor exemption is omitted from historical graphs; authored stale ignores still fail. */ +test('historical Knip removes a current-only exact vendor ignore without relaxing authored coverage', () => { + const f = fixture(); + try { + f.write('src/index.js', 'console.log("app");\n'); + f.write('src/forgotten.js', 'export const historicalDebt = 1;\n'); + const base = f.commit(); + const template = fileURLToPath(new URL('..', import.meta.url)); + for (const path of [...templateFiles(template), 'template-manifest.json']) { + const destination = join(f.cwd, 'tools/quality', path); + mkdirSync(dirname(destination), { recursive: true }); + cpSync(join(template, path), destination); + } + f.write( + 'quality.mjs', + 'import { record } from "./tools/quality/lib/baseline.mjs"; console.log(record("example"));\n', + ); + const config = { + entry: ['src/index.js!', 'quality.mjs'], + project: ['src/**/*.js!', '**/*.mjs'], + ignore: ['tools/quality/**'], + }; + f.write('knip.json', JSON.stringify(config)); + const accepted = f.run( + 'unused-full', + '--base', + base, + '--bootstrap', + '--owner', + 'quality', + '--expires', + '2099-01-01', + '--reason', + 'historical source debt', + '--issue', + 'TEST-1', + ); + assert.equal(accepted.status, 0, accepted.stderr); + config.ignore.push('src/missing/**'); + f.write('knip.json', JSON.stringify(config)); + const invalid = f.run('unused-full', '--base', base); + assert.equal(invalid.status, 1, invalid.stderr); + assert.match(invalid.stderr, /stale exclusion failure.*src\/missing/); + } finally { + f.close(); + } +}); + +/** Pinned formatting defines identical clone units for old and current source, while a new participant still fails the real gate. */ +test('canonical jscpd CLI preserves formatting-only debt and rejects a new clone', () => { + const f = fixture(); + try { + f.write( + 'quality.config.mjs', + `export default { schemaVersion: 1, profile: 'A', defaultBranch: 'main', sourceRoots: ['src'], duplicatePaths: ['src'], duplicateCanonicalFormat: true, duplicateFormats: ['javascript', 'typescript', 'jsx', 'tsx'], duplicateIgnore: [], duplicateMaxPercentage: 100 };\n`, + ); + const source = + 'export function calculate() { const label = "ready"; let value = 0; ' + + Array.from({ length: 20 }, (_, i) => `value += ${i};`).join('') + + 'return { label, value }; }'; + f.write('src/a.js', source); + f.write('src/b.js', source); + const base = f.commit(); + const initial = f.run( + 'duplicates', + '--base', + base, + '--bootstrap', + '--owner', + 'quality-fixture', + '--expires', + '2099-12-31', + '--reason', + 'Historical clone fixture', + '--issue', + 'https://example.invalid/quality', + ); + assert.equal(initial.status, 0, initial.stderr); + const baseline = JSON.parse( + readFileSync(join(f.cwd, 'quality/baselines/duplicates.json'), 'utf8'), + ); + assert.ok(baseline.entries.length > 0); + f.write( + 'src/a.js', + source.replaceAll(';', ';\n').replaceAll('"ready"', "'ready'"), + ); + const formatted = f.run('duplicates', '--base', base); + assert.equal(formatted.status, 0, formatted.stderr); + f.write('src/c.js', source); + const growth = f.run('duplicates', '--base', base); + assert.notEqual(growth.status, 0); + assert.match(growth.stderr, /New or increased|new\/increased/); + } finally { + f.close(); + } +}); + +/** Invalid syntax or a framework file without its formatter must fail canonical analysis instead of disappearing from coverage. */ +test('canonical jscpd fails closed for unsupported or malformed source', () => { + const f = fixture(); + try { + f.write( + 'quality.config.mjs', + `export default { schemaVersion: 1, profile: 'A', defaultBranch: 'main', sourceRoots: ['src'], duplicatePaths: ['src'], duplicateCanonicalFormat: true, duplicateIgnore: [], duplicateMaxPercentage: 100 };\n`, + ); + f.write('src/index.js', 'export const value = 1;'); + const base = f.commit(); + f.write('src/index.js', 'export const value = ;'); + assert.notEqual(f.run('duplicates', '--base', base).status, 0); + f.write('src/index.js', 'export const value = 1;'); + f.write( + 'src/Widget.svelte', + '

{value}

', + ); + const unsupported = f.run('duplicates', '--base', base); + assert.notEqual(unsupported.status, 0); + assert.match(unsupported.stderr, /framework formatter/); + } finally { + f.close(); + } +}); + +/** Current test-runner config is an analyzer input; historical application and test source must still come only from Git. */ +test('historical replay uses current Jest config without replacing trusted source', () => { + const f = fixture(); + try { + f.write('src/index.js', 'export const value = "historical";\n'); + f.write('jest.config.cjs', 'module.exports = { rootDir: "old" };\n'); + const base = f.commit(); + f.write('src/index.js', 'export const value = "current-only";\n'); + f.write('jest.config.cjs', 'module.exports = { rootDir: __dirname };\n'); + const historical = new URL('../lib/historical.mjs', import.meta.url).href; + const template = fileURLToPath(new URL('../', import.meta.url)); + const script = `import { historicalAnalysis } from ${JSON.stringify(historical)}; + import { readFileSync, existsSync } from 'node:fs'; + const value = historicalAnalysis(${JSON.stringify(base)}, {knipConfig:'knip.json'}, ${JSON.stringify(template)}, () => ({ + config: readFileSync('jest.config.cjs','utf8'), + source: readFileSync('src/index.js','utf8'), + newSource: existsSync('src/current-only.js') + })); process.stdout.write(JSON.stringify(value));`; + f.write( + 'src/current-only.js', + 'throw new Error("must not enter historical source");\n', + ); + const result = spawnSync( + process.execPath, + ['--input-type=module', '-e', script], + { cwd: f.cwd, encoding: 'utf8', timeout: 15000 }, + ); + assert.equal(result.status, 0, result.stderr); + const replay = JSON.parse(result.stdout); + assert.match(replay.config, /__dirname/); + assert.match(replay.source, /historical/); + assert.equal(replay.newSource, false); + } finally { + f.close(); + } +}); + +/** A fixed early callback cannot renumber later debt or lend its larger allowance to a different growing callback. */ +test('actual complexity CLI binds callback allowances to lexical owners', () => { + const f = fixture(); + try { + const preset = new URL('../eslint.mjs', import.meta.url).href; + f.write( + 'eslint.config.mjs', + `import { maintainabilityConfig, tseslint } from '${preset}'; export default [{languageOptions:{parser:tseslint.parser}}, ...maintainabilityConfig(), {rules:{complexity:['error',2]}}];`, + ); + const earlier = + 'const earlier = wrap((value) => { if (value.a) return 1; if (value.b) return 2; if (value.c) return 3; if (value.d) return 4; if (value.e) return 5; return 0; });'; + const later = + 'const later = wrap((value) => { if (value.a) return 1; if (value.b) return 2; return 0; });'; + f.write('src/index.js', `${earlier}\n${later}`); + const base = f.commit(); + const args = [ + 'report', + '--kind', + 'eslint', + '--base', + base, + '--bootstrap', + '--owner', + 'quality-fixture', + '--expires', + '2099-12-31', + '--reason', + 'Historical callback debt', + '--issue', + 'TEST-1', + '--', + process.execPath, + fileURLToPath(new URL('../complexity.mjs', import.meta.url)), + '--config', + 'eslint.config.mjs', + 'src/index.js', + ]; + const original = f.run(...args); + assert.equal(original.status, 0, original.stderr); + const originalBaseline = JSON.parse( + readFileSync(join(f.cwd, 'quality/baselines/complexity.json'), 'utf8'), + ); + assert.deepEqual( + originalBaseline.entries.map(({ value }) => value).sort(), + [3, 6], + ); + f.write( + 'src/index.js', + `const earlier = wrap((value) => value);\n${later}`, + ); + const fixed = f.run(...args); + assert.equal(fixed.status, 0, fixed.stderr); + const reducedBaseline = JSON.parse( + readFileSync(join(f.cwd, 'quality/baselines/complexity.json'), 'utf8'), + ); + assert.equal(reducedBaseline.entries.length, 1); + assert.equal( + reducedBaseline.entries[0].key, + originalBaseline.entries.find(({ value }) => value === 3).key, + ); + f.write( + 'src/index.js', + `const earlier = wrap((value) => value);\n${later.replace('return 0;', 'if (value.c) return 3; return 0;')}`, + ); + const growth = f.run(...args); + assert.equal(growth.status, 1, growth.stderr); + assert.match( + growth.stderr, + /Cannot baseline a new\/increased finding.*later/, + ); + } finally { + f.close(); + } +}); + +/** Class field initializers and static blocks are independent ESLint code paths and must keep their class ownership. */ +test('actual complexity CLI resolves class field and static block scopes', () => { + const f = fixture(); + try { + const preset = new URL('../eslint.mjs', import.meta.url).href; + f.write( + 'eslint.config.mjs', + `import { maintainabilityConfig, tseslint } from '${preset}'; export default [{languageOptions:{parser:tseslint.parser}}, ...maintainabilityConfig(), {rules:{complexity:['error',2]}}];`, + ); + f.write( + 'src/index.js', + `class First { + value = ready ? (active ? 1 : 2) : 3; + static { if (ready) start(); if (active) finish(); } + } + class Second { + value = ready ? (active ? 1 : 2) : 3; + static { if (ready) start(); if (active) finish(); } + }`, + ); + const base = f.commit(); + const result = f.run( + 'report', + '--kind', + 'eslint', + '--base', + base, + '--bootstrap', + '--owner', + 'quality-fixture', + '--expires', + '2099-12-31', + '--reason', + 'Historical class initializer debt', + '--issue', + 'TEST-1', + '--', + process.execPath, + fileURLToPath(new URL('../complexity.mjs', import.meta.url)), + '--config', + 'eslint.config.mjs', + 'src/index.js', + ); + assert.equal(result.status, 0, result.stderr); + const baseline = JSON.parse( + readFileSync(join(f.cwd, 'quality/baselines/complexity.json'), 'utf8'), + ); + assert.equal(baseline.entries.length, 4); + assert.equal(new Set(baseline.entries.map(({ key }) => key)).size, 4); + assert.ok(baseline.entries.every(({ value }) => value === 3)); + } finally { + f.close(); + } +}); + +/** A Make-shaped source has equal if statements in separate loops; trusted replay retains only the precise old depth allowance. */ +test('actual raw complexity CLI distinguishes lexical loops and rejects depth transfer', () => { + const f = fixture(); + try { + f.write( + 'eslint.config.mjs', + "export default [{rules:{'max-depth':['error',3]}}];", + ); + const shallow = + 'for (const ack of root.ack) { const item = record(ack); if (item) found.push(statusEvent(item)); }'; + const deep = + 'for (const entry of root.entry) { for (const change of entry.changes) { for (const status of change.statuses) { const item = record(status); if (item) found.push(statusEvent(item)); } } }'; + f.write('src/index.js', `function collect(root) { ${shallow} ${deep} }`); + const base = f.commit(); + const args = [ + 'report', + '--kind', + 'eslint', + '--base', + base, + '--bootstrap', + '--owner', + 'quality-fixture', + '--expires', + '2099-12-31', + '--reason', + 'Historical lexical loop depth', + '--issue', + 'TEST-1', + '--', + process.execPath, + fileURLToPath( + new URL('../node_modules/eslint/bin/eslint.js', import.meta.url), + ), + '--config', + 'eslint.config.mjs', + '--no-inline-config', + '--format', + 'json', + 'src/index.js', + ]; + const original = f.run(...args); + assert.equal(original.status, 0, original.stderr); + const old = JSON.parse( + readFileSync(join(f.cwd, 'quality/baselines/complexity.json'), 'utf8'), + ); + assert.equal(old.entries.length, 1); + assert.equal(old.entries[0].value, 4); + f.write('src/index.js', `function collect(root) { ${deep} }`); + const reduced = f.run(...args); + assert.equal(reduced.status, 0, reduced.stderr); + const retained = JSON.parse( + readFileSync(join(f.cwd, 'quality/baselines/complexity.json'), 'utf8'), + ); + assert.equal(retained.entries[0].key, old.entries[0].key); + f.write( + 'src/index.js', + `function collect(root) { if (root.ready) { if (root.active) { ${shallow} } } }`, + ); + const transfer = f.run(...args); + assert.equal(transfer.status, 1, transfer.stderr); + assert.match(transfer.stderr, /Cannot baseline a new\/increased finding/); + f.write( + 'src/index.js', + `function collect(root) { if (root.ready) { ${deep} } }`, + ); + const growth = f.run(...args); + assert.equal(growth.status, 1, growth.stderr); + assert.match(growth.stderr, /Cannot baseline a new\/increased finding/); + } finally { + f.close(); + } +}); + +/** Raw historical replay resolves Core-shaped duplicate try blocks while rejecting swaps, added scopes and increased nesting. */ +test('actual complexity CLI validates structural context without transferring debt', () => { + const f = fixture(); + try { + f.write( + 'eslint.config.mjs', + "export default [{rules:{'max-depth':['error',3]}}];", + ); + const text = + 'if (match) { if (template.rejected) { try { send(template); } catch (error) { record(error); } } else { saveText(template); } }'; + const document = text.replace('saveText', 'saveDocument'); + /** Retain branch code while varying only a surrounding while depth or branch sequence. */ + const source = (loops, branches) => + `function collect(root) { ${'while (root.ready) {'.repeat(loops)} if (root.templates) { for (const template of root.templates) { ${branches.join('\n')} } } ${'}'.repeat(loops)} }`; + f.write('src/index.js', source(2, [text, document])); + const base = f.commit(); + const args = [ + 'report', + '--kind', + 'eslint', + '--base', + base, + '--bootstrap', + '--owner', + 'quality-fixture', + '--expires', + '2099-12-31', + '--reason', + 'Historical structural branch depth', + '--issue', + 'TEST-1', + '--', + process.execPath, + fileURLToPath( + new URL('../node_modules/eslint/bin/eslint.js', import.meta.url), + ), + '--config', + 'eslint.config.mjs', + '--no-inline-config', + '--format', + 'json', + 'src/index.js', + ]; + const original = f.run(...args); + assert.equal(original.status, 0, original.stderr); + const old = JSON.parse( + readFileSync(join(f.cwd, 'quality/baselines/complexity.json'), 'utf8'), + ); + assert.ok(old.entries.some(({ key }) => key.includes('context-group:'))); + f.write('src/index.js', source(1, [text, document])); + const reduced = f.run(...args); + assert.equal(reduced.status, 0, reduced.stderr); + const retained = JSON.parse( + readFileSync(join(f.cwd, 'quality/baselines/complexity.json'), 'utf8'), + ); + assert.ok( + retained.entries.every((entry) => + old.entries.some( + (prior) => prior.key === entry.key && prior.value >= entry.value, + ), + ), + ); + for (const current of [ + source(2, [document, text]), + source(2, [text, document, text.replace('saveText', 'saveImage')]), + source(3, [text, document]), + ]) { + f.write('src/index.js', current); + const violation = f.run(...args); + assert.equal(violation.status, 1, violation.stderr); + assert.match( + violation.stderr, + /Cannot baseline a new\/increased finding/, + ); + } + } finally { + f.close(); + } +}); diff --git a/tools/quality/test/complexity.test.mjs b/tools/quality/test/complexity.test.mjs new file mode 100644 index 0000000..ccf0730 --- /dev/null +++ b/tools/quality/test/complexity.test.mjs @@ -0,0 +1,247 @@ +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; +import { + mkdtempSync, + writeFileSync, + readFileSync, + rmSync, + symlinkSync, +} from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import test from 'node:test'; +import { fileURLToPath } from 'node:url'; +import { runInNewContext } from 'node:vm'; + +import ts from 'typescript'; + +/** Run the shipped CLI against a disposable source file with real maintainability rules. */ +function fixture(t) { + const root = mkdtempSync(join(tmpdir(), 'canonical-complexity-')); + t.after(() => rmSync(root, { recursive: true, force: true })); + const preset = new URL('../eslint.mjs', import.meta.url).href; + writeFileSync( + join(root, 'eslint.config.mjs'), + `import { maintainabilityConfig, tseslint } from '${preset}'; export default [{languageOptions:{parser:tseslint.parser}}, ...maintainabilityConfig()];`, + ); + const cli = join(root, 'quality-complexity.mjs'); + symlinkSync( + fileURLToPath(new URL('../complexity.mjs', import.meta.url)), + cli, + ); + /** Preserve analyzer exit status and JSON rather than treating a missing report as an empty finding list. */ + return (source, fileName = 'source.js') => { + writeFileSync(join(root, fileName), source); + const result = spawnSync( + process.execPath, + [cli, '--config', 'eslint.config.mjs', fileName], + { cwd: root, encoding: 'utf8', timeout: 15000 }, + ); + assert.equal(readFileSync(join(root, fileName), 'utf8'), source); + return result; + }; +} + +/** Whitespace-only growth is neutral, while an actual extra statement still increases the measured function. */ +test('canonical CLI uses identical units for historical and current line debt', (t) => { + const run = fixture(t); + const statements = Array.from({ length: 80 }, () => 'value += 1;'); + const compact = `export function count() { let value = 0; ${statements.join('')} return value; }`; + const expanded = `export function count() {\n\nlet value = 0;\n${statements.join('\n\n')}\nreturn value;\n}`; + const original = run(compact), + whitespace = run(expanded); + assert.equal(original.status, 1, original.stderr); + assert.equal(whitespace.status, 1, whitespace.stderr); + const [before] = JSON.parse(original.stdout), + [after] = JSON.parse(whitespace.stdout); + assert.equal( + before.source + .split('\n') + .filter((line) => line.trim()) + .join('\n'), + after.source + .split('\n') + .filter((line) => line.trim()) + .join('\n'), + ); + assert.deepEqual( + before.messages.map(({ ruleId, message }) => ({ ruleId, message })), + after.messages.map(({ ruleId, message }) => ({ ruleId, message })), + ); + const growth = run( + compact.replace('return value;', 'value += 2; return value;'), + ); + assert.equal(growth.status, 1, growth.stderr); + const [increased] = JSON.parse(growth.stdout); + assert.notDeepEqual(increased.messages, before.messages); + assert.ok( + increased.source.split('\n').length > before.source.split('\n').length, + ); +}); + +/** A formatter/parser error is a failed analyzer, never a zero-debt report or a baselinable diagnostic. */ +test('canonical CLI fails closed for invalid syntax', (t) => { + const result = fixture(t)('export function broken( {'); + assert.equal(result.status, 2); + assert.equal(result.stdout, ''); + assert.ok(result.stderr.length > 0); +}); + +/** Source directives cannot hide measured debt, and unrelated historical framework directives cannot become parser diagnostics. */ +test('canonical CLI ignores inline configuration on both metric inputs', (t) => { + const run = fixture(t); + const body = `export function count() { let value = 0; ${Array.from({ length: 80 }, () => 'value += 1;').join('')} return value; }`; + const plain = run(body); + const annotated = run( + '/* eslint-disable unknown-framework/legacy-rule, max-lines-per-function */\n' + + body, + ); + assert.equal(plain.status, 1, plain.stderr); + assert.equal(annotated.status, 1, annotated.stderr); + const select = (result) => + JSON.parse(result.stdout).flatMap((file) => + file.messages.map(({ ruleId, message }) => ({ ruleId, message })), + ); + assert.deepEqual(select(annotated), select(plain)); + assert.ok( + select(annotated).some((item) => item.ruleId === 'max-lines-per-function'), + ); +}); + +/** Execute canonical TS/JSX through the same compiler settings to compare literals, child text and evaluation order. */ +function evaluate(source, fileName) { + const compiled = ts.transpileModule(source, { + fileName, + compilerOptions: { + target: ts.ScriptTarget.ES2022, + module: ts.ModuleKind.None, + jsx: ts.JsxEmit.React, + jsxFactory: 'element', + }, + }); + const context = {}; + runInNewContext(compiled.outputText, context, { timeout: 1000 }); + return JSON.parse(context.result); +} + +/** Callback documentation and JSX comments cannot change file/function line debt; actual instructions must still grow it. */ +test('canonical CLI strips JSX documentation before measuring wrapped line debt', (t) => { + const run = fixture(t); + const statements = Array.from({ length: 160 }, () => 'value += 1;').join( + '\n', + ); + const declarations = Array.from( + { length: 350 }, + (_, index) => `export const field${index} = ${index};`, + ).join('\n'); + const plain = `export function Card() { + let value = 0; + ${statements} + return
{field.label}
} />; + } + ${declarations}`; + const documented = plain + .replace( + 'export function', + '/** Render the editable panel and preserve its accumulated count. */\nexport function', + ) + .replace( + 'render={', + 'render={/** Provide the field label and accessible description to the panel. */ ', + ) + .replace( + '', + '{/* Keep the visible label inside the field container. */}', + ) + .replace( + 'value += 1;', + 'value += /* Increment the visible count once. */ 1;', + ); + const original = run(plain, 'source.tsx'); + const annotated = run(documented, 'source.tsx'); + assert.equal(original.status, 1, original.stderr); + assert.equal(annotated.status, 1, annotated.stderr); + const [before] = JSON.parse(original.stdout); + const [after] = JSON.parse(annotated.stdout); + assert.equal(after.source, before.source); + assert.deepEqual(after.messages, before.messages); + assert.ok(before.messages.some(({ ruleId }) => ruleId === 'max-lines')); + assert.ok( + before.messages.some(({ ruleId }) => ruleId === 'max-lines-per-function'), + ); + const growth = run( + documented.replace('let value = 0;', 'let value = 0; value += 2;'), + 'source.tsx', + ); + assert.equal(growth.status, 1, growth.stderr); + const [increased] = JSON.parse(growth.stdout); + assert.notDeepEqual( + increased.messages.map(({ ruleId, message }) => ({ ruleId, message })), + before.messages.map(({ ruleId, message }) => ({ ruleId, message })), + ); +}); + +/** Comment-like literals and rendered JSX text/element order survive printing; adjacent text nodes are normalized like DOM content. */ +test('canonical CLI preserves string, tagged-template and JSX semantics', (t) => { + const source = [ + `function element(type, props, ...children) { + const rendered = []; + for (const child of children) { + const previous = rendered.length - 1; + if (typeof child === 'string' && typeof rendered[previous] === 'string') rendered[previous] += child; + else rendered.push(child); + } + return {type, props, children: rendered}; + }`, + 'const value = "https://example.invalid/a/*literal*/";', + 'const raw = String.raw`line\\n/* literal */ ${value} // end`;', + 'const cooked = `first\nsecond ${value}`;', + String.raw`const expression = /\/\*literal\*\//u;`, + 'const node =
leading {/* actual comment */}{value} trailing
;', + 'globalThis.result = JSON.stringify({value, raw, cooked, matches: expression.test(value), node});', + ].join('\n'); + const result = fixture(t)(source, 'source.tsx'); + assert.equal(result.status, 0, result.stderr); + const [report] = JSON.parse(result.stdout); + assert.deepEqual( + evaluate(report.source, 'source.tsx'), + evaluate(source, 'source.tsx'), + ); + assert.equal( + evaluate(report.source, 'source.tsx').node.props.title, + '/* attribute */', + ); + assert.match(evaluate(report.source, 'source.tsx').raw, /line\\n/); +}); + +/** Comments near automatic semicolon insertion and adjacent unary operators cannot change executable statements. */ +test('canonical CLI preserves automatic-semicolon and operator semantics', (t) => { + const source = `function returned() { + return /* Preserve the original newline after return. */ + 42; + } + const sum = 1 + /* Keep the unary plus separate. */ +2; + globalThis.result = JSON.stringify({isUndefined: returned() === undefined, sum});`; + const result = fixture(t)(source); + assert.equal(result.status, 0, result.stderr); + const [report] = JSON.parse(result.stdout); + assert.deepEqual(evaluate(report.source, 'source.js'), { + isUndefined: true, + sum: 3, + }); + assert.deepEqual( + evaluate(report.source, 'source.js'), + evaluate(source, 'source.js'), + ); +}); + +/** Invalid TSX remains an analyzer failure even though the TypeScript printer can emit a recovered syntax tree. */ +test('canonical CLI fails closed before printing a recovered TSX tree', (t) => { + const result = fixture(t)( + 'export const view =
{/* valid comment */}
;', + 'source.tsx', + ); + assert.equal(result.status, 2); + assert.equal(result.stdout, ''); + assert.match(result.stderr, /Complexity parse failed/); +}); diff --git a/tools/quality/test/git-portability.test.mjs b/tools/quality/test/git-portability.test.mjs new file mode 100644 index 0000000..832c379 --- /dev/null +++ b/tools/quality/test/git-portability.test.mjs @@ -0,0 +1,100 @@ +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; +import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import test from 'node:test'; +import { fileURLToPath, pathToFileURL } from 'node:url'; + +/** Re-run both real Git fixture families under an old-Git command boundary; no successful Git operation is substituted. */ +test('Git fixtures retain real history when git init does not support branch flags', () => { + const cwd = mkdtempSync(join(tmpdir(), 'quality-old-git-')); + const log = join(cwd, 'git-calls.jsonl'); + const shim = join(cwd, 'reject-new-git-flags.mjs'); + // A Node preload avoids Unix executable/shebang assumptions and affects only this test's child processes. + writeFileSync( + shim, + ` +import childProcess from 'node:child_process'; +import { appendFileSync } from 'node:fs'; +import { syncBuiltinESMExports } from 'node:module'; +const actualSpawnSync = childProcess.spawnSync; +childProcess.spawnSync = function(command, args = [], options) { + if (command === 'git') { + appendFileSync(process.env.QUALITY_PORTABILITY_LOG, JSON.stringify(args) + '\\n'); + if (args[0] === 'init' && args.some((arg) => arg.startsWith('-b') || arg === '--initial-branch' || arg.startsWith('--initial-branch='))) { + return actualSpawnSync(process.execPath, ['-e', 'process.stderr.write("fixture: git init branch flags are unavailable\\\\n"); process.exit(97)'], options); + } + } + return actualSpawnSync(command, args, options); +}; +syncBuiltinESMExports(); +`, + ); + const env = { + ...process.env, + NODE_OPTIONS: `${process.env.NODE_OPTIONS ?? ''} --import=${pathToFileURL(shim).href}`, + QUALITY_PORTABILITY_LOG: log, + }; + // This is an independent runner, not a child shard controlled by the outer Node test harness. + delete env.NODE_TEST_CONTEXT; + try { + // Prove the child-process boundary actually rejects the formerly required invocation. + const unsupported = spawnSync( + process.execPath, + [ + '--input-type=module', + '-e', + ` + import { spawnSync } from 'node:child_process'; + const result = spawnSync('git', ['init', '-b', 'main'], {encoding:'utf8'}); + process.stderr.write(result.stderr ?? ''); + process.exit(result.status ?? 1); + `, + ], + { cwd, env, encoding: 'utf8' }, + ); + assert.equal(unsupported.status, 97, unsupported.stderr); + assert.match(unsupported.stderr, /branch flags are unavailable/); + const template = fileURLToPath(new URL('..', import.meta.url)); + const result = spawnSync( + process.execPath, + [ + '--test', + '--test-reporter=tap', + '--test-name-pattern=real CLI blocks undocumented|actual guards require all current docs', + join(template, 'test/cli.test.mjs'), + join(template, 'test/guard-history.test.mjs'), + ], + { + cwd: template, + env, + encoding: 'utf8', + timeout: 60_000, + maxBuffer: 8 * 1024 * 1024, + }, + ); + assert.equal(result.status, 0, `${result.stdout}\n${result.stderr}`); + assert.match(result.stdout, /# pass 2\b/); + assert.match(result.stdout, /# fail 0\b/); + const calls = readFileSync(log, 'utf8') + .trim() + .split('\n') + .map((line) => JSON.parse(line)); + assert.equal( + calls.filter((args) => JSON.stringify(args) === '["init"]').length, + 2, + ); + assert.equal( + calls.filter( + (args) => + JSON.stringify(args) === '["symbolic-ref","HEAD","refs/heads/main"]', + ).length, + 2, + ); + assert.ok(calls.some((args) => args[0] === 'commit')); + assert.ok(calls.some((args) => args[0] === 'show')); + } finally { + rmSync(cwd, { recursive: true, force: true }); + } +}); diff --git a/tools/quality/test/guard-history.test.mjs b/tools/quality/test/guard-history.test.mjs new file mode 100644 index 0000000..390086e --- /dev/null +++ b/tools/quality/test/guard-history.test.mjs @@ -0,0 +1,114 @@ +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import test from 'node:test'; +import { fileURLToPath } from 'node:url'; + +const runner = fileURLToPath(new URL('../run.mjs', import.meta.url)); + +/** Build independent Git history so the actual CLI must distinguish trusted historical syntax from current source failures. */ +function fixture() { + const cwd = mkdtempSync(join(tmpdir(), 'quality-guard-history-')); + const env = { ...process.env, CI: '', QUALITY_BASE: undefined }; + for (const name of Object.keys(env)) { + if (name.startsWith('GIT_')) delete env[name]; + } + env.GIT_CONFIG_GLOBAL = process.platform === 'win32' ? 'NUL' : '/dev/null'; + env.GIT_CONFIG_NOSYSTEM = '1'; + mkdirSync(join(cwd, 'src')); + writeFileSync( + join(cwd, 'quality.config.mjs'), + "export default {schemaVersion:1,profile:'B',defaultBranch:'main',sourceRoots:['src','quality.config.mjs']};\n", + ); + const git = (...args) => { + const result = spawnSync('git', args, { cwd, env, encoding: 'utf8' }); + assert.equal(result.status, 0, result.stderr); + return result.stdout.trim(); + }; + git('init'); + git('symbolic-ref', 'HEAD', 'refs/heads/main'); + git('config', 'user.name', 'Quality fixture'); + git('config', 'user.email', 'quality@example.invalid'); + return { + cwd, + write: (text) => writeFileSync(join(cwd, 'src/Widget.svelte'), text), + commit: () => { + git('add', '.'); + git('commit', '-m', 'test: historical syntax'); + return git('rev-parse', 'HEAD'); + }, + run: (base) => + spawnSync(process.execPath, [runner, 'guards', '--base', base], { + cwd, + env, + encoding: 'utf8', + timeout: 30_000, + }), + close: () => rmSync(cwd, { recursive: true, force: true }), + }; +} + +test('actual guards require all current docs after unparseable trusted Svelte history', () => { + const f = fixture(); + try { + // Historical markup embeds script text in a JavaScript template; the old script extractor cannot parse that extra unit. + f.write( + '\n', + ); + const base = f.commit(); + f.write( + '\n

Readable widget

', + ); + const undocumented = f.run(base); + assert.notEqual(undocumented.status, 0); + assert.match(undocumented.stderr, /document stable/); + assert.match(undocumented.stderr, /document changed/); + assert.doesNotMatch(undocumented.stderr, /Cannot parse/); + + f.write( + '\n

Readable widget

', + ); + const documented = f.run(base); + assert.equal(documented.status, 0, documented.stderr); + assert.match(documented.stdout, /guards: PASS/); + + f.write(''); + const invalidCurrent = f.run(base); + assert.notEqual(invalidCurrent.status, 0); + assert.match(invalidCurrent.stderr, /Cannot parse src\/Widget\.svelte/); + + const invalidBase = f.run('nonexistent-trusted-reference'); + assert.notEqual(invalidBase.status, 0); + assert.match(invalidBase.stderr, /git rev-parse failed/); + } finally { + f.close(); + } +}); + +test('historical fallback does not consume source I/O or configuration failures', () => { + const f = fixture(); + try { + f.write(''); + const base = f.commit(); + rmSync(join(f.cwd, 'src/Widget.svelte')); + mkdirSync(join(f.cwd, 'src/Widget.svelte')); + const invalidInput = f.run(base); + assert.notEqual(invalidInput.status, 0); + assert.match( + invalidInput.stderr, + /EISDIR|illegal operation on a directory/, + ); + + writeFileSync( + join(f.cwd, 'quality.config.mjs'), + 'export default {schemaVersion:1,profile:"unknown",sourceRoots:["src"]};', + ); + const invalidConfig = f.run(base); + assert.notEqual(invalidConfig.status, 0); + assert.match(invalidConfig.stderr, /concrete profile/); + } finally { + f.close(); + } +}); diff --git a/tools/quality/test/ratchet.test.mjs b/tools/quality/test/ratchet.test.mjs new file mode 100644 index 0000000..fc2376c --- /dev/null +++ b/tools/quality/test/ratchet.test.mjs @@ -0,0 +1,264 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { assess, parseJson } from '../lib/baseline.mjs'; +import { + knipRecords, + duplicateRecords, + eslintRecords, + tokenFingerprint, +} from '../lib/reports.mjs'; +import { functionsIn, suppressionErrors } from '../lib/guards.mjs'; + +const owner = { + owner: 'quality-maintainers', + reason: 'Existing complexity', + issue: '1MSG-156', + expires: '2026-11-12', +}; +const baseline = (entries) => ({ schemaVersion: 1, entries }); +const allowance = (key, value) => ({ key, value, ...owner }); + +test('growth cannot be offset by reductions, and reductions retire allowances', () => { + const old = baseline([allowance('a', 25), allowance('b', 20)]); + assert.match( + assess( + [ + { key: 'a', value: 26 }, + { key: 'b', value: 15 }, + ], + old, + old, + '2026-10-12', + ).join('\n'), + /increased/, + ); + assert.match( + assess( + [ + { key: 'a', value: 25 }, + { key: 'b', value: 15 }, + ], + old, + old, + '2026-10-12', + ).join('\n'), + /Reduce/, + ); +}); + +test('new or increased baselines, expiry extensions and stale allowances fail', () => { + const old = baseline([allowance('a', 25)]); + const next = baseline([ + { ...allowance('a', 26), expires: '2026-12-12' }, + allowance('new', 1), + ]); + const errors = assess( + [{ key: 'a', value: 26 }], + next, + old, + '2026-10-12', + ).join('\n'); + assert.match(errors, /expanded/); + assert.match(errors, /expiry extended/); + assert.match(errors, /stale/); + assert.match(assess([], old, old, '2026-12-01').join('\n'), /Expired/); +}); + +test('empty or malformed analyzer reports are not successful checks', () => { + assert.throws(() => parseJson('Killed', 'Knip'), /complete JSON/); + assert.throws(() => knipRecords({}), /schema/); + assert.throws( + () => + duplicateRecords({ + duplicates: [], + statistics: { total: { sources: 0 } }, + }), + /empty/, + ); + assert.throws(() => eslintRecords([]), /empty/); +}); + +test('Knip distinguishes unresolved imports, unused dependencies and exported symbols', () => { + const rows = knipRecords({ + issues: [ + { + file: 'src/a.ts', + exports: [{ name: 'thing', line: 3 }], + unresolved: [{ name: './missing', line: 1 }], + files: [], + }, + { file: 'package.json', dependencies: [{ name: 'unused' }] }, + ], + }); + assert.equal(rows.length, 3); + assert.ok(rows.some((row) => row.rule === 'unresolved')); + const moved = knipRecords({ + issues: [{ file: 'src/a.ts', exports: [{ name: 'thing', line: 99 }] }], + }); + assert.equal(rows.find((row) => row.rule === 'exports').key, moved[0].key); +}); + +test('duplicate identity ignores line moves but notices additional participants and extended code', () => { + const clone = { + format: 'typescript', + fragment: 'const value = input + 3;', + tokens: 7, + firstFile: { name: 'src/a.ts', start: 1, end: 2 }, + secondFile: { name: 'src/b.ts', start: 7, end: 8 }, + }; + const report = (clones) => ({ + duplicates: clones, + statistics: { total: { sources: 3 } }, + }); + const original = duplicateRecords(report([clone])); + const moved = duplicateRecords( + report([ + { ...clone, firstFile: { ...clone.firstFile, start: 9, end: 10 } }, + ]), + ); + assert.equal(original[0].key, moved[0].key); + assert.notEqual( + original[0].key, + duplicateRecords( + report([clone, { ...clone, secondFile: { name: 'src/c.ts' } }]), + )[0].key, + ); + assert.notEqual( + original[0].key, + duplicateRecords( + report([{ ...clone, fragment: clone.fragment + 'return value;' }]), + )[0].key, + ); + assert.equal( + tokenFingerprint('const a = 1;'), + tokenFingerprint('/* moved */ const a=1;'), + ); + assert.notEqual( + tokenFingerprint('const a="a b";'), + tokenFingerprint('const a="ab";'), + ); +}); + +test('documentation covers private methods, arrow helpers and Svelte scripts', () => { + const source = + '/** Resolve the current owner. */\nconst owner = () => 1;\nclass Foo {\n/** Release the acquired resource. */\nprivate release() {}\n}'; + const functions = functionsIn('src/a.ts', source); + assert.equal(functions.length, 2); + assert.ok(functions.every((fn) => fn.comments.length)); + assert.equal( + functionsIn( + 'View.svelte', + '

Hi

', + ).length, + 1, + ); + assert.throws( + () => functionsIn('broken.ts', 'function f( {'), + /Cannot parse/, + ); +}); + +test('documentation fingerprint preserves array holes and changes to callback ownership', () => { + const signature = (source) => functionsIn('src/a.ts', source)[0].signature; + assert.equal( + signature('function f() { return [1]; }'), + signature('function f() { return [1,]; }'), + ); + assert.notEqual( + signature('function f() { return []; }'), + signature('function f() { return [,]; }'), + ); + assert.notEqual( + signature('function f() { return [1]; }'), + signature('function f() { return [1,,]; }'), + ); + assert.notEqual( + functionsIn('src/a.ts', 'first(() => { return 1; });')[0].key, + functionsIn('src/a.ts', 'second(() => { return 1; });')[0].key, + ); +}); + +test('whole-file line limits keep their identity when the diagnostic moves between functions', () => { + const finding = (line) => + eslintRecords([ + { + filePath: 'lib/guards.mjs', + messages: [ + { + ruleId: 'max-lines', + message: 'File has too many lines (600). Maximum allowed is 500.', + line, + column: 1, + }, + ], + }, + ])[0]; + assert.equal(finding(20).key, 'lib/guards.mjs|max-lines|'); + assert.equal(finding(120).key, finding(20).key); +}); + +test('suppression gates do not mistake strings for directives', () => { + assert.equal( + suppressionErrors('a.ts', 'const example = "// @ts-ignore";', {}).length, + 0, + ); + assert.equal( + suppressionErrors('a.ts', '// @ts-nocheck\nexport const a = 1;', {}).length, + 1, + ); + assert.equal( + suppressionErrors('a.ts', '/* eslint-disable */\nexport const a = 1;', {}) + .length, + 1, + ); + assert.equal( + suppressionErrors( + 'a.ts', + '// eslint-disable-next-line no-alert -- Temporary browser compatibility\nalert(1);', + {}, + ).length, + 0, + ); + assert.equal( + suppressionErrors( + 'a.ts', + '// @ts-expect-error: Verify rejected primitive input\nf(1);', + {}, + ).length, + 1, + ); + assert.equal( + suppressionErrors( + 'negative.test.ts', + '// @ts-expect-error: Verify rejected primitive input\nf(1);', + { negativeTypeTests: ['*.test.ts'] }, + ).length, + 0, + ); +}); + +/** Formatting within template expressions and a chained call must not invent a new function or callback. */ +test('documentation identities preserve template-expression context and stable call chains', () => { + const before = + 'describe("groupIntoBlocks",()=>{it("splits a parent",()=>{const value=Array.from({length:3},(_,i)=>({key:`p.k${i}`,text:`Text ${i}`}));return value;});});'; + const after = + "describe('groupIntoBlocks', () => {\n it('splits a parent', () => {\n const value = Array.from({length:3}, (_, i) => ({\n key: `p.k${i}`,\n text: `Text ${i}`,\n })); return value;\n });\n});"; + const identity = (source) => + functionsIn('src/a.ts', source).map(({ key, signature }) => ({ + key, + signature, + })); + assert.deepEqual(identity(before), identity(after)); + assert.notDeepEqual( + identity(before), + identity(before.replace('Text ${i}', 'Different ${i}')), + ); + const chained = 'prefetch({ value: 1 }).catch(() => { recover(); });'; + const documented = + 'prefetch({ /** Explain the input. */ value: 1, }).catch(() => { recover(); });'; + assert.deepEqual(identity(chained), identity(documented)); + assert.notDeepEqual( + identity(chained), + identity(chained.replace('prefetch', 'send')), + ); +}); diff --git a/tools/quality/test/reports.test.mjs b/tools/quality/test/reports.test.mjs new file mode 100644 index 0000000..339ee55 --- /dev/null +++ b/tools/quality/test/reports.test.mjs @@ -0,0 +1,344 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; + +import { ESLint } from 'eslint'; + +import { eslintRecords } from '../lib/reports.mjs'; + +/** Generate real small-fixture diagnostics with low thresholds without changing the shipped policy. */ +async function analyze(source, rule = 'complexity', limit = 2) { + const eslint = new ESLint({ + overrideConfigFile: true, + overrideConfig: [ + { + languageOptions: { parserOptions: { ecmaFeatures: { jsx: true } } }, + rules: { [rule]: ['error', limit] }, + }, + ], + }); + const reports = await eslint.lintText(source, { filePath: 'fixture.js' }); + assert.equal(reports.length, 1); + assert.equal(reports[0].fatalErrorCount, 0); + return reports.map((report) => ({ + ...report, + filePath: 'fixture.js', + source, + })); +} + +/** Vary callback bodies while retaining their call site to probe allowance transfer rather than report counts. */ +function callback(branches, result = '0') { + return `(value) => { ${Array.from({ length: branches }, (_, index) => `if (value.p${index}) return ${index + 1};`).join(' ')} return ${result}; }`; +} + +/** Resolve the real analyzer report to stable keys, preserving parser and ambiguity failures. */ +async function findings(source, rule, limit) { + return eslintRecords(await analyze(source, rule, limit)); +} + +/** Variables and object/JSX properties name anonymous callbacks even when their containing call is unchanged. */ +test('callback identities retain all named variable and property owners', async () => { + const before = `const first = wrap(${callback(2)}); const second = wrap(${callback(3)}); + const options = { load: wrap(${callback(2)}), save: wrap(${callback(3)}) }; + const view = ;`; + const original = await findings(before); + assert.equal(original.length, 6); + assert.equal(new Set(original.map(({ key }) => key)).size, 6); + const current = await findings(before.replaceAll(callback(2), callback(0))); + assert.equal(current.length, 3); + assert.deepEqual( + current, + original.filter(({ value }) => value === 4), + ); +}); + +/** Method names alone cannot move allowances across class, instance/static, or enclosing function boundaries. */ +test('same method and nested function names keep class and function ownership', async () => { + const before = `class First { handle(value) { if (value.a) return 1; if (value.b) return 2; return 0; } + static handle(value) { if (value.a) return 1; if (value.b) return 2; if (value.c) return 3; return 0; } } + class Second { handle(value) { if (value.a) return 1; if (value.b) return 2; if (value.c) return 3; return 0; } } + function left() { function nested(value) { if (value.a) return 1; if (value.b) return 2; return 0; } return nested; } + function right() { function nested(value) { if (value.a) return 1; if (value.b) return 2; if (value.c) return 3; return 0; } return nested; }`; + const original = await findings(before); + assert.equal(original.length, 5); + const reduced = before.replaceAll( + 'if (value.a) return 1; if (value.b) return 2; return 0;', + 'return value;', + ); + assert.deepEqual( + await findings(reduced), + original.filter(({ value }) => value === 4), + ); +}); + +/** The call target and argument index distinguish callbacks without depending on another diagnostic's presence or order. */ +test('call targets and argument positions distinguish unnamed callbacks', async () => { + const source = `left.accept(${callback(2)}, ${callback(3)}); right.accept(${callback(2)});`; + const report = await analyze(source); + const original = eslintRecords(report); + assert.equal(original.length, 3); + const reordered = report.map((file) => ({ + ...file, + messages: [...file.messages].reverse(), + })); + assert.deepEqual(eslintRecords(reordered), original); + const reduced = source.replace( + `left.accept(${callback(2)},`, + `left.accept(${callback(0)},`, + ); + assert.deepEqual( + await findings(reduced), + original.filter( + ({ key, value }) => !(key.includes('"left"') && value === 3), + ), + ); +}); + +/** Identical caller/name chains require the whole sibling group as evidence, including callbacks currently below the limit. */ +test('ambiguous groups cannot borrow another callback body allowance', async () => { + const before = `run(${callback(5)}); run(${callback(2)});`; + const oldKeys = new Set((await findings(before)).map(({ key }) => key)); + const after = `run(${callback(0)}); run(${callback(5)});`; + const current = await findings(after); + assert.equal(current.length, 1); + assert.ok(current.every(({ key }) => !oldKeys.has(key))); + const belowThreshold = `run(${callback(0)}); run(${callback(2)});`; + const prior = await findings(belowThreshold); + const changedSibling = await findings( + `run(${callback(1)}); run(${callback(2)});`, + ); + assert.notEqual(prior[0].key, changedSibling[0].key); + const originalOrder = await findings( + `run(${callback(5)}); run(${callback(0)});`, + ); + const swappedBodies = await findings( + `run(${callback(0)}); run(${callback(5)});`, + ); + assert.notEqual(originalOrder[0].key, swappedBodies[0].key); +}); + +/** Formatting and comments leave ambiguous syntax fingerprints stable; literal/template/JSX content remains meaningful evidence. */ +test('ambiguous fingerprints preserve source semantics and ignore comments', async () => { + const first = callback(2, '`first ${value.name}`'); + const second = callback(2, 'second'); + const source = `run(${first}); run(${second});`; + const original = await findings(source); + assert.equal(original.length, 2); + assert.deepEqual( + await findings(source.replaceAll('if (', '/* Condition */\nif (')), + original, + ); + const changed = await findings( + source.replace('first ${value.name}', 'changed ${value.name}'), + ); + assert.ok( + changed.every(({ key }) => !original.some((entry) => entry.key === key)), + ); + const jsxChanged = await findings(source.replace('>second<', '>different<')); + assert.ok( + jsxChanged.every(({ key }) => !original.some((entry) => entry.key === key)), + ); +}); + +/** Equal bodies under the same lexical owner have no trustworthy correspondence, and duplicate reports cannot invent an ordinal fallback. */ +test('indistinguishable callbacks and duplicate diagnostics fail closed', async () => { + await assert.rejects( + () => findings(`run(${callback(2)}); run(${callback(2)});`), + /Ambiguous lexical scope/, + ); + const reports = await analyze(`const handler = wrap(${callback(2)});`); + reports[0].messages.push(reports[0].messages[0]); + assert.throws( + () => eslintRecords(reports), + /Duplicate ESLint diagnostic identity/, + ); +}); + +/** Separate deep branches have independent syntax owners, so a function cannot lend its deepest block's allowance to another block. */ +test('nested depth reports are keyed by syntax instead of diagnostic ordinal', async () => { + const source = + 'function check(value) { if (value.a) { if (value.b) { if (value.c) return 1; } } if (value.d) { if (value.e) { if (value.f) { if (value.g) return 2; } } } }'; + const records = await findings(source, 'max-depth', 2); + assert.ok(records.length > 1); + assert.equal(new Set(records.map(({ key }) => key)).size, records.length); +}); + +/** Recovered ASTs and missing function locations cannot silently attach findings to file-level debt. */ +test('invalid or missing scope evidence fails closed', () => { + const message = { + ruleId: 'complexity', + message: 'Arrow function has a complexity of 3. Maximum allowed is 2.', + line: 1, + column: 1, + }; + assert.throws( + () => + eslintRecords([ + { filePath: 'missing.js', source: '', messages: [message] }, + ]), + /No lexical scope/, + ); + assert.throws( + () => + eslintRecords([ + { + filePath: 'invalid.js', + source: 'function broken( {', + messages: [message], + }, + ]), + /Invalid syntax/, + ); +}); + +/** Equal statements under distinct lexical loop bindings are independently addressable even when only one is over threshold. */ +test('loop headers distinguish nesting and callback owners without body ordinals', async () => { + const source = `function collect(root) { + for (const ack of root.ack) { const item = record(ack); if (item) found.push(statusEvent(item)); } + for (const entry of root.entry) { for (const change of entry.changes) { + for (const status of change.statuses) { const item = record(status); if (item) found.push(statusEvent(item)); } + } } + }`; + const original = await findings(source, 'max-depth', 3); + assert.equal(original.length, 1); + assert.equal(original[0].value, 4); + assert.deepEqual( + await findings( + source.replace('const ack', '/* Header documentation */ const ack'), + 'max-depth', + 3, + ), + original, + ); + const callbacks = `for (const ack of root.ack) { run(${callback(2)}); } + for (const status of root.statuses) { run(${callback(2)}); } + for (const key in root.properties) { run(${callback(2)}); } + for (let index = 0; index < root.length; index++) { run(${callback(2)}); }`; + const owned = await findings(callbacks); + assert.equal(owned.length, 4); + assert.equal(new Set(owned.map(({ key }) => key)).size, 4); + const asynchronous = await findings( + `for await (const ack of root.ack) { run(${callback(2)}); }`, + ); + assert.equal(asynchronous.length, 1); + assert.ok(!owned.some(({ key }) => key === asynchronous[0].key)); + const shifted = await findings( + callbacks.replace('const ack of root.ack', 'const other of root.ack'), + ); + assert.equal( + shifted.filter(({ key }) => !owned.some((old) => old.key === key)).length, + 1, + ); +}); + +/** Repeated loops with identical headers remain ambiguous; distinct bindings must never enable ordinal-based allowance borrowing. */ +test('identical loop bindings do not disambiguate indistinguishable callbacks', async () => { + const loop = `for (const item of root.items) { run(${callback(2)}); }`; + await assert.rejects(() => findings(loop + loop), /Ambiguous lexical scope/); +}); + +/** Equal try blocks in text/document template branches need their differing surrounding branch bodies as evidence. */ +test('identical scopes use the nearest distinguishing structural branch context', async () => { + const source = `function templates(root) { + while (root.ready) { if (root.templates) { for (const template of root.templates) { + if (match) { if (template.rejected) { try { send(template); } catch (error) { record(error); } } else { saveText(template); } } + if (match) { if (template.rejected) { try { send(template); } catch (error) { record(error); } } else { saveDocument(template); } } + } } } + }`; + const records = await findings(source, 'max-depth', 3); + assert.ok(records.some(({ key }) => key.includes('context-group:'))); + assert.equal(new Set(records.map(({ key }) => key)).size, records.length); + const callbacks = `if (ready) { run(${callback(2)}); } else { run(${callback(2)}); } + try { run(${callback(2)}); } catch (error) { run(${callback(2)}); } finally { run(${callback(2)}); } + switch (kind) { case 'first': run(${callback(2)}); break; case 'second': run(${callback(2)}); break; default: run(${callback(2)}); } + while (active) { run(${callback(2)}); } + do { run(${callback(2)}); } while (active);`; + const owned = await findings(callbacks); + assert.equal(owned.length, 10); + assert.equal(new Set(owned.map(({ key }) => key)).size, 10); + assert.deepEqual( + await findings( + callbacks.replaceAll('run(', '/* Branch documentation */ run('), + ), + owned, + ); +}); + +/** Identical branches and predicates provide no trustworthy address merely because they appear at different source offsets. */ +test('identical structural ancestry still fails closed', async () => { + const branch = `if (ready) { run(${callback(2)}); }`; + await assert.rejects( + () => findings(branch + branch), + /Ambiguous lexical scope/, + ); +}); + +/** ESLint names object-property callbacks at the property token, which precedes the actual function start. */ +test('object property diagnostics resolve only their direct callable initializer', async () => { + for (const fn of [ + `async ${callback(2)}`, + 'async function(value) { if (value.p0) return 1; if (value.p1) return 2; return 0; }', + ]) { + const source = `const endpoints = { handler: ${fn}, unrelated: 1 };`; + const report = await analyze(source); + assert.equal(report[0].messages[0].column, source.indexOf('handler') + 1); + const records = eslintRecords(report); + assert.equal(records.length, 1); + assert.match(records[0].key, /handler/); + assert.deepEqual( + await findings(source.replace('handler:', 'handler: /* Contract */')), + records, + ); + for (const column of [ + source.indexOf('handler:') + 'handler'.length + 1, + source.indexOf('unrelated') + 1, + ]) { + assert.throws( + () => + eslintRecords([ + { + filePath: 'invalid-location.js', + source, + messages: [ + { + ruleId: 'complexity', + line: 1, + column, + message: 'Function has a complexity of 4.', + }, + ], + }, + ]), + /No lexical scope/, + ); + } + } + assert.throws( + () => + eslintRecords([ + { + filePath: 'invalid-location.js', + source: 'const settings = { threshold: 5 };', + messages: [ + { + ruleId: 'complexity', + line: 1, + column: 20, + message: 'Function has a complexity of 4.', + }, + ], + }, + ]), + /No lexical scope/, + ); +}); + +/** An object callback diagnostic inside another function must not consume that enclosing function's complexity allowance. */ +test('object callbacks retain their own budget inside enclosing functions', async () => { + const source = `function useCheckout() { return useMutation({ onError: ${callback(2)} }); }`; + const report = await analyze(source); + assert.equal(report[0].messages.length, 1); + const record = eslintRecords(report)[0]; + assert.match(record.scope, /PropertyAssignment.*onError.*ArrowFunction/); + assert.equal(record.value, 3); +}); diff --git a/tools/quality/test/suppression-syntax.test.mjs b/tools/quality/test/suppression-syntax.test.mjs new file mode 100644 index 0000000..4d5b0bf --- /dev/null +++ b/tools/quality/test/suppression-syntax.test.mjs @@ -0,0 +1,97 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { suppressionErrors } from '../lib/guards.mjs'; + +/** Template segments, regex bodies and JSX text are data even when they contain directive spelling. */ +test('suppression scanning preserves parsed literal boundaries', () => { + const sources = [ + [ + 'a.js', + 'const generated = `start ${name}\n/* eslint-disable */\n// @ts-nocheck\n`;', + ], + [ + 'a.ts', + 'const generated = `a ${`b ${name}\n// @ts-ignore\n`} c ${name} /* eslint-disable */`;', + ], + [ + 'a.mjs', + 'const generated = tag`head ${name}\n// @ts-nocheck\n${other} /* eslint-disable */`;', + ], + [ + 'a.ts', + String.raw`const pattern = /[/*]eslint-disable/; const other = /[//]@ts-ignore/;`, + ], + [ + 'a.tsx', + 'const view =
// @ts-ignore {name}/* eslint-disable */
;', + ], + [ + 'a.jsx', + 'const view =
{/* ordinary comment */} // @ts-ignore
;', + ], + [ + 'a.svelte', + '', + ], + ]; + for (const [path, source] of sources) { + assert.deepEqual( + suppressionErrors(path, source, {}), + [], + `${path}: ${source}`, + ); + } +}); + +/** Actual comments remain enforceable before, within and after expressions, including EOF trivia. */ +test('suppression scanning rejects comments inside template and JSX expressions', () => { + const sources = [ + ['a.js', 'const generated = `a ${ /* eslint-disable */ name } z`;'], + [ + 'a.ts', + 'const generated = `a ${`b ${ /* eslint-disable */ name } c`} d`;', + ], + ['a.mjs', 'const generated = `a ${name // @ts-ignore\n} z`;'], + ['a.cts', 'const generated = `a ${name} z`; // @ts-nocheck'], + ['a.tsx', 'const view =
{/* eslint-disable */ name}
;'], + ['a.jsx', 'const view =
;\n// @ts-ignore'], + ['a.ts', '/* eslint-disable */'], + [ + 'a.ts', + '/** @ts-ignore This comment is real documentation. */\nconst value = 1;', + ], + [ + 'a.ts', + String.raw`const pattern = /[/*]/; /* eslint-disable */ const value = 1;`, + ], + [ + 'a.svelte', + '', + ], + ]; + for (const [path, source] of sources) { + assert.equal( + suppressionErrors(path, source, {}).length, + 1, + `${path}: ${source}`, + ); + } +}); + +/** Malformed scoped comments must not gain an exemption merely by appearing in an interpolation. */ +test('suppression scanning retains scoped exception requirements', () => { + const source = 'const generated = `a ${ // eslint-disable-next-line\nname }`'; + assert.match(suppressionErrors('a.ts', source, {})[0], /must name rules/); + const negative = + 'const generated = `a ${ // @ts-expect-error: Verify an invalid primitive contract\nname }`'; + assert.match( + suppressionErrors('a.ts', negative, {})[0], + /negative type-test scope/, + ); + assert.deepEqual( + suppressionErrors('negative.test.ts', negative, { + negativeTypeTests: ['*.test.ts'], + }), + [], + ); +}); diff --git a/tools/quality/tsconfig.next.json b/tools/quality/tsconfig.next.json new file mode 100644 index 0000000..583277d --- /dev/null +++ b/tools/quality/tsconfig.next.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "module": "ESNext", + "moduleResolution": "Bundler", + "jsx": "preserve", + "noEmit": true, + "isolatedModules": true, + "strict": true, + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + "noEmitOnError": true, + "plugins": [{ "name": "next" }] + } +} diff --git a/tools/quality/tsconfig.node.json b/tools/quality/tsconfig.node.json new file mode 100644 index 0000000..cba7925 --- /dev/null +++ b/tools/quality/tsconfig.node.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true, + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + "noEmitOnError": true, + "forceConsistentCasingInFileNames": true + } +} diff --git a/tools/quality/tsconfig.svelte.json b/tools/quality/tsconfig.svelte.json new file mode 100644 index 0000000..da3596a --- /dev/null +++ b/tools/quality/tsconfig.svelte.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "module": "ESNext", + "moduleResolution": "Bundler", + "noEmit": true, + "isolatedModules": true, + "strict": true, + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + "noEmitOnError": true + } +} diff --git a/tsconfig.quality.json b/tsconfig.quality.json new file mode 100644 index 0000000..b446f45 --- /dev/null +++ b/tsconfig.quality.json @@ -0,0 +1,22 @@ +{ + "extends": "./typescript/tsconfig.quality.json", + "compilerOptions": { + "rootDir": ".", + "jsx": "preserve", + "typeRoots": ["./node_modules/@types", "./typescript/node_modules/@types"] + }, + "include": ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"], + "exclude": [ + "**/node_modules/**", + "**/dist/**", + "tools/quality/**", + "quality/reports/**", + "java/**", + "kotlin/**", + "scala/**", + "csharp/**", + "python/**", + "rust/**", + "ruby/**" + ] +} diff --git a/typescript/AGENTS.md b/typescript/AGENTS.md index 2843de4..910a3c4 100644 --- a/typescript/AGENTS.md +++ b/typescript/AGENTS.md @@ -6,7 +6,7 @@ ## Identity ```yaml -package: "@1msg/sdk" +package: '@1msg/sdk' registry: https://www.npmjs.com/package/@1msg/sdk repository: https://github.com/1msg/1msg-sdk/tree/main/typescript runtime: node>=18 @@ -45,13 +45,13 @@ Need WhatsApp messaging from Node/TS? ## Client map ```typescript -client.config // ClientConfig -client.messaging // MessagingApi — send/list messages, media, interactive -client.profile // ProfileApi — getMe -client.groups // GroupsApi — create/list/manage groups -client.flows // FlowsApi — WhatsApp Flows lifecycle -client.templates // TemplatesApi — listTemplates -client.sendMessage // convenience for sendMessage +client.config; // ClientConfig +client.messaging; // MessagingApi — send/list messages, media, interactive +client.profile; // ProfileApi — getMe +client.groups; // GroupsApi — create/list/manage groups +client.flows; // FlowsApi — WhatsApp Flows lifecycle +client.templates; // TemplatesApi — listTemplates +client.sendMessage; // convenience for sendMessage ``` ## Recipient rules @@ -90,7 +90,7 @@ operationId: initiateCall http: POST /initiateCall client: client.calling.initiateCall summary: Call action (connect / pre_accept / accept / reject / terminate) -description: Perform a WhatsApp Calling action (beta). Proxies upstream `POST /calling/calls`. Despite the historical path name `/initiateCall`, this endpoint handles **all** call actions: | action | Use | Required | |--------|-----|----------| | `connect` | Outbound business → user | `to` + `session` (`sdp_type: offer`) | | `pre_accept` | Inbound (optional, reduces audio clipping) | `call_id` + `session` (`sdp_type: answer`) | | `accept` | Inbound answer | `call_id` + `session` (`sdp_type: answer`) | | `reject` | Decline inbound | `call_id` | | `terminate` | Hang up | `call_id` | **SDP / media (critical)** - `accept` / `pre_accept` require a **WebRTC-generated SDP answer**. - Do **not** send Meta's offer SDP back as the answer. - Postman (or curl) alone **cannot** establish real media — you need a WebRTC or SIP stack. 1msg only proxies signaling. Answer within ~**30–60 seconds** of an inbound `connect` webhook or Meta terminates as unanswered. Common Meta errors include Calling not enabled (`138000`), no permission (`138006`), SDP validation failures. **Outbound** requires a prior Call Permission Request (CPR) acceptance. See the **Calling** tag overview for the full outbound flow and CPR limits. Trial / `subscriptionBlocked` → **403** plain text. Upstream failures often return HTTP 200 with `{ "response": { "error": "..." } }`. +description: Perform a WhatsApp Calling action (beta). Proxies upstream `POST /calling/calls`. Despite the historical path name `/initiateCall`, this endpoint handles **all** call actions: | action | Use | Required | |--------|-----|----------| | `connect` | Outbound business → user | `to` + `session` (`sdp_type: offer`) | | `pre_accept` | Inbound (optional, reduces audio clipping) | `call_id` + `session` (`sdp_type: answer`) | | `accept` | Inbound answer | `call_id` + `session` (`sdp_type: answer`) | | `reject` | Decline inbound | `call_id` | | `terminate` | Hang up | `call_id` | **SDP / media (critical)** - `accept` / `pre_accept` require a **WebRTC-generated SDP answer**. - Do **not** send Meta's offer SDP back as the answer. - Postman (or curl) alone **cannot** establish real media — you need a WebRTC or SIP stack. 1msg only proxies signaling. Answer within ~**30–60 seconds** of an inbound `connect` webhook or Meta terminates as unanswered. Common Meta errors include Calling not enabled (`138000`), no permission (`138006`), SDP validation failures. **Outbound** requires a prior Call Permission Request (CPR) acceptance. See the **Calling** tag overview for the full outbound flow and CPR limits. Trial / `subscriptionBlocked` → **403** plain text. Upstream failures often return HTTP 200 with `{ "response": { "error": "" } }`. `Invalid API KEY` is used only when Meta/360 body actually indicates an invalid API key or token. Other upstream 401s (notably call permission `138006`) pass through `error.message` / `error_user_msg`. typescript: initiateCall(token: string, initiateCallRequest: InitiateCallRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise requestBody: inline object responses: 200, 401, 500 @@ -129,12 +129,25 @@ operationId: getCommerce http: GET /commerce client: client.catalog.getCommerce summary: Get Commerce Settings -description: Returns catalog/cart commerce settings for the channel. - `is_catalog_visible` — show catalog storefront icon (`true`) or hide it (`false`). - `is_cart_enabled` — enable cart (`true`) or disable it (`false`). +description: Returns catalog/cart commerce settings for the channel. Fails with a provider error when the WABA has no catalog linked — that is an API/account limitation, not an MCP schema bug. - `is_catalog_visible` — show catalog storefront icon (`true`) or hide it (`false`). - `is_cart_enabled` — enable cart (`true`) or disable it (`false`). typescript: getCommerce(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise requestBody: none responses: 200, 401, 500 ``` +### createSettings + +```yaml +operationId: createSettings +http: POST /settings +client: client.channel.createSettings +summary: Update channel settings +description: Update channel settings. Only send fields you want to change. `webhookUrl` **replaces** the stored list (one URL string, or up to 5 URLs as an array). Passing an empty value clears webhooks. Repeating the same URL(s) also clears a sticky auto-disable. With several URLs, send the complete array to re-enable one of them — omitting a URL removes it from the channel. +typescript: createSettings(token: string, createSettingsRequest: CreateSettingsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> +requestBody: inline object +responses: 200, 401, 500 +``` + ### getConversationalAutomation ```yaml @@ -155,8 +168,21 @@ operationId: getStatus http: GET /status client: client.channel.getStatus summary: Get channel status -description: Returns WhatsApp Business API client connection status. -typescript: getStatus(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> +description: Return WhatsApp Cloud API connection status for this channel (`connected` when the number can send). May include `accountStatus`, messaging limit, and MM Lite availability. Optional `health_status_warning` appears only when Meta Graph health could not be loaded and a soft `connected` response is returned. Omitted on the normal path and when health details are not applicable for the channel — never an internal provider/transport name. +typescript: getStatus(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise +requestBody: none +responses: 200, 401, 500 +``` + +### listSettings + +```yaml +operationId: listSettings +http: GET /settings +client: client.channel.listSettings +summary: Get channel settings +description: Return channel settings: webhook URL(s), delivery flags, and analytics toggles. Auto-disable / circuit state matches `GET /webhook`. **Prefer `webhookStatuses`** (one row per configured URL). The breaker is per URL, not per channel. Channel-level `haveDisabledWebhooks` is `true` when **at least one** URL in `webhookUrl` is sticky auto-disabled — not "the channel is dead". Live URLs still receive events. Top-level `circuitState` / `reason` / `fails` / `trips` are a compatibility summary of one URL (first sticky-disabled, else first configured). This is the same `GET /settings` endpoint as the REST API (previously missing from MCP). +typescript: listSettings(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise requestBody: none responses: 200, 401, 500 ``` @@ -435,7 +461,7 @@ operationId: createUploadMedia http: POST /uploadMedia client: client.messaging.createUploadMedia summary: Upload media -description: Upload a file to WhatsApp media storage and get a numeric `mediaId` for later use with `send_file` / `send_sticker`. `body` is an HTTP(S) URL or a base64 data URI. +description: Upload a file to WhatsApp media storage and get a numeric `mediaId` for later use with `send_file` / `send_sticker` (`mediaId` field, not `body`). Pass the file as `body` **or** `url` — an HTTP(S) URL or a base64 data URI. The `mediaId` in the response is a numeric string (keep it as a string). typescript: createUploadMedia(token: string, createUploadMediaRequest: CreateUploadMediaRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise requestBody: inline object responses: 200 @@ -556,16 +582,16 @@ await client.messaging.sendButton(client.config.token, { ### sendCarousel -```yaml +````yaml operationId: sendCarousel http: POST /sendCarousel client: client.messaging.sendCarousel summary: Send Carousel -description: You can send product cards via Carousel in two ways: Template messages: do not require a 24-hour customer service window between you and the recipient. Use sendTemplate. Free-form messages: can be sent only when a customer service window is open between you and the recipient. Use sendCarousel. The message structure in /sendCarousel is largely similar to sending a template. However, in this case you must explicitly specify all elements that are created in advance when working with templates. This is because the message is sent without using a template. In /sendCarousel, for sending a Catalog Carousel there can be either 1 URL button or one or more quick reply buttons. -typescript: sendCarousel(token: string, params: Array, body?: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise +description: You can send product cards via Carousel in two ways: Template messages: do not require a 24-hour customer service window between you and the recipient. Use sendTemplate. Free-form messages: can be sent only when a customer service window is open between you and the recipient. Use sendCarousel. The message structure in /sendCarousel is largely similar to sending a template. However, in this case you must explicitly specify all elements that are created in advance when working with templates. This is because the message is sent without using a template. In /sendCarousel, for a Catalog Carousel there can be either 1 URL button or one or more quick reply buttons. Prefer the simple `cards` array (2–10 cards). Each card needs a header media/product plus a CTA URL or quick-reply buttons. Example: ```json { "phone": "79001234567", "body": "Pick a product", "cards": [ { "header": { "type": "image", "image": { "link": "https://example.com/1.jpg" } }, "body": { "text": "Card one" }, "type": "cta_url", "action": { "name": "cta_url", "parameters": { "url": "https://example.com/p1", "display_text": "Open" } } }, { "header": { "type": "image", "image": { "link": "https://example.com/2.jpg" } }, "body": { "text": "Card two" }, "type": "cta_url", "action": { "name": "cta_url", "parameters": { "url": "https://example.com/p2", "display_text": "Open" } } } ] } ``` `params` with a `CAROUSEL` component is the template-like alternative. +typescript: sendCarousel(token: string, body?: string, cards?: Array<{ [key: string]: any; }>, params?: Array, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise requestBody: inline object responses: 200, 400, 401, 429, 500 -``` +```` ```typescript await client.messaging.sendCarousel(client.config.token, { @@ -577,27 +603,30 @@ await client.messaging.sendCarousel(client.config.token, { ### sendContact -```yaml +````yaml operationId: sendContact http: POST /sendContact client: client.messaging.sendContact summary: Send a Contact +description: Send a WhatsApp contact card. Preferred simple body (legacy-compatible): ```json { "phone": "79001234567", "contact": { "name": "Lida", "phone": "+79181976551" } } ``` Cloud API shape also works: `contacts` is an array of objects with `name.formatted_name` and `phones[].phone` (E.164 string, **not** a timestamp). typescript: sendContact(token: string, sendContactRequest?: SendContactRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise requestBody: inline object responses: 200, 400, 401, 429, 500 -``` +```` ```typescript await client.messaging.sendContact(client.config.token, { phone: '12020721369', - contacts: [{ - name: { - formatted_name: 'John Doe', - first_name: 'John', - last_name: 'Doe', + contacts: [ + { + name: { + formatted_name: 'John Doe', + first_name: 'John', + last_name: 'Doe', + }, + phones: [{ phone: '+1234567890', type: 'HOME', wa_id: '' }], }, - phones: [{ phone: '+1234567890', type: 'HOME', wa_id: '' }], - }], + ], }); ``` @@ -689,10 +718,12 @@ await client.messaging.sendList(client.config.token, { body: 'This is a list message', buttonText: 'Click me', action: 'Action', - sections: [{ - title: 'Section 1', - rows: [{ id: '1', title: 'Row 1', description: 'Description for Row 1' }], - }], + sections: [ + { + title: 'Section 1', + rows: [{ id: '1', title: 'Row 1', description: 'Description for Row 1' }], + }, + ], }); ``` @@ -762,7 +793,7 @@ await client.sendMessage({ ### sendOrderDetails -```yaml +````yaml operationId: sendOrderDetails http: POST /sendOrderDetails client: client.messaging.sendOrderDetails @@ -771,7 +802,7 @@ description: Send a WhatsApp **order details** payment / invoice message using a typescript: sendOrderDetails(token: string, sendOrderDetailsRequest: SendOrderDetailsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise requestBody: inline object responses: 200, 400, 401, 500 -``` +```` ### sendPaymentRequest @@ -848,7 +879,7 @@ operationId: getMe http: GET /me client: client.profile.getMe summary: Get Profile Info -description: Get WhatsApp Business Account profile information +description: Return the WhatsApp Business profile for this channel: About, address, description, email, phone, websites, industry (`vertical`), and profile photo URL. typescript: getMe(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise requestBody: none responses: 200, 401, 500 @@ -866,7 +897,7 @@ http: POST /me client: client.profile.updateMe summary: Update profile info description: Update WhatsApp Business Account profile fields. At least one of about, description, email, photo, address, vertical, websites is required. Blocked when the channel subscription limit is exceeded. -typescript: updateMe(token: string, updateMeRequest?: UpdateMeRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> +typescript: updateMe(token: string, updateMeRequest: UpdateMeRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise requestBody: inline object responses: 200, 401, 422, 500 ``` @@ -878,7 +909,8 @@ operationId: addTemplate http: POST /addTemplate client: client.templates.addTemplate summary: Create message template -typescript: addTemplate(token: string, addTemplateRequest?: AddTemplateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> +description: Create a WABA message template (`name`, `category`, `language`, `components`). After create, Meta reviews the template; list it with `GET /templates`. +typescript: addTemplate(token: string, addTemplateRequest?: AddTemplateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise requestBody: inline object responses: 200, 401, 500 ``` @@ -915,7 +947,7 @@ responses: 200, 401, 500 ### sendTemplate -```yaml +````yaml operationId: sendTemplate http: POST /sendTemplate client: client.templates.sendTemplate @@ -924,7 +956,7 @@ description: Send a WhatsApp **template** message (works outside the 24-hour ses typescript: sendTemplate(token: string, sendTemplateRequest?: SendTemplateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> requestBody: inline object responses: 200 -``` +```` ```typescript await client.messaging.sendTemplate( @@ -981,7 +1013,7 @@ operationId: getWebhook http: GET /webhook client: client.webhooks.getWebhook summary: Get webhook URL -description: Returns the configured client webhook URL for this channel. +description: Return the webhook URL(s) currently configured for this channel, plus delivery status for each URL. `webhookUrl` is a string when a single URL is set, an array of strings when multiple URLs are configured, or `null` if none is set. **Prefer `webhookStatuses`.** The circuit breaker is per URL, not per channel. If 1 of 4 URLs is sticky-disabled, that URL is skipped; the other three still receive events. Send/receive are not affected. Channel-level `haveDisabledWebhooks`, `circuitState`, `reason`, `fails`, `trips`, and timestamps are a compatibility summary of **one** URL (the first sticky-disabled URL, else the first configured URL). They are not "the channel is dead". - `haveDisabledWebhooks` — `true` when **at least one** URL in `webhookUrl` is sticky auto-disabled. Live URLs still get events. - `circuitState` — compressed scalar for that same primary URL: `ok` | `degraded` | `open` | `half_open` | `disabled`. - `disabledWebhooks` — currently configured URLs that are sticky-disabled (subset of `webhookUrl`). - `webhookStatuses` — one row per currently configured URL. Use this array to see which endpoints are live vs skipped. - `fails` / `trips` / `firstFailAt` — **diagnostics for support**, not product UI. `fails` = failures in a rolling ~10 minute window (not lifetime). `trips` = failed recovery probes on the 15 min → 1 h → 6 h schedule (sticky disable after 3). Clients can ignore these and use `webhookStatuses` + `disabledWebhooks` only. Sticky disable skips delivery; it does not unconfigure the URL (it stays in `webhookUrl`). Re-enable with `POST /webhook` or `POST /settings`. Those endpoints **replace** the whole list — with multiple URLs, send the full array. typescript: getWebhook(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise requestBody: none responses: 200, 401, 500 @@ -994,8 +1026,8 @@ operationId: setWebhook http: POST /webhook client: client.webhooks.setWebhook summary: Set webhook URL -description: Configure the client webhook URL for inbound events. WhatsApp **Calling** events (`field=calls`) are forwarded as passthrough payloads with `type: "calls"` and `instanceId` (connect / status / terminate). Call permission replies arrive on the normal messages path (`call_permission_reply`). Details: **Calling** tag. -typescript: setWebhook(token: string, getWebhook200Response?: GetWebhook200Response, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> +description: Set the client webhook URL that receives inbound events for this channel. **Replaces** the stored webhook list (it does not append). To deliver the same events to several endpoints, pass an array in `webhookUrl` (max 5) or use `POST /settings`. With several URLs already configured, posting only the disabled URL **drops the others** — send the complete array to re-enable one of many. Incoming payloads include messages, delivery ACKs, group updates, coexistence echoes, and calling events. WhatsApp Calling payloads (`type: "calls"`) are documented under the **Calling** tag. Call permission replies arrive on the normal messages path (`call_permission_reply`). Repeating `POST /webhook` with the same URL(s) clears an auto-disable (self-serve re-enable). Send/receive are not affected by webhook auto-disable. +typescript: setWebhook(token: string, setWebhookRequest: SetWebhookRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise requestBody: inline object responses: 200, 401, 500 ``` @@ -1010,6 +1042,7 @@ import type { SendMessageRequest, MessageSentResponse, ProfileInfo } from '@1msg ### All exported models +- `AddTemplate200Response` (1 fields) - `AddTemplateRequest` (4 fields) - `BlockUserRequest` (1 fields) - `CallingSettings` (1 fields) @@ -1031,15 +1064,19 @@ import type { SendMessageRequest, MessageSentResponse, ProfileInfo } from '@1msg - `CreateReadMessage200Response` (1 fields) - `CreateReadMessage401Response` (1 fields) - `CreateReadMessageRequest` (3 fields) +- `CreateSettingsRequest` (6 fields) +- `CreateSettingsRequestWebhookUrl` - `CreateUploadMedia200Response` (1 fields) -- `CreateUploadMediaRequest` (1 fields) +- `CreateUploadMediaRequest` (2 fields) - `DeleteFlowsFlowId200Response` (2 fields) - `DeleteGroupsGroupId200Response` (2 fields) - `DeleteMediaLegacyRequest` (1 fields) - `ErrorResponse` (1 fields) - `GetCommerce200ResponseInner` (3 fields) - `GetMmLiteStatus200Response` (3 fields) -- `GetWebhook200Response` (1 fields) +- `GetStatus200Response` (5 fields) +- `GetWebhook200Response` (12 fields) +- `GetWebhook200ResponseWebhookUrl` - `GetWhatsappBusinessEncryption200Response` (3 fields) - `InitiateCallRequest` (6 fields) - `InitiateCallRequestSession` (2 fields) @@ -1049,6 +1086,8 @@ import type { SendMessageRequest, MessageSentResponse, ProfileInfo } from '@1msg - `ListBlockedUsers200Response` (1 fields) - `ListFlows200Response` (5 fields) - `ListMessages200Response` (2 fields) +- `ListSettings200Response` (18 fields) +- `ListSettings200ResponseWebhookUrl` - `ListTemplates200Response` (3 fields) - `MessageSentResponse` (4 fields) - `PatchFlowsFlowIdAssets200Response` (3 fields) @@ -1061,8 +1100,10 @@ import type { SendMessageRequest, MessageSentResponse, ProfileInfo } from '@1msg - `SendButtonRequest` (8 fields) - `SendButtonRequestSectionsInner` (2 fields) - `SendButtonRequestSectionsInnerReply` (2 fields) -- `SendCarouselRequest1` (5 fields) -- `SendContactRequest` (4 fields) +- `SendCarouselRequest1` (6 fields) +- `SendContactRequest` (5 fields) +- `SendContactRequestContact` (5 fields) +- `SendContactRequestContactName` - `SendContactRequestContactsInner` (7 fields) - `SendContactRequestContactsInnerName` (6 fields) - `SendContactRequestContactsInnerOrg` (3 fields) @@ -1089,16 +1130,22 @@ import type { SendMessageRequest, MessageSentResponse, ProfileInfo } from '@1msg - `SendStickerRequest` (5 fields) - `SendTemplateRequest` (10 fields) - `SendTemplateRequestLanguage` (2 fields) +- `SetWebhook200Response` (2 fields) +- `SetWebhook200ResponseWebhookUrl` +- `SetWebhookRequest` (1 fields) +- `SetWebhookRequestWebhookUrl` - `SetWhatsappBusinessEncryptionRequest` (1 fields) - `SuccessResponse` (1 fields) - `UpdateCallingSettings200Response` (3 fields) - `UpdateCallingSettings200ResponseResponse` (1 fields) +- `UpdateMe200Response` (1 fields) - `UpdateMeRequest` (7 fields) +- `WebhookUrlStatus` (9 fields) ## Error handling ```typescript -import { ResponseError } from "@1msg/sdk"; +import { ResponseError } from '@1msg/sdk'; // 400 validation, 401 auth, 429 rate limit, 500 server ``` @@ -1106,6 +1153,5 @@ import { ResponseError } from "@1msg/sdk"; openapi_title: 1MSG WhatsApp Business API (Public) openapi_version: 1.0.0 -operations: 60 -models: 84 - +operations: 62 +models: 99 diff --git a/typescript/README.md b/typescript/README.md index 1bc27a8..5037bcd 100644 --- a/typescript/README.md +++ b/typescript/README.md @@ -6,17 +6,17 @@ This document is auto-generated from the public OpenAPI contract plus generated TypeScript client signatures. It is intended to be exhaustive: every public operation, parameter, response code, type export, and common integration pattern is documented. -| | | -|---|---| -| **npm** | [`@1msg/sdk`](https://www.npmjs.com/package/@1msg/sdk) | -| **Source** | [github.com/1msg/1msg-sdk](https://github.com/1msg/1msg-sdk/tree/main/typescript) | -| **API docs** | [docs.1msg.io](https://docs.1msg.io/) | -| **Platform** | [platform.1msg.io](https://platform.1msg.io/) | -| **Support** | support@1msg.io | -| **OpenAPI version** | 1.0.0 | -| **Operations** | 60 | -| **Exported models** | 84 | -| **AI agent guide** | [AGENTS.md](./AGENTS.md) | +| | | +| ------------------- | --------------------------------------------------------------------------------- | +| **npm** | [`@1msg/sdk`](https://www.npmjs.com/package/@1msg/sdk) | +| **Source** | [github.com/1msg/1msg-sdk](https://github.com/1msg/1msg-sdk/tree/main/typescript) | +| **API docs** | [docs.1msg.io](https://docs.1msg.io/) | +| **Platform** | [platform.1msg.io](https://platform.1msg.io/) | +| **Support** | support@1msg.io | +| **OpenAPI version** | 1.0.0 | +| **Operations** | 62 | +| **Exported models** | 99 | +| **AI agent guide** | [AGENTS.md](./AGENTS.md) | --- @@ -66,11 +66,11 @@ pnpm add @1msg/sdk ## Requirements -| Variable | Where to get it | Example | -|----------|-----------------|---------| -| `baseUrl` | Platform → channel → API host | `https://api.1msg.io` | -| `instanceId` | Platform → channel id | `ODI371267300` | -| `token` | Platform → channel → API token | JWT or API key | +| Variable | Where to get it | Example | +| ------------ | ------------------------------ | --------------------- | +| `baseUrl` | Platform → channel → API host | `https://api.1msg.io` | +| `instanceId` | Platform → channel id | `ODI371267300` | +| `token` | Platform → channel → API token | JWT or API key | Use environment variables (`MSG_API_TOKEN`, `MSG_INSTANCE_ID`). Never commit tokens. @@ -97,13 +97,13 @@ createClient({ baseUrl: string; instanceId: string; token: string; }); ### `ClientConfig` fields -| Field | Type | Description | -|-------|------|-------------| -| `baseUrl` | string | API root, no trailing slash | -| `instanceId` | string | Channel instance id | -| `token` | string | Channel API token | -| `basePath` | getter | `{baseUrl}/{instanceId}` | -| `buildRequestUrl(path)` | method | Builds URL with `?token=` | +| Field | Type | Description | +| ----------------------- | ------ | --------------------------- | +| `baseUrl` | string | API root, no trailing slash | +| `instanceId` | string | Channel instance id | +| `token` | string | Channel API token | +| `basePath` | getter | `{baseUrl}/{instanceId}` | +| `buildRequestUrl(path)` | method | Builds URL with `?token=` | ## Authentication @@ -115,19 +115,19 @@ Every generated method accepts `token` as the **first argument**. ## Environments -| Environment | baseUrl | -|-------------|---------| -| Production | `https://api.1msg.io` | -| Staging | `https://api.stage.1msg.io` | -| Trial sandbox | See platform SDK page | +| Environment | baseUrl | +| ------------- | --------------------------- | +| Production | `https://api.1msg.io` | +| Staging | `https://api.stage.1msg.io` | +| Trial sandbox | See platform SDK page | ## Recipient addressing -| Format | Example | When | -|--------|---------|------| -| Individual chatId | `12020721369@c.us` | Known chat from API/webhook | -| Group chatId | `120363046942338209@g.us` | Group conversations | -| phone | `12020721369` | First message, no chatId yet | +| Format | Example | When | +| ----------------- | ------------------------- | ---------------------------- | +| Individual chatId | `12020721369@c.us` | Known chat from API/webhook | +| Group chatId | `120363046942338209@g.us` | Group conversations | +| phone | `12020721369` | First message, no chatId yet | Provide **either** `chatId` **or** `phone`, not both. @@ -157,12 +157,12 @@ createClient() → Client Wrapper around `client.messaging.sendMessage`. Prefer this for text messages. ```typescript -await client.sendMessage({ body: "Hi", chatId: "12020721369@c.us" }); +await client.sendMessage({ body: 'Hi', chatId: '12020721369@c.us' }); ``` ## API reference -**60 operations** documented below with HTTP mapping, schemas, SDK and cURL examples. +**62 operations** documented below with HTTP mapping, schemas, SDK and cURL examples. ## messaging @@ -172,13 +172,13 @@ Namespace: `client.messaging` → `MessagingApi` (23 operations) #### Mark message as read -| | | -|---|---| -| HTTP | `POST /readMessage` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `createReadMessage` | -| Signature | `createReadMessage(token: string, messageId?: string, msgId?: string, typingIndicator?: boolean, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /readMessage` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `createReadMessage` | +| Signature | `createReadMessage(token: string, messageId?: string, msgId?: string, typingIndicator?: boolean, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -191,19 +191,18 @@ Namespace: `client.messaging` → `MessagingApi` (23 operations) **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `messageId` | string | optional | | -| `msgId` | string | optional | | +| Field | Type | Required | Description | +| ----------------- | ------- | -------- | ------------------------------------------------------- | +| `messageId` | string | optional | | +| `msgId` | string | optional | | | `typingIndicator` | boolean | optional | Show WhatsApp typing indicator (max 25s or until reply) | - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Server response example | `—` | -| `401` | Invalid token | `—` | +| Status | Description | Schema | +| ------ | ----------------------- | ------ | +| `200` | Server response example | `—` | +| `401` | Invalid token | `—` | #### SDK example @@ -226,15 +225,15 @@ curl -X POST 'https://api.1msg.io/{instanceId}/readMessage?token={token}' \ #### Upload media -Upload a file to WhatsApp media storage and get a numeric `mediaId` for later use with `send_file` / `send_sticker`. `body` is an HTTP(S) URL or a base64 data URI. +Upload a file to WhatsApp media storage and get a numeric `mediaId` for later use with `send_file` / `send_sticker` (`mediaId` field, not `body`). Pass the file as `body` **or** `url` — an HTTP(S) URL or a base64 data URI. The `mediaId` in the response is a numeric string (keep it as a string). -| | | -|---|---| -| HTTP | `POST /uploadMedia` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `createUploadMedia` | -| Signature | `createUploadMedia(token: string, createUploadMediaRequest: CreateUploadMediaRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ----------------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /uploadMedia` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `createUploadMedia` | +| Signature | `createUploadMedia(token: string, createUploadMediaRequest: CreateUploadMediaRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -247,9 +246,10 @@ Upload a file to WhatsApp media storage and get a numeric `mediaId` for later us **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `body` | string | **required** | File HTTP(S) URL or base64 data URI (`data:;base64,...`) | +| Field | Type | Required | Description | +| ------ | ------ | -------- | -------------------------------------------------------------- | +| `body` | string | optional | File HTTP(S) URL or base64 data URI (`data:;base64,...`) | +| `url` | string | optional | Alias for `body` — public HTTP(S) URL of the file to upload | **OpenAPI example body** @@ -259,12 +259,11 @@ Upload a file to WhatsApp media storage and get a numeric `mediaId` for later us } ``` - **Responses** | Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | +| ------ | ----------- | ------ | +| `200` | OK | `—` | #### SDK example @@ -290,13 +289,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/uploadMedia?token={token}' \ Delete previously uploaded media by numeric `mediaId` (from `/uploadMedia`). This is the canonical deletion endpoint and uses the REST `DELETE` verb on the media resource path. The older `POST /deleteMedia` is a deprecated alias. -| | | -|---|---| -| HTTP | `DELETE /media/{mediaId}` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `deleteMedia` | -| Signature | `deleteMedia(token: string, mediaId: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ------------------------------------------------------------------------ | +| HTTP | `DELETE /media/{mediaId}` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `deleteMedia` | +| Signature | `deleteMedia(token: string, mediaId: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -313,12 +312,12 @@ Delete previously uploaded media by numeric `mediaId` (from `/uploadMedia`). Thi **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Operation successful | `SuccessResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | ----------------- | +| `200` | Operation successful | `SuccessResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -338,13 +337,13 @@ curl -X DELETE 'https://api.1msg.io/{instanceId}/media/{mediaId}?token={token}' **Deprecated.** Use `DELETE /media/{mediaId}` instead. This POST alias is kept for backward compatibility with earlier integrations. New integrations should call `DELETE /media/{mediaId}`: 1msg follows REST conventions for resource deletion going forward (delete a resource with the `DELETE` verb on its resource path). -| | | -|---|---| -| HTTP | `POST /deleteMedia` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `deleteMediaLegacy` | -| Signature | `deleteMediaLegacy(token: string, deleteMediaLegacyRequest: DeleteMediaLegacyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ----------------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /deleteMedia` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `deleteMediaLegacy` | +| Signature | `deleteMediaLegacy(token: string, deleteMediaLegacyRequest: DeleteMediaLegacyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -357,19 +356,18 @@ curl -X DELETE 'https://api.1msg.io/{instanceId}/media/{mediaId}?token={token}' **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| +| Field | Type | Required | Description | +| --------- | ------ | ------------ | --------------------- | | `mediaId` | string | **required** | Numeric WABA media id | - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Operation successful | `SuccessResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | ----------------- | +| `200` | Operation successful | `SuccessResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -389,13 +387,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/deleteMedia?token={token}' \ #### Get MM Lite availability and status -| | | -|---|---| -| HTTP | `GET /mmLiteStatus` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `getMmLiteStatus` | -| Signature | `getMmLiteStatus(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ----------------------------------------------------------- | +| HTTP | `GET /mmLiteStatus` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `getMmLiteStatus` | +| Signature | `getMmLiteStatus(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -408,11 +406,11 @@ curl -X POST 'https://api.1msg.io/{instanceId}/deleteMedia?token={token}' \ **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | MM Lite status for the channel | `—` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------- | +| `200` | MM Lite status for the channel | `—` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -432,13 +430,13 @@ curl -X GET 'https://api.1msg.io/{instanceId}/mmLiteStatus?token={token}' List stored chat history for this channel (requires history storage). Filter with `chatId`, `limit`, `last`, message numbers, or time bounds. -| | | -|---|---| -| HTTP | `GET /messages` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `listMessages` | -| Signature | `listMessages(token: string, chatId?: string, limit?: number, last?: boolean, lastMessageNumber?: number, firstMessageNumber?: number, minTime?: number, maxTime?: number, msgId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| HTTP | `GET /messages` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `listMessages` | +| Signature | `listMessages(token: string, chatId?: string, limit?: number, last?: boolean, lastMessageNumber?: number, firstMessageNumber?: number, minTime?: number, maxTime?: number, msgId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -463,8 +461,8 @@ List stored chat history for this channel (requires history storage). Filter wit **Responses** | Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | +| ------ | ----------- | ------ | +| `200` | OK | `—` | #### SDK example @@ -489,13 +487,13 @@ curl -X GET 'https://api.1msg.io/{instanceId}/messages?token={token}' Get WABA media URL and metadata by mediaId (from uploadMedia). The returned `url` is temporary and typically expires within ~5 minutes. -| | | -|---|---| -| HTTP | `GET /retrieveMedia` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `retrieveMedia` | -| Signature | `retrieveMedia(token: string, mediaId: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | -------------------------------------------------------------------------- | +| HTTP | `GET /retrieveMedia` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `retrieveMedia` | +| Signature | `retrieveMedia(token: string, mediaId: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -512,12 +510,12 @@ Get WABA media URL and metadata by mediaId (from uploadMedia). The returned `url **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Media metadata | `—` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------- | +| `200` | Media metadata | `—` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -537,13 +535,13 @@ curl -X GET 'https://api.1msg.io/{instanceId}/retrieveMedia?token={token}' Request shipping address from the user (WhatsApp interactive `address_message`). **India and Singapore only.** Requires: - Business WhatsApp number registered in that country - Recipient phone matching the country (`+91` ↔ `IN`, `+65` ↔ `SG`) Pass `country: "IN"` or `country: "SG"`. Eligibility is validated upstream; mismatches (e.g. Singapore phone with `country: "IN"`) return errors such as `Unsupported Interactive Message type` (HTTP 200 with `sent: false`). Optional action parameters: `values`, `saved_addresses`, `validation_errors`. -| | | -|---|---| -| HTTP | `POST /sendAddressMessage` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `sendAddressMessage` | -| Signature | `sendAddressMessage(token: string, sendAddressMessageRequest: SendAddressMessageRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | -------------------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /sendAddressMessage` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `sendAddressMessage` | +| Signature | `sendAddressMessage(token: string, sendAddressMessageRequest: SendAddressMessageRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -556,27 +554,26 @@ Request shipping address from the user (WhatsApp interactive `address_message`). **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | integer | optional | Recipient phone (E.164 digits, no +). Must match country. | -| `chatId` | string | optional | | -| `body` | string | **required** | Body text shown with the address request | -| `country` | enum("IN" | "SG") | optional | Address form country. Defaults to IN if omitted. (example="SG") | -| `values` | object | optional | Optional prefilled address fields | -| `saved_addresses` | array | optional | Optional previously saved addresses for the user | -| `validation_errors` | object | optional | Optional field validation errors when re-prompting | -| `quotedMsgId` | string | optional | | - +| Field | Type | Required | Description | +| ------------------- | ------------- | ------------ | --------------------------------------------------------- | +| `phone` | integer | optional | Recipient phone (E.164 digits, no +). Must match country. | +| `chatId` | string | optional | | +| `body` | string | **required** | Body text shown with the address request | +| `country` | enum("IN" | "SG") | optional | Address form country. Defaults to IN if omitted. (example="SG") | +| `values` | object | optional | Optional prefilled address fields | +| `saved_addresses` | array | optional | Optional previously saved addresses for the user | +| `validation_errors` | object | optional | Optional field validation errors when re-prompting | +| `quotedMsgId` | string | optional | | **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Message sent successfully | `MessageSentResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `429` | Rate limit exceeded | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------------- | +| `200` | Message sent successfully | `MessageSentResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `429` | Rate limit exceeded | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -596,13 +593,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendAddressMessage?token={token}' #### Send Reply Buttons Message -| | | -|---|---| -| HTTP | `POST /sendButton` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `sendButton` | -| Signature | `sendButton(token: string, sendButtonRequest?: SendButtonRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | --------------------------------------------------------------------------------------------- | +| HTTP | `POST /sendButton` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `sendButton` | +| Signature | `sendButton(token: string, sendButtonRequest?: SendButtonRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -615,16 +612,16 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendAddressMessage?token={token}' **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | string | optional | Recipient phone with country code. Use phone or chatId. | -| `chatId` | string | optional | Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. | -| `quotedMsgId` | string | optional | Optional Cloud API wamid to quote | -| `body` | string | optional | | -| `footer` | string | optional | | -| `header` | object | optional | Optional interactive header (text/image/video/document) | -| `buttons` | array | optional | Legacy alias for sections (`[{id,title}]`) | -| `sections` | array | optional | | +| Field | Type | Required | Description | +| ------------- | ------------- | -------- | -------------------------------------------------------------------------------------- | +| `phone` | string | optional | Recipient phone with country code. Use phone or chatId. | +| `chatId` | string | optional | Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. | +| `quotedMsgId` | string | optional | Optional Cloud API wamid to quote | +| `body` | string | optional | | +| `footer` | string | optional | | +| `header` | object | optional | Optional interactive header (text/image/video/document) | +| `buttons` | array | optional | Legacy alias for sections (`[{id,title}]`) | +| `sections` | array | optional | | **OpenAPI example body** @@ -645,16 +642,15 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendAddressMessage?token={token}' } ``` - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Message sent successfully | `MessageSentResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `429` | Rate limit exceeded | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------------- | +| `200` | Message sent successfully | `MessageSentResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `429` | Rate limit exceeded | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -692,15 +688,15 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendButton?token={token}' \ #### Send Carousel -You can send product cards via Carousel in two ways: Template messages: do not require a 24-hour customer service window between you and the recipient. Use sendTemplate. Free-form messages: can be sent only when a customer service window is open between you and the recipient. Use sendCarousel. The message structure in /sendCarousel is largely similar to sending a template. However, in this case you must explicitly specify all elements that are created in advance when working with templates. This is because the message is sent without using a template. In /sendCarousel, for sending a Catalog Carousel there can be either 1 URL button or one or more quick reply buttons. +You can send product cards via Carousel in two ways: Template messages: do not require a 24-hour customer service window between you and the recipient. Use sendTemplate. Free-form messages: can be sent only when a customer service window is open between you and the recipient. Use sendCarousel. The message structure in /sendCarousel is largely similar to sending a template. However, in this case you must explicitly specify all elements that are created in advance when working with templates. This is because the message is sent without using a template. In /sendCarousel, for a Catalog Carousel there can be either 1 URL button or one or more quick reply buttons. Prefer the simple `cards` array (2–10 cards). Each card needs a header media/product plus a CTA URL or quick-reply buttons. Example: `json { "phone": "79001234567", "body": "Pick a product", "cards": [ { "header": { "type": "image", "image": { "link": "https://example.com/1.jpg" } }, "body": { "text": "Card one" }, "type": "cta_url", "action": { "name": "cta_url", "parameters": { "url": "https://example.com/p1", "display_text": "Open" } } }, { "header": { "type": "image", "image": { "link": "https://example.com/2.jpg" } }, "body": { "text": "Card two" }, "type": "cta_url", "action": { "name": "cta_url", "parameters": { "url": "https://example.com/p2", "display_text": "Open" } } } ] } ` `params` with a `CAROUSEL` component is the template-like alternative. -| | | -|---|---| -| HTTP | `POST /sendCarousel` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `sendCarousel` | -| Signature | `sendCarousel(token: string, params: Array, body?: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /sendCarousel` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `sendCarousel` | +| Signature | `sendCarousel(token: string, body?: string, cards?: Array<{ [key: string]: any; }>, params?: Array, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -713,24 +709,24 @@ You can send product cards via Carousel in two ways: Template messages: do not r **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `body` | string | optional | | -| `params` | array | **required** | | -| `quotedMsgId` | string | optional | | -| `chatId` | string | optional | | -| `phone` | integer | optional | | - +| Field | Type | Required | Description | +| ------------- | ------------- | -------- | ------------------------------------------------------------------- | +| `body` | string | optional | Text shown above the carousel | +| `cards` | array | optional | Preferred. 2–10 carousel cards. | +| `params` | array | optional | Template-like alternative — include a CAROUSEL component with cards | +| `quotedMsgId` | string | optional | | +| `chatId` | string | optional | | +| `phone` | integer | optional | | **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Message sent successfully | `MessageSentResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `429` | Rate limit exceeded | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------------- | +| `200` | Message sent successfully | `MessageSentResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `429` | Rate limit exceeded | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -754,13 +750,15 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendCarousel?token={token}' \ #### Send a Contact -| | | -|---|---| -| HTTP | `POST /sendContact` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `sendContact` | -| Signature | `sendContact(token: string, sendContactRequest?: SendContactRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +Send a WhatsApp contact card. Preferred simple body (legacy-compatible): `json { "phone": "79001234567", "contact": { "name": "Lida", "phone": "+79181976551" } } ` Cloud API shape also works: `contacts` is an array of objects with `name.formatted_name` and `phones[].phone` (E.164 string, **not** a timestamp). + +| | | +| ----------- | ------------------------------------------------------------------------------------------------ | +| HTTP | `POST /sendContact` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `sendContact` | +| Signature | `sendContact(token: string, sendContactRequest?: SendContactRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -773,73 +771,56 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendCarousel?token={token}' \ **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | string | optional | Recipient phone with country code. Use phone or chatId. | -| `chatId` | string | optional | Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. | -| `quotedMsgId` | string | optional | | -| `contacts` | array | optional | | +| Field | Type | Required | Description | +| ------------- | ------------- | ------------ | -------------------------------------------------------------------------------------- | +| `phone` | string | optional | Recipient phone with country code. Use phone or chatId. | +| `chatId` | string | optional | Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. | +| `quotedMsgId` | string | optional | | +| `contact` | object | optional | Simple contact card. Use this or `contacts`. | +| `name` | string | object | **required** | Display name (string) or Cloud API name object | +| `phone` | string | **required** | Contact phone in E.164 (`+79181976551`), not a timestamp | +| `email` | string | optional | | +| `org` | object | optional | | +| `url` | string | optional | | +| `contacts` | array | optional | | **OpenAPI example body** ```json { "phone": "{{testPhone}}", - "contacts": [ - { - "name": { - "formatted_name": "John Doe", - "first_name": "John", - "last_name": "Doe", - "middle_name": "", - "suffix": "", - "prefix": "" - }, - "birthday": "", - "addresses": [], - "emails": [], - "org": { - "company": "", - "department": "", - "title": "" - }, - "phones": [ - { - "phone": "+1234567890", - "type": "HOME", - "wa_id": "" - } - ], - "urls": [] - } - ] + "contact": { + "name": "John Doe", + "phone": "+1234567890" + } } ``` - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Message sent successfully | `MessageSentResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `429` | Rate limit exceeded | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------------- | +| `200` | Message sent successfully | `MessageSentResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `429` | Rate limit exceeded | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example ```typescript await client.messaging.sendContact(client.config.token, { phone: '12020721369', - contacts: [{ - name: { - formatted_name: 'John Doe', - first_name: 'John', - last_name: 'Doe', + contacts: [ + { + name: { + formatted_name: 'John Doe', + first_name: 'John', + last_name: 'Doe', + }, + phones: [{ phone: '+1234567890', type: 'HOME', wa_id: '' }], }, - phones: [{ phone: '+1234567890', type: 'HOME', wa_id: '' }], - }], + ], }); ``` @@ -850,34 +831,10 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendContact?token={token}' \ -H 'Content-Type: application/json' \ -d '{ "phone": "{{testPhone}}", - "contacts": [ - { - "name": { - "formatted_name": "John Doe", - "first_name": "John", - "last_name": "Doe", - "middle_name": "", - "suffix": "", - "prefix": "" - }, - "birthday": "", - "addresses": [], - "emails": [], - "org": { - "company": "", - "department": "", - "title": "" - }, - "phones": [ - { - "phone": "+1234567890", - "type": "HOME", - "wa_id": "" - } - ], - "urls": [] - } - ] + "contact": { + "name": "John Doe", + "phone": "+1234567890" + } }' ``` @@ -887,13 +844,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendContact?token={token}' \ Send an interactive message with a single call-to-action URL button. -| | | -|---|---| -| HTTP | `POST /sendCtaUrl` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `sendCtaUrl` | -| Signature | `sendCtaUrl(token: string, sendCtaUrlRequest: SendCtaUrlRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | -------------------------------------------------------------------------------------------- | +| HTTP | `POST /sendCtaUrl` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `sendCtaUrl` | +| Signature | `sendCtaUrl(token: string, sendCtaUrlRequest: SendCtaUrlRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -906,27 +863,26 @@ Send an interactive message with a single call-to-action URL button. **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | integer | optional | | -| `chatId` | string | optional | | -| `body` | string | **required** | | -| `displayText` | string | **required** | Button label | -| `url` | string | **required** | | -| `header` | object | optional | | -| `footer` | string | optional | | -| `quotedMsgId` | string | optional | | - +| Field | Type | Required | Description | +| ------------- | ------- | ------------ | ------------ | +| `phone` | integer | optional | | +| `chatId` | string | optional | | +| `body` | string | **required** | | +| `displayText` | string | **required** | Button label | +| `url` | string | **required** | | +| `header` | object | optional | | +| `footer` | string | optional | | +| `quotedMsgId` | string | optional | | **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Message sent successfully | `MessageSentResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `429` | Rate limit exceeded | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------------- | +| `200` | Message sent successfully | `MessageSentResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `429` | Rate limit exceeded | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -948,13 +904,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendCtaUrl?token={token}' \ Send a file to an existing chat. (Only if the dialogue has an Open Session). Only one of two parameters is needed to determine the destination - chatId or phone. -| | | -|---|---| -| HTTP | `POST /sendFile` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `sendFile` | -| Signature | `sendFile(token: string, body?: string, filename?: string, mediaId?: string, mediaType?: SendFileMediaTypeEnum, voice?: boolean, caption?: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /sendFile` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `sendFile` | +| Signature | `sendFile(token: string, body?: string, filename?: string, mediaId?: string, mediaType?: SendFileMediaTypeEnum, voice?: boolean, caption?: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -967,17 +923,17 @@ Send a file to an existing chat. (Only if the dialogue has an Open Session). Onl **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `body` | string | optional | File source (required unless mediaId is set): - HTTP/HTTPS URL - Base64 data URI | -| `filename` | string | optional | File name with extension (required with body, not with mediaId) | -| `mediaId` | string | optional | WABA media id from uploadMedia (alternative to body) | -| `mediaType` | enum("image" | "video" | "audio" | "document") | optional | Required when using mediaId | -| `voice` | boolean | optional | Native WhatsApp voice note (audio/ogg only) | -| `caption` | string | optional | (maxLength=1024) | -| `quotedMsgId` | string | optional | | -| `chatId` | string | optional | | -| `phone` | integer | optional | | +| Field | Type | Required | Description | +| ------------- | ------------ | -------- | -------------------------------------------------------------------------------- | +| `body` | string | optional | File source (required unless mediaId is set): - HTTP/HTTPS URL - Base64 data URI | +| `filename` | string | optional | File name with extension (required with body, not with mediaId) | +| `mediaId` | string | optional | WABA media id from uploadMedia (alternative to body) | +| `mediaType` | enum("image" | "video" | "audio" | "document") | optional | Required when using mediaId | +| `voice` | boolean | optional | Native WhatsApp voice note (audio/ogg only) | +| `caption` | string | optional | (maxLength=1024) | +| `quotedMsgId` | string | optional | | +| `chatId` | string | optional | | +| `phone` | integer | optional | | **OpenAPI example body** @@ -990,16 +946,15 @@ Send a file to an existing chat. (Only if the dialogue has an Open Session). Onl } ``` - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Message sent successfully | `MessageSentResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `429` | Rate limit exceeded | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------------- | +| `200` | Message sent successfully | `MessageSentResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `429` | Rate limit exceeded | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -1033,13 +988,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendFile?token={token}' \ Send Interactive WhatsApp Flow message to an existing chat. (Only if the dialogue has an Open Session). Only one of two parameters is needed to determine the destination - chatId or phone. Use this method to send a published WhatsApp Flow as a service (interactive) message. If the 24-hour window is closed, send a template with a FLOW button via /sendTemplate. -| | | -|---|---| -| HTTP | `POST /sendFlow` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `sendFlow` | -| Signature | `sendFlow(token: string, body: string, flowId: string, flowToken: string, flowCta: string, header?: SendFlowRequestHeader, footer?: string, flowAction?: SendFlowFlowActionEnum, flowActionPayload?: object, flowMessageVersion?: string, mode?: SendFlowModeEnum, flowActionData?: object, flowActionScreen?: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /sendFlow` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `sendFlow` | +| Signature | `sendFlow(token: string, body: string, flowId: string, flowToken: string, flowCta: string, header?: SendFlowRequestHeader, footer?: string, flowAction?: SendFlowFlowActionEnum, flowActionPayload?: object, flowMessageVersion?: string, mode?: SendFlowModeEnum, flowActionData?: object, flowActionScreen?: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -1052,34 +1007,33 @@ Send Interactive WhatsApp Flow message to an existing chat. (Only if the dialogu **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `body` | string | **required** | | -| `header` | string | object | optional | | -| `footer` | string | optional | | -| `flowId` | string | **required** | | -| `flowToken` | string | **required** | | -| `flowCta` | string | **required** | | -| `flowAction` | enum("navigate" | "data_exchange") | optional | | -| `flowActionPayload` | object | optional | | -| `flowMessageVersion` | string | optional | | -| `mode` | enum("draft" | "published") | optional | | -| `flowActionData` | object | optional | | -| `flowActionScreen` | string | optional | | -| `quotedMsgId` | string | optional | | -| `chatId` | string | optional | | -| `phone` | integer | optional | | - +| Field | Type | Required | Description | +| -------------------- | --------------- | ---------------- | ----------- | +| `body` | string | **required** | | +| `header` | string | object | optional | | +| `footer` | string | optional | | +| `flowId` | string | **required** | | +| `flowToken` | string | **required** | | +| `flowCta` | string | **required** | | +| `flowAction` | enum("navigate" | "data_exchange") | optional | | +| `flowActionPayload` | object | optional | | +| `flowMessageVersion` | string | optional | | +| `mode` | enum("draft" | "published") | optional | | +| `flowActionData` | object | optional | | +| `flowActionScreen` | string | optional | | +| `quotedMsgId` | string | optional | | +| `chatId` | string | optional | | +| `phone` | integer | optional | | **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Message sent successfully | `MessageSentResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `429` | Rate limit exceeded | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------------- | +| `200` | Message sent successfully | `MessageSentResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `429` | Rate limit exceeded | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -1115,13 +1069,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendFlow?token={token}' \ #### Send List Message -| | | -|---|---| -| HTTP | `POST /sendList` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `sendList` | -| Signature | `sendList(token: string, sendListRequest?: SendListRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | --------------------------------------------------------------------------------------- | +| HTTP | `POST /sendList` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `sendList` | +| Signature | `sendList(token: string, sendListRequest?: SendListRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -1134,15 +1088,15 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendFlow?token={token}' \ **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | string | optional | Recipient phone with country code. Use phone or chatId. | -| `chatId` | string | optional | Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. | -| `quotedMsgId` | string | optional | | -| `body` | string | optional | | -| `buttonText` | string | optional | | -| `action` | string | optional | | -| `sections` | array | optional | | +| Field | Type | Required | Description | +| ------------- | ------------- | -------- | -------------------------------------------------------------------------------------- | +| `phone` | string | optional | Recipient phone with country code. Use phone or chatId. | +| `chatId` | string | optional | Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. | +| `quotedMsgId` | string | optional | | +| `body` | string | optional | | +| `buttonText` | string | optional | | +| `action` | string | optional | | +| `sections` | array | optional | | **OpenAPI example body** @@ -1167,16 +1121,15 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendFlow?token={token}' \ } ``` - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Message sent successfully | `MessageSentResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `429` | Rate limit exceeded | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------------- | +| `200` | Message sent successfully | `MessageSentResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `429` | Rate limit exceeded | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -1186,10 +1139,12 @@ await client.messaging.sendList(client.config.token, { body: 'This is a list message', buttonText: 'Click me', action: 'Action', - sections: [{ - title: 'Section 1', - rows: [{ id: '1', title: 'Row 1', description: 'Description for Row 1' }], - }], + sections: [ + { + title: 'Section 1', + rows: [{ id: '1', title: 'Row 1', description: 'Description for Row 1' }], + }, + ], }); ``` @@ -1224,13 +1179,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendList?token={token}' \ Send a location to an existing chat. (Only if the dialogue has an Open Session). Only one of two parameters is needed to determine the destination - chatId or phone. -| | | -|---|---| -| HTTP | `POST /sendLocation` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `sendLocation` | -| Signature | `sendLocation(token: string, lat: string, lng: string, address?: string, name?: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /sendLocation` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `sendLocation` | +| Signature | `sendLocation(token: string, lat: string, lng: string, address?: string, name?: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -1243,15 +1198,15 @@ Send a location to an existing chat. (Only if the dialogue has an Open Session). **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `lat` | string | **required** | | -| `lng` | string | **required** | | -| `address` | string | optional | | -| `name` | string | optional | | -| `quotedMsgId` | string | optional | | -| `chatId` | string | optional | | -| `phone` | integer | optional | | +| Field | Type | Required | Description | +| ------------- | ------- | ------------ | ----------- | +| `lat` | string | **required** | | +| `lng` | string | **required** | | +| `address` | string | optional | | +| `name` | string | optional | | +| `quotedMsgId` | string | optional | | +| `chatId` | string | optional | | +| `phone` | integer | optional | | **OpenAPI example body** @@ -1265,16 +1220,15 @@ Send a location to an existing chat. (Only if the dialogue has an Open Session). } ``` - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Message sent successfully | `MessageSentResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `429` | Rate limit exceeded | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------------- | +| `200` | Message sent successfully | `MessageSentResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `429` | Rate limit exceeded | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -1308,13 +1262,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendLocation?token={token}' \ #### Send Location Request Message -| | | -|---|---| -| HTTP | `POST /sendLocationRequest` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `sendLocationRequest` | -| Signature | `sendLocationRequest(token: string, sendLocationRequestRequest?: SendLocationRequestRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------ | +| HTTP | `POST /sendLocationRequest` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `sendLocationRequest` | +| Signature | `sendLocationRequest(token: string, sendLocationRequestRequest?: SendLocationRequestRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -1327,12 +1281,12 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendLocation?token={token}' \ **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | string | optional | Recipient phone with country code. Use phone or chatId. | -| `chatId` | string | optional | Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. | -| `quotedMsgId` | string | optional | | -| `body` | string | optional | | +| Field | Type | Required | Description | +| ------------- | ------ | -------- | -------------------------------------------------------------------------------------- | +| `phone` | string | optional | Recipient phone with country code. Use phone or chatId. | +| `chatId` | string | optional | Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. | +| `quotedMsgId` | string | optional | | +| `body` | string | optional | | **OpenAPI example body** @@ -1343,16 +1297,15 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendLocation?token={token}' \ } ``` - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Message sent successfully | `MessageSentResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `429` | Rate limit exceeded | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------------- | +| `200` | Message sent successfully | `MessageSentResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `429` | Rate limit exceeded | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -1380,13 +1333,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendLocationRequest?token={token} Send a message to an existing chat. (Only if the dialogue has an Open Session). The message will be added to the queue for sending and delivered even if the phone is disconnected from the Internet or authorization is not passed. Only one of two parameters is needed to determine the destination - chatId or phone. -| | | -|---|---| -| HTTP | `POST /sendMessage` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `sendMessage` | -| Signature | `sendMessage(token: string, body: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /sendMessage` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `sendMessage` | +| Signature | `sendMessage(token: string, body: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -1399,12 +1352,12 @@ Send a message to an existing chat. (Only if the dialogue has an Open Session). **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `body` | string | **required** | Message text, UTF-8 or UTF-16 string with emoji (minLength=1, maxLength=4096, example="Hello World 🌍") | -| `quotedMsgId` | string | optional | Message ID to quote/reply to (Cloud API wamid) (pattern=`^wamid\..+$`, example="wamid.HBgNMTIwMjA3MjEzNjkVAgARGBI5RTBCNUY0QUE2RjZBQzhGNDkA") | -| `chatId` | string | optional | Recipient chat ID: phone@c.us, group@g.us, or BSUID@lid (example="12020721369@c.us") | -| `phone` | integer | optional | Phone number starting with country code (alternative to chatId) (example=12020721369) | +| Field | Type | Required | Description | +| ------------- | ------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | +| `body` | string | **required** | Message text, UTF-8 or UTF-16 string with emoji (minLength=1, maxLength=4096, example="Hello World 🌍") | +| `quotedMsgId` | string | optional | Message ID to quote/reply to (Cloud API wamid) (pattern=`^wamid\..+$`, example="wamid.HBgNMTIwMjA3MjEzNjkVAgARGBI5RTBCNUY0QUE2RjZBQzhGNDkA") | +| `chatId` | string | optional | Recipient chat ID: phone@c.us, group@g.us, or BSUID@lid (example="12020721369@c.us") | +| `phone` | integer | optional | Phone number starting with country code (alternative to chatId) (example=12020721369) | **OpenAPI example body** @@ -1415,16 +1368,15 @@ Send a message to an existing chat. (Only if the dialogue has an Open Session). } ``` - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Message sent successfully | `MessageSentResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `429` | Rate limit exceeded | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------------- | +| `200` | Message sent successfully | `MessageSentResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `429` | Rate limit exceeded | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -1450,15 +1402,15 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendMessage?token={token}' \ #### Send order details (India payments template) -Send a WhatsApp **order details** payment / invoice message using a pre-approved **Utility** template that has an `ORDER_DETAILS` button. **India only** (WhatsApp Payments India). Requires: - India WhatsApp Business number - Commerce enabled on the channel (`GET`/`POST /commerce`) - Approved template with an `ORDER_DETAILS` button Use this method when you need structured fields (`order`, `referenceId`, `currency`, `paymentSettings`). The API appends a template button `sub_type: order_details` and sends via the same path as `POST /sendTemplate`. Works **outside the 24-hour session window** (template message). You can also send the same payload yourself with `POST /sendTemplate` by including a button component in `params`: ```json { "type": "button", "sub_type": "order_details", "index": 0, "parameters": [{ "type": "action", "action": { "order_details": { "reference_id": "order-123", "currency": "INR", "order": { "status": "pending", "items": [], "subtotal": { "offset": 100, "value": 50000 } } } } }] } ``` +Send a WhatsApp **order details** payment / invoice message using a pre-approved **Utility** template that has an `ORDER_DETAILS` button. **India only** (WhatsApp Payments India). Requires: - India WhatsApp Business number - Commerce enabled on the channel (`GET`/`POST /commerce`) - Approved template with an `ORDER_DETAILS` button Use this method when you need structured fields (`order`, `referenceId`, `currency`, `paymentSettings`). The API appends a template button `sub_type: order_details` and sends via the same path as `POST /sendTemplate`. Works **outside the 24-hour session window** (template message). You can also send the same payload yourself with `POST /sendTemplate` by including a button component in `params`: `json { "type": "button", "sub_type": "order_details", "index": 0, "parameters": [{ "type": "action", "action": { "order_details": { "reference_id": "order-123", "currency": "INR", "order": { "status": "pending", "items": [], "subtotal": { "offset": 100, "value": 50000 } } } } }] } ` -| | | -|---|---| -| HTTP | `POST /sendOrderDetails` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `sendOrderDetails` | -| Signature | `sendOrderDetails(token: string, sendOrderDetailsRequest: SendOrderDetailsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | -------------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /sendOrderDetails` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `sendOrderDetails` | +| Signature | `sendOrderDetails(token: string, sendOrderDetailsRequest: SendOrderDetailsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -1471,28 +1423,30 @@ Send a WhatsApp **order details** payment / invoice message using a pre-approved **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | integer | optional | Recipient phone (India E.164 digits, no +). Use phone or chatId. (example=919876543210) | -| `chatId` | string | optional | Recipient chatId (e.g. phone@c.us). Use phone or chatId. | -| `template` | string | **required** | Approved Utility template name that includes an ORDER_DETAILS button (example="order_details_utility") | -| `namespace` | string | **required** | Template namespace from the channel / template list (example="your_namespace_uuid") | -| `language` | object | **required** | Template language | - | `code` | string | **required** | Language code (example="en") | - | `policy` | string | optional | Optional language policy (example="deterministic") | -| `params` | array | optional | Extra template components (HEADER / BODY / etc.). If an order_details button is missing, the API appends one from order / referenceId / currency / paymentSettings. | -| `referenceId` | string | optional | Unique order / payment reference id (maps to reference_id) (example="order-123") | -| `currency` | string | optional | Currency code for India payments (example="INR") | -| `paymentSettings` | object | optional | Optional payment settings (UPI / payment gateway / payment link). Forwarded as payment_settings on the order_details action. | -| `order` | object | **required** | Order payload for the ORDER_DETAILS button. Typical fields: status, items[], subtotal, tax, shipping, discount. Amount objects use `{ "offset": 100, "value": }` (e.g. value 50000 with offset 100 = ₹500.00). | - | `status` | string | optional | Order status (example="pending") | - | `items` | array | **required** | Line items | - | `subtotal` | object | optional | | +| Field | Type | Required | Description | +| ----------------- | ------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `phone` | integer | optional | Recipient phone (India E.164 digits, no +). Use phone or chatId. (example=919876543210) | +| `chatId` | string | optional | Recipient chatId (e.g. phone@c.us). Use phone or chatId. | +| `template` | string | **required** | Approved Utility template name that includes an ORDER_DETAILS button (example="order_details_utility") | +| `namespace` | string | **required** | Template namespace from the channel / template list (example="your_namespace_uuid") | +| `language` | object | **required** | Template language | +| `code` | string | **required** | Language code (example="en") | +| `policy` | string | optional | Optional language policy (example="deterministic") | +| `params` | array | optional | Extra template components (HEADER / BODY / etc.). If an order_details button is missing, the API appends one from order / referenceId / currency / paymentSettings. | +| `referenceId` | string | optional | Unique order / payment reference id (maps to reference_id) (example="order-123") | +| `currency` | string | optional | Currency code for India payments (example="INR") | +| `paymentSettings` | object | optional | Optional payment settings (UPI / payment gateway / payment link). Forwarded as payment_settings on the order_details action. | +| `order` | object | **required** | Order payload for the ORDER_DETAILS button. Typical fields: status, items[], subtotal, tax, shipping, discount. Amount objects use `{ "offset": 100, "value": }` (e.g. value 50000 with offset 100 = ₹500.00). | +| `status` | string | optional | Order status (example="pending") | +| `items` | array | **required** | Line items | +| `subtotal` | object | optional | | + | `offset` | integer | optional | (example=100) | | `value` | integer | optional | (example=50000) | - | `tax` | object | optional | | - | `shipping` | object | optional | | - | `discount` | object | optional | | + +| `tax` | object | optional | | +| `shipping` | object | optional | | +| `discount` | object | optional | | **OpenAPI example body** @@ -1527,15 +1481,14 @@ Send a WhatsApp **order details** payment / invoice message using a pre-approved } ``` - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Message sent successfully | `MessageSentResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------------- | +| `200` | Message sent successfully | `MessageSentResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -1584,13 +1537,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendOrderDetails?token={token}' \ Send a regional payment request interactive message (beta scaffold). `region` must be IN, SG, or BR. Payload shape follows Meta regional payments docs; verify on stage before production use. Full regional builders are not implemented yet. -| | | -|---|---| -| HTTP | `POST /sendPaymentRequest` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `sendPaymentRequest` | -| Signature | `sendPaymentRequest(token: string, sendPaymentRequestRequest: SendPaymentRequestRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | -------------------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /sendPaymentRequest` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `sendPaymentRequest` | +| Signature | `sendPaymentRequest(token: string, sendPaymentRequestRequest: SendPaymentRequestRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -1603,23 +1556,22 @@ Send a regional payment request interactive message (beta scaffold). `region` mu **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | integer | **required** | | -| `region` | enum("IN" | "SG" | "BR") | **required** | | -| `body` | string | optional | | -| `interactive` | object | optional | | -| `action` | object | optional | | - +| Field | Type | Required | Description | +| ------------- | --------- | ------------ | ----------- | +| `phone` | integer | **required** | | +| `region` | enum("IN" | "SG" | "BR") | **required** | | +| `body` | string | optional | | +| `interactive` | object | optional | | +| `action` | object | optional | | **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Message sent successfully | `MessageSentResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------------- | +| `200` | Message sent successfully | `MessageSentResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -1641,13 +1593,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendPaymentRequest?token={token}' Send a single catalog product or a product list. Destination is `chatId` or `phone`. `action` is required: - single product: `{ "catalog_id": "...", "product_retailer_id": "..." }` - product list: `{ "catalog_id": "...", "sections": [{ "title": "...", "product_items": [{ "product_retailer_id": "..." }] }] }` -| | | -|---|---| -| HTTP | `POST /sendProduct` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `sendProduct` | -| Signature | `sendProduct(token: string, sendProductRequest: SendProductRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ----------------------------------------------------------------------------------------------- | +| HTTP | `POST /sendProduct` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `sendProduct` | +| Signature | `sendProduct(token: string, sendProductRequest: SendProductRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -1660,15 +1612,15 @@ Send a single catalog product or a product list. Destination is `chatId` or `pho **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | string | optional | Recipient phone with country code. Use phone or chatId. | -| `chatId` | string | optional | Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. | -| `quotedMsgId` | string | optional | | -| `body` | string | optional | Optional message text shown with the product | -| `footer` | string | optional | | -| `header` | string | optional | Text header (product list only) | -| `action` | object | **required** | Catalog action (`catalog_id` + `product_retailer_id`, or `sections` for a list) | +| Field | Type | Required | Description | +| ------------- | ------ | ------------ | -------------------------------------------------------------------------------------- | +| `phone` | string | optional | Recipient phone with country code. Use phone or chatId. | +| `chatId` | string | optional | Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. | +| `quotedMsgId` | string | optional | | +| `body` | string | optional | Optional message text shown with the product | +| `footer` | string | optional | | +| `header` | string | optional | Text header (product list only) | +| `action` | object | **required** | Catalog action (`catalog_id` + `product_retailer_id`, or `sections` for a list) | **OpenAPI example body** @@ -1683,16 +1635,15 @@ Send a single catalog product or a product list. Destination is `chatId` or `pho } ``` - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Message sent successfully | `MessageSentResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `429` | Rate limit exceeded | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------------- | +| `200` | Message sent successfully | `MessageSentResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `429` | Rate limit exceeded | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -1723,13 +1674,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendProduct?token={token}' \ #### Send Reaction -| | | -|---|---| -| HTTP | `POST /sendReaction` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `sendReaction` | -| Signature | `sendReaction(token: string, sendReactionRequest?: SendReactionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | --------------------------------------------------------------------------------------------------- | +| HTTP | `POST /sendReaction` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `sendReaction` | +| Signature | `sendReaction(token: string, sendReactionRequest?: SendReactionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -1742,12 +1693,12 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendProduct?token={token}' \ **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | string | optional | Recipient phone with country code. Use phone or chatId. | -| `chatId` | string | optional | Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. | -| `body` | string | optional | | -| `quotedMsgId` | string | optional | | +| Field | Type | Required | Description | +| ------------- | ------ | -------- | -------------------------------------------------------------------------------------- | +| `phone` | string | optional | Recipient phone with country code. Use phone or chatId. | +| `chatId` | string | optional | Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. | +| `body` | string | optional | | +| `quotedMsgId` | string | optional | | **OpenAPI example body** @@ -1759,16 +1710,15 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendProduct?token={token}' \ } ``` - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Message sent successfully | `MessageSentResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `429` | Rate limit exceeded | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------------- | +| `200` | Message sent successfully | `MessageSentResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `429` | Rate limit exceeded | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -1799,13 +1749,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/sendReaction?token={token}' \ Send a WhatsApp sticker by mediaId or link URL. -| | | -|---|---| -| HTTP | `POST /sendSticker` | -| SDK group | `client.messaging` | -| API class | `MessagingApi` | -| operationId | `sendSticker` | -| Signature | `sendSticker(token: string, sendStickerRequest: SendStickerRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ----------------------------------------------------------------------------------------------- | +| HTTP | `POST /sendSticker` | +| SDK group | `client.messaging` | +| API class | `MessagingApi` | +| operationId | `sendSticker` | +| Signature | `sendSticker(token: string, sendStickerRequest: SendStickerRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -1818,24 +1768,23 @@ Send a WhatsApp sticker by mediaId or link URL. **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | integer | optional | | -| `chatId` | string | optional | | -| `mediaId` | string | optional | WABA media id from uploadMedia | -| `link` | string | optional | Public URL to webp sticker | -| `quotedMsgId` | string | optional | | - +| Field | Type | Required | Description | +| ------------- | ------- | -------- | ------------------------------ | +| `phone` | integer | optional | | +| `chatId` | string | optional | | +| `mediaId` | string | optional | WABA media id from uploadMedia | +| `link` | string | optional | Public URL to webp sticker | +| `quotedMsgId` | string | optional | | **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Message sent successfully | `MessageSentResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `429` | Rate limit exceeded | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------------- | +| `200` | Message sent successfully | `MessageSentResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `429` | Rate limit exceeded | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -1859,15 +1808,15 @@ Namespace: `client.profile` → `ProfileApi` (2 operations) #### Get Profile Info -Get WhatsApp Business Account profile information +Return the WhatsApp Business profile for this channel: About, address, description, email, phone, websites, industry (`vertical`), and profile photo URL. -| | | -|---|---| -| HTTP | `GET /me` | -| SDK group | `client.profile` | -| API class | `ProfileApi` | -| operationId | `getMe` | -| Signature | `getMe(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ------------------------------------------------- | +| HTTP | `GET /me` | +| SDK group | `client.profile` | +| API class | `ProfileApi` | +| operationId | `getMe` | +| Signature | `getMe(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -1880,11 +1829,11 @@ Get WhatsApp Business Account profile information **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Profile information | `ProfileInfo` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------- | +| `200` | Profile information | `ProfileInfo` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -1904,13 +1853,13 @@ curl -X GET 'https://api.1msg.io/{instanceId}/me?token={token}' Update WhatsApp Business Account profile fields. At least one of about, description, email, photo, address, vertical, websites is required. Blocked when the channel subscription limit is exceeded. -| | | -|---|---| -| HTTP | `POST /me` | -| SDK group | `client.profile` | -| API class | `ProfileApi` | -| operationId | `updateMe` | -| Signature | `updateMe(token: string, updateMeRequest?: UpdateMeRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | +| | | +| ----------- | -------------------------------------------------------------------------------------- | +| HTTP | `POST /me` | +| SDK group | `client.profile` | +| API class | `ProfileApi` | +| operationId | `updateMe` | +| Signature | `updateMe(token: string, updateMeRequest: UpdateMeRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -1923,25 +1872,33 @@ Update WhatsApp Business Account profile fields. At least one of about, descript **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `about` | string | optional | Profile About section | -| `address` | string | optional | | -| `description` | string | optional | Business description (max 256 characters) | -| `email` | string | optional | | -| `vertical` | string | optional | Industry of the business | -| `photo` | string | optional | HTTPS URL or data:image/...;base64,... payload | -| `websites` | array | optional | | +| Field | Type | Required | Description | +| ------------- | ------------- | -------- | ----------------------------------------------------------------------- | +| `about` | string | optional | Profile About section (WhatsApp status text) (example="Available 9–18") | +| `address` | string | optional | Business address shown on the profile | +| `description` | string | optional | Business description (max 256 characters) | +| `email` | string | optional | Business email shown on the profile (example="support@example.com") | +| `vertical` | string | optional | Industry of the business | +| `photo` | string | optional | HTTPS URL or data:image/...;base64,... payload | +| `websites` | array | optional | Business website URLs | + +**OpenAPI example body** +```json +{ + "about": "Available 9–18", + "email": "support@example.com" +} +``` **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Profile updated | `—` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `422` | Wrong request (no updatable fields) | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------- | +| `200` | Profile updated | `—` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `422` | Wrong request (no updatable fields) | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -1954,7 +1911,10 @@ await client.profile.updateMe(client.config.token, {}); ```bash curl -X POST 'https://api.1msg.io/{instanceId}/me?token={token}' \ -H 'Content-Type: application/json' \ - -d '{}' + -d '{ + "about": "Available 9–18", + "email": "support@example.com" + }' ``` ## groups @@ -1965,13 +1925,13 @@ Namespace: `client.groups` → `GroupsApi` (7 operations) #### Create Group -| | | -|---|---| -| HTTP | `POST /groups` | -| SDK group | `client.groups` | -| API class | `GroupsApi` | -| operationId | `createGroups` | -| Signature | `createGroups(token: string, createGroupsRequest: CreateGroupsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | -------------------------------------------------------------------------------------------------- | +| HTTP | `POST /groups` | +| SDK group | `client.groups` | +| API class | `GroupsApi` | +| operationId | `createGroups` | +| Signature | `createGroups(token: string, createGroupsRequest: CreateGroupsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -1984,17 +1944,16 @@ Namespace: `client.groups` → `GroupsApi` (7 operations) **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `groupName` | string | **required** | Group subject / name | -| `description` | string | optional | Optional group description | - +| Field | Type | Required | Description | +| ------------- | ------ | ------------ | -------------------------- | +| `groupName` | string | **required** | Group subject / name | +| `description` | string | optional | Optional group description | **Responses** | Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | +| ------ | ----------- | ------ | +| `200` | OK | `—` | #### SDK example @@ -2019,13 +1978,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/groups?token={token}' \ Update group subject, description, and/or profile picture. Path `groupId` is the WABA group id (without `@g.us`). -| | | -|---|---| -| HTTP | `POST /groups/{groupId}` | -| SDK group | `client.groups` | -| API class | `GroupsApi` | -| operationId | `createGroupsGroupId` | -| Signature | `createGroupsGroupId(groupId: string, token: string, createGroupsGroupIdRequest: CreateGroupsGroupIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | +| | | +| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /groups/{groupId}` | +| SDK group | `client.groups` | +| API class | `GroupsApi` | +| operationId | `createGroupsGroupId` | +| Signature | `createGroupsGroupId(groupId: string, token: string, createGroupsGroupIdRequest: CreateGroupsGroupIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | #### Authentication @@ -2038,10 +1997,10 @@ Update group subject, description, and/or profile picture. Path `groupId` is the **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `subject` | string | optional | New group subject / name | -| `description` | string | optional | New group description | +| Field | Type | Required | Description | +| ---------------------- | ------ | -------- | ---------------------------------------------------------- | +| `subject` | string | optional | New group subject / name | +| `description` | string | optional | New group description | | `profile_picture_file` | string | optional | Image URL or base64 data URI for the group profile picture | **OpenAPI example body** @@ -2053,12 +2012,11 @@ Update group subject, description, and/or profile picture. Path `groupId` is the } ``` - **Responses** | Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | +| ------ | ----------- | ------ | +| `200` | OK | `—` | #### SDK example @@ -2081,13 +2039,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/groups/{groupId}?token={token}' \ #### Reset Invite Link -| | | -|---|---| -| HTTP | `POST /groups/{groupId}/inviteLink` | -| SDK group | `client.groups` | -| API class | `GroupsApi` | -| operationId | `createGroupsGroupIdInvitelink` | -| Signature | `createGroupsGroupIdInvitelink(groupId: string, token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | +| | | +| ----------- | ------------------------------------------------------------------------------------------ | +| HTTP | `POST /groups/{groupId}/inviteLink` | +| SDK group | `client.groups` | +| API class | `GroupsApi` | +| operationId | `createGroupsGroupIdInvitelink` | +| Signature | `createGroupsGroupIdInvitelink(groupId: string, token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | #### Authentication @@ -2101,8 +2059,8 @@ curl -X POST 'https://api.1msg.io/{instanceId}/groups/{groupId}?token={token}' \ **Responses** | Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | +| ------ | ----------- | ------ | +| `200` | OK | `—` | #### SDK example @@ -2120,13 +2078,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/groups/{groupId}/inviteLink?token #### Delete Group -| | | -|---|---| -| HTTP | `DELETE /groups/{groupId}` | -| SDK group | `client.groups` | -| API class | `GroupsApi` | -| operationId | `deleteGroupsGroupId` | -| Signature | `deleteGroupsGroupId(groupId: string, token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | -------------------------------------------------------------------------------- | +| HTTP | `DELETE /groups/{groupId}` | +| SDK group | `client.groups` | +| API class | `GroupsApi` | +| operationId | `deleteGroupsGroupId` | +| Signature | `deleteGroupsGroupId(groupId: string, token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -2140,8 +2098,8 @@ curl -X POST 'https://api.1msg.io/{instanceId}/groups/{groupId}/inviteLink?token **Responses** | Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | +| ------ | ----------- | ------ | +| `200` | OK | `—` | #### SDK example @@ -2159,13 +2117,13 @@ curl -X DELETE 'https://api.1msg.io/{instanceId}/groups/{groupId}?token={token}' #### Get Group Info -| | | -|---|---| -| HTTP | `GET /groups/{groupId}` | -| SDK group | `client.groups` | -| API class | `GroupsApi` | -| operationId | `getGroupsGroupId` | -| Signature | `getGroupsGroupId(groupId: string, token: string, fields?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | +| | | +| ----------- | ---------------------------------------------------------------------------------------------- | +| HTTP | `GET /groups/{groupId}` | +| SDK group | `client.groups` | +| API class | `GroupsApi` | +| operationId | `getGroupsGroupId` | +| Signature | `getGroupsGroupId(groupId: string, token: string, fields?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | #### Authentication @@ -2183,8 +2141,8 @@ curl -X DELETE 'https://api.1msg.io/{instanceId}/groups/{groupId}?token={token}' **Responses** | Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | +| ------ | ----------- | ------ | +| `200` | OK | `—` | #### SDK example @@ -2202,13 +2160,13 @@ curl -X GET 'https://api.1msg.io/{instanceId}/groups/{groupId}?token={token}' #### Get Invite Link -| | | -|---|---| -| HTTP | `GET /groups/{groupId}/inviteLink` | -| SDK group | `client.groups` | -| API class | `GroupsApi` | -| operationId | `getGroupsGroupIdInvitelink` | -| Signature | `getGroupsGroupIdInvitelink(groupId: string, token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | +| | | +| ----------- | --------------------------------------------------------------------------------------- | +| HTTP | `GET /groups/{groupId}/inviteLink` | +| SDK group | `client.groups` | +| API class | `GroupsApi` | +| operationId | `getGroupsGroupIdInvitelink` | +| Signature | `getGroupsGroupIdInvitelink(groupId: string, token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | #### Authentication @@ -2222,8 +2180,8 @@ curl -X GET 'https://api.1msg.io/{instanceId}/groups/{groupId}?token={token}' **Responses** | Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | +| ------ | ----------- | ------ | +| `200` | OK | `—` | #### SDK example @@ -2243,13 +2201,13 @@ curl -X GET 'https://api.1msg.io/{instanceId}/groups/{groupId}/inviteLink?token= List WhatsApp groups for this channel. Paginate with `limit`, `before`, and `after`. -| | | -|---|---| -| HTTP | `GET /groups` | -| SDK group | `client.groups` | -| API class | `GroupsApi` | -| operationId | `listGroups` | -| Signature | `listGroups(token: string, limit?: number, before?: string, after?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | +| | | +| ----------- | ------------------------------------------------------------------------------------------------------- | +| HTTP | `GET /groups` | +| SDK group | `client.groups` | +| API class | `GroupsApi` | +| operationId | `listGroups` | +| Signature | `listGroups(token: string, limit?: number, before?: string, after?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | #### Authentication @@ -2269,8 +2227,8 @@ List WhatsApp groups for this channel. Paginate with `limit`, `before`, and `aft **Responses** | Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | +| ------ | ----------- | ------ | +| `200` | OK | `—` | #### SDK example @@ -2294,13 +2252,13 @@ Namespace: `client.flows` → `FlowsApi` (11 operations) Create a WhatsApp Flow (`name` + `categories` required). Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. -| | | -|---|---| -| HTTP | `POST /flows` | -| SDK group | `client.flows` | -| API class | `FlowsApi` | -| operationId | `createFlows` | -| Signature | `createFlows(token: string, createFlowsRequest: CreateFlowsRequest, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ----------------------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /flows` | +| SDK group | `client.flows` | +| API class | `FlowsApi` | +| operationId | `createFlows` | +| Signature | `createFlows(token: string, createFlowsRequest: CreateFlowsRequest, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -2317,33 +2275,30 @@ Create a WhatsApp Flow (`name` + `categories` required). Currently returns HTTP **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `name` | string | **required** | Flow name | -| `categories` | array | **required** | One or more Flow categories | -| `endpointUri` | string | optional | HTTPS endpoint for the Flow data channel | -| `publish` | boolean | optional | Publish immediately after create | -| `flowJson` | object | optional | Optional Flow JSON document | +| Field | Type | Required | Description | +| ------------- | -------------------- | ------------ | ---------------------------------------- | +| `name` | string | **required** | Flow name | +| `categories` | array | **required** | One or more Flow categories | +| `endpointUri` | string | optional | HTTPS endpoint for the Flow data channel | +| `publish` | boolean | optional | Publish immediately after create | +| `flowJson` | object | optional | Optional Flow JSON document | **OpenAPI example body** ```json { "name": "lead_form", - "categories": [ - "LEAD_GENERATION" - ], + "categories": ["LEAD_GENERATION"], "publish": false } ``` - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | -| `501` | WhatsApp Flows are not available on this channel yet | `—` | +| Status | Description | Schema | +| ------ | ---------------------------------------------------- | ------ | +| `200` | OK | `—` | +| `501` | WhatsApp Flows are not available on this channel yet | `—` | #### SDK example @@ -2369,13 +2324,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/flows?token={token}' \ #### Deprecate Flow -| | | -|---|---| -| HTTP | `POST /flows/{flowId}/deprecate` | -| SDK group | `client.flows` | -| API class | `FlowsApi` | -| operationId | `createFlowsFlowIdDeprecate` | -| Signature | `createFlowsFlowIdDeprecate(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | +| | | +| ----------- | -------------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /flows/{flowId}/deprecate` | +| SDK group | `client.flows` | +| API class | `FlowsApi` | +| operationId | `createFlowsFlowIdDeprecate` | +| Signature | `createFlowsFlowIdDeprecate(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | #### Authentication @@ -2393,8 +2348,8 @@ curl -X POST 'https://api.1msg.io/{instanceId}/flows?token={token}' \ **Responses** | Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | +| ------ | ----------- | ------ | +| `200` | OK | `—` | #### SDK example @@ -2412,13 +2367,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/flows/{flowId}/deprecate?token={t #### Publish Flow -| | | -|---|---| -| HTTP | `POST /flows/{flowId}/publish` | -| SDK group | `client.flows` | -| API class | `FlowsApi` | -| operationId | `createFlowsFlowIdPublish` | -| Signature | `createFlowsFlowIdPublish(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------ | +| HTTP | `POST /flows/{flowId}/publish` | +| SDK group | `client.flows` | +| API class | `FlowsApi` | +| operationId | `createFlowsFlowIdPublish` | +| Signature | `createFlowsFlowIdPublish(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | #### Authentication @@ -2436,8 +2391,8 @@ curl -X POST 'https://api.1msg.io/{instanceId}/flows/{flowId}/deprecate?token={t **Responses** | Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | +| ------ | ----------- | ------ | +| `200` | OK | `—` | #### SDK example @@ -2455,13 +2410,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/flows/{flowId}/publish?token={tok #### Delete Flow -| | | -|---|---| -| HTTP | `DELETE /flows/{flowId}` | -| SDK group | `client.flows` | -| API class | `FlowsApi` | -| operationId | `deleteFlowsFlowId` | -| Signature | `deleteFlowsFlowId(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ----------------------------------------------------------------------------------------------------- | +| HTTP | `DELETE /flows/{flowId}` | +| SDK group | `client.flows` | +| API class | `FlowsApi` | +| operationId | `deleteFlowsFlowId` | +| Signature | `deleteFlowsFlowId(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -2479,8 +2434,8 @@ curl -X POST 'https://api.1msg.io/{instanceId}/flows/{flowId}/publish?token={tok **Responses** | Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | +| ------ | ----------- | ------ | +| `200` | OK | `—` | #### SDK example @@ -2498,13 +2453,13 @@ curl -X DELETE 'https://api.1msg.io/{instanceId}/flows/{flowId}?token={token}' #### Get Flow Details -| | | -|---|---| -| HTTP | `GET /flows/{flowId}` | -| SDK group | `client.flows` | -| API class | `FlowsApi` | -| operationId | `getFlowsFlowId` | -| Signature | `getFlowsFlowId(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | -------------------------------------------------------------------------------------------------- | +| HTTP | `GET /flows/{flowId}` | +| SDK group | `client.flows` | +| API class | `FlowsApi` | +| operationId | `getFlowsFlowId` | +| Signature | `getFlowsFlowId(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -2522,8 +2477,8 @@ curl -X DELETE 'https://api.1msg.io/{instanceId}/flows/{flowId}?token={token}' **Responses** | Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | +| ------ | ----------- | ------ | +| `200` | OK | `—` | #### SDK example @@ -2541,13 +2496,13 @@ curl -X GET 'https://api.1msg.io/{instanceId}/flows/{flowId}?token={token}' #### Preview Flow -| | | -|---|---| -| HTTP | `GET /flows/{flowId}/preview` | -| SDK group | `client.flows` | -| API class | `FlowsApi` | -| operationId | `getFlowsFlowIdPreview` | -| Signature | `getFlowsFlowIdPreview(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | +| | | +| ----------- | --------------------------------------------------------------------------------------------------------- | +| HTTP | `GET /flows/{flowId}/preview` | +| SDK group | `client.flows` | +| API class | `FlowsApi` | +| operationId | `getFlowsFlowIdPreview` | +| Signature | `getFlowsFlowIdPreview(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | #### Authentication @@ -2565,8 +2520,8 @@ curl -X GET 'https://api.1msg.io/{instanceId}/flows/{flowId}?token={token}' **Responses** | Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | +| ------ | ----------- | ------ | +| `200` | OK | `—` | #### SDK example @@ -2586,13 +2541,13 @@ curl -X GET 'https://api.1msg.io/{instanceId}/flows/{flowId}/preview?token={toke Retrieve the WhatsApp business public key and signature status for this channel's phone number. Required before publishing or sending Flows that use data encryption. -| | | -|---|---| -| HTTP | `GET /whatsapp_business_encryption` | -| SDK group | `client.flows` | -| API class | `FlowsApi` | -| operationId | `getWhatsappBusinessEncryption` | -| Signature | `getWhatsappBusinessEncryption(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ------------------------------------------------------------------------- | +| HTTP | `GET /whatsapp_business_encryption` | +| SDK group | `client.flows` | +| API class | `FlowsApi` | +| operationId | `getWhatsappBusinessEncryption` | +| Signature | `getWhatsappBusinessEncryption(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -2605,11 +2560,11 @@ Retrieve the WhatsApp business public key and signature status for this channel' **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Business encryption key status | `—` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------- | +| `200` | Business encryption key status | `—` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -2629,13 +2584,13 @@ curl -X GET 'https://api.1msg.io/{instanceId}/whatsapp_business_encryption?token List WhatsApp Flows for the WABA. Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. -| | | -|---|---| -| HTTP | `GET /flows` | -| SDK group | `client.flows` | -| API class | `FlowsApi` | -| operationId | `listFlows` | -| Signature | `listFlows(token: string, wabaAccountId?: string, fields?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ---------------------------------------------------------------------------------------------- | +| HTTP | `GET /flows` | +| SDK group | `client.flows` | +| API class | `FlowsApi` | +| operationId | `listFlows` | +| Signature | `listFlows(token: string, wabaAccountId?: string, fields?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -2653,10 +2608,10 @@ List WhatsApp Flows for the WABA. Currently returns HTTP 501 until the Meta Grap **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | -| `501` | WhatsApp Flows are not available on this channel yet | `—` | +| Status | Description | Schema | +| ------ | ---------------------------------------------------- | ------ | +| `200` | OK | `—` | +| `501` | WhatsApp Flows are not available on this channel yet | `—` | #### SDK example @@ -2676,13 +2631,13 @@ curl -X GET 'https://api.1msg.io/{instanceId}/flows?token={token}' Replace the Flow JSON document (`flowJson`). Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. -| | | -|---|---| -| HTTP | `PATCH /flows/{flowId}/assets` | -| SDK group | `client.flows` | -| API class | `FlowsApi` | -| operationId | `patchFlowsFlowIdAssets` | -| Signature | `patchFlowsFlowIdAssets(flowId: string, token: string, patchFlowsFlowIdAssetsRequest: PatchFlowsFlowIdAssetsRequest, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| HTTP | `PATCH /flows/{flowId}/assets` | +| SDK group | `client.flows` | +| API class | `FlowsApi` | +| operationId | `patchFlowsFlowIdAssets` | +| Signature | `patchFlowsFlowIdAssets(flowId: string, token: string, patchFlowsFlowIdAssetsRequest: PatchFlowsFlowIdAssetsRequest, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -2699,17 +2654,16 @@ Replace the Flow JSON document (`flowJson`). Currently returns HTTP 501 until th **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| +| Field | Type | Required | Description | +| ---------- | ------ | ------------ | --------------------------- | | `flowJson` | object | **required** | WhatsApp Flow JSON document | - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | -| `501` | WhatsApp Flows are not available on this channel yet | `—` | +| Status | Description | Schema | +| ------ | ---------------------------------------------------- | ------ | +| `200` | OK | `—` | +| `501` | WhatsApp Flows are not available on this channel yet | `—` | #### SDK example @@ -2731,13 +2685,13 @@ curl -X PATCH 'https://api.1msg.io/{instanceId}/flows/{flowId}/assets?token={tok Update Flow `name`, `categories`, and/or `endpointUri`. Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. -| | | -|---|---| -| HTTP | `PATCH /flows/{flowId}/metadata` | -| SDK group | `client.flows` | -| API class | `FlowsApi` | -| operationId | `patchFlowsFlowIdMetadata` | -| Signature | `patchFlowsFlowIdMetadata(flowId: string, token: string, patchFlowsFlowIdMetadataRequest: PatchFlowsFlowIdMetadataRequest, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| HTTP | `PATCH /flows/{flowId}/metadata` | +| SDK group | `client.flows` | +| API class | `FlowsApi` | +| operationId | `patchFlowsFlowIdMetadata` | +| Signature | `patchFlowsFlowIdMetadata(flowId: string, token: string, patchFlowsFlowIdMetadataRequest: PatchFlowsFlowIdMetadataRequest, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | #### Authentication @@ -2754,19 +2708,18 @@ Update Flow `name`, `categories`, and/or `endpointUri`. Currently returns HTTP 5 **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `name` | string | optional | | -| `categories` | array | optional | | -| `endpointUri` | string | optional | HTTPS endpoint for the Flow data channel | - +| Field | Type | Required | Description | +| ------------- | -------------------- | --------- | ---------------------------------------- | +| `name` | string | optional | | +| `categories` | array | optional | | +| `endpointUri` | string | optional | HTTPS endpoint for the Flow data channel | **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | -| `501` | WhatsApp Flows are not available on this channel yet | `—` | +| Status | Description | Schema | +| ------ | ---------------------------------------------------- | ------ | +| `200` | OK | `—` | +| `501` | WhatsApp Flows are not available on this channel yet | `—` | #### SDK example @@ -2788,13 +2741,13 @@ curl -X PATCH 'https://api.1msg.io/{instanceId}/flows/{flowId}/metadata?token={t Upload and sign a 2048-bit RSA business public key (PEM) for this channel's phone number. Meta requires a signed key before Flow publish/send. Only one active key per number; a new upload replaces the previous key. -| | | -|---|---| -| HTTP | `POST /whatsapp_business_encryption` | -| SDK group | `client.flows` | -| API class | `FlowsApi` | -| operationId | `setWhatsappBusinessEncryption` | -| Signature | `setWhatsappBusinessEncryption(token: string, setWhatsappBusinessEncryptionRequest: SetWhatsappBusinessEncryptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /whatsapp_business_encryption` | +| SDK group | `client.flows` | +| API class | `FlowsApi` | +| operationId | `setWhatsappBusinessEncryption` | +| Signature | `setWhatsappBusinessEncryption(token: string, setWhatsappBusinessEncryptionRequest: SetWhatsappBusinessEncryptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -2807,19 +2760,18 @@ Upload and sign a 2048-bit RSA business public key (PEM) for this channel's phon **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| +| Field | Type | Required | Description | +| --------------------- | ------ | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | `business_public_key` | string | **required** | 2048-bit RSA public key in PEM format (example="-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...\n-----END PUBLIC KEY-----\n") | - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Public key uploaded and signed | `—` | -| `400` | Missing or invalid PEM key | `—` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------- | +| `200` | Public key uploaded and signed | `—` | +| `400` | Missing or invalid PEM key | `—` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -2843,13 +2795,15 @@ Namespace: `client.templates` → `TemplatesApi` (4 operations) #### Create message template -| | | -|---|---| -| HTTP | `POST /addTemplate` | -| SDK group | `client.templates` | -| API class | `TemplatesApi` | -| operationId | `addTemplate` | -| Signature | `addTemplate(token: string, addTemplateRequest?: AddTemplateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | +Create a WABA message template (`name`, `category`, `language`, `components`). After create, Meta reviews the template; list it with `GET /templates`. + +| | | +| ----------- | ------------------------------------------------------------------------------------------------ | +| HTTP | `POST /addTemplate` | +| SDK group | `client.templates` | +| API class | `TemplatesApi` | +| operationId | `addTemplate` | +| Signature | `addTemplate(token: string, addTemplateRequest?: AddTemplateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -2862,21 +2816,36 @@ Namespace: `client.templates` → `TemplatesApi` (4 operations) **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `name` | string | optional | | -| `category` | string | optional | | -| `language` | string | optional | | -| `components` | array | optional | | +| Field | Type | Required | Description | +| ------------ | ------------- | -------- | ------------------------------------------------------------- | +| `name` | string | optional | Template name (example="hello_world") | +| `category` | string | optional | MARKETING, UTILITY, or AUTHENTICATION (example="UTILITY") | +| `language` | string | optional | Template language code (e.g. en_US) (example="en_US") | +| `components` | array | optional | Template components (HEADER, BODY, FOOTER, BUTTONS, CAROUSEL) | +**OpenAPI example body** + +```json +{ + "name": "hello_world", + "category": "UTILITY", + "language": "en_US", + "components": [ + { + "type": "BODY", + "text": "Hello {{1}}" + } + ] +} +``` **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Template created | `—` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | ------------------------------------------------------------ | --------------- | +| `200` | Template created. Provider payload is wrapped in `response`. | `—` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -2889,7 +2858,17 @@ await client.templates.addTemplate(client.config.token, {}); ```bash curl -X POST 'https://api.1msg.io/{instanceId}/addTemplate?token={token}' \ -H 'Content-Type: application/json' \ - -d '{}' + -d '{ + "name": "hello_world", + "category": "UTILITY", + "language": "en_US", + "components": [ + { + "type": "BODY", + "text": "Hello {{1}}" + } + ] + }' ``` ### `listTemplates` @@ -2898,13 +2877,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/addTemplate?token={token}' \ List message templates. Paginate with `limit` / `offset`; sort by `id`, `name`, or `status`. -| | | -|---|---| -| HTTP | `GET /templates` | -| SDK group | `client.templates` | -| API class | `TemplatesApi` | -| operationId | `listTemplates` | -| Signature | `listTemplates(token: string, limit?: number, offset?: number, sort?: ListTemplatesSortEnum, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ------------------------------------------------------------------------------------------------------------------------ | +| HTTP | `GET /templates` | +| SDK group | `client.templates` | +| API class | `TemplatesApi` | +| operationId | `listTemplates` | +| Signature | `listTemplates(token: string, limit?: number, offset?: number, sort?: ListTemplatesSortEnum, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -2924,8 +2903,8 @@ List message templates. Paginate with `limit` / `offset`; sort by `id`, `name`, **Responses** | Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | +| ------ | ----------- | ------ | +| `200` | OK | `—` | #### SDK example @@ -2945,13 +2924,13 @@ curl -X GET 'https://api.1msg.io/{instanceId}/templates?token={token}' Delete a message template by `name` (all language versions of that name). -| | | -|---|---| -| HTTP | `POST /removeTemplate` | -| SDK group | `client.templates` | -| API class | `TemplatesApi` | -| operationId | `removeTemplate` | -| Signature | `removeTemplate(token: string, removeTemplateRequest: RemoveTemplateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | +| | | +| ----------- | -------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /removeTemplate` | +| SDK group | `client.templates` | +| API class | `TemplatesApi` | +| operationId | `removeTemplate` | +| Signature | `removeTemplate(token: string, removeTemplateRequest: RemoveTemplateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | #### Authentication @@ -2964,8 +2943,8 @@ Delete a message template by `name` (all language versions of that name). **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| +| Field | Type | Required | Description | +| ------ | ------ | ------------ | ----------------------- | | `name` | string | **required** | Template name to delete | **OpenAPI example body** @@ -2976,14 +2955,13 @@ Delete a message template by `name` (all language versions of that name). } ``` - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Template removed | `—` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------- | +| `200` | Template removed | `—` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -3005,15 +2983,15 @@ curl -X POST 'https://api.1msg.io/{instanceId}/removeTemplate?token={token}' \ #### Send Template Message -Send a WhatsApp **template** message (works outside the 24-hour session window). Use this tool — not `send_message` — when the 24h session is closed. `params` MUST be Cloud API **component objects**, never a flat list of strings and never the old On-Prem `hsm` / `localizable_params` format. Example body variable `{{1}}`: ```json { "type": "body", "parameters": [{ "type": "text", "text": "Ivan" }] } ``` Do not send `"type": "hsm"` and do not send `params: ["Ivan", "123"]`. Supported `params` button `sub_type` values include: `url`, `quick_reply`, `copy_code` / `coupon_code`, `catalog`, `flow`, `limited_time_offer`, and **`order_details`** (WhatsApp Payments **India only** — requires an approved Utility template with an ORDER_DETAILS button). Convenience wrapper with structured fields: `POST /sendOrderDetails`. +Send a WhatsApp **template** message (works outside the 24-hour session window). Use this tool — not `send_message` — when the 24h session is closed. `params` MUST be Cloud API **component objects**, never a flat list of strings and never the old On-Prem `hsm` / `localizable_params` format. Example body variable `{{1}}`: `json { "type": "body", "parameters": [{ "type": "text", "text": "Ivan" }] } ` Do not send `"type": "hsm"` and do not send `params: ["Ivan", "123"]`. Supported `params` button `sub_type` values include: `url`, `quick_reply`, `copy_code` / `coupon_code`, `catalog`, `flow`, `limited_time_offer`, and **`order_details`** (WhatsApp Payments **India only** — requires an approved Utility template with an ORDER_DETAILS button). Convenience wrapper with structured fields: `POST /sendOrderDetails`. -| | | -|---|---| -| HTTP | `POST /sendTemplate` | -| SDK group | `client.templates` | -| API class | `TemplatesApi` | -| operationId | `sendTemplate` | -| Signature | `sendTemplate(token: string, sendTemplateRequest?: SendTemplateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | +| | | +| ----------- | --------------------------------------------------------------------------------------------------- | +| HTTP | `POST /sendTemplate` | +| SDK group | `client.templates` | +| API class | `TemplatesApi` | +| operationId | `sendTemplate` | +| Signature | `sendTemplate(token: string, sendTemplateRequest?: SendTemplateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | #### Authentication @@ -3026,20 +3004,20 @@ Send a WhatsApp **template** message (works outside the 24-hour session window). **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `template` | string | optional | Approved template name (template `name`, not the old HSM `element_name`) | -| `language` | object | optional | Template language. `policy` is usually `deterministic`. | - | `policy` | string | optional | (example="deterministic") | - | `code` | string | optional | (example="en") | -| `namespace` | string | optional | Template namespace from `list_templates` | -| `params` | array | optional | Template components in WhatsApp Cloud API format. Each item is an object with `type` (`body`, `header`, `button`) and `parameters` (objects with `type` + `text` / media / action). Never a list of strings. Never HSM `localizable_params`. | -| `phone` | string | optional | Recipient phone with country code (use phone or chatId) | -| `chatId` | string | optional | Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. | -| `quotedMsgId` | string | optional | Optional Cloud API wamid to quote | -| `useMMlite` | boolean | optional | Force Marketing Messages API (POST marketing_messages). If omitted: auto for MARKETING category when channel has mm_lite_enabled and mm_lite_available service settings. | -| `messageActivitySharing` | boolean | optional | Sets message_activity_sharing on WABA payload. Enables click tracking webhooks. Requires MM Lite path. Ignored on Cloud API fallback. | -| `messageSendTtlSeconds` | integer | optional | Template message TTL in seconds (message_send_ttl_seconds). MARKETING via MM Lite: 43200–2592000. AUTHENTICATION: 30–900. UTILITY: 30–43200. AUTH/UTILITY also accept -1 (30-day custom TTL). | +| Field | Type | Required | Description | +| ------------------------ | ------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `template` | string | optional | Approved template name (template `name`, not the old HSM `element_name`) | +| `language` | object | optional | Template language. Always set `policy` to `deterministic`. | +| `policy` | string | optional | Must be `deterministic` (example="deterministic") | +| `code` | string | optional | (example="en") | +| `namespace` | string | optional | Template namespace from `list_templates` | +| `params` | array | optional | Template components in WhatsApp Cloud API format. Each item is an object with `type` (`body`, `header`, `button`) and `parameters` (objects with `type` + `text` / media / action). Never a list of strings. Never HSM `localizable_params`. | +| `phone` | string | optional | Recipient phone with country code (use phone or chatId) | +| `chatId` | string | optional | Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. | +| `quotedMsgId` | string | optional | Optional Cloud API wamid to quote | +| `useMMlite` | boolean | optional | Force Marketing Messages API (POST marketing_messages). If omitted: auto for MARKETING category when channel has mm_lite_enabled and mm_lite_available service settings. | +| `messageActivitySharing` | boolean | optional | Sets message_activity_sharing on WABA payload. Enables click tracking webhooks. Requires MM Lite path. Ignored on Cloud API fallback. | +| `messageSendTtlSeconds` | integer | optional | Template message TTL in seconds (message_send_ttl_seconds). MARKETING via MM Lite: 43200–2592000. AUTHENTICATION: 30–900. UTILITY: 30–43200. AUTH/UTILITY also accept -1 (30-day custom TTL). | **OpenAPI example body** @@ -3066,12 +3044,11 @@ Send a WhatsApp **template** message (works outside the 24-hour session window). } ``` - **Responses** | Status | Description | Schema | -|--------|-------------|--------| -| `200` | OK | `—` | +| ------ | ----------- | ------ | +| `200` | OK | `—` | #### SDK example @@ -3123,13 +3100,13 @@ Namespace: `client.calling` → `CallingApi` (3 operations) Return WhatsApp Calling API settings for this channel (beta). Proxies upstream `GET /calling/settings`. **Prerequisites** - Number must be eligible for Meta Calling (Cloud API; not COEX) - Trial / `subscriptionBlocked` channels receive **403** plain text - You need your own WebRTC or SIP stack; 1msg is a **signaling proxy** only and does **not** store call history or recordings See the **Calling** tag overview for inbound/outbound flows and webhooks. -| | | -|---|---| -| HTTP | `GET /callingSettings` | -| SDK group | `client.calling` | -| API class | `CallingApi` | -| operationId | `getCallingSettings` | -| Signature | `getCallingSettings(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | -------------------------------------------------------------- | +| HTTP | `GET /callingSettings` | +| SDK group | `client.calling` | +| API class | `CallingApi` | +| operationId | `getCallingSettings` | +| Signature | `getCallingSettings(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -3142,11 +3119,11 @@ Return WhatsApp Calling API settings for this channel (beta). Proxies upstream ` **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Calling settings (and possibly other Cloud API settings Meta returns) | `CallingSettings` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------------------------------------- | ----------------- | +| `200` | Calling settings (and possibly other Cloud API settings Meta returns) | `CallingSettings` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -3164,15 +3141,15 @@ curl -X GET 'https://api.1msg.io/{instanceId}/callingSettings?token={token}' #### Call action (connect / pre_accept / accept / reject / terminate) -Perform a WhatsApp Calling action (beta). Proxies upstream `POST /calling/calls`. Despite the historical path name `/initiateCall`, this endpoint handles **all** call actions: | action | Use | Required | |--------|-----|----------| | `connect` | Outbound business → user | `to` + `session` (`sdp_type: offer`) | | `pre_accept` | Inbound (optional, reduces audio clipping) | `call_id` + `session` (`sdp_type: answer`) | | `accept` | Inbound answer | `call_id` + `session` (`sdp_type: answer`) | | `reject` | Decline inbound | `call_id` | | `terminate` | Hang up | `call_id` | **SDP / media (critical)** - `accept` / `pre_accept` require a **WebRTC-generated SDP answer**. - Do **not** send Meta's offer SDP back as the answer. - Postman (or curl) alone **cannot** establish real media — you need a WebRTC or SIP stack. 1msg only proxies signaling. Answer within ~**30–60 seconds** of an inbound `connect` webhook or Meta terminates as unanswered. Common Meta errors include Calling not enabled (`138000`), no permission (`138006`), SDP validation failures. **Outbound** requires a prior Call Permission Request (CPR) acceptance. See the **Calling** tag overview for the full outbound flow and CPR limits. Trial / `subscriptionBlocked` → **403** plain text. Upstream failures often return HTTP 200 with `{ "response": { "error": "..." } }`. +Perform a WhatsApp Calling action (beta). Proxies upstream `POST /calling/calls`. Despite the historical path name `/initiateCall`, this endpoint handles **all** call actions: | action | Use | Required | |--------|-----|----------| | `connect` | Outbound business → user | `to` + `session` (`sdp_type: offer`) | | `pre_accept` | Inbound (optional, reduces audio clipping) | `call_id` + `session` (`sdp_type: answer`) | | `accept` | Inbound answer | `call_id` + `session` (`sdp_type: answer`) | | `reject` | Decline inbound | `call_id` | | `terminate` | Hang up | `call_id` | **SDP / media (critical)** - `accept` / `pre_accept` require a **WebRTC-generated SDP answer**. - Do **not** send Meta's offer SDP back as the answer. - Postman (or curl) alone **cannot** establish real media — you need a WebRTC or SIP stack. 1msg only proxies signaling. Answer within ~**30–60 seconds** of an inbound `connect` webhook or Meta terminates as unanswered. Common Meta errors include Calling not enabled (`138000`), no permission (`138006`), SDP validation failures. **Outbound** requires a prior Call Permission Request (CPR) acceptance. See the **Calling** tag overview for the full outbound flow and CPR limits. Trial / `subscriptionBlocked` → **403** plain text. Upstream failures often return HTTP 200 with `{ "response": { "error": "" } }`. `Invalid API KEY` is used only when Meta/360 body actually indicates an invalid API key or token. Other upstream 401s (notably call permission `138006`) pass through `error.message` / `error_user_msg`. -| | | -|---|---| -| HTTP | `POST /initiateCall` | -| SDK group | `client.calling` | -| API class | `CallingApi` | -| operationId | `initiateCall` | -| Signature | `initiateCall(token: string, initiateCallRequest: InitiateCallRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | -------------------------------------------------------------------------------------------------- | +| HTTP | `POST /initiateCall` | +| SDK group | `client.calling` | +| API class | `CallingApi` | +| operationId | `initiateCall` | +| Signature | `initiateCall(token: string, initiateCallRequest: InitiateCallRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -3185,25 +3162,24 @@ Perform a WhatsApp Calling action (beta). Proxies upstream `POST /calling/calls` **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `messaging_product` | enum("whatsapp") | **required** | Must be `whatsapp` (example="whatsapp") | -| `action` | enum("connect" | "pre_accept" | "accept" | "reject" | "terminate") | **required** | Call control action (example="connect") | -| `call_id` | string | optional | WhatsApp call id from the inbound/outbound calls webhook (`calls[].id`). Required for `pre_accept`, `accept`, `reject`, `terminate`. (example="wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh") | -| `to` | string | optional | Recipient WhatsApp user phone (digits, country code, no +). Required for outbound `connect`. (example="12185552828") | -| `biz_opaque_callback_data` | string | optional | Optional opaque string echoed on later call webhooks for correlation (maxLength=512, example="order-123-callback") | -| `session` | object | optional | WebRTC SDP session (required for connect / pre_accept / accept) | - | `sdp_type` | enum("offer" | "answer") | **required** | offer for outbound connect; answer for pre_accept/accept (example="offer") | - | `sdp` | string | **required** | Full SDP (RFC 8866). Replace placeholders with SDP from your WebRTC stack. Must negotiate ICE, DTLS-SRTP, and OPUS for WhatsApp media. (example="[REPLACE_WITH_WEBRTC_SDP]") | - +| Field | Type | Required | Description | +| -------------------------- | ---------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `messaging_product` | enum("whatsapp") | **required** | Must be `whatsapp` (example="whatsapp") | +| `action` | enum("connect" | "pre_accept" | "accept" | "reject" | "terminate") | **required** | Call control action (example="connect") | +| `call_id` | string | optional | WhatsApp call id from the inbound/outbound calls webhook (`calls[].id`). Required for `pre_accept`, `accept`, `reject`, `terminate`. (example="wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh") | +| `to` | string | optional | Recipient WhatsApp user phone (digits, country code, no +). Required for outbound `connect`. (example="12185552828") | +| `biz_opaque_callback_data` | string | optional | Optional opaque string echoed on later call webhooks for correlation (maxLength=512, example="order-123-callback") | +| `session` | object | optional | WebRTC SDP session (required for connect / pre_accept / accept) | +| `sdp_type` | enum("offer" | "answer") | **required** | offer for outbound connect; answer for pre_accept/accept (example="offer") | +| `sdp` | string | **required** | Full SDP (RFC 8866). Replace placeholders with SDP from your WebRTC stack. Must negotiate ICE, DTLS-SRTP, and OPUS for WhatsApp media. (example="[REPLACE_WITH_WEBRTC_SDP]") | **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Call action result from upstream, or legacy error wrapper | `InitiateCallResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------------------------- | ---------------------- | +| `200` | Call action result from upstream, or legacy error wrapper | `InitiateCallResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -3225,13 +3201,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/initiateCall?token={token}' \ Enable, disable, or update WhatsApp Calling settings (beta). Proxies upstream `POST /calling/settings`. Body is forwarded as-is (1msg does not validate fields). **Common fields under `calling`** - `status` (`ENABLED` | `DISABLED`) — required to turn calling on/off - `call_icon_visibility` (`DEFAULT` | `DISABLE_ALL`) — optional - `callback_permission_status` (`ENABLED` | `DISABLED`) — optional; when enabled, inbound user calls grant callback permission - `call_hours` — optional hours / timezone object - `sip` — optional SIP trunk; when SIP is ENABLED, Graph call actions and calling webhooks are not used - `srtp_key_exchange_protocol` (`DTLS` | `SDES`) — SDES only with SIP - `video.status` — optional Meta may accept only one feature group per request — prefer focused updates (e.g. enable status first, then SIP). Trial / `subscriptionBlocked` → **403** plain text. -| | | -|---|---| -| HTTP | `POST /callingSettings` | -| SDK group | `client.calling` | -| API class | `CallingApi` | -| operationId | `updateCallingSettings` | -| Signature | `updateCallingSettings(token: string, callingSettings: CallingSettings, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | --------------------------------------------------------------------------------------------------- | +| HTTP | `POST /callingSettings` | +| SDK group | `client.calling` | +| API class | `CallingApi` | +| operationId | `updateCallingSettings` | +| Signature | `updateCallingSettings(token: string, callingSettings: CallingSettings, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -3244,36 +3220,37 @@ Enable, disable, or update WhatsApp Calling settings (beta). Proxies upstream `P **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `calling` | object | optional | Calling feature configuration for the business phone number | - | `status` | enum("ENABLED" | "DISABLED") | optional | Enable or disable Calling API on this number (example="ENABLED") | - | `call_icon_visibility` | enum("DEFAULT" | "DISABLE_ALL") | optional | Controls call icon visibility in the WhatsApp client (example="DEFAULT") | - | `callback_permission_status` | enum("ENABLED" | "DISABLED") | optional | When ENABLED, a user who calls your business automatically grants call permission for business-initiated callbacks (subject to Meta rules). (example="ENABLED") | - | `srtp_key_exchange_protocol` | enum("DTLS" | "SDES") | optional | SRTP key exchange. DTLS is default/recommended. SDES is only valid when SIP signaling is enabled. (example="DTLS") | - | `call_hours` | object | optional | Optional call hours / timezone configuration (Meta shape) | +| Field | Type | Required | Description | +| ---------------------------- | -------------- | -------------- | ----------------------------------------------------------- | +| `calling` | object | optional | Calling feature configuration for the business phone number | +| `status` | enum("ENABLED" | "DISABLED") | optional | Enable or disable Calling API on this number (example="ENABLED") | +| `call_icon_visibility` | enum("DEFAULT" | "DISABLE_ALL") | optional | Controls call icon visibility in the WhatsApp client (example="DEFAULT") | +| `callback_permission_status` | enum("ENABLED" | "DISABLED") | optional | When ENABLED, a user who calls your business automatically grants call permission for business-initiated callbacks (subject to Meta rules). (example="ENABLED") | +| `srtp_key_exchange_protocol` | enum("DTLS" | "SDES") | optional | SRTP key exchange. DTLS is default/recommended. SDES is only valid when SIP signaling is enabled. (example="DTLS") | +| `call_hours` | object | optional | Optional call hours / timezone configuration (Meta shape) | + | `status` | string | optional | (example="ENABLED") | | `timezone` | string | optional | (example="America/Los_Angeles") | | `day_of_week_start` | string | optional | (example="MONDAY") | - | `sip` | object | optional | SIP trunk settings. When SIP is ENABLED, Graph call actions and calling webhooks are not used — Meta dials your SIP server directly. | - | `status` | enum("ENABLED" | "DISABLED") | optional | (example="DISABLED") | - | `servers` | array | optional | | - | `video` | object | optional | Video calling toggle when supported | - | `status` | enum("ENABLED" | "DISABLED") | optional | | - | `audio` | object | optional | Audio settings (typically response-only) | - | `status` | string | optional | | - | `restrictions` | object | optional | Calling restrictions (response-only) | - | `ip_addresses` | object | optional | Meta media IP ranges (response-only) | - | `call_icons` | object | optional | Call icon country restrictions (response-only) | +| `sip` | object | optional | SIP trunk settings. When SIP is ENABLED, Graph call actions and calling webhooks are not used — Meta dials your SIP server directly. | +| `status` | enum("ENABLED" | "DISABLED") | optional | (example="DISABLED") | +| `servers` | array | optional | | +| `video` | object | optional | Video calling toggle when supported | +| `status` | enum("ENABLED" | "DISABLED") | optional | | +| `audio` | object | optional | Audio settings (typically response-only) | +| `status` | string | optional | | +| `restrictions` | object | optional | Calling restrictions (response-only) | +| `ip_addresses` | object | optional | Meta media IP ranges (response-only) | +| `call_icons` | object | optional | Call icon country restrictions (response-only) | **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Usually `{ "success": true }` from upstream, or legacy `{ "result": "success" }` / `{ "response": { "error": "..." } }`. | `—` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | ------------------------------------------------------------------------------------------------------------------------ | --------------- | +| `200` | Usually `{ "success": true }` from upstream, or legacy `{ "result": "success" }` / `{ "response": { "error": "..." } }`. | `—` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -3299,13 +3276,13 @@ Namespace: `client.catalog` → `CatalogApi` (2 operations) Update catalog/cart commerce settings via the `params` object. - `params.is_catalog_visible` — show catalog storefront icon (`true`) or hide it (`false`). - `params.is_cart_enabled` — enable cart (`true`) or disable it (`false`). Blocked when the channel subscription limit is exceeded. Requires a commerce-capable channel (Cloud Functions `/commerceWAV2`). -| | | -|---|---| -| HTTP | `POST /commerce` | -| SDK group | `client.catalog` | -| API class | `CatalogApi` | -| operationId | `createCommerce` | -| Signature | `createCommerce(token: string, createCommerceRequest: CreateCommerceRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | -------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /commerce` | +| SDK group | `client.catalog` | +| API class | `CatalogApi` | +| operationId | `createCommerce` | +| Signature | `createCommerce(token: string, createCommerceRequest: CreateCommerceRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -3318,11 +3295,11 @@ Update catalog/cart commerce settings via the `params` object. - `params.is_cata **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `params` | object | **required** | | - | `is_cart_enabled` | boolean | **required** | Enable cart | - | `is_catalog_visible` | boolean | **required** | Show catalog storefront icon | +| Field | Type | Required | Description | +| -------------------- | ------- | ------------ | ---------------------------- | +| `params` | object | **required** | | +| `is_cart_enabled` | boolean | **required** | Enable cart | +| `is_catalog_visible` | boolean | **required** | Show catalog storefront icon | **OpenAPI example body** @@ -3335,14 +3312,13 @@ Update catalog/cart commerce settings via the `params` object. - `params.is_cata } ``` - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Commerce updated | `—` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------- | +| `200` | Commerce updated | `—` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -3367,15 +3343,15 @@ curl -X POST 'https://api.1msg.io/{instanceId}/commerce?token={token}' \ #### Get Commerce Settings -Returns catalog/cart commerce settings for the channel. - `is_catalog_visible` — show catalog storefront icon (`true`) or hide it (`false`). - `is_cart_enabled` — enable cart (`true`) or disable it (`false`). +Returns catalog/cart commerce settings for the channel. Fails with a provider error when the WABA has no catalog linked — that is an API/account limitation, not an MCP schema bug. - `is_catalog_visible` — show catalog storefront icon (`true`) or hide it (`false`). - `is_cart_enabled` — enable cart (`true`) or disable it (`false`). -| | | -|---|---| -| HTTP | `GET /commerce` | -| SDK group | `client.catalog` | -| API class | `CatalogApi` | -| operationId | `getCommerce` | -| Signature | `getCommerce(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ------------------------------------------------------- | +| HTTP | `GET /commerce` | +| SDK group | `client.catalog` | +| API class | `CatalogApi` | +| operationId | `getCommerce` | +| Signature | `getCommerce(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -3388,11 +3364,11 @@ Returns catalog/cart commerce settings for the channel. - `is_catalog_visible` **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Commerce settings | `—` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------- | +| `200` | Commerce settings | `—` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -3408,7 +3384,75 @@ curl -X GET 'https://api.1msg.io/{instanceId}/commerce?token={token}' ## channel -Namespace: `client.channel` → `ChannelApi` (3 operations) +Namespace: `client.channel` → `ChannelApi` (5 operations) + +### `createSettings` + +#### Update channel settings + +Update channel settings. Only send fields you want to change. `webhookUrl` **replaces** the stored list (one URL string, or up to 5 URLs as an array). Passing an empty value clears webhooks. Repeating the same URL(s) also clears a sticky auto-disable. With several URLs, send the complete array to re-enable one of them — omitting a URL removes it from the channel. + +| | | +| ----------- | -------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /settings` | +| SDK group | `client.channel` | +| API class | `ChannelApi` | +| operationId | `createSettings` | +| Signature | `createSettings(token: string, createSettingsRequest: CreateSettingsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | + +#### Authentication + +- Query parameter `token` (required on every call) +- SDK: pass `client.config.token` as the first method argument + +#### Request + +- `token` (string, required) — channel API token + +**Request body schema** + +| Field | Type | Required | Description | +| --------------------------------- | ------- | ------------- | ----------- | +| `webhookUrl` | string | array | optional | Replacement webhook URL, or array of URLs (max 5) | +| `guaranteedHooks` | boolean | optional | | +| `ackNotificationsOn` | boolean | optional | | +| `rawHooks` | boolean | optional | | +| `template_analytics_enabled` | boolean | optional | | +| `cta_url_link_tracking_opted_out` | boolean | optional | | + +**OpenAPI example body** + +```json +{ + "webhookUrl": "https://example.com/webhook", + "ackNotificationsOn": true +} +``` + +**Responses** + +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------- | +| `200` | Updated settings | `—` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | + +#### SDK example + +```typescript +await client.channel.createSettings(client.config.token, {}); +``` + +#### cURL equivalent + +```bash +curl -X POST 'https://api.1msg.io/{instanceId}/settings?token={token}' \ + -H 'Content-Type: application/json' \ + -d '{ + "webhookUrl": "https://example.com/webhook", + "ackNotificationsOn": true + }' +``` ### `getConversationalAutomation` @@ -3416,13 +3460,13 @@ Namespace: `client.channel` → `ChannelApi` (3 operations) Get WhatsApp conversational components for the channel (welcome message, ice-breaker prompts, and slash commands). Proxies Meta/360dialog `GET /conversational_automation`. When `enable_welcome_message` is true and a user opens chat for the first time, Meta delivers a webhook message with `type: request_welcome`. The inbound formatter exposes that as `type: "request_welcome"` and `meta.request_welcome: true` so your webhook can send a custom welcome reply. -| | | -|---|---| -| HTTP | `GET /conversationalAutomation` | -| SDK group | `client.channel` | -| API class | `ChannelApi` | -| operationId | `getConversationalAutomation` | -| Signature | `getConversationalAutomation(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ----------------------------------------------------------------------- | +| HTTP | `GET /conversationalAutomation` | +| SDK group | `client.channel` | +| API class | `ChannelApi` | +| operationId | `getConversationalAutomation` | +| Signature | `getConversationalAutomation(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -3435,11 +3479,11 @@ Get WhatsApp conversational components for the channel (welcome message, ice-bre **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Conversational automation settings | `ConversationalAutomation` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | -------------------------- | +| `200` | Conversational automation settings | `ConversationalAutomation` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -3457,15 +3501,15 @@ curl -X GET 'https://api.1msg.io/{instanceId}/conversationalAutomation?token={to #### Get channel status -Returns WhatsApp Business API client connection status. +Return WhatsApp Cloud API connection status for this channel (`connected` when the number can send). May include `accountStatus`, messaging limit, and MM Lite availability. Optional `health_status_warning` appears only when Meta Graph health could not be loaded and a soft `connected` response is returned. Omitted on the normal path and when health details are not applicable for the channel — never an internal provider/transport name. -| | | -|---|---| -| HTTP | `GET /status` | -| SDK group | `client.channel` | -| API class | `ChannelApi` | -| operationId | `getStatus` | -| Signature | `getStatus(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | +| | | +| ----------- | ----------------------------------------------------- | +| HTTP | `GET /status` | +| SDK group | `client.channel` | +| API class | `ChannelApi` | +| operationId | `getStatus` | +| Signature | `getStatus(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -3478,11 +3522,11 @@ Returns WhatsApp Business API client connection status. **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Channel status | `—` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------- | +| `200` | Channel status | `—` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -3496,19 +3540,62 @@ await client.channel.getStatus(client.config.token); curl -X GET 'https://api.1msg.io/{instanceId}/status?token={token}' ``` +### `listSettings` + +#### Get channel settings + +Return channel settings: webhook URL(s), delivery flags, and analytics toggles. Auto-disable / circuit state matches `GET /webhook`. **Prefer `webhookStatuses`** (one row per configured URL). The breaker is per URL, not per channel. Channel-level `haveDisabledWebhooks` is `true` when **at least one** URL in `webhookUrl` is sticky auto-disabled — not "the channel is dead". Live URLs still receive events. Top-level `circuitState` / `reason` / `fails` / `trips` are a compatibility summary of one URL (first sticky-disabled, else first configured). This is the same `GET /settings` endpoint as the REST API (previously missing from MCP). + +| | | +| ----------- | -------------------------------------------------------- | +| HTTP | `GET /settings` | +| SDK group | `client.channel` | +| API class | `ChannelApi` | +| operationId | `listSettings` | +| Signature | `listSettings(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | + +#### Authentication + +- Query parameter `token` (required on every call) +- SDK: pass `client.config.token` as the first method argument + +#### Request + +- `token` (string, required) — channel API token + +**Responses** + +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------- | +| `200` | Current settings | `—` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | + +#### SDK example + +```typescript +await client.channel.listSettings(client.config.token); +``` + +#### cURL equivalent + +```bash +curl -X GET 'https://api.1msg.io/{instanceId}/settings?token={token}' +``` + ### `setConversationalAutomation` #### Set conversational automation settings Update WhatsApp conversational components. Allowed body fields (others are ignored): - `enable_welcome_message` (boolean) - `prompts` (string[], max 4, each ≤ 80 chars) - `commands` (`{ command_name, command_description }[]`) Proxies Meta/360dialog `POST /conversational_automation`. -| | | -|---|---| -| HTTP | `POST /conversationalAutomation` | -| SDK group | `client.channel` | -| API class | `ChannelApi` | -| operationId | `setConversationalAutomation` | -| Signature | `setConversationalAutomation(token: string, conversationalAutomation: ConversationalAutomation, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | +| | | +| ----------- | --------------------------------------------------------------------------------------------------------------------------- | +| HTTP | `POST /conversationalAutomation` | +| SDK group | `client.channel` | +| API class | `ChannelApi` | +| operationId | `setConversationalAutomation` | +| Signature | `setConversationalAutomation(token: string, conversationalAutomation: ConversationalAutomation, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | #### Authentication @@ -3521,20 +3608,18 @@ Update WhatsApp conversational components. Allowed body fields (others are ignor **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `enable_welcome_message` | boolean | optional | Enable the automatic welcome message for new conversations | -| `prompts` | array | optional | Ice-breaker prompt strings (max 4, each ≤ 80 characters) | -| `commands` | array | optional | Slash commands shown in WhatsApp | +| Field | Type | Required | Description | +| ------------------------ | ------------- | -------- | ---------------------------------------------------------- | +| `enable_welcome_message` | boolean | optional | Enable the automatic welcome message for new conversations | +| `prompts` | array | optional | Ice-breaker prompt strings (max 4, each ≤ 80 characters) | +| `commands` | array | optional | Slash commands shown in WhatsApp | **OpenAPI example body** ```json { "enable_welcome_message": true, - "prompts": [ - "How can I help?" - ], + "prompts": ["How can I help?"], "commands": [ { "command_name": "help", @@ -3544,14 +3629,13 @@ Update WhatsApp conversational components. Allowed body fields (others are ignor } ``` - **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Updated settings from WABA, or legacy response.error wrapper on upstream failure. | `—` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------------------------------------------------- | --------------- | +| `200` | Updated settings from WABA, or legacy response.error wrapper on upstream failure. | `—` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -3586,13 +3670,13 @@ Namespace: `client.users` → `UsersApi` (3 operations) #### Block WhatsApp user -| | | -|---|---| -| HTTP | `POST /blockUser` | -| SDK group | `client.users` | -| API class | `UsersApi` | -| operationId | `blockUser` | -| Signature | `blockUser(token: string, blockUserRequest: BlockUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ----------------------------------------------------------------------------------------- | +| HTTP | `POST /blockUser` | +| SDK group | `client.users` | +| API class | `UsersApi` | +| operationId | `blockUser` | +| Signature | `blockUser(token: string, blockUserRequest: BlockUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -3605,19 +3689,18 @@ Namespace: `client.users` → `UsersApi` (3 operations) **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | integer | **required** | | - +| Field | Type | Required | Description | +| ------- | ------- | ------------ | ----------- | +| `phone` | integer | **required** | | **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Operation successful | `SuccessResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | ----------------- | +| `200` | Operation successful | `SuccessResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -3639,13 +3722,13 @@ curl -X POST 'https://api.1msg.io/{instanceId}/blockUser?token={token}' \ Returns users currently blocked on this WhatsApp channel (WABA `GET /block_users`). Same channel token auth as `blockUser` / `unblockUser`. -| | | -|---|---| -| HTTP | `GET /blockedUsers` | -| SDK group | `client.users` | -| API class | `UsersApi` | -| operationId | `listBlockedUsers` | -| Signature | `listBlockedUsers(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ------------------------------------------------------------ | +| HTTP | `GET /blockedUsers` | +| SDK group | `client.users` | +| API class | `UsersApi` | +| operationId | `listBlockedUsers` | +| Signature | `listBlockedUsers(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -3658,11 +3741,11 @@ Returns users currently blocked on this WhatsApp channel (WABA `GET /block_users **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Blocked users list | `—` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------- | +| `200` | Blocked users list | `—` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -3680,13 +3763,13 @@ curl -X GET 'https://api.1msg.io/{instanceId}/blockedUsers?token={token}' #### Unblock WhatsApp user -| | | -|---|---| -| HTTP | `POST /unblockUser` | -| SDK group | `client.users` | -| API class | `UsersApi` | -| operationId | `unblockUser` | -| Signature | `unblockUser(token: string, blockUserRequest: BlockUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ------------------------------------------------------------------------------------------- | +| HTTP | `POST /unblockUser` | +| SDK group | `client.users` | +| API class | `UsersApi` | +| operationId | `unblockUser` | +| Signature | `unblockUser(token: string, blockUserRequest: BlockUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -3699,19 +3782,18 @@ curl -X GET 'https://api.1msg.io/{instanceId}/blockedUsers?token={token}' **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | integer | **required** | | - +| Field | Type | Required | Description | +| ------- | ------- | ------------ | ----------- | +| `phone` | integer | **required** | | **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Operation successful | `SuccessResponse` | -| `400` | Invalid request parameters | `ErrorResponse` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | ----------------- | +| `200` | Operation successful | `SuccessResponse` | +| `400` | Invalid request parameters | `ErrorResponse` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -3735,15 +3817,15 @@ Namespace: `client.webhooks` → `WebhooksApi` (2 operations) #### Get webhook URL -Returns the configured client webhook URL for this channel. +Return the webhook URL(s) currently configured for this channel, plus delivery status for each URL. `webhookUrl` is a string when a single URL is set, an array of strings when multiple URLs are configured, or `null` if none is set. **Prefer `webhookStatuses`.** The circuit breaker is per URL, not per channel. If 1 of 4 URLs is sticky-disabled, that URL is skipped; the other three still receive events. Send/receive are not affected. Channel-level `haveDisabledWebhooks`, `circuitState`, `reason`, `fails`, `trips`, and timestamps are a compatibility summary of **one** URL (the first sticky-disabled URL, else the first configured URL). They are not "the channel is dead". - `haveDisabledWebhooks` — `true` when **at least one** URL in `webhookUrl` is sticky auto-disabled. Live URLs still get events. - `circuitState` — compressed scalar for that same primary URL: `ok` | `degraded` | `open` | `half_open` | `disabled`. - `disabledWebhooks` — currently configured URLs that are sticky-disabled (subset of `webhookUrl`). - `webhookStatuses` — one row per currently configured URL. Use this array to see which endpoints are live vs skipped. - `fails` / `trips` / `firstFailAt` — **diagnostics for support**, not product UI. `fails` = failures in a rolling ~10 minute window (not lifetime). `trips` = failed recovery probes on the 15 min → 1 h → 6 h schedule (sticky disable after 3). Clients can ignore these and use `webhookStatuses` + `disabledWebhooks` only. Sticky disable skips delivery; it does not unconfigure the URL (it stays in `webhookUrl`). Re-enable with `POST /webhook` or `POST /settings`. Those endpoints **replace** the whole list — with multiple URLs, send the full array. -| | | -|---|---| -| HTTP | `GET /webhook` | -| SDK group | `client.webhooks` | -| API class | `WebhooksApi` | -| operationId | `getWebhook` | -| Signature | `getWebhook(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | +| | | +| ----------- | ------------------------------------------------------ | +| HTTP | `GET /webhook` | +| SDK group | `client.webhooks` | +| API class | `WebhooksApi` | +| operationId | `getWebhook` | +| Signature | `getWebhook(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -3756,11 +3838,11 @@ Returns the configured client webhook URL for this channel. **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Current webhook URL | `—` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | ---------------------------------------------- | --------------- | +| `200` | Current webhook URL and per-URL circuit status | `—` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example @@ -3778,15 +3860,15 @@ curl -X GET 'https://api.1msg.io/{instanceId}/webhook?token={token}' #### Set webhook URL -Configure the client webhook URL for inbound events. WhatsApp **Calling** events (`field=calls`) are forwarded as passthrough payloads with `type: "calls"` and `instanceId` (connect / status / terminate). Call permission replies arrive on the normal messages path (`call_permission_reply`). Details: **Calling** tag. +Set the client webhook URL that receives inbound events for this channel. **Replaces** the stored webhook list (it does not append). To deliver the same events to several endpoints, pass an array in `webhookUrl` (max 5) or use `POST /settings`. With several URLs already configured, posting only the disabled URL **drops the others** — send the complete array to re-enable one of many. Incoming payloads include messages, delivery ACKs, group updates, coexistence echoes, and calling events. WhatsApp Calling payloads (`type: "calls"`) are documented under the **Calling** tag. Call permission replies arrive on the normal messages path (`call_permission_reply`). Repeating `POST /webhook` with the same URL(s) clears an auto-disable (self-serve re-enable). Send/receive are not affected by webhook auto-disable. -| | | -|---|---| -| HTTP | `POST /webhook` | -| SDK group | `client.webhooks` | -| API class | `WebhooksApi` | -| operationId | `setWebhook` | -| Signature | `setWebhook(token: string, getWebhook200Response?: GetWebhook200Response, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>` | +| | | +| ----------- | -------------------------------------------------------------------------------------------- | +| HTTP | `POST /webhook` | +| SDK group | `client.webhooks` | +| API class | `WebhooksApi` | +| operationId | `setWebhook` | +| Signature | `setWebhook(token: string, setWebhookRequest: SetWebhookRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise` | #### Authentication @@ -3799,23 +3881,22 @@ Configure the client webhook URL for inbound events. WhatsApp **Calling** events **Request body schema** -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `webhookUrl` | string | optional | | - +| Field | Type | Required | Description | +| ------------ | ------ | ------------- | ------------ | +| `webhookUrl` | string | array | **required** | HTTP or HTTPS URL, or array of URLs (max 5). Replaces the stored list. Empty values are rejected — clear webhooks with `POST /settings`. | **Responses** -| Status | Description | Schema | -|--------|-------------|--------| -| `200` | Webhook configured | `—` | -| `401` | Invalid or missing authentication token | `ErrorResponse` | -| `500` | Internal server error | `ErrorResponse` | +| Status | Description | Schema | +| ------ | --------------------------------------- | --------------- | +| `200` | Webhook configured | `—` | +| `401` | Invalid or missing authentication token | `ErrorResponse` | +| `500` | Internal server error | `ErrorResponse` | #### SDK example ```typescript -await client.webhooks.setWebhook(client.config.token, undefined); +await client.webhooks.setWebhook(client.config.token, {}); ``` #### cURL equivalent @@ -3834,650 +3915,752 @@ All models below are exported from `@1msg/sdk`. Import by name: import type { SendMessageRequest, MessageSentResponse } from '@1msg/sdk'; ``` +### `AddTemplate200Response` + +Check if a given object implements the AddTemplate200Response interface. + +| Field | Type | Required | Description | +| ---------- | ---------------------- | -------- | ----------- | +| `response` | `{ [key: string]: any` | optional | — | + ### `AddTemplateRequest` Check if a given object implements the AddTemplateRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `name` | `string` | optional | — | -| `category` | `string` | optional | — | -| `language` | `string` | optional | — | -| `components` | `Array<{ [key: string]: any` | optional | — | +| Field | Type | Required | Description | +| ------------ | ---------------------------- | -------- | ----------- | +| `name` | `string` | optional | — | +| `category` | `string` | optional | — | +| `language` | `string` | optional | — | +| `components` | `Array<{ [key: string]: any` | optional | — | ### `BlockUserRequest` Check if a given object implements the BlockUserRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | `number` | **required** | — | +| Field | Type | Required | Description | +| ------- | -------- | ------------ | ----------- | +| `phone` | `number` | **required** | — | ### `CallingSettings` Check if a given object implements the CallingSettings interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `calling` | object | optional | Calling feature configuration for the business phone number | - | `status` | enum("ENABLED" | "DISABLED") | optional | Enable or disable Calling API on this number (example="ENABLED") | - | `call_icon_visibility` | enum("DEFAULT" | "DISABLE_ALL") | optional | Controls call icon visibility in the WhatsApp client (example="DEFAULT") | - | `callback_permission_status` | enum("ENABLED" | "DISABLED") | optional | When ENABLED, a user who calls your business automatically grants call permission for business-initiated callbacks (subject to Meta rules). (example="ENABLED") | - | `srtp_key_exchange_protocol` | enum("DTLS" | "SDES") | optional | SRTP key exchange. DTLS is default/recommended. SDES is only valid when SIP signaling is enabled. (example="DTLS") | - | `call_hours` | object | optional | Optional call hours / timezone configuration (Meta shape) | +| Field | Type | Required | Description | +| ---------------------------- | -------------- | -------------- | ----------------------------------------------------------- | +| `calling` | object | optional | Calling feature configuration for the business phone number | +| `status` | enum("ENABLED" | "DISABLED") | optional | Enable or disable Calling API on this number (example="ENABLED") | +| `call_icon_visibility` | enum("DEFAULT" | "DISABLE_ALL") | optional | Controls call icon visibility in the WhatsApp client (example="DEFAULT") | +| `callback_permission_status` | enum("ENABLED" | "DISABLED") | optional | When ENABLED, a user who calls your business automatically grants call permission for business-initiated callbacks (subject to Meta rules). (example="ENABLED") | +| `srtp_key_exchange_protocol` | enum("DTLS" | "SDES") | optional | SRTP key exchange. DTLS is default/recommended. SDES is only valid when SIP signaling is enabled. (example="DTLS") | +| `call_hours` | object | optional | Optional call hours / timezone configuration (Meta shape) | + | `status` | string | optional | (example="ENABLED") | | `timezone` | string | optional | (example="America/Los_Angeles") | | `day_of_week_start` | string | optional | (example="MONDAY") | - | `sip` | object | optional | SIP trunk settings. When SIP is ENABLED, Graph call actions and calling webhooks are not used — Meta dials your SIP server directly. | - | `status` | enum("ENABLED" | "DISABLED") | optional | (example="DISABLED") | - | `servers` | array | optional | | - | `video` | object | optional | Video calling toggle when supported | - | `status` | enum("ENABLED" | "DISABLED") | optional | | - | `audio` | object | optional | Audio settings (typically response-only) | - | `status` | string | optional | | - | `restrictions` | object | optional | Calling restrictions (response-only) | - | `ip_addresses` | object | optional | Meta media IP ranges (response-only) | - | `call_icons` | object | optional | Call icon country restrictions (response-only) | + +| `sip` | object | optional | SIP trunk settings. When SIP is ENABLED, Graph call actions and calling webhooks are not used — Meta dials your SIP server directly. | +| `status` | enum("ENABLED" | "DISABLED") | optional | (example="DISABLED") | +| `servers` | array | optional | | +| `video` | object | optional | Video calling toggle when supported | +| `status` | enum("ENABLED" | "DISABLED") | optional | | +| `audio` | object | optional | Audio settings (typically response-only) | +| `status` | string | optional | | +| `restrictions` | object | optional | Calling restrictions (response-only) | +| `ip_addresses` | object | optional | Meta media IP ranges (response-only) | +| `call_icons` | object | optional | Call icon country restrictions (response-only) | ### `CallingSettingsCalling` @export -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `status` | `CallingSettingsCallingStatusEnum` | optional | — | -| `callIconVisibility` | `CallingSettingsCallingCallIconVisibilityEnum` | optional | — | -| `callbackPermissionStatus` | `CallingSettingsCallingCallbackPermissionStatusEnum` | optional | — | -| `srtpKeyExchangeProtocol` | `CallingSettingsCallingSrtpKeyExchangeProtocolEnum` | optional | — | -| `callHours` | `CallingSettingsCallingCallHours` | optional | — | -| `sip` | `CallingSettingsCallingSip` | optional | — | -| `video` | `CallingSettingsCallingVideo` | optional | — | -| `audio` | `CallingSettingsCallingAudio` | optional | — | -| `restrictions` | `{ [key: string]: any` | optional | — | -| `ipAddresses` | `{ [key: string]: any` | optional | — | -| `callIcons` | `{ [key: string]: any` | optional | — | +| Field | Type | Required | Description | +| -------------------------- | ---------------------------------------------------- | -------- | ----------- | +| `status` | `CallingSettingsCallingStatusEnum` | optional | — | +| `callIconVisibility` | `CallingSettingsCallingCallIconVisibilityEnum` | optional | — | +| `callbackPermissionStatus` | `CallingSettingsCallingCallbackPermissionStatusEnum` | optional | — | +| `srtpKeyExchangeProtocol` | `CallingSettingsCallingSrtpKeyExchangeProtocolEnum` | optional | — | +| `callHours` | `CallingSettingsCallingCallHours` | optional | — | +| `sip` | `CallingSettingsCallingSip` | optional | — | +| `video` | `CallingSettingsCallingVideo` | optional | — | +| `audio` | `CallingSettingsCallingAudio` | optional | — | +| `restrictions` | `{ [key: string]: any` | optional | — | +| `ipAddresses` | `{ [key: string]: any` | optional | — | +| `callIcons` | `{ [key: string]: any` | optional | — | ### `CallingSettingsCallingAudio` Check if a given object implements the CallingSettingsCallingAudio interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `status` | `string` | optional | — | +| Field | Type | Required | Description | +| -------- | -------- | -------- | ----------- | +| `status` | `string` | optional | — | ### `CallingSettingsCallingCallHours` Check if a given object implements the CallingSettingsCallingCallHours interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `status` | `string` | optional | — | -| `timezone` | `string` | optional | — | -| `dayOfWeekStart` | `string` | optional | — | +| Field | Type | Required | Description | +| ---------------- | -------- | -------- | ----------- | +| `status` | `string` | optional | — | +| `timezone` | `string` | optional | — | +| `dayOfWeekStart` | `string` | optional | — | ### `CallingSettingsCallingSip` @export -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `status` | `CallingSettingsCallingSipStatusEnum` | optional | — | -| `servers` | `Array` | optional | — | +| Field | Type | Required | Description | +| --------- | ---------------------------------------------- | -------- | ----------- | +| `status` | `CallingSettingsCallingSipStatusEnum` | optional | — | +| `servers` | `Array` | optional | — | ### `CallingSettingsCallingSipServersInner` Check if a given object implements the CallingSettingsCallingSipServersInner interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `hostname` | `string` | optional | — | -| `port` | `number` | optional | — | -| `requestUriUserParams` | `{ [key: string]: string` | optional | — | -| `sipUserPassword` | `string` | optional | — | -| `password` | `string` | optional | — | -| `appId` | `string` | optional | — | +| Field | Type | Required | Description | +| ---------------------- | ------------------------- | -------- | ----------- | +| `hostname` | `string` | optional | — | +| `port` | `number` | optional | — | +| `requestUriUserParams` | `{ [key: string]: string` | optional | — | +| `sipUserPassword` | `string` | optional | — | +| `password` | `string` | optional | — | +| `appId` | `string` | optional | — | ### `CallingSettingsCallingVideo` @export -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `status` | `CallingSettingsCallingVideoStatusEnum` | optional | — | +| Field | Type | Required | Description | +| -------- | --------------------------------------- | -------- | ----------- | +| `status` | `CallingSettingsCallingVideoStatusEnum` | optional | — | ### `ConversationalAutomation` Check if a given object implements the ConversationalAutomation interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `enable_welcome_message` | boolean | optional | Enable the automatic welcome message for new conversations | -| `prompts` | array | optional | Ice-breaker prompt strings (max 4, each ≤ 80 characters) | -| `commands` | array | optional | Slash commands shown in WhatsApp | +| Field | Type | Required | Description | +| ------------------------ | ------------- | -------- | ---------------------------------------------------------- | +| `enable_welcome_message` | boolean | optional | Enable the automatic welcome message for new conversations | +| `prompts` | array | optional | Ice-breaker prompt strings (max 4, each ≤ 80 characters) | +| `commands` | array | optional | Slash commands shown in WhatsApp | ### `ConversationalAutomationCommandsInner` Check if a given object implements the ConversationalAutomationCommandsInner interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `commandName` | `string` | **required** | — | -| `commandDescription` | `string` | **required** | — | +| Field | Type | Required | Description | +| -------------------- | -------- | ------------ | ----------- | +| `commandName` | `string` | **required** | — | +| `commandDescription` | `string` | **required** | — | ### `CreateCommerce200Response` Check if a given object implements the CreateCommerce200Response interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `success` | `boolean` | optional | — | +| Field | Type | Required | Description | +| --------- | --------- | -------- | ----------- | +| `success` | `boolean` | optional | — | ### `CreateCommerceRequest` Check if a given object implements the CreateCommerceRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `params` | `CreateCommerceRequestParams` | **required** | — | +| Field | Type | Required | Description | +| -------- | ----------------------------- | ------------ | ----------- | +| `params` | `CreateCommerceRequestParams` | **required** | — | ### `CreateCommerceRequestParams` Check if a given object implements the CreateCommerceRequestParams interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `isCartEnabled` | `boolean` | **required** | — | -| `isCatalogVisible` | `boolean` | **required** | — | +| Field | Type | Required | Description | +| ------------------ | --------- | ------------ | ----------- | +| `isCartEnabled` | `boolean` | **required** | — | +| `isCatalogVisible` | `boolean` | **required** | — | ### `CreateFlowsRequest` @export -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `name` | `string` | **required** | — | -| `categories` | `Array` | **required** | — | -| `endpointUri` | `string` | optional | — | -| `publish` | `boolean` | optional | — | -| `flowJson` | `{ [key: string]: any` | optional | — | +| Field | Type | Required | Description | +| ------------- | ----------------------------------------- | ------------ | ----------- | +| `name` | `string` | **required** | — | +| `categories` | `Array` | **required** | — | +| `endpointUri` | `string` | optional | — | +| `publish` | `boolean` | optional | — | +| `flowJson` | `{ [key: string]: any` | optional | — | ### `CreateGroups200Response` Check if a given object implements the CreateGroups200Response interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `error` | `any | null` | optional | — | +| Field | Type | Required | Description | +| ------- | ---- | -------- | ----------- | +| `error` | `any | null` | optional | — | ### `CreateGroupsGroupIdRequest` Check if a given object implements the CreateGroupsGroupIdRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `subject` | `string` | optional | — | -| `description` | `string` | optional | — | -| `profilePictureFile` | `string` | optional | — | +| Field | Type | Required | Description | +| -------------------- | -------- | -------- | ----------- | +| `subject` | `string` | optional | — | +| `description` | `string` | optional | — | +| `profilePictureFile` | `string` | optional | — | ### `CreateGroupsRequest` Check if a given object implements the CreateGroupsRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `groupName` | `string` | **required** | — | -| `description` | `string` | optional | — | +| Field | Type | Required | Description | +| ------------- | -------- | ------------ | ----------- | +| `groupName` | `string` | **required** | — | +| `description` | `string` | optional | — | ### `CreateReadMessage200Response` Check if a given object implements the CreateReadMessage200Response interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `result` | `string` | optional | — | +| Field | Type | Required | Description | +| -------- | -------- | -------- | ----------- | +| `result` | `string` | optional | — | ### `CreateReadMessage401Response` Check if a given object implements the CreateReadMessage401Response interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `error` | `string` | optional | — | +| Field | Type | Required | Description | +| ------- | -------- | -------- | ----------- | +| `error` | `string` | optional | — | ### `CreateReadMessageRequest` Check if a given object implements the CreateReadMessageRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `messageId` | `string` | optional | — | -| `msgId` | `string` | optional | — | -| `typingIndicator` | `boolean` | optional | — | +| Field | Type | Required | Description | +| ----------------- | --------- | -------- | ----------- | +| `messageId` | `string` | optional | — | +| `msgId` | `string` | optional | — | +| `typingIndicator` | `boolean` | optional | — | + +### `CreateSettingsRequest` + +Check if a given object implements the CreateSettingsRequest interface. + +| Field | Type | Required | Description | +| ---------------------------- | --------------------------------- | -------- | ----------- | +| `webhookUrl` | `CreateSettingsRequestWebhookUrl` | optional | — | +| `guaranteedHooks` | `boolean` | optional | — | +| `ackNotificationsOn` | `boolean` | optional | — | +| `rawHooks` | `boolean` | optional | — | +| `templateAnalyticsEnabled` | `boolean` | optional | — | +| `ctaUrlLinkTrackingOptedOut` | `boolean` | optional | — | + +### `CreateSettingsRequestWebhookUrl` + +_No property metadata — see generated TypeScript interface._ ### `CreateUploadMedia200Response` Check if a given object implements the CreateUploadMedia200Response interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `mediaId` | `string` | optional | — | +| Field | Type | Required | Description | +| --------- | -------- | -------- | ----------- | +| `mediaId` | `string` | optional | — | ### `CreateUploadMediaRequest` Check if a given object implements the CreateUploadMediaRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `body` | `string` | **required** | — | +| Field | Type | Required | Description | +| ------ | -------- | -------- | ----------- | +| `body` | `string` | optional | — | +| `url` | `string` | optional | — | ### `DeleteFlowsFlowId200Response` Check if a given object implements the DeleteFlowsFlowId200Response interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `success` | `boolean` | optional | — | -| `error` | `any | null` | optional | — | +| Field | Type | Required | Description | +| --------- | --------- | -------- | ----------- | +| `success` | `boolean` | optional | — | +| `error` | `any | null` | optional | — | ### `DeleteGroupsGroupId200Response` Check if a given object implements the DeleteGroupsGroupId200Response interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `success` | `boolean` | optional | — | -| `response` | `{ [key: string]: any` | optional | — | +| Field | Type | Required | Description | +| ---------- | ---------------------- | -------- | ----------- | +| `success` | `boolean` | optional | — | +| `response` | `{ [key: string]: any` | optional | — | ### `DeleteMediaLegacyRequest` Check if a given object implements the DeleteMediaLegacyRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `mediaId` | `string` | **required** | — | +| Field | Type | Required | Description | +| --------- | -------- | ------------ | ----------- | +| `mediaId` | `string` | **required** | — | ### `ErrorResponse` Check if a given object implements the ErrorResponse interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| +| Field | Type | Required | Description | +| ------- | ------ | -------- | ------------- | | `error` | string | optional | Error message | ### `GetCommerce200ResponseInner` Check if a given object implements the GetCommerce200ResponseInner interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `id` | `string` | optional | — | -| `isCartEnabled` | `boolean` | optional | — | -| `isCatalogVisible` | `boolean` | optional | — | +| Field | Type | Required | Description | +| ------------------ | --------- | -------- | ----------- | +| `id` | `string` | optional | — | +| `isCartEnabled` | `boolean` | optional | — | +| `isCatalogVisible` | `boolean` | optional | — | ### `GetMmLiteStatus200Response` Check if a given object implements the GetMmLiteStatus200Response interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `available` | `boolean` | optional | — | -| `status` | `string` | optional | — | -| `message` | `string` | optional | — | +| Field | Type | Required | Description | +| ----------- | --------- | -------- | ----------- | +| `available` | `boolean` | optional | — | +| `status` | `string` | optional | — | +| `message` | `string` | optional | — | + +### `GetStatus200Response` + +Check if a given object implements the GetStatus200Response interface. + +| Field | Type | Required | Description | +| --------------------- | --------- | -------- | ----------- | +| `isCloud` | `boolean` | optional | — | +| `status` | `string` | optional | — | +| `accountStatus` | `string` | optional | — | +| `mmLiteAvailable` | `boolean` | optional | — | +| `healthStatusWarning` | `string` | optional | — | ### `GetWebhook200Response` -Check if a given object implements the GetWebhook200Response interface. +@export + +| Field | Type | Required | Description | +| ---------------------- | --------------------------------------- | -------- | ----------- | +| `webhookUrl` | `GetWebhook200ResponseWebhookUrl | null` | optional | — | +| `haveDisabledWebhooks` | `boolean` | optional | — | +| `circuitState` | `GetWebhook200ResponseCircuitStateEnum` | optional | — | +| `reason` | `string` | optional | — | +| `fails` | `number` | optional | — | +| `trips` | `number` | optional | — | +| `disabledAt` | `number` | optional | — | +| `firstFailAt` | `number` | optional | — | +| `lastStatus` | `number` | optional | — | +| `nextProbeAt` | `number` | optional | — | +| `disabledWebhooks` | `Array<{ [key: string]: any` | optional | — | +| `webhookStatuses` | `Array` | optional | — | + +### `GetWebhook200ResponseWebhookUrl` -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `webhookUrl` | `string` | optional | — | +_No property metadata — see generated TypeScript interface._ ### `GetWhatsappBusinessEncryption200Response` @export -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `businessPublicKey` | `string` | optional | — | -| `businessPublicKeySignatureStatus` | `GetWhatsappBusinessEncryption200ResponseBusinessPublicKeySignatureStatusEnum` | optional | — | -| `data` | `Array<{ [key: string]: any` | optional | — | +| Field | Type | Required | Description | +| ---------------------------------- | ------------------------------------------------------------------------------ | -------- | ----------- | +| `businessPublicKey` | `string` | optional | — | +| `businessPublicKeySignatureStatus` | `GetWhatsappBusinessEncryption200ResponseBusinessPublicKeySignatureStatusEnum` | optional | — | +| `data` | `Array<{ [key: string]: any` | optional | — | ### `InitiateCallRequest` @export -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `messaging_product` | enum("whatsapp") | **required** | Must be `whatsapp` (example="whatsapp") | -| `action` | enum("connect" | "pre_accept" | "accept" | "reject" | "terminate") | **required** | Call control action (example="connect") | -| `call_id` | string | optional | WhatsApp call id from the inbound/outbound calls webhook (`calls[].id`). Required for `pre_accept`, `accept`, `reject`, `terminate`. (example="wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh") | -| `to` | string | optional | Recipient WhatsApp user phone (digits, country code, no +). Required for outbound `connect`. (example="12185552828") | -| `biz_opaque_callback_data` | string | optional | Optional opaque string echoed on later call webhooks for correlation (maxLength=512, example="order-123-callback") | -| `session` | object | optional | WebRTC SDP session (required for connect / pre_accept / accept) | - | `sdp_type` | enum("offer" | "answer") | **required** | offer for outbound connect; answer for pre_accept/accept (example="offer") | - | `sdp` | string | **required** | Full SDP (RFC 8866). Replace placeholders with SDP from your WebRTC stack. Must negotiate ICE, DTLS-SRTP, and OPUS for WhatsApp media. (example="[REPLACE_WITH_WEBRTC_SDP]") | +| Field | Type | Required | Description | +| -------------------------- | ---------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `messaging_product` | enum("whatsapp") | **required** | Must be `whatsapp` (example="whatsapp") | +| `action` | enum("connect" | "pre_accept" | "accept" | "reject" | "terminate") | **required** | Call control action (example="connect") | +| `call_id` | string | optional | WhatsApp call id from the inbound/outbound calls webhook (`calls[].id`). Required for `pre_accept`, `accept`, `reject`, `terminate`. (example="wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh") | +| `to` | string | optional | Recipient WhatsApp user phone (digits, country code, no +). Required for outbound `connect`. (example="12185552828") | +| `biz_opaque_callback_data` | string | optional | Optional opaque string echoed on later call webhooks for correlation (maxLength=512, example="order-123-callback") | +| `session` | object | optional | WebRTC SDP session (required for connect / pre_accept / accept) | +| `sdp_type` | enum("offer" | "answer") | **required** | offer for outbound connect; answer for pre_accept/accept (example="offer") | +| `sdp` | string | **required** | Full SDP (RFC 8866). Replace placeholders with SDP from your WebRTC stack. Must negotiate ICE, DTLS-SRTP, and OPUS for WhatsApp media. (example="[REPLACE_WITH_WEBRTC_SDP]") | ### `InitiateCallRequestSession` @export -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `sdpType` | `InitiateCallRequestSessionSdpTypeEnum` | **required** | — | -| `sdp` | `string` | **required** | — | +| Field | Type | Required | Description | +| --------- | --------------------------------------- | ------------ | ----------- | +| `sdpType` | `InitiateCallRequestSessionSdpTypeEnum` | **required** | — | +| `sdp` | `string` | **required** | — | ### `InitiateCallResponse` Check if a given object implements the InitiateCallResponse interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `messaging_product` | string | optional | (example="whatsapp") | -| `success` | boolean | optional | (example=true) | -| `calls` | array | optional | Present on outbound `connect` — contains the new call id | -| `result` | string | optional | Legacy success marker when upstream returns an empty body (example="success") | -| `response` | object | optional | Present when 1msg wraps an upstream error | - | `error` | string | optional | | +| Field | Type | Required | Description | +| ------------------- | ------------- | -------- | ----------------------------------------------------------------------------- | +| `messaging_product` | string | optional | (example="whatsapp") | +| `success` | boolean | optional | (example=true) | +| `calls` | array | optional | Present on outbound `connect` — contains the new call id | +| `result` | string | optional | Legacy success marker when upstream returns an empty body (example="success") | +| `response` | object | optional | Present when 1msg wraps an upstream error | +| `error` | string | optional | | ### `InitiateCallResponseCallsInner` Check if a given object implements the InitiateCallResponseCallsInner interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `id` | `string` | optional | — | +| Field | Type | Required | Description | +| ----- | -------- | -------- | ----------- | +| `id` | `string` | optional | — | ### `InitiateCallResponseResponse` Check if a given object implements the InitiateCallResponseResponse interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `error` | `string` | optional | — | +| Field | Type | Required | Description | +| ------- | -------- | -------- | ----------- | +| `error` | `string` | optional | — | ### `ListBlockedUsers200Response` Check if a given object implements the ListBlockedUsers200Response interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `blockedUsers` | `Array<{ [key: string]: any` | optional | — | +| Field | Type | Required | Description | +| -------------- | ---------------------------- | -------- | ----------- | +| `blockedUsers` | `Array<{ [key: string]: any` | optional | — | ### `ListFlows200Response` Check if a given object implements the ListFlows200Response interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `items` | `Array<{ [key: string]: any` | optional | — | -| `paging` | `{ [key: string]: any` | optional | — | -| `count` | `number` | optional | — | -| `total` | `number` | optional | — | -| `error` | `any | null` | optional | — | +| Field | Type | Required | Description | +| -------- | ---------------------------- | -------- | ----------- | +| `items` | `Array<{ [key: string]: any` | optional | — | +| `paging` | `{ [key: string]: any` | optional | — | +| `count` | `number` | optional | — | +| `total` | `number` | optional | — | +| `error` | `any | null` | optional | — | ### `ListMessages200Response` Check if a given object implements the ListMessages200Response interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `notice` | `string` | optional | — | -| `messages` | `Array<{ [key: string]: any` | optional | — | +| Field | Type | Required | Description | +| ---------- | ---------------------------- | -------- | ----------- | +| `notice` | `string` | optional | — | +| `messages` | `Array<{ [key: string]: any` | optional | — | + +### `ListSettings200Response` + +@export + +| Field | Type | Required | Description | +| ---------------------------- | ----------------------------------------- | -------- | ----------- | +| `webhookUrl` | `ListSettings200ResponseWebhookUrl` | optional | — | +| `guaranteedHooks` | `boolean` | optional | — | +| `ackNotificationsOn` | `boolean` | optional | — | +| `rawHooks` | `boolean` | optional | — | +| `mmLiteEnabled` | `boolean` | optional | — | +| `templateAnalyticsEnabled` | `boolean` | optional | — | +| `ctaUrlLinkTrackingOptedOut` | `boolean` | optional | — | +| `haveDisabledWebhooks` | `boolean` | optional | — | +| `circuitState` | `ListSettings200ResponseCircuitStateEnum` | optional | — | +| `reason` | `string` | optional | — | +| `fails` | `number` | optional | — | +| `trips` | `number` | optional | — | +| `disabledAt` | `number` | optional | — | +| `firstFailAt` | `number` | optional | — | +| `lastStatus` | `number` | optional | — | +| `nextProbeAt` | `number` | optional | — | +| `disabledWebhooks` | `Array<{ [key: string]: any` | optional | — | +| `webhookStatuses` | `Array` | optional | — | + +### `ListSettings200ResponseWebhookUrl` + +_No property metadata — see generated TypeScript interface._ ### `ListTemplates200Response` Check if a given object implements the ListTemplates200Response interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `total` | `number` | optional | — | -| `templates` | `Array<{ [key: string]: any` | optional | — | -| `error` | `{ [key: string]: any` | optional | — | +| Field | Type | Required | Description | +| ----------- | ---------------------------- | -------- | ----------- | +| `total` | `number` | optional | — | +| `templates` | `Array<{ [key: string]: any` | optional | — | +| `error` | `{ [key: string]: any` | optional | — | ### `MessageSentResponse` Check if a given object implements the MessageSentResponse interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `sent` | boolean | optional | Whether the message was successfully queued for sending | -| `id` | string | optional | Message ID | -| `message` | string | optional | Status message | -| `description` | string | optional | Detailed description | +| Field | Type | Required | Description | +| ------------- | ------- | -------- | ------------------------------------------------------- | +| `sent` | boolean | optional | Whether the message was successfully queued for sending | +| `id` | string | optional | Message ID | +| `message` | string | optional | Status message | +| `description` | string | optional | Detailed description | ### `PatchFlowsFlowIdAssets200Response` Check if a given object implements the PatchFlowsFlowIdAssets200Response interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `success` | `boolean` | optional | — | -| `validationErrors` | `Array<{ [key: string]: any` | optional | — | -| `error` | `any | null` | optional | — | +| Field | Type | Required | Description | +| ------------------ | ---------------------------- | -------- | ----------- | +| `success` | `boolean` | optional | — | +| `validationErrors` | `Array<{ [key: string]: any` | optional | — | +| `error` | `any | null` | optional | — | ### `PatchFlowsFlowIdAssetsRequest` Check if a given object implements the PatchFlowsFlowIdAssetsRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `flowJson` | `{ [key: string]: any` | **required** | — | +| Field | Type | Required | Description | +| ---------- | ---------------------- | ------------ | ----------- | +| `flowJson` | `{ [key: string]: any` | **required** | — | ### `PatchFlowsFlowIdMetadataRequest` @export -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `name` | `string` | optional | — | -| `categories` | `Array` | optional | — | -| `endpointUri` | `string` | optional | — | +| Field | Type | Required | Description | +| ------------- | ------------------------------------------------------ | -------- | ----------- | +| `name` | `string` | optional | — | +| `categories` | `Array` | optional | — | +| `endpointUri` | `string` | optional | — | ### `ProfileInfo` @export -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `about` | string | optional | Profile's About section | -| `address` | string | optional | Address of the business | -| `description` | string | optional | Description of the business | -| `email` | string | optional | Business email | -| `phone` | string | optional | Linked phone number | -| `vertical` | enum("Automotive" | "Beauty, Spa and Salon" | "Clothing and Apparel" | "Education" | "Entertainment" | "Event Planning and Service" | "Finance and Banking" | "Food and Grocery" | "Public Service" | "Hotel and Lodging" | "Medical and Health" | "Non-profit" | "Professional Services" | "Shopping and Retail" | "Travel and Transportation" | "Restaurant" | "Other") | optional | Industry of the business | -| `photo` | string | optional | Profile photo URL | -| `websites` | array | optional | | +| Field | Type | Required | Description | +| ------------- | ----------------- | ----------------------- | --------------------------- | +| `about` | string | optional | Profile's About section | +| `address` | string | optional | Address of the business | +| `description` | string | optional | Description of the business | +| `email` | string | optional | Business email | +| `phone` | string | optional | Linked phone number | +| `vertical` | enum("Automotive" | "Beauty, Spa and Salon" | "Clothing and Apparel" | "Education" | "Entertainment" | "Event Planning and Service" | "Finance and Banking" | "Food and Grocery" | "Public Service" | "Hotel and Lodging" | "Medical and Health" | "Non-profit" | "Professional Services" | "Shopping and Retail" | "Travel and Transportation" | "Restaurant" | "Other") | optional | Industry of the business | +| `photo` | string | optional | Profile photo URL | +| `websites` | array | optional | | ### `RemoveTemplateRequest` Check if a given object implements the RemoveTemplateRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `name` | `string` | **required** | — | +| Field | Type | Required | Description | +| ------ | -------- | ------------ | ----------- | +| `name` | `string` | **required** | — | ### `RetrieveMedia200Response` Check if a given object implements the RetrieveMedia200Response interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `url` | `string` | optional | — | -| `mimeType` | `string` | optional | — | -| `sha256` | `string` | optional | — | -| `fileSize` | `number` | optional | — | -| `id` | `string` | optional | — | +| Field | Type | Required | Description | +| ---------- | -------- | -------- | ----------- | +| `url` | `string` | optional | — | +| `mimeType` | `string` | optional | — | +| `sha256` | `string` | optional | — | +| `fileSize` | `number` | optional | — | +| `id` | `string` | optional | — | ### `SendAddressMessageRequest` @export -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | `number` | optional | — | -| `chatId` | `string` | optional | — | -| `body` | `string` | **required** | — | -| `country` | `SendAddressMessageRequestCountryEnum` | optional | — | -| `values` | `{ [key: string]: any` | optional | — | -| `savedAddresses` | `Array<{ [key: string]: any` | optional | — | -| `validationErrors` | `{ [key: string]: any` | optional | — | -| `quotedMsgId` | `string` | optional | — | +| Field | Type | Required | Description | +| ------------------ | -------------------------------------- | ------------ | ----------- | +| `phone` | `number` | optional | — | +| `chatId` | `string` | optional | — | +| `body` | `string` | **required** | — | +| `country` | `SendAddressMessageRequestCountryEnum` | optional | — | +| `values` | `{ [key: string]: any` | optional | — | +| `savedAddresses` | `Array<{ [key: string]: any` | optional | — | +| `validationErrors` | `{ [key: string]: any` | optional | — | +| `quotedMsgId` | `string` | optional | — | ### `SendButtonRequest` Check if a given object implements the SendButtonRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | `string` | optional | — | -| `chatId` | `string` | optional | — | -| `quotedMsgId` | `string` | optional | — | -| `body` | `string` | optional | — | -| `footer` | `string` | optional | — | -| `header` | `{ [key: string]: any` | optional | — | -| `buttons` | `Array` | optional | — | -| `sections` | `Array` | optional | — | +| Field | Type | Required | Description | +| ------------- | --------------------------------------- | -------- | ----------- | +| `phone` | `string` | optional | — | +| `chatId` | `string` | optional | — | +| `quotedMsgId` | `string` | optional | — | +| `body` | `string` | optional | — | +| `footer` | `string` | optional | — | +| `header` | `{ [key: string]: any` | optional | — | +| `buttons` | `Array` | optional | — | +| `sections` | `Array` | optional | — | ### `SendButtonRequestSectionsInner` Check if a given object implements the SendButtonRequestSectionsInner interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `type` | `string` | optional | — | -| `reply` | `SendButtonRequestSectionsInnerReply` | optional | — | +| Field | Type | Required | Description | +| ------- | ------------------------------------- | -------- | ----------- | +| `type` | `string` | optional | — | +| `reply` | `SendButtonRequestSectionsInnerReply` | optional | — | ### `SendButtonRequestSectionsInnerReply` Check if a given object implements the SendButtonRequestSectionsInnerReply interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `id` | `string` | optional | — | -| `title` | `string` | optional | — | +| Field | Type | Required | Description | +| ------- | -------- | -------- | ----------- | +| `id` | `string` | optional | — | +| `title` | `string` | optional | — | ### `SendCarouselRequest1` Check if a given object implements the SendCarouselRequest1 interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `body` | `string` | optional | — | -| `params` | `Array` | **required** | — | -| `quotedMsgId` | `string` | optional | — | -| `chatId` | `string` | optional | — | -| `phone` | `number` | optional | — | +| Field | Type | Required | Description | +| ------------- | ---------------------------- | -------- | ----------- | +| `body` | `string` | optional | — | +| `cards` | `Array<{ [key: string]: any` | optional | — | +| `params` | `Array` | optional | — | +| `quotedMsgId` | `string` | optional | — | +| `chatId` | `string` | optional | — | +| `phone` | `number` | optional | — | ### `SendContactRequest` Check if a given object implements the SendContactRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | `string` | optional | — | -| `chatId` | `string` | optional | — | -| `quotedMsgId` | `string` | optional | — | -| `contacts` | `Array` | optional | — | +| Field | Type | Required | Description | +| ------------- | ---------------------------------------- | -------- | ----------- | +| `phone` | `string` | optional | — | +| `chatId` | `string` | optional | — | +| `quotedMsgId` | `string` | optional | — | +| `contact` | `SendContactRequestContact` | optional | — | +| `contacts` | `Array` | optional | — | + +### `SendContactRequestContact` + +Check if a given object implements the SendContactRequestContact interface. + +| Field | Type | Required | Description | +| ------- | ------------------------------- | ------------ | ----------- | +| `name` | `SendContactRequestContactName` | **required** | — | +| `phone` | `string` | **required** | — | +| `email` | `string` | optional | — | +| `org` | `{ [key: string]: any` | optional | — | +| `url` | `string` | optional | — | + +### `SendContactRequestContactName` + +_No property metadata — see generated TypeScript interface._ ### `SendContactRequestContactsInner` Check if a given object implements the SendContactRequestContactsInner interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `name` | `SendContactRequestContactsInnerName` | optional | — | -| `birthday` | `string` | optional | — | -| `addresses` | `Array<{ [key: string]: any` | optional | — | -| `emails` | `Array<{ [key: string]: any` | optional | — | -| `org` | `SendContactRequestContactsInnerOrg` | optional | — | -| `phones` | `Array` | optional | — | -| `urls` | `Array<{ [key: string]: any` | optional | — | +| Field | Type | Required | Description | +| ----------- | --------------------------------------------------- | -------- | ----------- | +| `name` | `SendContactRequestContactsInnerName` | optional | — | +| `birthday` | `string` | optional | — | +| `addresses` | `Array<{ [key: string]: any` | optional | — | +| `emails` | `Array<{ [key: string]: any` | optional | — | +| `org` | `SendContactRequestContactsInnerOrg` | optional | — | +| `phones` | `Array` | optional | — | +| `urls` | `Array<{ [key: string]: any` | optional | — | ### `SendContactRequestContactsInnerName` Check if a given object implements the SendContactRequestContactsInnerName interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `formattedName` | `string` | optional | — | -| `firstName` | `string` | optional | — | -| `lastName` | `string` | optional | — | -| `middleName` | `string` | optional | — | -| `suffix` | `string` | optional | — | -| `prefix` | `string` | optional | — | +| Field | Type | Required | Description | +| --------------- | -------- | -------- | ----------- | +| `formattedName` | `string` | optional | — | +| `firstName` | `string` | optional | — | +| `lastName` | `string` | optional | — | +| `middleName` | `string` | optional | — | +| `suffix` | `string` | optional | — | +| `prefix` | `string` | optional | — | ### `SendContactRequestContactsInnerOrg` Check if a given object implements the SendContactRequestContactsInnerOrg interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `company` | `string` | optional | — | -| `department` | `string` | optional | — | -| `title` | `string` | optional | — | +| Field | Type | Required | Description | +| ------------ | -------- | -------- | ----------- | +| `company` | `string` | optional | — | +| `department` | `string` | optional | — | +| `title` | `string` | optional | — | ### `SendContactRequestContactsInnerPhonesInner` Check if a given object implements the SendContactRequestContactsInnerPhonesInner interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | `string` | optional | — | -| `type` | `string` | optional | — | -| `waId` | `string` | optional | — | +| Field | Type | Required | Description | +| ------- | -------- | -------- | ----------- | +| `phone` | `string` | optional | — | +| `type` | `string` | optional | — | +| `waId` | `string` | optional | — | ### `SendCtaUrlRequest` Check if a given object implements the SendCtaUrlRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | `number` | optional | — | -| `chatId` | `string` | optional | — | -| `body` | `string` | **required** | — | -| `displayText` | `string` | **required** | — | -| `url` | `string` | **required** | — | -| `header` | `{ [key: string]: any` | optional | — | -| `footer` | `string` | optional | — | -| `quotedMsgId` | `string` | optional | — | +| Field | Type | Required | Description | +| ------------- | ---------------------- | ------------ | ----------- | +| `phone` | `number` | optional | — | +| `chatId` | `string` | optional | — | +| `body` | `string` | **required** | — | +| `displayText` | `string` | **required** | — | +| `url` | `string` | **required** | — | +| `header` | `{ [key: string]: any` | optional | — | +| `footer` | `string` | optional | — | +| `quotedMsgId` | `string` | optional | — | ### `SendFileRequest` @export -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `body` | string | optional | File source (required unless mediaId is set): - HTTP/HTTPS URL - Base64 data URI | -| `filename` | string | optional | File name with extension (required with body, not with mediaId) | -| `mediaId` | string | optional | WABA media id from uploadMedia (alternative to body) | -| `mediaType` | enum("image" | "video" | "audio" | "document") | optional | Required when using mediaId | -| `voice` | boolean | optional | Native WhatsApp voice note (audio/ogg only) | -| `caption` | string | optional | (maxLength=1024) | -| `quotedMsgId` | string | optional | | -| `chatId` | string | optional | | -| `phone` | integer | optional | | +| Field | Type | Required | Description | +| ------------- | ------------ | -------- | -------------------------------------------------------------------------------- | +| `body` | string | optional | File source (required unless mediaId is set): - HTTP/HTTPS URL - Base64 data URI | +| `filename` | string | optional | File name with extension (required with body, not with mediaId) | +| `mediaId` | string | optional | WABA media id from uploadMedia (alternative to body) | +| `mediaType` | enum("image" | "video" | "audio" | "document") | optional | Required when using mediaId | +| `voice` | boolean | optional | Native WhatsApp voice note (audio/ogg only) | +| `caption` | string | optional | (maxLength=1024) | +| `quotedMsgId` | string | optional | | +| `chatId` | string | optional | | +| `phone` | integer | optional | | ### `SendFlowRequest1` @export -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `body` | `string` | **required** | — | -| `header` | `SendFlowRequest1Header` | optional | — | -| `footer` | `string` | optional | — | -| `flowId` | `string` | **required** | — | -| `flowToken` | `string` | **required** | — | -| `flowCta` | `string` | **required** | — | -| `flowAction` | `SendFlowRequest1FlowActionEnum` | optional | — | -| `flowActionPayload` | `object` | optional | — | -| `flowMessageVersion` | `string` | optional | — | -| `mode` | `SendFlowRequest1ModeEnum` | optional | — | -| `flowActionData` | `object` | optional | — | -| `flowActionScreen` | `string` | optional | — | -| `quotedMsgId` | `string` | optional | — | -| `chatId` | `string` | optional | — | -| `phone` | `number` | optional | — | +| Field | Type | Required | Description | +| -------------------- | -------------------------------- | ------------ | ----------- | +| `body` | `string` | **required** | — | +| `header` | `SendFlowRequest1Header` | optional | — | +| `footer` | `string` | optional | — | +| `flowId` | `string` | **required** | — | +| `flowToken` | `string` | **required** | — | +| `flowCta` | `string` | **required** | — | +| `flowAction` | `SendFlowRequest1FlowActionEnum` | optional | — | +| `flowActionPayload` | `object` | optional | — | +| `flowMessageVersion` | `string` | optional | — | +| `mode` | `SendFlowRequest1ModeEnum` | optional | — | +| `flowActionData` | `object` | optional | — | +| `flowActionScreen` | `string` | optional | — | +| `quotedMsgId` | `string` | optional | — | +| `chatId` | `string` | optional | — | +| `phone` | `number` | optional | — | ### `SendFlowRequest1Header` @@ -4491,252 +4674,301 @@ _No property metadata — see generated TypeScript interface._ Check if a given object implements the SendListRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | `string` | optional | — | -| `chatId` | `string` | optional | — | -| `quotedMsgId` | `string` | optional | — | -| `body` | `string` | optional | — | -| `buttonText` | `string` | optional | — | -| `action` | `string` | optional | — | -| `sections` | `Array` | optional | — | +| Field | Type | Required | Description | +| ------------- | ------------------------------------- | -------- | ----------- | +| `phone` | `string` | optional | — | +| `chatId` | `string` | optional | — | +| `quotedMsgId` | `string` | optional | — | +| `body` | `string` | optional | — | +| `buttonText` | `string` | optional | — | +| `action` | `string` | optional | — | +| `sections` | `Array` | optional | — | ### `SendListRequestSectionsInner` Check if a given object implements the SendListRequestSectionsInner interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `title` | `string` | optional | — | -| `rows` | `Array` | optional | — | +| Field | Type | Required | Description | +| ------- | ---------------------------------------------- | -------- | ----------- | +| `title` | `string` | optional | — | +| `rows` | `Array` | optional | — | ### `SendListRequestSectionsInnerRowsInner` Check if a given object implements the SendListRequestSectionsInnerRowsInner interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `id` | `string` | optional | — | -| `title` | `string` | optional | — | -| `description` | `string` | optional | — | +| Field | Type | Required | Description | +| ------------- | -------- | -------- | ----------- | +| `id` | `string` | optional | — | +| `title` | `string` | optional | — | +| `description` | `string` | optional | — | ### `SendLocationRequest1` Check if a given object implements the SendLocationRequest1 interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `lat` | `string` | **required** | — | -| `lng` | `string` | **required** | — | -| `address` | `string` | optional | — | -| `name` | `string` | optional | — | -| `quotedMsgId` | `string` | optional | — | -| `chatId` | `string` | optional | — | -| `phone` | `number` | optional | — | +| Field | Type | Required | Description | +| ------------- | -------- | ------------ | ----------- | +| `lat` | `string` | **required** | — | +| `lng` | `string` | **required** | — | +| `address` | `string` | optional | — | +| `name` | `string` | optional | — | +| `quotedMsgId` | `string` | optional | — | +| `chatId` | `string` | optional | — | +| `phone` | `number` | optional | — | ### `SendLocationRequestRequest` Check if a given object implements the SendLocationRequestRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | `string` | optional | — | -| `chatId` | `string` | optional | — | -| `quotedMsgId` | `string` | optional | — | -| `body` | `string` | optional | — | +| Field | Type | Required | Description | +| ------------- | -------- | -------- | ----------- | +| `phone` | `string` | optional | — | +| `chatId` | `string` | optional | — | +| `quotedMsgId` | `string` | optional | — | +| `body` | `string` | optional | — | ### `SendMessageRequest` Check if a given object implements the SendMessageRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `body` | string | **required** | Message text, UTF-8 or UTF-16 string with emoji (minLength=1, maxLength=4096, example="Hello World 🌍") | -| `quotedMsgId` | string | optional | Message ID to quote/reply to (Cloud API wamid) (pattern=`^wamid\..+$`, example="wamid.HBgNMTIwMjA3MjEzNjkVAgARGBI5RTBCNUY0QUE2RjZBQzhGNDkA") | -| `chatId` | string | optional | Recipient chat ID: phone@c.us, group@g.us, or BSUID@lid (example="12020721369@c.us") | -| `phone` | integer | optional | Phone number starting with country code (alternative to chatId) (example=12020721369) | +| Field | Type | Required | Description | +| ------------- | ------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | +| `body` | string | **required** | Message text, UTF-8 or UTF-16 string with emoji (minLength=1, maxLength=4096, example="Hello World 🌍") | +| `quotedMsgId` | string | optional | Message ID to quote/reply to (Cloud API wamid) (pattern=`^wamid\..+$`, example="wamid.HBgNMTIwMjA3MjEzNjkVAgARGBI5RTBCNUY0QUE2RjZBQzhGNDkA") | +| `chatId` | string | optional | Recipient chat ID: phone@c.us, group@g.us, or BSUID@lid (example="12020721369@c.us") | +| `phone` | integer | optional | Phone number starting with country code (alternative to chatId) (example=12020721369) | ### `SendOrderDetailsRequest` Check if a given object implements the SendOrderDetailsRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | `number` | optional | — | -| `chatId` | `string` | optional | — | -| `template` | `string` | **required** | — | -| `namespace` | `string` | **required** | — | -| `language` | `SendOrderDetailsRequestLanguage` | **required** | — | -| `params` | `Array<{ [key: string]: any` | optional | — | -| `referenceId` | `string` | optional | — | -| `currency` | `string` | optional | — | -| `paymentSettings` | `{ [key: string]: any` | optional | — | -| `order` | `SendOrderDetailsRequestOrder` | **required** | — | +| Field | Type | Required | Description | +| ----------------- | --------------------------------- | ------------ | ----------- | +| `phone` | `number` | optional | — | +| `chatId` | `string` | optional | — | +| `template` | `string` | **required** | — | +| `namespace` | `string` | **required** | — | +| `language` | `SendOrderDetailsRequestLanguage` | **required** | — | +| `params` | `Array<{ [key: string]: any` | optional | — | +| `referenceId` | `string` | optional | — | +| `currency` | `string` | optional | — | +| `paymentSettings` | `{ [key: string]: any` | optional | — | +| `order` | `SendOrderDetailsRequestOrder` | **required** | — | ### `SendOrderDetailsRequestLanguage` Check if a given object implements the SendOrderDetailsRequestLanguage interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `code` | `string` | **required** | — | -| `policy` | `string` | optional | — | +| Field | Type | Required | Description | +| -------- | -------- | ------------ | ----------- | +| `code` | `string` | **required** | — | +| `policy` | `string` | optional | — | ### `SendOrderDetailsRequestOrder` Check if a given object implements the SendOrderDetailsRequestOrder interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `status` | `string` | optional | — | -| `items` | `Array` | **required** | — | -| `subtotal` | `SendOrderDetailsRequestOrderItemsInnerAmount` | optional | — | -| `tax` | `{ [key: string]: any` | optional | — | -| `shipping` | `{ [key: string]: any` | optional | — | -| `discount` | `{ [key: string]: any` | optional | — | +| Field | Type | Required | Description | +| ---------- | ----------------------------------------------- | ------------ | ----------- | +| `status` | `string` | optional | — | +| `items` | `Array` | **required** | — | +| `subtotal` | `SendOrderDetailsRequestOrderItemsInnerAmount` | optional | — | +| `tax` | `{ [key: string]: any` | optional | — | +| `shipping` | `{ [key: string]: any` | optional | — | +| `discount` | `{ [key: string]: any` | optional | — | ### `SendOrderDetailsRequestOrderItemsInner` Check if a given object implements the SendOrderDetailsRequestOrderItemsInner interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `retailerId` | `string` | optional | — | -| `name` | `string` | optional | — | -| `quantity` | `number` | optional | — | -| `amount` | `SendOrderDetailsRequestOrderItemsInnerAmount` | optional | — | +| Field | Type | Required | Description | +| ------------ | ---------------------------------------------- | -------- | ----------- | +| `retailerId` | `string` | optional | — | +| `name` | `string` | optional | — | +| `quantity` | `number` | optional | — | +| `amount` | `SendOrderDetailsRequestOrderItemsInnerAmount` | optional | — | ### `SendOrderDetailsRequestOrderItemsInnerAmount` Check if a given object implements the SendOrderDetailsRequestOrderItemsInnerAmount interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `offset` | `number` | optional | — | -| `value` | `number` | optional | — | +| Field | Type | Required | Description | +| -------- | -------- | -------- | ----------- | +| `offset` | `number` | optional | — | +| `value` | `number` | optional | — | ### `SendPaymentRequestRequest` @export -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | `number` | **required** | — | -| `region` | `SendPaymentRequestRequestRegionEnum` | **required** | — | -| `body` | `string` | optional | — | -| `interactive` | `{ [key: string]: any` | optional | — | -| `action` | `{ [key: string]: any` | optional | — | +| Field | Type | Required | Description | +| ------------- | ------------------------------------- | ------------ | ----------- | +| `phone` | `number` | **required** | — | +| `region` | `SendPaymentRequestRequestRegionEnum` | **required** | — | +| `body` | `string` | optional | — | +| `interactive` | `{ [key: string]: any` | optional | — | +| `action` | `{ [key: string]: any` | optional | — | ### `SendProductRequest` Check if a given object implements the SendProductRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | `string` | optional | — | -| `chatId` | `string` | optional | — | -| `quotedMsgId` | `string` | optional | — | -| `body` | `string` | optional | — | -| `footer` | `string` | optional | — | -| `header` | `string` | optional | — | -| `action` | `{ [key: string]: any` | **required** | — | +| Field | Type | Required | Description | +| ------------- | ---------------------- | ------------ | ----------- | +| `phone` | `string` | optional | — | +| `chatId` | `string` | optional | — | +| `quotedMsgId` | `string` | optional | — | +| `body` | `string` | optional | — | +| `footer` | `string` | optional | — | +| `header` | `string` | optional | — | +| `action` | `{ [key: string]: any` | **required** | — | ### `SendReactionRequest` Check if a given object implements the SendReactionRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | `string` | optional | — | -| `chatId` | `string` | optional | — | -| `body` | `string` | optional | — | -| `quotedMsgId` | `string` | optional | — | +| Field | Type | Required | Description | +| ------------- | -------- | -------- | ----------- | +| `phone` | `string` | optional | — | +| `chatId` | `string` | optional | — | +| `body` | `string` | optional | — | +| `quotedMsgId` | `string` | optional | — | ### `SendStickerRequest` Check if a given object implements the SendStickerRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `phone` | `number` | optional | — | -| `chatId` | `string` | optional | — | -| `mediaId` | `string` | optional | — | -| `link` | `string` | optional | — | -| `quotedMsgId` | `string` | optional | — | +| Field | Type | Required | Description | +| ------------- | -------- | -------- | ----------- | +| `phone` | `number` | optional | — | +| `chatId` | `string` | optional | — | +| `mediaId` | `string` | optional | — | +| `link` | `string` | optional | — | +| `quotedMsgId` | `string` | optional | — | ### `SendTemplateRequest` Check if a given object implements the SendTemplateRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `template` | `string` | optional | — | -| `language` | `SendTemplateRequestLanguage` | optional | — | -| `namespace` | `string` | optional | — | -| `params` | `Array<{ [key: string]: any` | optional | — | -| `phone` | `string` | optional | — | -| `chatId` | `string` | optional | — | -| `quotedMsgId` | `string` | optional | — | -| `useMMlite` | `boolean` | optional | — | -| `messageActivitySharing` | `boolean` | optional | — | -| `messageSendTtlSeconds` | `number` | optional | — | +| Field | Type | Required | Description | +| ------------------------ | ----------------------------- | -------- | ----------- | +| `template` | `string` | optional | — | +| `language` | `SendTemplateRequestLanguage` | optional | — | +| `namespace` | `string` | optional | — | +| `params` | `Array<{ [key: string]: any` | optional | — | +| `phone` | `string` | optional | — | +| `chatId` | `string` | optional | — | +| `quotedMsgId` | `string` | optional | — | +| `useMMlite` | `boolean` | optional | — | +| `messageActivitySharing` | `boolean` | optional | — | +| `messageSendTtlSeconds` | `number` | optional | — | ### `SendTemplateRequestLanguage` Check if a given object implements the SendTemplateRequestLanguage interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `policy` | `string` | optional | — | -| `code` | `string` | optional | — | +| Field | Type | Required | Description | +| -------- | -------- | -------- | ----------- | +| `policy` | `string` | optional | — | +| `code` | `string` | optional | — | + +### `SetWebhook200Response` + +Check if a given object implements the SetWebhook200Response interface. + +| Field | Type | Required | Description | +| ------------ | --------------------------------- | -------- | ----------- | +| `set` | `boolean` | optional | — | +| `webhookUrl` | `SetWebhook200ResponseWebhookUrl` | optional | — | + +### `SetWebhook200ResponseWebhookUrl` + +_No property metadata — see generated TypeScript interface._ + +### `SetWebhookRequest` + +Check if a given object implements the SetWebhookRequest interface. + +| Field | Type | Required | Description | +| ------------ | ----------------------------- | ------------ | ----------- | +| `webhookUrl` | `SetWebhookRequestWebhookUrl` | **required** | — | + +### `SetWebhookRequestWebhookUrl` + +_No property metadata — see generated TypeScript interface._ ### `SetWhatsappBusinessEncryptionRequest` Check if a given object implements the SetWhatsappBusinessEncryptionRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `businessPublicKey` | `string` | **required** | — | +| Field | Type | Required | Description | +| ------------------- | -------- | ------------ | ----------- | +| `businessPublicKey` | `string` | **required** | — | ### `SuccessResponse` Check if a given object implements the SuccessResponse interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| +| Field | Type | Required | Description | +| -------- | ------ | -------- | ---------------- | | `result` | string | optional | Operation result | ### `UpdateCallingSettings200Response` Check if a given object implements the UpdateCallingSettings200Response interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `success` | `boolean` | optional | — | -| `result` | `string` | optional | — | -| `response` | `UpdateCallingSettings200ResponseResponse` | optional | — | +| Field | Type | Required | Description | +| ---------- | ------------------------------------------ | -------- | ----------- | +| `success` | `boolean` | optional | — | +| `result` | `string` | optional | — | +| `response` | `UpdateCallingSettings200ResponseResponse` | optional | — | ### `UpdateCallingSettings200ResponseResponse` Check if a given object implements the UpdateCallingSettings200ResponseResponse interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `error` | `string` | optional | — | +| Field | Type | Required | Description | +| ------- | -------- | -------- | ----------- | +| `error` | `string` | optional | — | + +### `UpdateMe200Response` + +Check if a given object implements the UpdateMe200Response interface. + +| Field | Type | Required | Description | +| -------- | -------- | -------- | ----------- | +| `result` | `string` | optional | — | ### `UpdateMeRequest` Check if a given object implements the UpdateMeRequest interface. -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `about` | `string` | optional | — | -| `address` | `string` | optional | — | -| `description` | `string` | optional | — | -| `email` | `string` | optional | — | -| `vertical` | `string` | optional | — | -| `photo` | `string` | optional | — | -| `websites` | `Array` | optional | — | +| Field | Type | Required | Description | +| ------------- | --------------- | -------- | ----------- | +| `about` | `string` | optional | — | +| `address` | `string` | optional | — | +| `description` | `string` | optional | — | +| `email` | `string` | optional | — | +| `vertical` | `string` | optional | — | +| `photo` | `string` | optional | — | +| `websites` | `Array` | optional | — | + +### `WebhookUrlStatus` + +@export + +| Field | Type | Required | Description | +| -------------- | --------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `url` | string | **required** | This webhook URL (same string as in `webhookUrl`) | +| `circuitState` | enum("ok" | "degraded" | "open" | "half_open" | "disabled") | **required** | Delivery state for this URL only. `ok` delivering; `degraded` recent qualifying fails (still delivering, warning email on the 2nd fail); `open` skipping most deliveries pending a probe; `half_open` probe in flight (resume only on HTTP 2xx); `disabled` sticky auto-disabled until self-serve re-enable (`POST /webhook` / `POST /settings` with this URL) or a successful probe before sticky disable. | +| `reason` | string | optional | Last qualifying fail reason, e.g. `http_404` or `timeout_or_network` | +| `fails` | integer | optional | Diagnostic only — safe for clients to ignore. Number of qualifying delivery failures in the rolling ~10 minute breaker window (not lifetime, not "how many times the customer retried"). Prefer `circuitState` / `disabledWebhooks`. | +| `trips` | integer | optional | Diagnostic only — safe for clients to ignore. How many recovery probes already failed for this URL. Probes run on a schedule (≈15 min → 1 h → 6 h); sticky disable after 3 failed probes. The 6 h step is the last probe, not a blind "unblock in 6 hours" timer. | +| `disabledAt` | integer | optional | Epoch milliseconds when this URL became sticky-disabled | +| `firstFailAt` | integer | optional | Diagnostic only. Epoch ms of the first fail in the current ~10 minute window (pairs with `fails`; not a customer-facing period). | +| `lastStatus` | integer | optional | Last HTTP status from this URL, when known | +| `nextProbeAt` | integer | optional | Epoch milliseconds of the next half-open probe, if any | ## Cookbook — common integration recipes @@ -4848,13 +5080,14 @@ SDK semver is independent from OpenAPI `info.version`. Patch releases ship doc f ## Troubleshooting -| Symptom | Likely cause | Fix | -|---------|--------------|-----| -| `fetch failed` | Wrong `baseUrl` or network | Verify host, use `https://api.1msg.io` | -| Message not delivered | 24h window closed | Use `sendTemplate` | -| `429` errors | Rate limit | Back off exponentially | -| Type errors on request objects | Stale SDK | Upgrade `@1msg/sdk` | -| Empty template list | No approved templates on WABA | Create templates in Meta Business Manager | +| Symptom | Likely cause | Fix | +| ------------------------------ | ----------------------------- | ----------------------------------------- | +| `fetch failed` | Wrong `baseUrl` or network | Verify host, use `https://api.1msg.io` | +| Message not delivered | 24h window closed | Use `sendTemplate` | +| `429` errors | Rate limit | Back off exponentially | +| Type errors on request objects | Stale SDK | Upgrade `@1msg/sdk` | +| Empty template list | No approved templates on WABA | Create templates in Meta Business Manager | + ## Error handling Non-2xx responses throw `ResponseError` with `.response: Response`. @@ -4879,4 +5112,3 @@ Docs regenerate on `npm run generate:sdk`. npm versions are immutable — patch ## License MIT © 1MSG - diff --git a/typescript/package-lock.json b/typescript/package-lock.json new file mode 100644 index 0000000..50c4c67 --- /dev/null +++ b/typescript/package-lock.json @@ -0,0 +1,3863 @@ +{ + "name": "@1msg/sdk", + "version": "1.0.4", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@1msg/sdk", + "version": "1.0.4", + "license": "MIT", + "devDependencies": { + "@types/jest": "^29.5.14", + "jest": "^29.5.0", + "ts-jest": "^29.1.0", + "typescript": "^5.1.3" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.10.tgz", + "integrity": "sha512-EMCx3AGZ3WfAl6ht7AyQoPm2Lh+BGYEMdc4Q6Hf7uSCDOZFuLq44qNwL+iaim8VlyYhRAo4X43+weadK8ZB4Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.9.tgz", + "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz", + "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.10.tgz", + "integrity": "sha512-B3lYAs2nkKskbgQ1nfy8Ma9ao9Q1rntTAQHrzzyDuj+TSO+X3le6PfWwqDvodsb+OumE10eMFfuMCTQSQ5iuIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.9", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "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, + "license": "MIT" + }, + "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, + "license": "ISC", + "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" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@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.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "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 + } + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@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": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "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 + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@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.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "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" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@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/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "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.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "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, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.14", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", + "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/node": { + "version": "26.6.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.5.tgz", + "integrity": "sha512-uMzsv9stDdofIZBx4UGh4Z9ZgXnGC9seRDscilBcTHAeOFk67MZg/k9bWVfO+bk4qZmG+l52hRnLwUiH2LnJTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~8.9.0" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "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/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/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "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" + } + }, + "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, + "license": "BSD-3-Clause", + "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-istanbul/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, + "license": "BSD-3-Clause", + "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/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "license": "MIT", + "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.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@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-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "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, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.28", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.28.tgz", + "integrity": "sha512-br0LOmjJqr6Rt4AEkadbcNf67Zpo7EPwKsWbjnRrJIa1QYFHQBqM4C7F2WTbV8ahTEcg1Eo+Y0aWjjORInYFyA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz", + "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==", + "dev": true, + "license": "MIT", + "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, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.29.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.3.tgz", + "integrity": "sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==", + "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" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.11.26", + "caniuse-lite": "^1.0.30001813", + "electron-to-chromium": "^1.5.439", + "node-releases": "^2.0.57", + "update-browserslist-db": "^1.3.3" + }, + "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, + "license": "MIT", + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.2.tgz", + "integrity": "sha512-V2o8YS2EhrKMO9AumnkK0ynynfFlsajpYupwq7S46H5mhcanwxDkNTw3K67wPIcKTH1ffkA4vhMOtAc7gRmPZw==", + "dev": true, + "license": "MIT", + "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, + "license": "MIT" + }, + "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, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001815", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001815.tgz", + "integrity": "sha512-uDybUEyfgbyJJ93J1vikTylBX31AkdVYeVPeffMQpf8XN7hSfr0oZOn4VFOIMNvtU5+rHvC5Udg2TgtJKHm23Q==", + "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" + } + ], + "license": "CC-BY-4.0" + }, + "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/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, + "license": "MIT", + "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/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "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, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "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/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/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, + "license": "MIT" + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/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/dedent": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": 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, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.452", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.452.tgz", + "integrity": "sha512-cVvk1YBSj6571VmV6hdJTqj94Y79xSu8cj6Y9t6ae4Y4431z8/7EJFvu3rVp90xhfuv9BpPKUmaLfTo4+FOGBg==", + "dev": true, + "license": "ISC" + }, + "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, + "license": "MIT", + "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, + "license": "MIT" + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "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/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": "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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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/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/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.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fb-watchman": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.4.tgz", + "integrity": "sha512-tGQtaoYisPDriJBN0mT5yZSyNETnJGA1gTYxaVRAE5KUO3LI9kPUc9WIu8JXcxaIci+faIKlzXqXyPgrmubtBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bser": "2.1.2" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^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/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/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, + "license": "MIT", + "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, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-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/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "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/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/handlebars": { + "version": "4.7.10", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.10.tgz", + "integrity": "sha512-P5VJMVM7qgBn6vjXMw8WG9uVI+ncf2pi72j4de4yz5ZULLj2RGqLYaKOYGsgyrViQ0tePOVlN1tDCCXXtFqXKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.8", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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, + "license": "MIT" + }, + "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/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "license": "MIT", + "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, + "license": "MIT", + "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==", + "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/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, + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.17.0.tgz", + "integrity": "sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.4" + }, + "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-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, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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-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/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/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/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, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "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.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "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-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "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-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "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.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "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-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@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.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "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.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "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, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "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.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "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-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@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.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "license": "MIT", + "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.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@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-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "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/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/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, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.2.tgz", + "integrity": "sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "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, + "license": "MIT" + }, + "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, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/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, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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, + "license": "MIT" + }, + "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, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "license": "MIT" + }, + "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, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.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-dir/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "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/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/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/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "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, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/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, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.58", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.58.tgz", + "integrity": "sha512-BdiKAgbfRlvfMq/XzO/AF9NPmaA8a+YpLAyAFTVFBj3gARrAIfWvNq7Q7NE4se3KgFu0KkrvQMxTS0XVnsGzHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "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/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/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/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "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, + "license": "MIT", + "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, + "license": "MIT", + "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, + "license": "MIT", + "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, + "license": "MIT", + "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/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "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-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, + "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": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "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, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "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, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/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/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "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/resolve": { + "version": "1.22.13", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.13.tgz", + "integrity": "sha512-Dj/cW9zBV2aRj6XzCxuGIs3ESZKv02jixne3q6jFZYZ3/Tg09gHHviSMDL4kObh9pqSahdRHEnDoaP2gn8YLhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.17.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "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, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "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, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "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/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/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, + "license": "BSD-3-Clause", + "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, + "license": "MIT", + "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, + "license": "BSD-3-Clause" + }, + "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, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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/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-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, + "license": "MIT", + "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, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "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/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, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "license": "BSD-3-Clause" + }, + "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/ts-jest": { + "version": "29.4.14", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.14.tgz", + "integrity": "sha512-+943G6wCX5E3VpzTQhBGBFntCmdT+QAkTvUlp03edTONFBvqskuXPhpyX16xdUotO4P5HQKyppldSWjocoltLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bs-logger": "^0.2.6", + "fast-json-stable-stringify": "^2.1.0", + "handlebars": "^4.7.9", + "json5": "^2.2.3", + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.8.5", + "type-fest": "^4.41.0", + "yargs-parser": "^21.1.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <9", + "@jest/transform": "^29.0.0 || ^30.0.0", + "@jest/types": "^29.0.0 || ^30.0.0", + "babel-jest": "^29.0.0 || ^30.0.0", + "jest": "^29.0.0 || ^30.0.0", + "jest-util": "^29.0.0 || ^30.0.0", + "typescript": ">=4.3 <7" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/transform": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jest-util": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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, + "license": "MIT", + "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, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/undici-types": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz", + "integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz", + "integrity": "sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==", + "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" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.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, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "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/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "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/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/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": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "dev": true, + "license": "MIT", + "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, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/typescript/src/__tests__/client-config.test.ts b/typescript/src/__tests__/client-config.test.ts index 23ccaa3..04f35d1 100644 --- a/typescript/src/__tests__/client-config.test.ts +++ b/typescript/src/__tests__/client-config.test.ts @@ -15,9 +15,7 @@ describe('ClientConfig', () => { it('builds request URL with token query param', () => { const config = new ClientConfig(baseOptions); const url = config.buildRequestUrl('/sendMessage'); - expect(url).toBe( - 'https://api.stage.1msg.io/ODI371267300/sendMessage?token=test-api-token', - ); + expect(url).toBe('https://api.stage.1msg.io/ODI371267300/sendMessage?token=test-api-token'); }); it('normalizes trailing slash on baseUrl', () => { diff --git a/typescript/src/__tests__/client.test.ts b/typescript/src/__tests__/client.test.ts index 31016c3..61f0a31 100644 --- a/typescript/src/__tests__/client.test.ts +++ b/typescript/src/__tests__/client.test.ts @@ -1,6 +1,7 @@ -import { createClient } from '../client'; import type { MessageSentResponse } from '../generated/src/models/MessageSentResponse'; +import { createClient } from '../client'; + describe('Client', () => { const options = { baseUrl: 'https://api.stage.1msg.io', @@ -16,9 +17,7 @@ describe('Client', () => { id: 'msg-id', }; - const spy = jest - .spyOn(client.messaging, 'sendMessage') - .mockResolvedValue(response); + const spy = jest.spyOn(client.messaging, 'sendMessage').mockResolvedValue(response); const result = await client.sendMessage({ body: 'Hello from SDK', @@ -60,8 +59,6 @@ describe('Client', () => { it('uses instance-scoped basePath from config', () => { const client = createClient(options); - expect(client.config.basePath).toBe( - 'https://api.stage.1msg.io/ODI371267300', - ); + expect(client.config.basePath).toBe('https://api.stage.1msg.io/ODI371267300'); }); }); diff --git a/typescript/src/__tests__/wire-contract.test.ts b/typescript/src/__tests__/wire-contract.test.ts new file mode 100644 index 0000000..e0320ce --- /dev/null +++ b/typescript/src/__tests__/wire-contract.test.ts @@ -0,0 +1,51 @@ +import { MessagingApi } from '../generated/src/apis/MessagingApi'; +import { SendMessageRequestToJSON } from '../generated/src/models/SendMessageRequest'; +import { Configuration, ResponseError } from '../generated/src/runtime'; +import { sendMessageFixture, sendMessagePhoneFixture } from './fixtures/send-message'; + +/** Inspect token placement, form body and omission of unspecified optional fields at the fetch boundary. */ +it('sends the configured instance, query token and only present form fields', async () => { + const fetchApi = jest.fn, Parameters>(); + fetchApi.mockResolvedValue( + new Response(JSON.stringify({ sent: true, id: 'fixture-id', message: 'fixture-id' }), { + status: 200, + headers: { 'Content-Type': 'application/json' }, + }), + ); + const api = new MessagingApi( + new Configuration({ basePath: 'https://fixture.invalid/instance', fetchApi }), + ); + const result = await api.sendMessage('fixture-token', 'hello', undefined, 'chat@c.us'); + expect(result.sent).toBe(true); + expect(fetchApi).toHaveBeenCalledTimes(1); + const call = fetchApi.mock.calls[0]; + if (!call) throw new Error('Expected captured fetch boundary'); + const [url, init] = call; + expect(url).toBe('https://fixture.invalid/instance/sendMessage?token=fixture-token'); + expect(init?.method).toBe('POST'); + expect(init?.body).toBeInstanceOf(URLSearchParams); + if (!(init?.body instanceof URLSearchParams)) throw new Error('Expected form serialization'); + expect(Object.fromEntries(init.body)).toEqual({ body: 'hello', chatId: 'chat@c.us' }); + expect(init).not.toHaveProperty('credentials'); +}); + +/** Preserve non-success status and response details instead of resolving a fabricated success model. */ +it('rejects non-success responses as a typed response error', async () => { + const fetchApi = jest.fn, Parameters>(); + fetchApi.mockResolvedValue( + new Response(JSON.stringify({ error: 'fixture failure' }), { status: 400 }), + ); + const api = new MessagingApi( + new Configuration({ basePath: 'https://fixture.invalid/instance', fetchApi }), + ); + const result = api.sendMessage('fixture-token', 'hello', undefined, 'chat@c.us'); + await expect(result).rejects.toBeInstanceOf(ResponseError); +}); + +/** JSON encoding must omit unspecified optional fields, including after exact-optional type repair. */ +it('serializes absent optional model fields without undefined wire values', () => { + const result: unknown = SendMessageRequestToJSON(sendMessageFixture); + expect(JSON.parse(JSON.stringify(result))).toEqual(sendMessageFixture); + const phone: unknown = SendMessageRequestToJSON(sendMessagePhoneFixture); + expect(JSON.parse(JSON.stringify(phone))).toEqual(sendMessagePhoneFixture); +}); diff --git a/typescript/src/client-config.ts b/typescript/src/client-config.ts index a3fba9a..c827d5c 100644 --- a/typescript/src/client-config.ts +++ b/typescript/src/client-config.ts @@ -16,6 +16,7 @@ export class ClientConfig { readonly instanceId: string; readonly token: string; + /** Validate and normalize the three required connection fields before any request. */ constructor(options: ClientConfigOptions) { if (!options.baseUrl?.trim()) { throw new Error('ClientConfig.baseUrl is required'); @@ -48,6 +49,7 @@ export class ClientConfig { return url.toString(); } + /** Remove redundant URL separators without changing the configured API root. */ private static stripTrailingSlash(value: string): string { return value.replace(/\/+$/, ''); } diff --git a/typescript/src/client.ts b/typescript/src/client.ts index 6a38a06..d55fcc4 100644 --- a/typescript/src/client.ts +++ b/typescript/src/client.ts @@ -1,5 +1,7 @@ +import type { MessageSentResponse } from './generated/src/models/MessageSentResponse'; +import type { SendMessageRequest } from './generated/src/models/SendMessageRequest'; + import { ClientConfig, type ClientConfigOptions } from './client-config'; -import { Configuration } from './generated/src/runtime'; import { CallingApi, CatalogApi, @@ -12,8 +14,7 @@ import { UsersApi, WebhooksApi, } from './generated/src/apis'; -import type { SendMessageRequest } from './generated/src/models/SendMessageRequest'; -import type { MessageSentResponse } from './generated/src/models/MessageSentResponse'; +import { Configuration } from './generated/src/runtime'; export type { ClientConfigOptions } from './client-config'; export { ClientConfig } from './client-config'; @@ -35,6 +36,7 @@ export class Client { readonly webhooks: WebhooksApi; readonly calling: CallingApi; + /** Share one instance-qualified base path across the generated API groups. */ constructor(config: ClientConfig) { this.config = config; const configuration = new Configuration({ diff --git a/typescript/src/generated/src/apis/CallingApi.ts b/typescript/src/generated/src/apis/CallingApi.ts new file mode 100644 index 0000000..d922e4b --- /dev/null +++ b/typescript/src/generated/src/apis/CallingApi.ts @@ -0,0 +1,328 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from '../runtime'; +import { + type CallingSettings, + CallingSettingsFromJSON, + CallingSettingsToJSON, +} from '../models/CallingSettings'; +import { + type ErrorResponse, + ErrorResponseFromJSON, + ErrorResponseToJSON, +} from '../models/ErrorResponse'; +import { + type InitiateCallRequest, + InitiateCallRequestFromJSON, + InitiateCallRequestToJSON, +} from '../models/InitiateCallRequest'; +import { + type InitiateCallResponse, + InitiateCallResponseFromJSON, + InitiateCallResponseToJSON, +} from '../models/InitiateCallResponse'; +import { + type UpdateCallingSettings200Response, + UpdateCallingSettings200ResponseFromJSON, + UpdateCallingSettings200ResponseToJSON, +} from '../models/UpdateCallingSettings200Response'; + +export interface GetCallingSettingsRequest { + token: string; +} + +export interface InitiateCallOperationRequest { + token: string; + initiateCallRequest: InitiateCallRequest; +} + +export interface UpdateCallingSettingsRequest { + token: string; + callingSettings: CallingSettings; +} + +/** + * CallingApi - interface + * + * @export + * @interface CallingApiInterface + */ +export interface CallingApiInterface { + /** + * Creates request options for getCallingSettings without sending the request + * @param {string} token JWT token or API key for authorization + * @throws {RequiredError} + * @memberof CallingApiInterface + */ + getCallingSettingsRequestOpts(requestParameters: GetCallingSettingsRequest): Promise; + + /** + * Return WhatsApp Calling API settings for this channel (beta). Proxies upstream `GET /calling/settings`. **Prerequisites** - Number must be eligible for Meta Calling (Cloud API; not COEX) - Trial / `subscriptionBlocked` channels receive **403** plain text - You need your own WebRTC or SIP stack; 1msg is a **signaling proxy** only and does **not** store call history or recordings See the **Calling** tag overview for inbound/outbound flows and webhooks. + * @summary Get calling settings + * @param {string} token JWT token or API key for authorization + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CallingApiInterface + */ + getCallingSettingsRaw(requestParameters: GetCallingSettingsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Return WhatsApp Calling API settings for this channel (beta). Proxies upstream `GET /calling/settings`. **Prerequisites** - Number must be eligible for Meta Calling (Cloud API; not COEX) - Trial / `subscriptionBlocked` channels receive **403** plain text - You need your own WebRTC or SIP stack; 1msg is a **signaling proxy** only and does **not** store call history or recordings See the **Calling** tag overview for inbound/outbound flows and webhooks. + * Get calling settings + */ + getCallingSettings(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for initiateCall without sending the request + * @param {string} token JWT token or API key for authorization + * @param {InitiateCallRequest} initiateCallRequest + * @throws {RequiredError} + * @memberof CallingApiInterface + */ + initiateCallRequestOpts(requestParameters: InitiateCallOperationRequest): Promise; + + /** + * Perform a WhatsApp Calling action (beta). Proxies upstream `POST /calling/calls`. Despite the historical path name `/initiateCall`, this endpoint handles **all** call actions: | action | Use | Required | |--------|-----|----------| | `connect` | Outbound business → user | `to` + `session` (`sdp_type: offer`) | | `pre_accept` | Inbound (optional, reduces audio clipping) | `call_id` + `session` (`sdp_type: answer`) | | `accept` | Inbound answer | `call_id` + `session` (`sdp_type: answer`) | | `reject` | Decline inbound | `call_id` | | `terminate` | Hang up | `call_id` | **SDP / media (critical)** - `accept` / `pre_accept` require a **WebRTC-generated SDP answer**. - Do **not** send Meta\'s offer SDP back as the answer. - Postman (or curl) alone **cannot** establish real media — you need a WebRTC or SIP stack. 1msg only proxies signaling. Answer within ~**30–60 seconds** of an inbound `connect` webhook or Meta terminates as unanswered. Common Meta errors include Calling not enabled (`138000`), no permission (`138006`), SDP validation failures. **Outbound** requires a prior Call Permission Request (CPR) acceptance. See the **Calling** tag overview for the full outbound flow and CPR limits. Trial / `subscriptionBlocked` → **403** plain text. Upstream failures often return HTTP 200 with `{ \"response\": { \"error\": \"\" } }`. `Invalid API KEY` is used only when Meta/360 body actually indicates an invalid API key or token. Other upstream 401s (notably call permission `138006`) pass through `error.message` / `error_user_msg`. + * @summary Call action (connect / pre_accept / accept / reject / terminate) + * @param {string} token JWT token or API key for authorization + * @param {InitiateCallRequest} initiateCallRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CallingApiInterface + */ + initiateCallRaw(requestParameters: InitiateCallOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Perform a WhatsApp Calling action (beta). Proxies upstream `POST /calling/calls`. Despite the historical path name `/initiateCall`, this endpoint handles **all** call actions: | action | Use | Required | |--------|-----|----------| | `connect` | Outbound business → user | `to` + `session` (`sdp_type: offer`) | | `pre_accept` | Inbound (optional, reduces audio clipping) | `call_id` + `session` (`sdp_type: answer`) | | `accept` | Inbound answer | `call_id` + `session` (`sdp_type: answer`) | | `reject` | Decline inbound | `call_id` | | `terminate` | Hang up | `call_id` | **SDP / media (critical)** - `accept` / `pre_accept` require a **WebRTC-generated SDP answer**. - Do **not** send Meta\'s offer SDP back as the answer. - Postman (or curl) alone **cannot** establish real media — you need a WebRTC or SIP stack. 1msg only proxies signaling. Answer within ~**30–60 seconds** of an inbound `connect` webhook or Meta terminates as unanswered. Common Meta errors include Calling not enabled (`138000`), no permission (`138006`), SDP validation failures. **Outbound** requires a prior Call Permission Request (CPR) acceptance. See the **Calling** tag overview for the full outbound flow and CPR limits. Trial / `subscriptionBlocked` → **403** plain text. Upstream failures often return HTTP 200 with `{ \"response\": { \"error\": \"\" } }`. `Invalid API KEY` is used only when Meta/360 body actually indicates an invalid API key or token. Other upstream 401s (notably call permission `138006`) pass through `error.message` / `error_user_msg`. + * Call action (connect / pre_accept / accept / reject / terminate) + */ + initiateCall(token: string, initiateCallRequest: InitiateCallRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for updateCallingSettings without sending the request + * @param {string} token JWT token or API key for authorization + * @param {CallingSettings} callingSettings + * @throws {RequiredError} + * @memberof CallingApiInterface + */ + updateCallingSettingsRequestOpts(requestParameters: UpdateCallingSettingsRequest): Promise; + + /** + * Enable, disable, or update WhatsApp Calling settings (beta). Proxies upstream `POST /calling/settings`. Body is forwarded as-is (1msg does not validate fields). **Common fields under `calling`** - `status` (`ENABLED` | `DISABLED`) — required to turn calling on/off - `call_icon_visibility` (`DEFAULT` | `DISABLE_ALL`) — optional - `callback_permission_status` (`ENABLED` | `DISABLED`) — optional; when enabled, inbound user calls grant callback permission - `call_hours` — optional hours / timezone object - `sip` — optional SIP trunk; when SIP is ENABLED, Graph call actions and calling webhooks are not used - `srtp_key_exchange_protocol` (`DTLS` | `SDES`) — SDES only with SIP - `video.status` — optional Meta may accept only one feature group per request — prefer focused updates (e.g. enable status first, then SIP). Trial / `subscriptionBlocked` → **403** plain text. + * @summary Update calling settings + * @param {string} token JWT token or API key for authorization + * @param {CallingSettings} callingSettings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CallingApiInterface + */ + updateCallingSettingsRaw(requestParameters: UpdateCallingSettingsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Enable, disable, or update WhatsApp Calling settings (beta). Proxies upstream `POST /calling/settings`. Body is forwarded as-is (1msg does not validate fields). **Common fields under `calling`** - `status` (`ENABLED` | `DISABLED`) — required to turn calling on/off - `call_icon_visibility` (`DEFAULT` | `DISABLE_ALL`) — optional - `callback_permission_status` (`ENABLED` | `DISABLED`) — optional; when enabled, inbound user calls grant callback permission - `call_hours` — optional hours / timezone object - `sip` — optional SIP trunk; when SIP is ENABLED, Graph call actions and calling webhooks are not used - `srtp_key_exchange_protocol` (`DTLS` | `SDES`) — SDES only with SIP - `video.status` — optional Meta may accept only one feature group per request — prefer focused updates (e.g. enable status first, then SIP). Trial / `subscriptionBlocked` → **403** plain text. + * Update calling settings + */ + updateCallingSettings(token: string, callingSettings: CallingSettings, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + +} + +/** + * + */ +export class CallingApi extends runtime.BaseAPI implements CallingApiInterface { + + /** + * Creates request options for getCallingSettings without sending the request + */ + async getCallingSettingsRequestOpts(requestParameters: GetCallingSettingsRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling getCallingSettings().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/callingSettings`; + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Return WhatsApp Calling API settings for this channel (beta). Proxies upstream `GET /calling/settings`. **Prerequisites** - Number must be eligible for Meta Calling (Cloud API; not COEX) - Trial / `subscriptionBlocked` channels receive **403** plain text - You need your own WebRTC or SIP stack; 1msg is a **signaling proxy** only and does **not** store call history or recordings See the **Calling** tag overview for inbound/outbound flows and webhooks. + * Get calling settings + */ + async getCallingSettingsRaw(requestParameters: GetCallingSettingsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.getCallingSettingsRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CallingSettingsFromJSON(jsonValue)); + } + + /** + * Return WhatsApp Calling API settings for this channel (beta). Proxies upstream `GET /calling/settings`. **Prerequisites** - Number must be eligible for Meta Calling (Cloud API; not COEX) - Trial / `subscriptionBlocked` channels receive **403** plain text - You need your own WebRTC or SIP stack; 1msg is a **signaling proxy** only and does **not** store call history or recordings See the **Calling** tag overview for inbound/outbound flows and webhooks. + * Get calling settings + */ + async getCallingSettings(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getCallingSettingsRaw({ token: token }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for initiateCall without sending the request + */ + async initiateCallRequestOpts(requestParameters: InitiateCallOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling initiateCall().' + ); + } + + if (requestParameters['initiateCallRequest'] == null) { + throw new runtime.RequiredError( + 'initiateCallRequest', + 'Required parameter "initiateCallRequest" was null or undefined when calling initiateCall().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/initiateCall`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: InitiateCallRequestToJSON(requestParameters['initiateCallRequest']), + }; + } + + /** + * Perform a WhatsApp Calling action (beta). Proxies upstream `POST /calling/calls`. Despite the historical path name `/initiateCall`, this endpoint handles **all** call actions: | action | Use | Required | |--------|-----|----------| | `connect` | Outbound business → user | `to` + `session` (`sdp_type: offer`) | | `pre_accept` | Inbound (optional, reduces audio clipping) | `call_id` + `session` (`sdp_type: answer`) | | `accept` | Inbound answer | `call_id` + `session` (`sdp_type: answer`) | | `reject` | Decline inbound | `call_id` | | `terminate` | Hang up | `call_id` | **SDP / media (critical)** - `accept` / `pre_accept` require a **WebRTC-generated SDP answer**. - Do **not** send Meta\'s offer SDP back as the answer. - Postman (or curl) alone **cannot** establish real media — you need a WebRTC or SIP stack. 1msg only proxies signaling. Answer within ~**30–60 seconds** of an inbound `connect` webhook or Meta terminates as unanswered. Common Meta errors include Calling not enabled (`138000`), no permission (`138006`), SDP validation failures. **Outbound** requires a prior Call Permission Request (CPR) acceptance. See the **Calling** tag overview for the full outbound flow and CPR limits. Trial / `subscriptionBlocked` → **403** plain text. Upstream failures often return HTTP 200 with `{ \"response\": { \"error\": \"\" } }`. `Invalid API KEY` is used only when Meta/360 body actually indicates an invalid API key or token. Other upstream 401s (notably call permission `138006`) pass through `error.message` / `error_user_msg`. + * Call action (connect / pre_accept / accept / reject / terminate) + */ + async initiateCallRaw(requestParameters: InitiateCallOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.initiateCallRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => InitiateCallResponseFromJSON(jsonValue)); + } + + /** + * Perform a WhatsApp Calling action (beta). Proxies upstream `POST /calling/calls`. Despite the historical path name `/initiateCall`, this endpoint handles **all** call actions: | action | Use | Required | |--------|-----|----------| | `connect` | Outbound business → user | `to` + `session` (`sdp_type: offer`) | | `pre_accept` | Inbound (optional, reduces audio clipping) | `call_id` + `session` (`sdp_type: answer`) | | `accept` | Inbound answer | `call_id` + `session` (`sdp_type: answer`) | | `reject` | Decline inbound | `call_id` | | `terminate` | Hang up | `call_id` | **SDP / media (critical)** - `accept` / `pre_accept` require a **WebRTC-generated SDP answer**. - Do **not** send Meta\'s offer SDP back as the answer. - Postman (or curl) alone **cannot** establish real media — you need a WebRTC or SIP stack. 1msg only proxies signaling. Answer within ~**30–60 seconds** of an inbound `connect` webhook or Meta terminates as unanswered. Common Meta errors include Calling not enabled (`138000`), no permission (`138006`), SDP validation failures. **Outbound** requires a prior Call Permission Request (CPR) acceptance. See the **Calling** tag overview for the full outbound flow and CPR limits. Trial / `subscriptionBlocked` → **403** plain text. Upstream failures often return HTTP 200 with `{ \"response\": { \"error\": \"\" } }`. `Invalid API KEY` is used only when Meta/360 body actually indicates an invalid API key or token. Other upstream 401s (notably call permission `138006`) pass through `error.message` / `error_user_msg`. + * Call action (connect / pre_accept / accept / reject / terminate) + */ + async initiateCall(token: string, initiateCallRequest: InitiateCallRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.initiateCallRaw({ token: token, initiateCallRequest: initiateCallRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for updateCallingSettings without sending the request + */ + async updateCallingSettingsRequestOpts(requestParameters: UpdateCallingSettingsRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling updateCallingSettings().' + ); + } + + if (requestParameters['callingSettings'] == null) { + throw new runtime.RequiredError( + 'callingSettings', + 'Required parameter "callingSettings" was null or undefined when calling updateCallingSettings().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/callingSettings`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: CallingSettingsToJSON(requestParameters['callingSettings']), + }; + } + + /** + * Enable, disable, or update WhatsApp Calling settings (beta). Proxies upstream `POST /calling/settings`. Body is forwarded as-is (1msg does not validate fields). **Common fields under `calling`** - `status` (`ENABLED` | `DISABLED`) — required to turn calling on/off - `call_icon_visibility` (`DEFAULT` | `DISABLE_ALL`) — optional - `callback_permission_status` (`ENABLED` | `DISABLED`) — optional; when enabled, inbound user calls grant callback permission - `call_hours` — optional hours / timezone object - `sip` — optional SIP trunk; when SIP is ENABLED, Graph call actions and calling webhooks are not used - `srtp_key_exchange_protocol` (`DTLS` | `SDES`) — SDES only with SIP - `video.status` — optional Meta may accept only one feature group per request — prefer focused updates (e.g. enable status first, then SIP). Trial / `subscriptionBlocked` → **403** plain text. + * Update calling settings + */ + async updateCallingSettingsRaw(requestParameters: UpdateCallingSettingsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.updateCallingSettingsRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => UpdateCallingSettings200ResponseFromJSON(jsonValue)); + } + + /** + * Enable, disable, or update WhatsApp Calling settings (beta). Proxies upstream `POST /calling/settings`. Body is forwarded as-is (1msg does not validate fields). **Common fields under `calling`** - `status` (`ENABLED` | `DISABLED`) — required to turn calling on/off - `call_icon_visibility` (`DEFAULT` | `DISABLE_ALL`) — optional - `callback_permission_status` (`ENABLED` | `DISABLED`) — optional; when enabled, inbound user calls grant callback permission - `call_hours` — optional hours / timezone object - `sip` — optional SIP trunk; when SIP is ENABLED, Graph call actions and calling webhooks are not used - `srtp_key_exchange_protocol` (`DTLS` | `SDES`) — SDES only with SIP - `video.status` — optional Meta may accept only one feature group per request — prefer focused updates (e.g. enable status first, then SIP). Trial / `subscriptionBlocked` → **403** plain text. + * Update calling settings + */ + async updateCallingSettings(token: string, callingSettings: CallingSettings, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updateCallingSettingsRaw({ token: token, callingSettings: callingSettings }, initOverrides); + return await response.value(); + } + +} diff --git a/typescript/src/generated/src/apis/CatalogApi.ts b/typescript/src/generated/src/apis/CatalogApi.ts new file mode 100644 index 0000000..efdd81c --- /dev/null +++ b/typescript/src/generated/src/apis/CatalogApi.ts @@ -0,0 +1,228 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from '../runtime'; +import { + type CreateCommerce200Response, + CreateCommerce200ResponseFromJSON, + CreateCommerce200ResponseToJSON, +} from '../models/CreateCommerce200Response'; +import { + type CreateCommerceRequest, + CreateCommerceRequestFromJSON, + CreateCommerceRequestToJSON, +} from '../models/CreateCommerceRequest'; +import { + type ErrorResponse, + ErrorResponseFromJSON, + ErrorResponseToJSON, +} from '../models/ErrorResponse'; +import { + type GetCommerce200ResponseInner, + GetCommerce200ResponseInnerFromJSON, + GetCommerce200ResponseInnerToJSON, +} from '../models/GetCommerce200ResponseInner'; + +export interface CreateCommerceOperationRequest { + token: string; + createCommerceRequest: CreateCommerceRequest; +} + +export interface GetCommerceRequest { + token: string; +} + +/** + * CatalogApi - interface + * + * @export + * @interface CatalogApiInterface + */ +export interface CatalogApiInterface { + /** + * Creates request options for createCommerce without sending the request + * @param {string} token JWT token or API key for authorization + * @param {CreateCommerceRequest} createCommerceRequest + * @throws {RequiredError} + * @memberof CatalogApiInterface + */ + createCommerceRequestOpts(requestParameters: CreateCommerceOperationRequest): Promise; + + /** + * Update catalog/cart commerce settings via the `params` object. - `params.is_catalog_visible` — show catalog storefront icon (`true`) or hide it (`false`). - `params.is_cart_enabled` — enable cart (`true`) or disable it (`false`). Blocked when the channel subscription limit is exceeded. Requires a commerce-capable channel (Cloud Functions `/commerceWAV2`). + * @summary Set Commerce Settings + * @param {string} token JWT token or API key for authorization + * @param {CreateCommerceRequest} createCommerceRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CatalogApiInterface + */ + createCommerceRaw(requestParameters: CreateCommerceOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Update catalog/cart commerce settings via the `params` object. - `params.is_catalog_visible` — show catalog storefront icon (`true`) or hide it (`false`). - `params.is_cart_enabled` — enable cart (`true`) or disable it (`false`). Blocked when the channel subscription limit is exceeded. Requires a commerce-capable channel (Cloud Functions `/commerceWAV2`). + * Set Commerce Settings + */ + createCommerce(token: string, createCommerceRequest: CreateCommerceRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for getCommerce without sending the request + * @param {string} token JWT token or API key for authorization + * @throws {RequiredError} + * @memberof CatalogApiInterface + */ + getCommerceRequestOpts(requestParameters: GetCommerceRequest): Promise; + + /** + * Returns catalog/cart commerce settings for the channel. Fails with a provider error when the WABA has no catalog linked — that is an API/account limitation, not an MCP schema bug. - `is_catalog_visible` — show catalog storefront icon (`true`) or hide it (`false`). - `is_cart_enabled` — enable cart (`true`) or disable it (`false`). + * @summary Get Commerce Settings + * @param {string} token JWT token or API key for authorization + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CatalogApiInterface + */ + getCommerceRaw(requestParameters: GetCommerceRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; + + /** + * Returns catalog/cart commerce settings for the channel. Fails with a provider error when the WABA has no catalog linked — that is an API/account limitation, not an MCP schema bug. - `is_catalog_visible` — show catalog storefront icon (`true`) or hide it (`false`). - `is_cart_enabled` — enable cart (`true`) or disable it (`false`). + * Get Commerce Settings + */ + getCommerce(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + +} + +/** + * + */ +export class CatalogApi extends runtime.BaseAPI implements CatalogApiInterface { + + /** + * Creates request options for createCommerce without sending the request + */ + async createCommerceRequestOpts(requestParameters: CreateCommerceOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling createCommerce().' + ); + } + + if (requestParameters['createCommerceRequest'] == null) { + throw new runtime.RequiredError( + 'createCommerceRequest', + 'Required parameter "createCommerceRequest" was null or undefined when calling createCommerce().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/commerce`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: CreateCommerceRequestToJSON(requestParameters['createCommerceRequest']), + }; + } + + /** + * Update catalog/cart commerce settings via the `params` object. - `params.is_catalog_visible` — show catalog storefront icon (`true`) or hide it (`false`). - `params.is_cart_enabled` — enable cart (`true`) or disable it (`false`). Blocked when the channel subscription limit is exceeded. Requires a commerce-capable channel (Cloud Functions `/commerceWAV2`). + * Set Commerce Settings + */ + async createCommerceRaw(requestParameters: CreateCommerceOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.createCommerceRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CreateCommerce200ResponseFromJSON(jsonValue)); + } + + /** + * Update catalog/cart commerce settings via the `params` object. - `params.is_catalog_visible` — show catalog storefront icon (`true`) or hide it (`false`). - `params.is_cart_enabled` — enable cart (`true`) or disable it (`false`). Blocked when the channel subscription limit is exceeded. Requires a commerce-capable channel (Cloud Functions `/commerceWAV2`). + * Set Commerce Settings + */ + async createCommerce(token: string, createCommerceRequest: CreateCommerceRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createCommerceRaw({ token: token, createCommerceRequest: createCommerceRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for getCommerce without sending the request + */ + async getCommerceRequestOpts(requestParameters: GetCommerceRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling getCommerce().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/commerce`; + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Returns catalog/cart commerce settings for the channel. Fails with a provider error when the WABA has no catalog linked — that is an API/account limitation, not an MCP schema bug. - `is_catalog_visible` — show catalog storefront icon (`true`) or hide it (`false`). - `is_cart_enabled` — enable cart (`true`) or disable it (`false`). + * Get Commerce Settings + */ + async getCommerceRaw(requestParameters: GetCommerceRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const requestOptions = await this.getCommerceRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(GetCommerce200ResponseInnerFromJSON)); + } + + /** + * Returns catalog/cart commerce settings for the channel. Fails with a provider error when the WABA has no catalog linked — that is an API/account limitation, not an MCP schema bug. - `is_catalog_visible` — show catalog storefront icon (`true`) or hide it (`false`). - `is_cart_enabled` — enable cart (`true`) or disable it (`false`). + * Get Commerce Settings + */ + async getCommerce(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getCommerceRaw({ token: token }, initOverrides); + return await response.value(); + } + +} diff --git a/typescript/src/generated/src/apis/ChannelApi.ts b/typescript/src/generated/src/apis/ChannelApi.ts new file mode 100644 index 0000000..07471d2 --- /dev/null +++ b/typescript/src/generated/src/apis/ChannelApi.ts @@ -0,0 +1,492 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from '../runtime'; +import { + type ConversationalAutomation, + ConversationalAutomationFromJSON, + ConversationalAutomationToJSON, +} from '../models/ConversationalAutomation'; +import { + type CreateSettingsRequest, + CreateSettingsRequestFromJSON, + CreateSettingsRequestToJSON, +} from '../models/CreateSettingsRequest'; +import { + type ErrorResponse, + ErrorResponseFromJSON, + ErrorResponseToJSON, +} from '../models/ErrorResponse'; +import { + type GetStatus200Response, + GetStatus200ResponseFromJSON, + GetStatus200ResponseToJSON, +} from '../models/GetStatus200Response'; +import { + type ListSettings200Response, + ListSettings200ResponseFromJSON, + ListSettings200ResponseToJSON, +} from '../models/ListSettings200Response'; + +export interface CreateSettingsOperationRequest { + token: string; + createSettingsRequest: CreateSettingsRequest; +} + +export interface GetConversationalAutomationRequest { + token: string; +} + +export interface GetStatusRequest { + token: string; +} + +export interface ListSettingsRequest { + token: string; +} + +export interface SetConversationalAutomationRequest { + token: string; + conversationalAutomation: ConversationalAutomation; +} + +/** + * ChannelApi - interface + * + * @export + * @interface ChannelApiInterface + */ +export interface ChannelApiInterface { + /** + * Creates request options for createSettings without sending the request + * @param {string} token JWT token or API key for authorization + * @param {CreateSettingsRequest} createSettingsRequest + * @throws {RequiredError} + * @memberof ChannelApiInterface + */ + createSettingsRequestOpts(requestParameters: CreateSettingsOperationRequest): Promise; + + /** + * Update channel settings. Only send fields you want to change. `webhookUrl` **replaces** the stored list (one URL string, or up to 5 URLs as an array). Passing an empty value clears webhooks. Repeating the same URL(s) also clears a sticky auto-disable. With several URLs, send the complete array to re-enable one of them — omitting a URL removes it from the channel. + * @summary Update channel settings + * @param {string} token JWT token or API key for authorization + * @param {CreateSettingsRequest} createSettingsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ChannelApiInterface + */ + createSettingsRaw(requestParameters: CreateSettingsOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Update channel settings. Only send fields you want to change. `webhookUrl` **replaces** the stored list (one URL string, or up to 5 URLs as an array). Passing an empty value clears webhooks. Repeating the same URL(s) also clears a sticky auto-disable. With several URLs, send the complete array to re-enable one of them — omitting a URL removes it from the channel. + * Update channel settings + */ + createSettings(token: string, createSettingsRequest: CreateSettingsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>; + + /** + * Creates request options for getConversationalAutomation without sending the request + * @param {string} token JWT token or API key for authorization + * @throws {RequiredError} + * @memberof ChannelApiInterface + */ + getConversationalAutomationRequestOpts(requestParameters: GetConversationalAutomationRequest): Promise; + + /** + * Get WhatsApp conversational components for the channel (welcome message, ice-breaker prompts, and slash commands). Proxies Meta/360dialog `GET /conversational_automation`. When `enable_welcome_message` is true and a user opens chat for the first time, Meta delivers a webhook message with `type: request_welcome`. The inbound formatter exposes that as `type: \"request_welcome\"` and `meta.request_welcome: true` so your webhook can send a custom welcome reply. + * @summary Get conversational automation settings + * @param {string} token JWT token or API key for authorization + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ChannelApiInterface + */ + getConversationalAutomationRaw(requestParameters: GetConversationalAutomationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Get WhatsApp conversational components for the channel (welcome message, ice-breaker prompts, and slash commands). Proxies Meta/360dialog `GET /conversational_automation`. When `enable_welcome_message` is true and a user opens chat for the first time, Meta delivers a webhook message with `type: request_welcome`. The inbound formatter exposes that as `type: \"request_welcome\"` and `meta.request_welcome: true` so your webhook can send a custom welcome reply. + * Get conversational automation settings + */ + getConversationalAutomation(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for getStatus without sending the request + * @param {string} token JWT token or API key for authorization + * @throws {RequiredError} + * @memberof ChannelApiInterface + */ + getStatusRequestOpts(requestParameters: GetStatusRequest): Promise; + + /** + * Return WhatsApp Cloud API connection status for this channel (`connected` when the number can send). May include `accountStatus`, messaging limit, and MM Lite availability. Optional `health_status_warning` appears only when Meta Graph health could not be loaded and a soft `connected` response is returned. Omitted on the normal path and when health details are not applicable for the channel — never an internal provider/transport name. + * @summary Get channel status + * @param {string} token JWT token or API key for authorization + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ChannelApiInterface + */ + getStatusRaw(requestParameters: GetStatusRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Return WhatsApp Cloud API connection status for this channel (`connected` when the number can send). May include `accountStatus`, messaging limit, and MM Lite availability. Optional `health_status_warning` appears only when Meta Graph health could not be loaded and a soft `connected` response is returned. Omitted on the normal path and when health details are not applicable for the channel — never an internal provider/transport name. + * Get channel status + */ + getStatus(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for listSettings without sending the request + * @param {string} token JWT token or API key for authorization + * @throws {RequiredError} + * @memberof ChannelApiInterface + */ + listSettingsRequestOpts(requestParameters: ListSettingsRequest): Promise; + + /** + * Return channel settings: webhook URL(s), delivery flags, and analytics toggles. Auto-disable / circuit state matches `GET /webhook`. **Prefer `webhookStatuses`** (one row per configured URL). The breaker is per URL, not per channel. Channel-level `haveDisabledWebhooks` is `true` when **at least one** URL in `webhookUrl` is sticky auto-disabled — not \"the channel is dead\". Live URLs still receive events. Top-level `circuitState` / `reason` / `fails` / `trips` are a compatibility summary of one URL (first sticky-disabled, else first configured). This is the same `GET /settings` endpoint as the REST API (previously missing from MCP). + * @summary Get channel settings + * @param {string} token JWT token or API key for authorization + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ChannelApiInterface + */ + listSettingsRaw(requestParameters: ListSettingsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Return channel settings: webhook URL(s), delivery flags, and analytics toggles. Auto-disable / circuit state matches `GET /webhook`. **Prefer `webhookStatuses`** (one row per configured URL). The breaker is per URL, not per channel. Channel-level `haveDisabledWebhooks` is `true` when **at least one** URL in `webhookUrl` is sticky auto-disabled — not \"the channel is dead\". Live URLs still receive events. Top-level `circuitState` / `reason` / `fails` / `trips` are a compatibility summary of one URL (first sticky-disabled, else first configured). This is the same `GET /settings` endpoint as the REST API (previously missing from MCP). + * Get channel settings + */ + listSettings(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for setConversationalAutomation without sending the request + * @param {string} token JWT token or API key for authorization + * @param {ConversationalAutomation} conversationalAutomation + * @throws {RequiredError} + * @memberof ChannelApiInterface + */ + setConversationalAutomationRequestOpts(requestParameters: SetConversationalAutomationRequest): Promise; + + /** + * Update WhatsApp conversational components. Allowed body fields (others are ignored): - `enable_welcome_message` (boolean) - `prompts` (string[], max 4, each ≤ 80 chars) - `commands` (`{ command_name, command_description }[]`) Proxies Meta/360dialog `POST /conversational_automation`. + * @summary Set conversational automation settings + * @param {string} token JWT token or API key for authorization + * @param {ConversationalAutomation} conversationalAutomation + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ChannelApiInterface + */ + setConversationalAutomationRaw(requestParameters: SetConversationalAutomationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Update WhatsApp conversational components. Allowed body fields (others are ignored): - `enable_welcome_message` (boolean) - `prompts` (string[], max 4, each ≤ 80 chars) - `commands` (`{ command_name, command_description }[]`) Proxies Meta/360dialog `POST /conversational_automation`. + * Set conversational automation settings + */ + setConversationalAutomation(token: string, conversationalAutomation: ConversationalAutomation, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>; + +} + +/** + * + */ +export class ChannelApi extends runtime.BaseAPI implements ChannelApiInterface { + + /** + * Creates request options for createSettings without sending the request + */ + async createSettingsRequestOpts(requestParameters: CreateSettingsOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling createSettings().' + ); + } + + if (requestParameters['createSettingsRequest'] == null) { + throw new runtime.RequiredError( + 'createSettingsRequest', + 'Required parameter "createSettingsRequest" was null or undefined when calling createSettings().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/settings`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: CreateSettingsRequestToJSON(requestParameters['createSettingsRequest']), + }; + } + + /** + * Update channel settings. Only send fields you want to change. `webhookUrl` **replaces** the stored list (one URL string, or up to 5 URLs as an array). Passing an empty value clears webhooks. Repeating the same URL(s) also clears a sticky auto-disable. With several URLs, send the complete array to re-enable one of them — omitting a URL removes it from the channel. + * Update channel settings + */ + async createSettingsRaw(requestParameters: CreateSettingsOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.createSettingsRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + * Update channel settings. Only send fields you want to change. `webhookUrl` **replaces** the stored list (one URL string, or up to 5 URLs as an array). Passing an empty value clears webhooks. Repeating the same URL(s) also clears a sticky auto-disable. With several URLs, send the complete array to re-enable one of them — omitting a URL removes it from the channel. + * Update channel settings + */ + async createSettings(token: string, createSettingsRequest: CreateSettingsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> { + const response = await this.createSettingsRaw({ token: token, createSettingsRequest: createSettingsRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for getConversationalAutomation without sending the request + */ + async getConversationalAutomationRequestOpts(requestParameters: GetConversationalAutomationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling getConversationalAutomation().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/conversationalAutomation`; + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Get WhatsApp conversational components for the channel (welcome message, ice-breaker prompts, and slash commands). Proxies Meta/360dialog `GET /conversational_automation`. When `enable_welcome_message` is true and a user opens chat for the first time, Meta delivers a webhook message with `type: request_welcome`. The inbound formatter exposes that as `type: \"request_welcome\"` and `meta.request_welcome: true` so your webhook can send a custom welcome reply. + * Get conversational automation settings + */ + async getConversationalAutomationRaw(requestParameters: GetConversationalAutomationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.getConversationalAutomationRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ConversationalAutomationFromJSON(jsonValue)); + } + + /** + * Get WhatsApp conversational components for the channel (welcome message, ice-breaker prompts, and slash commands). Proxies Meta/360dialog `GET /conversational_automation`. When `enable_welcome_message` is true and a user opens chat for the first time, Meta delivers a webhook message with `type: request_welcome`. The inbound formatter exposes that as `type: \"request_welcome\"` and `meta.request_welcome: true` so your webhook can send a custom welcome reply. + * Get conversational automation settings + */ + async getConversationalAutomation(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getConversationalAutomationRaw({ token: token }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for getStatus without sending the request + */ + async getStatusRequestOpts(requestParameters: GetStatusRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling getStatus().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/status`; + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Return WhatsApp Cloud API connection status for this channel (`connected` when the number can send). May include `accountStatus`, messaging limit, and MM Lite availability. Optional `health_status_warning` appears only when Meta Graph health could not be loaded and a soft `connected` response is returned. Omitted on the normal path and when health details are not applicable for the channel — never an internal provider/transport name. + * Get channel status + */ + async getStatusRaw(requestParameters: GetStatusRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.getStatusRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => GetStatus200ResponseFromJSON(jsonValue)); + } + + /** + * Return WhatsApp Cloud API connection status for this channel (`connected` when the number can send). May include `accountStatus`, messaging limit, and MM Lite availability. Optional `health_status_warning` appears only when Meta Graph health could not be loaded and a soft `connected` response is returned. Omitted on the normal path and when health details are not applicable for the channel — never an internal provider/transport name. + * Get channel status + */ + async getStatus(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getStatusRaw({ token: token }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for listSettings without sending the request + */ + async listSettingsRequestOpts(requestParameters: ListSettingsRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling listSettings().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/settings`; + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Return channel settings: webhook URL(s), delivery flags, and analytics toggles. Auto-disable / circuit state matches `GET /webhook`. **Prefer `webhookStatuses`** (one row per configured URL). The breaker is per URL, not per channel. Channel-level `haveDisabledWebhooks` is `true` when **at least one** URL in `webhookUrl` is sticky auto-disabled — not \"the channel is dead\". Live URLs still receive events. Top-level `circuitState` / `reason` / `fails` / `trips` are a compatibility summary of one URL (first sticky-disabled, else first configured). This is the same `GET /settings` endpoint as the REST API (previously missing from MCP). + * Get channel settings + */ + async listSettingsRaw(requestParameters: ListSettingsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.listSettingsRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ListSettings200ResponseFromJSON(jsonValue)); + } + + /** + * Return channel settings: webhook URL(s), delivery flags, and analytics toggles. Auto-disable / circuit state matches `GET /webhook`. **Prefer `webhookStatuses`** (one row per configured URL). The breaker is per URL, not per channel. Channel-level `haveDisabledWebhooks` is `true` when **at least one** URL in `webhookUrl` is sticky auto-disabled — not \"the channel is dead\". Live URLs still receive events. Top-level `circuitState` / `reason` / `fails` / `trips` are a compatibility summary of one URL (first sticky-disabled, else first configured). This is the same `GET /settings` endpoint as the REST API (previously missing from MCP). + * Get channel settings + */ + async listSettings(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.listSettingsRaw({ token: token }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for setConversationalAutomation without sending the request + */ + async setConversationalAutomationRequestOpts(requestParameters: SetConversationalAutomationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling setConversationalAutomation().' + ); + } + + if (requestParameters['conversationalAutomation'] == null) { + throw new runtime.RequiredError( + 'conversationalAutomation', + 'Required parameter "conversationalAutomation" was null or undefined when calling setConversationalAutomation().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/conversationalAutomation`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: ConversationalAutomationToJSON(requestParameters['conversationalAutomation']), + }; + } + + /** + * Update WhatsApp conversational components. Allowed body fields (others are ignored): - `enable_welcome_message` (boolean) - `prompts` (string[], max 4, each ≤ 80 chars) - `commands` (`{ command_name, command_description }[]`) Proxies Meta/360dialog `POST /conversational_automation`. + * Set conversational automation settings + */ + async setConversationalAutomationRaw(requestParameters: SetConversationalAutomationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.setConversationalAutomationRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + * Update WhatsApp conversational components. Allowed body fields (others are ignored): - `enable_welcome_message` (boolean) - `prompts` (string[], max 4, each ≤ 80 chars) - `commands` (`{ command_name, command_description }[]`) Proxies Meta/360dialog `POST /conversational_automation`. + * Set conversational automation settings + */ + async setConversationalAutomation(token: string, conversationalAutomation: ConversationalAutomation, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> { + const response = await this.setConversationalAutomationRaw({ token: token, conversationalAutomation: conversationalAutomation }, initOverrides); + return await response.value(); + } + +} diff --git a/typescript/src/generated/src/apis/FlowsApi.ts b/typescript/src/generated/src/apis/FlowsApi.ts new file mode 100644 index 0000000..a27d24f --- /dev/null +++ b/typescript/src/generated/src/apis/FlowsApi.ts @@ -0,0 +1,1177 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from '../runtime'; +import { + type CreateCommerce200Response, + CreateCommerce200ResponseFromJSON, + CreateCommerce200ResponseToJSON, +} from '../models/CreateCommerce200Response'; +import { + type CreateFlowsRequest, + CreateFlowsRequestFromJSON, + CreateFlowsRequestToJSON, +} from '../models/CreateFlowsRequest'; +import { + type CreateGroups200Response, + CreateGroups200ResponseFromJSON, + CreateGroups200ResponseToJSON, +} from '../models/CreateGroups200Response'; +import { + type CreateReadMessage401Response, + CreateReadMessage401ResponseFromJSON, + CreateReadMessage401ResponseToJSON, +} from '../models/CreateReadMessage401Response'; +import { + type DeleteFlowsFlowId200Response, + DeleteFlowsFlowId200ResponseFromJSON, + DeleteFlowsFlowId200ResponseToJSON, +} from '../models/DeleteFlowsFlowId200Response'; +import { + type ErrorResponse, + ErrorResponseFromJSON, + ErrorResponseToJSON, +} from '../models/ErrorResponse'; +import { + type GetWhatsappBusinessEncryption200Response, + GetWhatsappBusinessEncryption200ResponseFromJSON, + GetWhatsappBusinessEncryption200ResponseToJSON, +} from '../models/GetWhatsappBusinessEncryption200Response'; +import { + type ListFlows200Response, + ListFlows200ResponseFromJSON, + ListFlows200ResponseToJSON, +} from '../models/ListFlows200Response'; +import { + type PatchFlowsFlowIdAssets200Response, + PatchFlowsFlowIdAssets200ResponseFromJSON, + PatchFlowsFlowIdAssets200ResponseToJSON, +} from '../models/PatchFlowsFlowIdAssets200Response'; +import { + type PatchFlowsFlowIdAssetsRequest, + PatchFlowsFlowIdAssetsRequestFromJSON, + PatchFlowsFlowIdAssetsRequestToJSON, +} from '../models/PatchFlowsFlowIdAssetsRequest'; +import { + type PatchFlowsFlowIdMetadataRequest, + PatchFlowsFlowIdMetadataRequestFromJSON, + PatchFlowsFlowIdMetadataRequestToJSON, +} from '../models/PatchFlowsFlowIdMetadataRequest'; +import { + type SetWhatsappBusinessEncryptionRequest, + SetWhatsappBusinessEncryptionRequestFromJSON, + SetWhatsappBusinessEncryptionRequestToJSON, +} from '../models/SetWhatsappBusinessEncryptionRequest'; + +export interface CreateFlowsOperationRequest { + token: string; + createFlowsRequest: CreateFlowsRequest; + wabaAccountId?: (string) | undefined; +} + +export interface CreateFlowsFlowIdDeprecateRequest { + flowId: string; + token: string; + wabaAccountId?: (string) | undefined; +} + +export interface CreateFlowsFlowIdPublishRequest { + flowId: string; + token: string; + wabaAccountId?: (string) | undefined; +} + +export interface DeleteFlowsFlowIdRequest { + flowId: string; + token: string; + wabaAccountId?: (string) | undefined; +} + +export interface GetFlowsFlowIdRequest { + flowId: string; + token: string; + wabaAccountId?: (string) | undefined; +} + +export interface GetFlowsFlowIdPreviewRequest { + flowId: string; + token: string; + wabaAccountId?: (string) | undefined; +} + +export interface GetWhatsappBusinessEncryptionRequest { + token: string; +} + +export interface ListFlowsRequest { + token: string; + wabaAccountId?: (string) | undefined; + fields?: (string) | undefined; +} + +export interface PatchFlowsFlowIdAssetsOperationRequest { + flowId: string; + token: string; + patchFlowsFlowIdAssetsRequest: PatchFlowsFlowIdAssetsRequest; + wabaAccountId?: (string) | undefined; +} + +export interface PatchFlowsFlowIdMetadataOperationRequest { + flowId: string; + token: string; + patchFlowsFlowIdMetadataRequest: PatchFlowsFlowIdMetadataRequest; + wabaAccountId?: (string) | undefined; +} + +export interface SetWhatsappBusinessEncryptionOperationRequest { + token: string; + setWhatsappBusinessEncryptionRequest: SetWhatsappBusinessEncryptionRequest; +} + +/** + * FlowsApi - interface + * + * @export + * @interface FlowsApiInterface + */ +export interface FlowsApiInterface { + /** + * Creates request options for createFlows without sending the request + * @param {string} token JWT token or API key for authorization + * @param {CreateFlowsRequest} createFlowsRequest + * @param {string} [wabaAccountId] + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + createFlowsRequestOpts(requestParameters: CreateFlowsOperationRequest): Promise; + + /** + * Create a WhatsApp Flow (`name` + `categories` required). Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. + * @summary Create Flow + * @param {string} token JWT token or API key for authorization + * @param {CreateFlowsRequest} createFlowsRequest + * @param {string} [wabaAccountId] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + createFlowsRaw(requestParameters: CreateFlowsOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Create a WhatsApp Flow (`name` + `categories` required). Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. + * Create Flow + */ + createFlows(token: string, createFlowsRequest: CreateFlowsRequest, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for createFlowsFlowIdDeprecate without sending the request + * @param {string} flowId Flow ID + * @param {string} token JWT token or API key for authorization + * @param {string} [wabaAccountId] + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + createFlowsFlowIdDeprecateRequestOpts(requestParameters: CreateFlowsFlowIdDeprecateRequest): Promise; + + /** + * + * @summary Deprecate Flow + * @param {string} flowId Flow ID + * @param {string} token JWT token or API key for authorization + * @param {string} [wabaAccountId] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + createFlowsFlowIdDeprecateRaw(requestParameters: CreateFlowsFlowIdDeprecateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Deprecate Flow + */ + createFlowsFlowIdDeprecate(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>; + + /** + * Creates request options for createFlowsFlowIdPublish without sending the request + * @param {string} flowId Flow ID + * @param {string} token JWT token or API key for authorization + * @param {string} [wabaAccountId] + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + createFlowsFlowIdPublishRequestOpts(requestParameters: CreateFlowsFlowIdPublishRequest): Promise; + + /** + * + * @summary Publish Flow + * @param {string} flowId Flow ID + * @param {string} token JWT token or API key for authorization + * @param {string} [wabaAccountId] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + createFlowsFlowIdPublishRaw(requestParameters: CreateFlowsFlowIdPublishRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Publish Flow + */ + createFlowsFlowIdPublish(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>; + + /** + * Creates request options for deleteFlowsFlowId without sending the request + * @param {string} flowId Flow ID + * @param {string} token JWT token or API key for authorization + * @param {string} [wabaAccountId] + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + deleteFlowsFlowIdRequestOpts(requestParameters: DeleteFlowsFlowIdRequest): Promise; + + /** + * + * @summary Delete Flow + * @param {string} flowId Flow ID + * @param {string} token JWT token or API key for authorization + * @param {string} [wabaAccountId] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + deleteFlowsFlowIdRaw(requestParameters: DeleteFlowsFlowIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Delete Flow + */ + deleteFlowsFlowId(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for getFlowsFlowId without sending the request + * @param {string} flowId Flow ID + * @param {string} token JWT token or API key for authorization + * @param {string} [wabaAccountId] + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + getFlowsFlowIdRequestOpts(requestParameters: GetFlowsFlowIdRequest): Promise; + + /** + * + * @summary Get Flow Details + * @param {string} flowId Flow ID + * @param {string} token JWT token or API key for authorization + * @param {string} [wabaAccountId] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + getFlowsFlowIdRaw(requestParameters: GetFlowsFlowIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Get Flow Details + */ + getFlowsFlowId(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for getFlowsFlowIdPreview without sending the request + * @param {string} flowId Flow ID + * @param {string} token JWT token or API key for authorization + * @param {string} [wabaAccountId] + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + getFlowsFlowIdPreviewRequestOpts(requestParameters: GetFlowsFlowIdPreviewRequest): Promise; + + /** + * + * @summary Preview Flow + * @param {string} flowId Flow ID + * @param {string} token JWT token or API key for authorization + * @param {string} [wabaAccountId] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + getFlowsFlowIdPreviewRaw(requestParameters: GetFlowsFlowIdPreviewRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Preview Flow + */ + getFlowsFlowIdPreview(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>; + + /** + * Creates request options for getWhatsappBusinessEncryption without sending the request + * @param {string} token JWT token or API key for authorization + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + getWhatsappBusinessEncryptionRequestOpts(requestParameters: GetWhatsappBusinessEncryptionRequest): Promise; + + /** + * Retrieve the WhatsApp business public key and signature status for this channel\'s phone number. Required before publishing or sending Flows that use data encryption. + * @summary Get business encryption public key + * @param {string} token JWT token or API key for authorization + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + getWhatsappBusinessEncryptionRaw(requestParameters: GetWhatsappBusinessEncryptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Retrieve the WhatsApp business public key and signature status for this channel\'s phone number. Required before publishing or sending Flows that use data encryption. + * Get business encryption public key + */ + getWhatsappBusinessEncryption(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for listFlows without sending the request + * @param {string} token JWT token or API key for authorization + * @param {string} [wabaAccountId] + * @param {string} [fields] Comma-separated Flow fields to return + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + listFlowsRequestOpts(requestParameters: ListFlowsRequest): Promise; + + /** + * List WhatsApp Flows for the WABA. Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. + * @summary List Flows + * @param {string} token JWT token or API key for authorization + * @param {string} [wabaAccountId] + * @param {string} [fields] Comma-separated Flow fields to return + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + listFlowsRaw(requestParameters: ListFlowsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * List WhatsApp Flows for the WABA. Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. + * List Flows + */ + listFlows(token: string, wabaAccountId?: string, fields?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for patchFlowsFlowIdAssets without sending the request + * @param {string} flowId Flow ID + * @param {string} token JWT token or API key for authorization + * @param {PatchFlowsFlowIdAssetsRequest} patchFlowsFlowIdAssetsRequest + * @param {string} [wabaAccountId] + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + patchFlowsFlowIdAssetsRequestOpts(requestParameters: PatchFlowsFlowIdAssetsOperationRequest): Promise; + + /** + * Replace the Flow JSON document (`flowJson`). Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. + * @summary Update Flow Structure + * @param {string} flowId Flow ID + * @param {string} token JWT token or API key for authorization + * @param {PatchFlowsFlowIdAssetsRequest} patchFlowsFlowIdAssetsRequest + * @param {string} [wabaAccountId] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + patchFlowsFlowIdAssetsRaw(requestParameters: PatchFlowsFlowIdAssetsOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Replace the Flow JSON document (`flowJson`). Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. + * Update Flow Structure + */ + patchFlowsFlowIdAssets(flowId: string, token: string, patchFlowsFlowIdAssetsRequest: PatchFlowsFlowIdAssetsRequest, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for patchFlowsFlowIdMetadata without sending the request + * @param {string} flowId Flow ID + * @param {string} token JWT token or API key for authorization + * @param {PatchFlowsFlowIdMetadataRequest} patchFlowsFlowIdMetadataRequest + * @param {string} [wabaAccountId] + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + patchFlowsFlowIdMetadataRequestOpts(requestParameters: PatchFlowsFlowIdMetadataOperationRequest): Promise; + + /** + * Update Flow `name`, `categories`, and/or `endpointUri`. Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. + * @summary Update Flow Metadata + * @param {string} flowId Flow ID + * @param {string} token JWT token or API key for authorization + * @param {PatchFlowsFlowIdMetadataRequest} patchFlowsFlowIdMetadataRequest + * @param {string} [wabaAccountId] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + patchFlowsFlowIdMetadataRaw(requestParameters: PatchFlowsFlowIdMetadataOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Update Flow `name`, `categories`, and/or `endpointUri`. Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. + * Update Flow Metadata + */ + patchFlowsFlowIdMetadata(flowId: string, token: string, patchFlowsFlowIdMetadataRequest: PatchFlowsFlowIdMetadataRequest, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>; + + /** + * Creates request options for setWhatsappBusinessEncryption without sending the request + * @param {string} token JWT token or API key for authorization + * @param {SetWhatsappBusinessEncryptionRequest} setWhatsappBusinessEncryptionRequest + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + setWhatsappBusinessEncryptionRequestOpts(requestParameters: SetWhatsappBusinessEncryptionOperationRequest): Promise; + + /** + * Upload and sign a 2048-bit RSA business public key (PEM) for this channel\'s phone number. Meta requires a signed key before Flow publish/send. Only one active key per number; a new upload replaces the previous key. + * @summary Set business encryption public key + * @param {string} token JWT token or API key for authorization + * @param {SetWhatsappBusinessEncryptionRequest} setWhatsappBusinessEncryptionRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof FlowsApiInterface + */ + setWhatsappBusinessEncryptionRaw(requestParameters: SetWhatsappBusinessEncryptionOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Upload and sign a 2048-bit RSA business public key (PEM) for this channel\'s phone number. Meta requires a signed key before Flow publish/send. Only one active key per number; a new upload replaces the previous key. + * Set business encryption public key + */ + setWhatsappBusinessEncryption(token: string, setWhatsappBusinessEncryptionRequest: SetWhatsappBusinessEncryptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + +} + +/** + * + */ +export class FlowsApi extends runtime.BaseAPI implements FlowsApiInterface { + + /** + * Creates request options for createFlows without sending the request + */ + async createFlowsRequestOpts(requestParameters: CreateFlowsOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling createFlows().' + ); + } + + if (requestParameters['createFlowsRequest'] == null) { + throw new runtime.RequiredError( + 'createFlowsRequest', + 'Required parameter "createFlowsRequest" was null or undefined when calling createFlows().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + if (requestParameters['wabaAccountId'] != null) { + queryParameters['wabaAccountId'] = requestParameters['wabaAccountId']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/flows`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: CreateFlowsRequestToJSON(requestParameters['createFlowsRequest']), + }; + } + + /** + * Create a WhatsApp Flow (`name` + `categories` required). Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. + * Create Flow + */ + async createFlowsRaw(requestParameters: CreateFlowsOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.createFlowsRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CreateGroups200ResponseFromJSON(jsonValue)); + } + + /** + * Create a WhatsApp Flow (`name` + `categories` required). Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. + * Create Flow + */ + async createFlows(token: string, createFlowsRequest: CreateFlowsRequest, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createFlowsRaw({ token: token, createFlowsRequest: createFlowsRequest, wabaAccountId: wabaAccountId }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for createFlowsFlowIdDeprecate without sending the request + */ + async createFlowsFlowIdDeprecateRequestOpts(requestParameters: CreateFlowsFlowIdDeprecateRequest): Promise { + if (requestParameters['flowId'] == null) { + throw new runtime.RequiredError( + 'flowId', + 'Required parameter "flowId" was null or undefined when calling createFlowsFlowIdDeprecate().' + ); + } + + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling createFlowsFlowIdDeprecate().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + if (requestParameters['wabaAccountId'] != null) { + queryParameters['wabaAccountId'] = requestParameters['wabaAccountId']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/flows/{flowId}/deprecate`; + urlPath = urlPath.replace('{flowId}', encodeURIComponent(String(requestParameters['flowId']))); + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Deprecate Flow + */ + async createFlowsFlowIdDeprecateRaw(requestParameters: CreateFlowsFlowIdDeprecateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.createFlowsFlowIdDeprecateRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + * Deprecate Flow + */ + async createFlowsFlowIdDeprecate(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> { + const response = await this.createFlowsFlowIdDeprecateRaw({ flowId: flowId, token: token, wabaAccountId: wabaAccountId }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for createFlowsFlowIdPublish without sending the request + */ + async createFlowsFlowIdPublishRequestOpts(requestParameters: CreateFlowsFlowIdPublishRequest): Promise { + if (requestParameters['flowId'] == null) { + throw new runtime.RequiredError( + 'flowId', + 'Required parameter "flowId" was null or undefined when calling createFlowsFlowIdPublish().' + ); + } + + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling createFlowsFlowIdPublish().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + if (requestParameters['wabaAccountId'] != null) { + queryParameters['wabaAccountId'] = requestParameters['wabaAccountId']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/flows/{flowId}/publish`; + urlPath = urlPath.replace('{flowId}', encodeURIComponent(String(requestParameters['flowId']))); + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Publish Flow + */ + async createFlowsFlowIdPublishRaw(requestParameters: CreateFlowsFlowIdPublishRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.createFlowsFlowIdPublishRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + * Publish Flow + */ + async createFlowsFlowIdPublish(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> { + const response = await this.createFlowsFlowIdPublishRaw({ flowId: flowId, token: token, wabaAccountId: wabaAccountId }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for deleteFlowsFlowId without sending the request + */ + async deleteFlowsFlowIdRequestOpts(requestParameters: DeleteFlowsFlowIdRequest): Promise { + if (requestParameters['flowId'] == null) { + throw new runtime.RequiredError( + 'flowId', + 'Required parameter "flowId" was null or undefined when calling deleteFlowsFlowId().' + ); + } + + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling deleteFlowsFlowId().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + if (requestParameters['wabaAccountId'] != null) { + queryParameters['wabaAccountId'] = requestParameters['wabaAccountId']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/flows/{flowId}`; + urlPath = urlPath.replace('{flowId}', encodeURIComponent(String(requestParameters['flowId']))); + + return { + path: urlPath, + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Delete Flow + */ + async deleteFlowsFlowIdRaw(requestParameters: DeleteFlowsFlowIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.deleteFlowsFlowIdRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => DeleteFlowsFlowId200ResponseFromJSON(jsonValue)); + } + + /** + * Delete Flow + */ + async deleteFlowsFlowId(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.deleteFlowsFlowIdRaw({ flowId: flowId, token: token, wabaAccountId: wabaAccountId }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for getFlowsFlowId without sending the request + */ + async getFlowsFlowIdRequestOpts(requestParameters: GetFlowsFlowIdRequest): Promise { + if (requestParameters['flowId'] == null) { + throw new runtime.RequiredError( + 'flowId', + 'Required parameter "flowId" was null or undefined when calling getFlowsFlowId().' + ); + } + + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling getFlowsFlowId().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + if (requestParameters['wabaAccountId'] != null) { + queryParameters['wabaAccountId'] = requestParameters['wabaAccountId']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/flows/{flowId}`; + urlPath = urlPath.replace('{flowId}', encodeURIComponent(String(requestParameters['flowId']))); + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Get Flow Details + */ + async getFlowsFlowIdRaw(requestParameters: GetFlowsFlowIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.getFlowsFlowIdRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CreateGroups200ResponseFromJSON(jsonValue)); + } + + /** + * Get Flow Details + */ + async getFlowsFlowId(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getFlowsFlowIdRaw({ flowId: flowId, token: token, wabaAccountId: wabaAccountId }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for getFlowsFlowIdPreview without sending the request + */ + async getFlowsFlowIdPreviewRequestOpts(requestParameters: GetFlowsFlowIdPreviewRequest): Promise { + if (requestParameters['flowId'] == null) { + throw new runtime.RequiredError( + 'flowId', + 'Required parameter "flowId" was null or undefined when calling getFlowsFlowIdPreview().' + ); + } + + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling getFlowsFlowIdPreview().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + if (requestParameters['wabaAccountId'] != null) { + queryParameters['wabaAccountId'] = requestParameters['wabaAccountId']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/flows/{flowId}/preview`; + urlPath = urlPath.replace('{flowId}', encodeURIComponent(String(requestParameters['flowId']))); + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Preview Flow + */ + async getFlowsFlowIdPreviewRaw(requestParameters: GetFlowsFlowIdPreviewRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.getFlowsFlowIdPreviewRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + * Preview Flow + */ + async getFlowsFlowIdPreview(flowId: string, token: string, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> { + const response = await this.getFlowsFlowIdPreviewRaw({ flowId: flowId, token: token, wabaAccountId: wabaAccountId }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for getWhatsappBusinessEncryption without sending the request + */ + async getWhatsappBusinessEncryptionRequestOpts(requestParameters: GetWhatsappBusinessEncryptionRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling getWhatsappBusinessEncryption().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/whatsapp_business_encryption`; + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Retrieve the WhatsApp business public key and signature status for this channel\'s phone number. Required before publishing or sending Flows that use data encryption. + * Get business encryption public key + */ + async getWhatsappBusinessEncryptionRaw(requestParameters: GetWhatsappBusinessEncryptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.getWhatsappBusinessEncryptionRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => GetWhatsappBusinessEncryption200ResponseFromJSON(jsonValue)); + } + + /** + * Retrieve the WhatsApp business public key and signature status for this channel\'s phone number. Required before publishing or sending Flows that use data encryption. + * Get business encryption public key + */ + async getWhatsappBusinessEncryption(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getWhatsappBusinessEncryptionRaw({ token: token }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for listFlows without sending the request + */ + async listFlowsRequestOpts(requestParameters: ListFlowsRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling listFlows().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + if (requestParameters['wabaAccountId'] != null) { + queryParameters['wabaAccountId'] = requestParameters['wabaAccountId']; + } + + if (requestParameters['fields'] != null) { + queryParameters['fields'] = requestParameters['fields']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/flows`; + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * List WhatsApp Flows for the WABA. Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. + * List Flows + */ + async listFlowsRaw(requestParameters: ListFlowsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.listFlowsRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ListFlows200ResponseFromJSON(jsonValue)); + } + + /** + * List WhatsApp Flows for the WABA. Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. + * List Flows + */ + async listFlows(token: string, wabaAccountId?: string, fields?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.listFlowsRaw({ token: token, wabaAccountId: wabaAccountId, fields: fields }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for patchFlowsFlowIdAssets without sending the request + */ + async patchFlowsFlowIdAssetsRequestOpts(requestParameters: PatchFlowsFlowIdAssetsOperationRequest): Promise { + if (requestParameters['flowId'] == null) { + throw new runtime.RequiredError( + 'flowId', + 'Required parameter "flowId" was null or undefined when calling patchFlowsFlowIdAssets().' + ); + } + + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling patchFlowsFlowIdAssets().' + ); + } + + if (requestParameters['patchFlowsFlowIdAssetsRequest'] == null) { + throw new runtime.RequiredError( + 'patchFlowsFlowIdAssetsRequest', + 'Required parameter "patchFlowsFlowIdAssetsRequest" was null or undefined when calling patchFlowsFlowIdAssets().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + if (requestParameters['wabaAccountId'] != null) { + queryParameters['wabaAccountId'] = requestParameters['wabaAccountId']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/flows/{flowId}/assets`; + urlPath = urlPath.replace('{flowId}', encodeURIComponent(String(requestParameters['flowId']))); + + return { + path: urlPath, + method: 'PATCH', + headers: headerParameters, + query: queryParameters, + body: PatchFlowsFlowIdAssetsRequestToJSON(requestParameters['patchFlowsFlowIdAssetsRequest']), + }; + } + + /** + * Replace the Flow JSON document (`flowJson`). Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. + * Update Flow Structure + */ + async patchFlowsFlowIdAssetsRaw(requestParameters: PatchFlowsFlowIdAssetsOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.patchFlowsFlowIdAssetsRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => PatchFlowsFlowIdAssets200ResponseFromJSON(jsonValue)); + } + + /** + * Replace the Flow JSON document (`flowJson`). Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. + * Update Flow Structure + */ + async patchFlowsFlowIdAssets(flowId: string, token: string, patchFlowsFlowIdAssetsRequest: PatchFlowsFlowIdAssetsRequest, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.patchFlowsFlowIdAssetsRaw({ flowId: flowId, token: token, patchFlowsFlowIdAssetsRequest: patchFlowsFlowIdAssetsRequest, wabaAccountId: wabaAccountId }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for patchFlowsFlowIdMetadata without sending the request + */ + async patchFlowsFlowIdMetadataRequestOpts(requestParameters: PatchFlowsFlowIdMetadataOperationRequest): Promise { + if (requestParameters['flowId'] == null) { + throw new runtime.RequiredError( + 'flowId', + 'Required parameter "flowId" was null or undefined when calling patchFlowsFlowIdMetadata().' + ); + } + + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling patchFlowsFlowIdMetadata().' + ); + } + + if (requestParameters['patchFlowsFlowIdMetadataRequest'] == null) { + throw new runtime.RequiredError( + 'patchFlowsFlowIdMetadataRequest', + 'Required parameter "patchFlowsFlowIdMetadataRequest" was null or undefined when calling patchFlowsFlowIdMetadata().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + if (requestParameters['wabaAccountId'] != null) { + queryParameters['wabaAccountId'] = requestParameters['wabaAccountId']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/flows/{flowId}/metadata`; + urlPath = urlPath.replace('{flowId}', encodeURIComponent(String(requestParameters['flowId']))); + + return { + path: urlPath, + method: 'PATCH', + headers: headerParameters, + query: queryParameters, + body: PatchFlowsFlowIdMetadataRequestToJSON(requestParameters['patchFlowsFlowIdMetadataRequest']), + }; + } + + /** + * Update Flow `name`, `categories`, and/or `endpointUri`. Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. + * Update Flow Metadata + */ + async patchFlowsFlowIdMetadataRaw(requestParameters: PatchFlowsFlowIdMetadataOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.patchFlowsFlowIdMetadataRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + * Update Flow `name`, `categories`, and/or `endpointUri`. Currently returns HTTP 501 until the Meta Graph Flows rewrite is available. + * Update Flow Metadata + */ + async patchFlowsFlowIdMetadata(flowId: string, token: string, patchFlowsFlowIdMetadataRequest: PatchFlowsFlowIdMetadataRequest, wabaAccountId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> { + const response = await this.patchFlowsFlowIdMetadataRaw({ flowId: flowId, token: token, patchFlowsFlowIdMetadataRequest: patchFlowsFlowIdMetadataRequest, wabaAccountId: wabaAccountId }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for setWhatsappBusinessEncryption without sending the request + */ + async setWhatsappBusinessEncryptionRequestOpts(requestParameters: SetWhatsappBusinessEncryptionOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling setWhatsappBusinessEncryption().' + ); + } + + if (requestParameters['setWhatsappBusinessEncryptionRequest'] == null) { + throw new runtime.RequiredError( + 'setWhatsappBusinessEncryptionRequest', + 'Required parameter "setWhatsappBusinessEncryptionRequest" was null or undefined when calling setWhatsappBusinessEncryption().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/whatsapp_business_encryption`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: SetWhatsappBusinessEncryptionRequestToJSON(requestParameters['setWhatsappBusinessEncryptionRequest']), + }; + } + + /** + * Upload and sign a 2048-bit RSA business public key (PEM) for this channel\'s phone number. Meta requires a signed key before Flow publish/send. Only one active key per number; a new upload replaces the previous key. + * Set business encryption public key + */ + async setWhatsappBusinessEncryptionRaw(requestParameters: SetWhatsappBusinessEncryptionOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.setWhatsappBusinessEncryptionRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CreateCommerce200ResponseFromJSON(jsonValue)); + } + + /** + * Upload and sign a 2048-bit RSA business public key (PEM) for this channel\'s phone number. Meta requires a signed key before Flow publish/send. Only one active key per number; a new upload replaces the previous key. + * Set business encryption public key + */ + async setWhatsappBusinessEncryption(token: string, setWhatsappBusinessEncryptionRequest: SetWhatsappBusinessEncryptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.setWhatsappBusinessEncryptionRaw({ token: token, setWhatsappBusinessEncryptionRequest: setWhatsappBusinessEncryptionRequest }, initOverrides); + return await response.value(); + } + +} diff --git a/typescript/src/generated/src/apis/GroupsApi.ts b/typescript/src/generated/src/apis/GroupsApi.ts new file mode 100644 index 0000000..a0696ff --- /dev/null +++ b/typescript/src/generated/src/apis/GroupsApi.ts @@ -0,0 +1,719 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from '../runtime'; +import { + type CreateGroups200Response, + CreateGroups200ResponseFromJSON, + CreateGroups200ResponseToJSON, +} from '../models/CreateGroups200Response'; +import { + type CreateGroupsGroupIdRequest, + CreateGroupsGroupIdRequestFromJSON, + CreateGroupsGroupIdRequestToJSON, +} from '../models/CreateGroupsGroupIdRequest'; +import { + type CreateGroupsRequest, + CreateGroupsRequestFromJSON, + CreateGroupsRequestToJSON, +} from '../models/CreateGroupsRequest'; +import { + type DeleteGroupsGroupId200Response, + DeleteGroupsGroupId200ResponseFromJSON, + DeleteGroupsGroupId200ResponseToJSON, +} from '../models/DeleteGroupsGroupId200Response'; + +export interface CreateGroupsOperationRequest { + token: string; + createGroupsRequest: CreateGroupsRequest; +} + +export interface CreateGroupsGroupIdOperationRequest { + groupId: string; + token: string; + createGroupsGroupIdRequest: CreateGroupsGroupIdRequest; +} + +export interface CreateGroupsGroupIdInvitelinkRequest { + groupId: string; + token: string; +} + +export interface DeleteGroupsGroupIdRequest { + groupId: string; + token: string; +} + +export interface GetGroupsGroupIdRequest { + groupId: string; + token: string; + fields?: (string) | undefined; +} + +export interface GetGroupsGroupIdInvitelinkRequest { + groupId: string; + token: string; +} + +export interface ListGroupsRequest { + token: string; + limit?: (number) | undefined; + before?: (string) | undefined; + after?: (string) | undefined; +} + +/** + * GroupsApi - interface + * + * @export + * @interface GroupsApiInterface + */ +export interface GroupsApiInterface { + /** + * Creates request options for createGroups without sending the request + * @param {string} token JWT token or API key for authorization + * @param {CreateGroupsRequest} createGroupsRequest + * @throws {RequiredError} + * @memberof GroupsApiInterface + */ + createGroupsRequestOpts(requestParameters: CreateGroupsOperationRequest): Promise; + + /** + * + * @summary Create Group + * @param {string} token JWT token or API key for authorization + * @param {CreateGroupsRequest} createGroupsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof GroupsApiInterface + */ + createGroupsRaw(requestParameters: CreateGroupsOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Create Group + */ + createGroups(token: string, createGroupsRequest: CreateGroupsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for createGroupsGroupId without sending the request + * @param {string} groupId + * @param {string} token JWT token or API key for authorization + * @param {CreateGroupsGroupIdRequest} createGroupsGroupIdRequest + * @throws {RequiredError} + * @memberof GroupsApiInterface + */ + createGroupsGroupIdRequestOpts(requestParameters: CreateGroupsGroupIdOperationRequest): Promise; + + /** + * Update group subject, description, and/or profile picture. Path `groupId` is the WABA group id (without `@g.us`). + * @summary Update Group Info + * @param {string} groupId + * @param {string} token JWT token or API key for authorization + * @param {CreateGroupsGroupIdRequest} createGroupsGroupIdRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof GroupsApiInterface + */ + createGroupsGroupIdRaw(requestParameters: CreateGroupsGroupIdOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Update group subject, description, and/or profile picture. Path `groupId` is the WABA group id (without `@g.us`). + * Update Group Info + */ + createGroupsGroupId(groupId: string, token: string, createGroupsGroupIdRequest: CreateGroupsGroupIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>; + + /** + * Creates request options for createGroupsGroupIdInvitelink without sending the request + * @param {string} groupId + * @param {string} token JWT token or API key for authorization + * @throws {RequiredError} + * @memberof GroupsApiInterface + */ + createGroupsGroupIdInvitelinkRequestOpts(requestParameters: CreateGroupsGroupIdInvitelinkRequest): Promise; + + /** + * + * @summary Reset Invite Link + * @param {string} groupId + * @param {string} token JWT token or API key for authorization + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof GroupsApiInterface + */ + createGroupsGroupIdInvitelinkRaw(requestParameters: CreateGroupsGroupIdInvitelinkRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Reset Invite Link + */ + createGroupsGroupIdInvitelink(groupId: string, token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>; + + /** + * Creates request options for deleteGroupsGroupId without sending the request + * @param {string} groupId + * @param {string} token JWT token or API key for authorization + * @throws {RequiredError} + * @memberof GroupsApiInterface + */ + deleteGroupsGroupIdRequestOpts(requestParameters: DeleteGroupsGroupIdRequest): Promise; + + /** + * + * @summary Delete Group + * @param {string} groupId + * @param {string} token JWT token or API key for authorization + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof GroupsApiInterface + */ + deleteGroupsGroupIdRaw(requestParameters: DeleteGroupsGroupIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Delete Group + */ + deleteGroupsGroupId(groupId: string, token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for getGroupsGroupId without sending the request + * @param {string} groupId + * @param {string} token JWT token or API key for authorization + * @param {string} [fields] Comma-separated group fields to return + * @throws {RequiredError} + * @memberof GroupsApiInterface + */ + getGroupsGroupIdRequestOpts(requestParameters: GetGroupsGroupIdRequest): Promise; + + /** + * + * @summary Get Group Info + * @param {string} groupId + * @param {string} token JWT token or API key for authorization + * @param {string} [fields] Comma-separated group fields to return + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof GroupsApiInterface + */ + getGroupsGroupIdRaw(requestParameters: GetGroupsGroupIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Get Group Info + */ + getGroupsGroupId(groupId: string, token: string, fields?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>; + + /** + * Creates request options for getGroupsGroupIdInvitelink without sending the request + * @param {string} groupId + * @param {string} token JWT token or API key for authorization + * @throws {RequiredError} + * @memberof GroupsApiInterface + */ + getGroupsGroupIdInvitelinkRequestOpts(requestParameters: GetGroupsGroupIdInvitelinkRequest): Promise; + + /** + * + * @summary Get Invite Link + * @param {string} groupId + * @param {string} token JWT token or API key for authorization + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof GroupsApiInterface + */ + getGroupsGroupIdInvitelinkRaw(requestParameters: GetGroupsGroupIdInvitelinkRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Get Invite Link + */ + getGroupsGroupIdInvitelink(groupId: string, token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>; + + /** + * Creates request options for listGroups without sending the request + * @param {string} token JWT token or API key for authorization + * @param {number} [limit] Max groups to return + * @param {string} [before] Cursor for the previous page + * @param {string} [after] Cursor for the next page + * @throws {RequiredError} + * @memberof GroupsApiInterface + */ + listGroupsRequestOpts(requestParameters: ListGroupsRequest): Promise; + + /** + * List WhatsApp groups for this channel. Paginate with `limit`, `before`, and `after`. + * @summary Get Groups List + * @param {string} token JWT token or API key for authorization + * @param {number} [limit] Max groups to return + * @param {string} [before] Cursor for the previous page + * @param {string} [after] Cursor for the next page + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof GroupsApiInterface + */ + listGroupsRaw(requestParameters: ListGroupsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * List WhatsApp groups for this channel. Paginate with `limit`, `before`, and `after`. + * Get Groups List + */ + listGroups(token: string, limit?: number, before?: string, after?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>; + +} + +/** + * + */ +export class GroupsApi extends runtime.BaseAPI implements GroupsApiInterface { + + /** + * Creates request options for createGroups without sending the request + */ + async createGroupsRequestOpts(requestParameters: CreateGroupsOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling createGroups().' + ); + } + + if (requestParameters['createGroupsRequest'] == null) { + throw new runtime.RequiredError( + 'createGroupsRequest', + 'Required parameter "createGroupsRequest" was null or undefined when calling createGroups().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/groups`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: CreateGroupsRequestToJSON(requestParameters['createGroupsRequest']), + }; + } + + /** + * Create Group + */ + async createGroupsRaw(requestParameters: CreateGroupsOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.createGroupsRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CreateGroups200ResponseFromJSON(jsonValue)); + } + + /** + * Create Group + */ + async createGroups(token: string, createGroupsRequest: CreateGroupsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createGroupsRaw({ token: token, createGroupsRequest: createGroupsRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for createGroupsGroupId without sending the request + */ + async createGroupsGroupIdRequestOpts(requestParameters: CreateGroupsGroupIdOperationRequest): Promise { + if (requestParameters['groupId'] == null) { + throw new runtime.RequiredError( + 'groupId', + 'Required parameter "groupId" was null or undefined when calling createGroupsGroupId().' + ); + } + + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling createGroupsGroupId().' + ); + } + + if (requestParameters['createGroupsGroupIdRequest'] == null) { + throw new runtime.RequiredError( + 'createGroupsGroupIdRequest', + 'Required parameter "createGroupsGroupIdRequest" was null or undefined when calling createGroupsGroupId().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/groups/{groupId}`; + urlPath = urlPath.replace('{groupId}', encodeURIComponent(String(requestParameters['groupId']))); + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: CreateGroupsGroupIdRequestToJSON(requestParameters['createGroupsGroupIdRequest']), + }; + } + + /** + * Update group subject, description, and/or profile picture. Path `groupId` is the WABA group id (without `@g.us`). + * Update Group Info + */ + async createGroupsGroupIdRaw(requestParameters: CreateGroupsGroupIdOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.createGroupsGroupIdRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + * Update group subject, description, and/or profile picture. Path `groupId` is the WABA group id (without `@g.us`). + * Update Group Info + */ + async createGroupsGroupId(groupId: string, token: string, createGroupsGroupIdRequest: CreateGroupsGroupIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> { + const response = await this.createGroupsGroupIdRaw({ groupId: groupId, token: token, createGroupsGroupIdRequest: createGroupsGroupIdRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for createGroupsGroupIdInvitelink without sending the request + */ + async createGroupsGroupIdInvitelinkRequestOpts(requestParameters: CreateGroupsGroupIdInvitelinkRequest): Promise { + if (requestParameters['groupId'] == null) { + throw new runtime.RequiredError( + 'groupId', + 'Required parameter "groupId" was null or undefined when calling createGroupsGroupIdInvitelink().' + ); + } + + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling createGroupsGroupIdInvitelink().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/groups/{groupId}/inviteLink`; + urlPath = urlPath.replace('{groupId}', encodeURIComponent(String(requestParameters['groupId']))); + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Reset Invite Link + */ + async createGroupsGroupIdInvitelinkRaw(requestParameters: CreateGroupsGroupIdInvitelinkRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.createGroupsGroupIdInvitelinkRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + * Reset Invite Link + */ + async createGroupsGroupIdInvitelink(groupId: string, token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> { + const response = await this.createGroupsGroupIdInvitelinkRaw({ groupId: groupId, token: token }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for deleteGroupsGroupId without sending the request + */ + async deleteGroupsGroupIdRequestOpts(requestParameters: DeleteGroupsGroupIdRequest): Promise { + if (requestParameters['groupId'] == null) { + throw new runtime.RequiredError( + 'groupId', + 'Required parameter "groupId" was null or undefined when calling deleteGroupsGroupId().' + ); + } + + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling deleteGroupsGroupId().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/groups/{groupId}`; + urlPath = urlPath.replace('{groupId}', encodeURIComponent(String(requestParameters['groupId']))); + + return { + path: urlPath, + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Delete Group + */ + async deleteGroupsGroupIdRaw(requestParameters: DeleteGroupsGroupIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.deleteGroupsGroupIdRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => DeleteGroupsGroupId200ResponseFromJSON(jsonValue)); + } + + /** + * Delete Group + */ + async deleteGroupsGroupId(groupId: string, token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.deleteGroupsGroupIdRaw({ groupId: groupId, token: token }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for getGroupsGroupId without sending the request + */ + async getGroupsGroupIdRequestOpts(requestParameters: GetGroupsGroupIdRequest): Promise { + if (requestParameters['groupId'] == null) { + throw new runtime.RequiredError( + 'groupId', + 'Required parameter "groupId" was null or undefined when calling getGroupsGroupId().' + ); + } + + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling getGroupsGroupId().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + if (requestParameters['fields'] != null) { + queryParameters['fields'] = requestParameters['fields']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/groups/{groupId}`; + urlPath = urlPath.replace('{groupId}', encodeURIComponent(String(requestParameters['groupId']))); + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Get Group Info + */ + async getGroupsGroupIdRaw(requestParameters: GetGroupsGroupIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.getGroupsGroupIdRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + * Get Group Info + */ + async getGroupsGroupId(groupId: string, token: string, fields?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> { + const response = await this.getGroupsGroupIdRaw({ groupId: groupId, token: token, fields: fields }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for getGroupsGroupIdInvitelink without sending the request + */ + async getGroupsGroupIdInvitelinkRequestOpts(requestParameters: GetGroupsGroupIdInvitelinkRequest): Promise { + if (requestParameters['groupId'] == null) { + throw new runtime.RequiredError( + 'groupId', + 'Required parameter "groupId" was null or undefined when calling getGroupsGroupIdInvitelink().' + ); + } + + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling getGroupsGroupIdInvitelink().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/groups/{groupId}/inviteLink`; + urlPath = urlPath.replace('{groupId}', encodeURIComponent(String(requestParameters['groupId']))); + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Get Invite Link + */ + async getGroupsGroupIdInvitelinkRaw(requestParameters: GetGroupsGroupIdInvitelinkRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.getGroupsGroupIdInvitelinkRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + * Get Invite Link + */ + async getGroupsGroupIdInvitelink(groupId: string, token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> { + const response = await this.getGroupsGroupIdInvitelinkRaw({ groupId: groupId, token: token }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for listGroups without sending the request + */ + async listGroupsRequestOpts(requestParameters: ListGroupsRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling listGroups().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + if (requestParameters['limit'] != null) { + queryParameters['limit'] = requestParameters['limit']; + } + + if (requestParameters['before'] != null) { + queryParameters['before'] = requestParameters['before']; + } + + if (requestParameters['after'] != null) { + queryParameters['after'] = requestParameters['after']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/groups`; + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * List WhatsApp groups for this channel. Paginate with `limit`, `before`, and `after`. + * Get Groups List + */ + async listGroupsRaw(requestParameters: ListGroupsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.listGroupsRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + * List WhatsApp groups for this channel. Paginate with `limit`, `before`, and `after`. + * Get Groups List + */ + async listGroups(token: string, limit?: number, before?: string, after?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> { + const response = await this.listGroupsRaw({ token: token, limit: limit, before: before, after: after }, initOverrides); + return await response.value(); + } + +} diff --git a/typescript/src/generated/src/apis/MessagingApi.ts b/typescript/src/generated/src/apis/MessagingApi.ts new file mode 100644 index 0000000..1fb77aa --- /dev/null +++ b/typescript/src/generated/src/apis/MessagingApi.ts @@ -0,0 +1,2716 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from '../runtime'; +import { objectToJSON } from '../runtime'; +import { + type CreateReadMessage200Response, + CreateReadMessage200ResponseFromJSON, + CreateReadMessage200ResponseToJSON, +} from '../models/CreateReadMessage200Response'; +import { + type CreateReadMessage401Response, + CreateReadMessage401ResponseFromJSON, + CreateReadMessage401ResponseToJSON, +} from '../models/CreateReadMessage401Response'; +import { + type CreateUploadMedia200Response, + CreateUploadMedia200ResponseFromJSON, + CreateUploadMedia200ResponseToJSON, +} from '../models/CreateUploadMedia200Response'; +import { + type CreateUploadMediaRequest, + CreateUploadMediaRequestFromJSON, + CreateUploadMediaRequestToJSON, +} from '../models/CreateUploadMediaRequest'; +import { + type DeleteMediaLegacyRequest, + DeleteMediaLegacyRequestFromJSON, + DeleteMediaLegacyRequestToJSON, +} from '../models/DeleteMediaLegacyRequest'; +import { + type ErrorResponse, + ErrorResponseFromJSON, + ErrorResponseToJSON, +} from '../models/ErrorResponse'; +import { + type GetMmLiteStatus200Response, + GetMmLiteStatus200ResponseFromJSON, + GetMmLiteStatus200ResponseToJSON, +} from '../models/GetMmLiteStatus200Response'; +import { + type ListMessages200Response, + ListMessages200ResponseFromJSON, + ListMessages200ResponseToJSON, +} from '../models/ListMessages200Response'; +import { + type MessageSentResponse, + MessageSentResponseFromJSON, + MessageSentResponseToJSON, +} from '../models/MessageSentResponse'; +import { + type RetrieveMedia200Response, + RetrieveMedia200ResponseFromJSON, + RetrieveMedia200ResponseToJSON, +} from '../models/RetrieveMedia200Response'; +import { + type SendAddressMessageRequest, + SendAddressMessageRequestFromJSON, + SendAddressMessageRequestToJSON, +} from '../models/SendAddressMessageRequest'; +import { + type SendButtonRequest, + SendButtonRequestFromJSON, + SendButtonRequestToJSON, +} from '../models/SendButtonRequest'; +import { + type SendContactRequest, + SendContactRequestFromJSON, + SendContactRequestToJSON, +} from '../models/SendContactRequest'; +import { + type SendCtaUrlRequest, + SendCtaUrlRequestFromJSON, + SendCtaUrlRequestToJSON, +} from '../models/SendCtaUrlRequest'; +import { + type SendFlowRequestHeader, + SendFlowRequestHeaderFromJSON, + SendFlowRequestHeaderToJSON, +} from '../models/SendFlowRequestHeader'; +import { + type SendListRequest, + SendListRequestFromJSON, + SendListRequestToJSON, +} from '../models/SendListRequest'; +import { + type SendLocationRequestRequest, + SendLocationRequestRequestFromJSON, + SendLocationRequestRequestToJSON, +} from '../models/SendLocationRequestRequest'; +import { + type SendOrderDetailsRequest, + SendOrderDetailsRequestFromJSON, + SendOrderDetailsRequestToJSON, +} from '../models/SendOrderDetailsRequest'; +import { + type SendPaymentRequestRequest, + SendPaymentRequestRequestFromJSON, + SendPaymentRequestRequestToJSON, +} from '../models/SendPaymentRequestRequest'; +import { + type SendProductRequest, + SendProductRequestFromJSON, + SendProductRequestToJSON, +} from '../models/SendProductRequest'; +import { + type SendReactionRequest, + SendReactionRequestFromJSON, + SendReactionRequestToJSON, +} from '../models/SendReactionRequest'; +import { + type SendStickerRequest, + SendStickerRequestFromJSON, + SendStickerRequestToJSON, +} from '../models/SendStickerRequest'; +import { + type SuccessResponse, + SuccessResponseFromJSON, + SuccessResponseToJSON, +} from '../models/SuccessResponse'; + +export interface CreateReadMessageRequest { + token: string; + messageId?: (string) | undefined; + msgId?: (string) | undefined; + typingIndicator?: (boolean) | undefined; +} + +export interface CreateUploadMediaOperationRequest { + token: string; + createUploadMediaRequest: CreateUploadMediaRequest; +} + +export interface DeleteMediaRequest { + token: string; + mediaId: string; +} + +export interface DeleteMediaLegacyOperationRequest { + token: string; + deleteMediaLegacyRequest: DeleteMediaLegacyRequest; +} + +export interface GetMmLiteStatusRequest { + token: string; +} + +export interface ListMessagesRequest { + token: string; + chatId?: (string) | undefined; + limit?: (number) | undefined; + last?: (boolean) | undefined; + lastMessageNumber?: (number) | undefined; + firstMessageNumber?: (number) | undefined; + minTime?: (number) | undefined; + maxTime?: (number) | undefined; + msgId?: (string) | undefined; +} + +export interface RetrieveMediaRequest { + token: string; + mediaId: string; +} + +export interface SendAddressMessageOperationRequest { + token: string; + sendAddressMessageRequest: SendAddressMessageRequest; +} + +export interface SendButtonOperationRequest { + token: string; + sendButtonRequest?: (SendButtonRequest) | undefined; +} + +export interface SendCarouselRequest { + token: string; + body?: (string) | undefined; + cards?: (Array<{ [key: string]: any; }>) | undefined; + params?: (Array) | undefined; + quotedMsgId?: (string) | undefined; + chatId?: (string) | undefined; + phone?: (number) | undefined; +} + +export interface SendContactOperationRequest { + token: string; + sendContactRequest?: (SendContactRequest) | undefined; +} + +export interface SendCtaUrlOperationRequest { + token: string; + sendCtaUrlRequest: SendCtaUrlRequest; +} + +export interface SendFileRequest { + token: string; + body?: (string) | undefined; + filename?: (string) | undefined; + mediaId?: (string) | undefined; + mediaType?: (SendFileMediaTypeEnum) | undefined; + voice?: (boolean) | undefined; + caption?: (string) | undefined; + quotedMsgId?: (string) | undefined; + chatId?: (string) | undefined; + phone?: (number) | undefined; +} + +export interface SendFlowRequest { + token: string; + body: string; + flowId: string; + flowToken: string; + flowCta: string; + header?: (SendFlowRequestHeader) | undefined; + footer?: (string) | undefined; + flowAction?: (SendFlowFlowActionEnum) | undefined; + flowActionPayload?: (object) | undefined; + flowMessageVersion?: (string) | undefined; + mode?: (SendFlowModeEnum) | undefined; + flowActionData?: (object) | undefined; + flowActionScreen?: (string) | undefined; + quotedMsgId?: (string) | undefined; + chatId?: (string) | undefined; + phone?: (number) | undefined; +} + +export interface SendListOperationRequest { + token: string; + sendListRequest?: (SendListRequest) | undefined; +} + +export interface SendLocationRequest { + token: string; + lat: string; + lng: string; + address?: (string) | undefined; + name?: (string) | undefined; + quotedMsgId?: (string) | undefined; + chatId?: (string) | undefined; + phone?: (number) | undefined; +} + +export interface SendLocationRequestOperationRequest { + token: string; + sendLocationRequestRequest?: (SendLocationRequestRequest) | undefined; +} + +export interface SendMessageRequest { + token: string; + body: string; + quotedMsgId?: (string) | undefined; + chatId?: (string) | undefined; + phone?: (number) | undefined; +} + +export interface SendOrderDetailsOperationRequest { + token: string; + sendOrderDetailsRequest: SendOrderDetailsRequest; +} + +export interface SendPaymentRequestOperationRequest { + token: string; + sendPaymentRequestRequest: SendPaymentRequestRequest; +} + +export interface SendProductOperationRequest { + token: string; + sendProductRequest: SendProductRequest; +} + +export interface SendReactionOperationRequest { + token: string; + sendReactionRequest?: (SendReactionRequest) | undefined; +} + +export interface SendStickerOperationRequest { + token: string; + sendStickerRequest: SendStickerRequest; +} + +/** + * MessagingApi - interface + * + * @export + * @interface MessagingApiInterface + */ +export interface MessagingApiInterface { + /** + * Creates request options for createReadMessage without sending the request + * @param {string} token JWT token or API key for authorization + * @param {string} [messageId] + * @param {string} [msgId] + * @param {boolean} [typingIndicator] Show WhatsApp typing indicator (max 25s or until reply) + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + createReadMessageRequestOpts(requestParameters: CreateReadMessageRequest): Promise; + + /** + * + * @summary Mark message as read + * @param {string} token JWT token or API key for authorization + * @param {string} [messageId] + * @param {string} [msgId] + * @param {boolean} [typingIndicator] Show WhatsApp typing indicator (max 25s or until reply) + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + createReadMessageRaw(requestParameters: CreateReadMessageRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Mark message as read + */ + createReadMessage(token: string, messageId?: string, msgId?: string, typingIndicator?: boolean, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for createUploadMedia without sending the request + * @param {string} token JWT token or API key for authorization + * @param {CreateUploadMediaRequest} createUploadMediaRequest + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + createUploadMediaRequestOpts(requestParameters: CreateUploadMediaOperationRequest): Promise; + + /** + * Upload a file to WhatsApp media storage and get a numeric `mediaId` for later use with `send_file` / `send_sticker` (`mediaId` field, not `body`). Pass the file as `body` **or** `url` — an HTTP(S) URL or a base64 data URI. The `mediaId` in the response is a numeric string (keep it as a string). + * @summary Upload media + * @param {string} token JWT token or API key for authorization + * @param {CreateUploadMediaRequest} createUploadMediaRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + createUploadMediaRaw(requestParameters: CreateUploadMediaOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Upload a file to WhatsApp media storage and get a numeric `mediaId` for later use with `send_file` / `send_sticker` (`mediaId` field, not `body`). Pass the file as `body` **or** `url` — an HTTP(S) URL or a base64 data URI. The `mediaId` in the response is a numeric string (keep it as a string). + * Upload media + */ + createUploadMedia(token: string, createUploadMediaRequest: CreateUploadMediaRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for deleteMedia without sending the request + * @param {string} token JWT token or API key for authorization + * @param {string} mediaId Numeric WABA media id + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + deleteMediaRequestOpts(requestParameters: DeleteMediaRequest): Promise; + + /** + * Delete previously uploaded media by numeric `mediaId` (from `/uploadMedia`). This is the canonical deletion endpoint and uses the REST `DELETE` verb on the media resource path. The older `POST /deleteMedia` is a deprecated alias. + * @summary Delete media from WABA storage + * @param {string} token JWT token or API key for authorization + * @param {string} mediaId Numeric WABA media id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + deleteMediaRaw(requestParameters: DeleteMediaRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Delete previously uploaded media by numeric `mediaId` (from `/uploadMedia`). This is the canonical deletion endpoint and uses the REST `DELETE` verb on the media resource path. The older `POST /deleteMedia` is a deprecated alias. + * Delete media from WABA storage + */ + deleteMedia(token: string, mediaId: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for deleteMediaLegacy without sending the request + * @param {string} token JWT token or API key for authorization + * @param {DeleteMediaLegacyRequest} deleteMediaLegacyRequest + * @deprecated + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + deleteMediaLegacyRequestOpts(requestParameters: DeleteMediaLegacyOperationRequest): Promise; + + /** + * **Deprecated.** Use `DELETE /media/{mediaId}` instead. This POST alias is kept for backward compatibility with earlier integrations. New integrations should call `DELETE /media/{mediaId}`: 1msg follows REST conventions for resource deletion going forward (delete a resource with the `DELETE` verb on its resource path). + * @summary Delete media from WABA storage (deprecated alias) + * @param {string} token JWT token or API key for authorization + * @param {DeleteMediaLegacyRequest} deleteMediaLegacyRequest + * @param {*} [options] Override http request option. + * @deprecated + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + deleteMediaLegacyRaw(requestParameters: DeleteMediaLegacyOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * **Deprecated.** Use `DELETE /media/{mediaId}` instead. This POST alias is kept for backward compatibility with earlier integrations. New integrations should call `DELETE /media/{mediaId}`: 1msg follows REST conventions for resource deletion going forward (delete a resource with the `DELETE` verb on its resource path). + * Delete media from WABA storage (deprecated alias) + * @deprecated + */ + deleteMediaLegacy(token: string, deleteMediaLegacyRequest: DeleteMediaLegacyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for getMmLiteStatus without sending the request + * @param {string} token JWT token or API key for authorization + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + getMmLiteStatusRequestOpts(requestParameters: GetMmLiteStatusRequest): Promise; + + /** + * + * @summary Get MM Lite availability and status + * @param {string} token JWT token or API key for authorization + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + getMmLiteStatusRaw(requestParameters: GetMmLiteStatusRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Get MM Lite availability and status + */ + getMmLiteStatus(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for listMessages without sending the request + * @param {string} token JWT token or API key for authorization + * @param {string} [chatId] Filter messages for one chat (`phone@c.us`, group `@g.us`, or BSUID `@lid`) + * @param {number} [limit] Max rows to return (default 100) + * @param {boolean} [last] If true, return the latest messages (DESC). Default false. + * @param {number} [lastMessageNumber] + * @param {number} [firstMessageNumber] + * @param {number} [minTime] Unix timestamp lower bound + * @param {number} [maxTime] Unix timestamp upper bound + * @param {string} [msgId] Filter by stored message id + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + listMessagesRequestOpts(requestParameters: ListMessagesRequest): Promise; + + /** + * List stored chat history for this channel (requires history storage). Filter with `chatId`, `limit`, `last`, message numbers, or time bounds. + * @summary Get messages list + * @param {string} token JWT token or API key for authorization + * @param {string} [chatId] Filter messages for one chat (`phone@c.us`, group `@g.us`, or BSUID `@lid`) + * @param {number} [limit] Max rows to return (default 100) + * @param {boolean} [last] If true, return the latest messages (DESC). Default false. + * @param {number} [lastMessageNumber] + * @param {number} [firstMessageNumber] + * @param {number} [minTime] Unix timestamp lower bound + * @param {number} [maxTime] Unix timestamp upper bound + * @param {string} [msgId] Filter by stored message id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + listMessagesRaw(requestParameters: ListMessagesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * List stored chat history for this channel (requires history storage). Filter with `chatId`, `limit`, `last`, message numbers, or time bounds. + * Get messages list + */ + listMessages(token: string, chatId?: string, limit?: number, last?: boolean, lastMessageNumber?: number, firstMessageNumber?: number, minTime?: number, maxTime?: number, msgId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for retrieveMedia without sending the request + * @param {string} token JWT token or API key for authorization + * @param {string} mediaId + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + retrieveMediaRequestOpts(requestParameters: RetrieveMediaRequest): Promise; + + /** + * Get WABA media URL and metadata by mediaId (from uploadMedia). The returned `url` is temporary and typically expires within ~5 minutes. + * @summary Retrieve uploaded media metadata + * @param {string} token JWT token or API key for authorization + * @param {string} mediaId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + retrieveMediaRaw(requestParameters: RetrieveMediaRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Get WABA media URL and metadata by mediaId (from uploadMedia). The returned `url` is temporary and typically expires within ~5 minutes. + * Retrieve uploaded media metadata + */ + retrieveMedia(token: string, mediaId: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for sendAddressMessage without sending the request + * @param {string} token JWT token or API key for authorization + * @param {SendAddressMessageRequest} sendAddressMessageRequest + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendAddressMessageRequestOpts(requestParameters: SendAddressMessageOperationRequest): Promise; + + /** + * Request shipping address from the user (WhatsApp interactive `address_message`). **India and Singapore only.** Requires: - Business WhatsApp number registered in that country - Recipient phone matching the country (`+91` ↔ `IN`, `+65` ↔ `SG`) Pass `country: \"IN\"` or `country: \"SG\"`. Eligibility is validated upstream; mismatches (e.g. Singapore phone with `country: \"IN\"`) return errors such as `Unsupported Interactive Message type` (HTTP 200 with `sent: false`). Optional action parameters: `values`, `saved_addresses`, `validation_errors`. + * @summary Send address request message + * @param {string} token JWT token or API key for authorization + * @param {SendAddressMessageRequest} sendAddressMessageRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendAddressMessageRaw(requestParameters: SendAddressMessageOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Request shipping address from the user (WhatsApp interactive `address_message`). **India and Singapore only.** Requires: - Business WhatsApp number registered in that country - Recipient phone matching the country (`+91` ↔ `IN`, `+65` ↔ `SG`) Pass `country: \"IN\"` or `country: \"SG\"`. Eligibility is validated upstream; mismatches (e.g. Singapore phone with `country: \"IN\"`) return errors such as `Unsupported Interactive Message type` (HTTP 200 with `sent: false`). Optional action parameters: `values`, `saved_addresses`, `validation_errors`. + * Send address request message + */ + sendAddressMessage(token: string, sendAddressMessageRequest: SendAddressMessageRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for sendButton without sending the request + * @param {string} token JWT token or API key for authorization + * @param {SendButtonRequest} [sendButtonRequest] + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendButtonRequestOpts(requestParameters: SendButtonOperationRequest): Promise; + + /** + * + * @summary Send Reply Buttons Message + * @param {string} token JWT token or API key for authorization + * @param {SendButtonRequest} [sendButtonRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendButtonRaw(requestParameters: SendButtonOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Send Reply Buttons Message + */ + sendButton(token: string, sendButtonRequest?: SendButtonRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for sendCarousel without sending the request + * @param {string} token JWT token or API key for authorization + * @param {string} [body] Text shown above the carousel. Optional. If omitted and params include a body component, the body will be taken from params. + * @param {Array<{ [key: string]: any; }>} [cards] Preferred. 2–10 carousel cards (header + body + CTA or quick replies). + * @param {Array} [params] Required. Template-like structure (same as sendTemplate params). Must include a CAROUSEL component and its cards. Structure: - params[] item with type CAROUSEL and cards (2..10) - cards[] item: - components[] items: - header: parameters[0] with type image/video/product - image: {\\\"image\\\": {\\\"link\\\": \\\"https://...\\\"}} - video: {\\\"video\\\": {\\\"link\\\": \\\"https://...\\\"}} - product: {\\\"product\\\": {\\\"catalog_id\\\": \\\"...\\\", \\\"product_retailer_id\\\": \\\"...\\\"}} - button: sub_type url or quick_reply - url: parameters {\\\"text\\\": \\\"Button\\\", \\\"url\\\": \\\"https://...\\\"} - quick_reply: parameters[] of {\\\"id\\\": \\\"...\\\", \\\"text\\\": \\\"...\\\"} + * @param {string} [quotedMsgId] Quoted message ID (Cloud API) + * @param {string} [chatId] Required if phone is not set. Chat ID from the message list. Examples: 12020721369@c.us or 120363046942338209@g.us(group) + * @param {number} [phone] Required if chatId is not set. A phone number starting with the country code. USA example: 12020721369. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendCarouselRequestOpts(requestParameters: SendCarouselRequest): Promise; + + /** + * You can send product cards via Carousel in two ways: Template messages: do not require a 24-hour customer service window between you and the recipient. Use sendTemplate. Free-form messages: can be sent only when a customer service window is open between you and the recipient. Use sendCarousel. The message structure in /sendCarousel is largely similar to sending a template. However, in this case you must explicitly specify all elements that are created in advance when working with templates. This is because the message is sent without using a template. In /sendCarousel, for a Catalog Carousel there can be either 1 URL button or one or more quick reply buttons. Prefer the simple `cards` array (2–10 cards). Each card needs a header media/product plus a CTA URL or quick-reply buttons. Example: ```json { \"phone\": \"79001234567\", \"body\": \"Pick a product\", \"cards\": [ { \"header\": { \"type\": \"image\", \"image\": { \"link\": \"https://example.com/1.jpg\" } }, \"body\": { \"text\": \"Card one\" }, \"type\": \"cta_url\", \"action\": { \"name\": \"cta_url\", \"parameters\": { \"url\": \"https://example.com/p1\", \"display_text\": \"Open\" } } }, { \"header\": { \"type\": \"image\", \"image\": { \"link\": \"https://example.com/2.jpg\" } }, \"body\": { \"text\": \"Card two\" }, \"type\": \"cta_url\", \"action\": { \"name\": \"cta_url\", \"parameters\": { \"url\": \"https://example.com/p2\", \"display_text\": \"Open\" } } } ] } ``` `params` with a `CAROUSEL` component is the template-like alternative. + * @summary Send Carousel + * @param {string} token JWT token or API key for authorization + * @param {string} [body] Text shown above the carousel. Optional. If omitted and params include a body component, the body will be taken from params. + * @param {Array<{ [key: string]: any; }>} [cards] Preferred. 2–10 carousel cards (header + body + CTA or quick replies). + * @param {Array} [params] Required. Template-like structure (same as sendTemplate params). Must include a CAROUSEL component and its cards. Structure: - params[] item with type CAROUSEL and cards (2..10) - cards[] item: - components[] items: - header: parameters[0] with type image/video/product - image: {\\\"image\\\": {\\\"link\\\": \\\"https://...\\\"}} - video: {\\\"video\\\": {\\\"link\\\": \\\"https://...\\\"}} - product: {\\\"product\\\": {\\\"catalog_id\\\": \\\"...\\\", \\\"product_retailer_id\\\": \\\"...\\\"}} - button: sub_type url or quick_reply - url: parameters {\\\"text\\\": \\\"Button\\\", \\\"url\\\": \\\"https://...\\\"} - quick_reply: parameters[] of {\\\"id\\\": \\\"...\\\", \\\"text\\\": \\\"...\\\"} + * @param {string} [quotedMsgId] Quoted message ID (Cloud API) + * @param {string} [chatId] Required if phone is not set. Chat ID from the message list. Examples: 12020721369@c.us or 120363046942338209@g.us(group) + * @param {number} [phone] Required if chatId is not set. A phone number starting with the country code. USA example: 12020721369. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendCarouselRaw(requestParameters: SendCarouselRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * You can send product cards via Carousel in two ways: Template messages: do not require a 24-hour customer service window between you and the recipient. Use sendTemplate. Free-form messages: can be sent only when a customer service window is open between you and the recipient. Use sendCarousel. The message structure in /sendCarousel is largely similar to sending a template. However, in this case you must explicitly specify all elements that are created in advance when working with templates. This is because the message is sent without using a template. In /sendCarousel, for a Catalog Carousel there can be either 1 URL button or one or more quick reply buttons. Prefer the simple `cards` array (2–10 cards). Each card needs a header media/product plus a CTA URL or quick-reply buttons. Example: ```json { \"phone\": \"79001234567\", \"body\": \"Pick a product\", \"cards\": [ { \"header\": { \"type\": \"image\", \"image\": { \"link\": \"https://example.com/1.jpg\" } }, \"body\": { \"text\": \"Card one\" }, \"type\": \"cta_url\", \"action\": { \"name\": \"cta_url\", \"parameters\": { \"url\": \"https://example.com/p1\", \"display_text\": \"Open\" } } }, { \"header\": { \"type\": \"image\", \"image\": { \"link\": \"https://example.com/2.jpg\" } }, \"body\": { \"text\": \"Card two\" }, \"type\": \"cta_url\", \"action\": { \"name\": \"cta_url\", \"parameters\": { \"url\": \"https://example.com/p2\", \"display_text\": \"Open\" } } } ] } ``` `params` with a `CAROUSEL` component is the template-like alternative. + * Send Carousel + */ + sendCarousel(token: string, body?: string, cards?: Array<{ [key: string]: any; }>, params?: Array, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for sendContact without sending the request + * @param {string} token JWT token or API key for authorization + * @param {SendContactRequest} [sendContactRequest] + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendContactRequestOpts(requestParameters: SendContactOperationRequest): Promise; + + /** + * Send a WhatsApp contact card. Preferred simple body (legacy-compatible): ```json { \"phone\": \"79001234567\", \"contact\": { \"name\": \"Lida\", \"phone\": \"+79181976551\" } } ``` Cloud API shape also works: `contacts` is an array of objects with `name.formatted_name` and `phones[].phone` (E.164 string, **not** a timestamp). + * @summary Send a Contact + * @param {string} token JWT token or API key for authorization + * @param {SendContactRequest} [sendContactRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendContactRaw(requestParameters: SendContactOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Send a WhatsApp contact card. Preferred simple body (legacy-compatible): ```json { \"phone\": \"79001234567\", \"contact\": { \"name\": \"Lida\", \"phone\": \"+79181976551\" } } ``` Cloud API shape also works: `contacts` is an array of objects with `name.formatted_name` and `phones[].phone` (E.164 string, **not** a timestamp). + * Send a Contact + */ + sendContact(token: string, sendContactRequest?: SendContactRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for sendCtaUrl without sending the request + * @param {string} token JWT token or API key for authorization + * @param {SendCtaUrlRequest} sendCtaUrlRequest + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendCtaUrlRequestOpts(requestParameters: SendCtaUrlOperationRequest): Promise; + + /** + * Send an interactive message with a single call-to-action URL button. + * @summary Send CTA URL interactive message + * @param {string} token JWT token or API key for authorization + * @param {SendCtaUrlRequest} sendCtaUrlRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendCtaUrlRaw(requestParameters: SendCtaUrlOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Send an interactive message with a single call-to-action URL button. + * Send CTA URL interactive message + */ + sendCtaUrl(token: string, sendCtaUrlRequest: SendCtaUrlRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for sendFile without sending the request + * @param {string} token JWT token or API key for authorization + * @param {string} [body] File source (required unless mediaId is set): - HTTP/HTTPS URL - Base64 data URI + * @param {string} [filename] File name with extension (required with body, not with mediaId) + * @param {string} [mediaId] WABA media id from uploadMedia (alternative to body) + * @param {string} [mediaType] Required when using mediaId + * @param {boolean} [voice] Native WhatsApp voice note (audio/ogg only) + * @param {string} [caption] + * @param {string} [quotedMsgId] + * @param {string} [chatId] + * @param {number} [phone] + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendFileRequestOpts(requestParameters: SendFileRequest): Promise; + + /** + * Send a file to an existing chat. (Only if the dialogue has an Open Session). Only one of two parameters is needed to determine the destination - chatId or phone. + * @summary Send a File + * @param {string} token JWT token or API key for authorization + * @param {string} [body] File source (required unless mediaId is set): - HTTP/HTTPS URL - Base64 data URI + * @param {string} [filename] File name with extension (required with body, not with mediaId) + * @param {string} [mediaId] WABA media id from uploadMedia (alternative to body) + * @param {string} [mediaType] Required when using mediaId + * @param {boolean} [voice] Native WhatsApp voice note (audio/ogg only) + * @param {string} [caption] + * @param {string} [quotedMsgId] + * @param {string} [chatId] + * @param {number} [phone] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendFileRaw(requestParameters: SendFileRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Send a file to an existing chat. (Only if the dialogue has an Open Session). Only one of two parameters is needed to determine the destination - chatId or phone. + * Send a File + */ + sendFile(token: string, body?: string, filename?: string, mediaId?: string, mediaType?: SendFileMediaTypeEnum, voice?: boolean, caption?: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for sendFlow without sending the request + * @param {string} token JWT token or API key for authorization + * @param {string} body Flow message body text + * @param {string} flowId Published Flow ID + * @param {string} flowToken Flow token generated by the business + * @param {string} flowCta CTA button text + * @param {SendFlowRequestHeader} [header] + * @param {string} [footer] Footer text + * @param {string} [flowAction] Flow action type + * @param {object} [flowActionPayload] Required for flowAction=navigate (screen is required). Ignored for data_exchange. If data is provided, it must be a non-empty object. + * @param {string} [flowMessageVersion] Flow message version (default \\\"3\\\") + * @param {string} [mode] Flow mode (draft or published). If omitted, provider default applies + * @param {object} [flowActionData] Shortcut for flowActionPayload.data (optional) + * @param {string} [flowActionScreen] Shortcut for flowActionPayload.screen (optional) + * @param {string} [quotedMsgId] Quoted message ID (Cloud API) + * @param {string} [chatId] Required if phone is not set. Chat ID from the message list. Examples: 12020721369@c.us or 120363046942338209@g.us(group) + * @param {number} [phone] Required if chatId is not set. A phone number starting with the country code. USA example: 12020721369. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendFlowRequestOpts(requestParameters: SendFlowRequest): Promise; + + /** + * Send Interactive WhatsApp Flow message to an existing chat. (Only if the dialogue has an Open Session). Only one of two parameters is needed to determine the destination - chatId or phone. Use this method to send a published WhatsApp Flow as a service (interactive) message. If the 24-hour window is closed, send a template with a FLOW button via /sendTemplate. + * @summary Send WhatsApp Flow Message + * @param {string} token JWT token or API key for authorization + * @param {string} body Flow message body text + * @param {string} flowId Published Flow ID + * @param {string} flowToken Flow token generated by the business + * @param {string} flowCta CTA button text + * @param {SendFlowRequestHeader} [header] + * @param {string} [footer] Footer text + * @param {string} [flowAction] Flow action type + * @param {object} [flowActionPayload] Required for flowAction=navigate (screen is required). Ignored for data_exchange. If data is provided, it must be a non-empty object. + * @param {string} [flowMessageVersion] Flow message version (default \\\"3\\\") + * @param {string} [mode] Flow mode (draft or published). If omitted, provider default applies + * @param {object} [flowActionData] Shortcut for flowActionPayload.data (optional) + * @param {string} [flowActionScreen] Shortcut for flowActionPayload.screen (optional) + * @param {string} [quotedMsgId] Quoted message ID (Cloud API) + * @param {string} [chatId] Required if phone is not set. Chat ID from the message list. Examples: 12020721369@c.us or 120363046942338209@g.us(group) + * @param {number} [phone] Required if chatId is not set. A phone number starting with the country code. USA example: 12020721369. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendFlowRaw(requestParameters: SendFlowRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Send Interactive WhatsApp Flow message to an existing chat. (Only if the dialogue has an Open Session). Only one of two parameters is needed to determine the destination - chatId or phone. Use this method to send a published WhatsApp Flow as a service (interactive) message. If the 24-hour window is closed, send a template with a FLOW button via /sendTemplate. + * Send WhatsApp Flow Message + */ + sendFlow(token: string, body: string, flowId: string, flowToken: string, flowCta: string, header?: SendFlowRequestHeader, footer?: string, flowAction?: SendFlowFlowActionEnum, flowActionPayload?: object, flowMessageVersion?: string, mode?: SendFlowModeEnum, flowActionData?: object, flowActionScreen?: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for sendList without sending the request + * @param {string} token JWT token or API key for authorization + * @param {SendListRequest} [sendListRequest] + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendListRequestOpts(requestParameters: SendListOperationRequest): Promise; + + /** + * + * @summary Send List Message + * @param {string} token JWT token or API key for authorization + * @param {SendListRequest} [sendListRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendListRaw(requestParameters: SendListOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Send List Message + */ + sendList(token: string, sendListRequest?: SendListRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for sendLocation without sending the request + * @param {string} token JWT token or API key for authorization + * @param {string} lat Latitude of the location. Example: 45.018337 + * @param {string} lng Longitude of the location. Example: -73.968285 + * @param {string} [address] Address of the location. Only displayed if name is present. Example: 9766 Valley View St., New York, NY 10024 + * @param {string} [name] Name of the location. Example: Facebook HQ + * @param {string} [quotedMsgId] Quoted message ID (Cloud API) + * @param {string} [chatId] Required if phone is not set. Chat ID from the message list. Examples: 12020721369@c.us or 120363046942338209@g.us(group) + * @param {number} [phone] Required if chatId is not set. A phone number starting with the country code. USA example: 12020721369. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendLocationRequestOpts(requestParameters: SendLocationRequest): Promise; + + /** + * Send a location to an existing chat. (Only if the dialogue has an Open Session). Only one of two parameters is needed to determine the destination - chatId or phone. + * @summary Send a Location + * @param {string} token JWT token or API key for authorization + * @param {string} lat Latitude of the location. Example: 45.018337 + * @param {string} lng Longitude of the location. Example: -73.968285 + * @param {string} [address] Address of the location. Only displayed if name is present. Example: 9766 Valley View St., New York, NY 10024 + * @param {string} [name] Name of the location. Example: Facebook HQ + * @param {string} [quotedMsgId] Quoted message ID (Cloud API) + * @param {string} [chatId] Required if phone is not set. Chat ID from the message list. Examples: 12020721369@c.us or 120363046942338209@g.us(group) + * @param {number} [phone] Required if chatId is not set. A phone number starting with the country code. USA example: 12020721369. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendLocationRaw(requestParameters: SendLocationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Send a location to an existing chat. (Only if the dialogue has an Open Session). Only one of two parameters is needed to determine the destination - chatId or phone. + * Send a Location + */ + sendLocation(token: string, lat: string, lng: string, address?: string, name?: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for sendLocationRequest without sending the request + * @param {string} token JWT token or API key for authorization + * @param {SendLocationRequestRequest} [sendLocationRequestRequest] + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendLocationRequestRequestOpts(requestParameters: SendLocationRequestOperationRequest): Promise; + + /** + * + * @summary Send Location Request Message + * @param {string} token JWT token or API key for authorization + * @param {SendLocationRequestRequest} [sendLocationRequestRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendLocationRequestRaw(requestParameters: SendLocationRequestOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Send Location Request Message + */ + sendLocationRequest(token: string, sendLocationRequestRequest?: SendLocationRequestRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for sendMessage without sending the request + * @param {string} token JWT token or API key for authorization + * @param {string} body Message text, UTF-8 or UTF-16 string with emoji + * @param {string} [quotedMsgId] Message ID to quote/reply to (Cloud API wamid) + * @param {string} [chatId] Recipient chat ID: phone@c.us, group@g.us, or BSUID@lid + * @param {number} [phone] Phone number starting with country code (alternative to chatId) + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendMessageRequestOpts(requestParameters: SendMessageRequest): Promise; + + /** + * Send a message to an existing chat. (Only if the dialogue has an Open Session). The message will be added to the queue for sending and delivered even if the phone is disconnected from the Internet or authorization is not passed. Only one of two parameters is needed to determine the destination - chatId or phone. + * @summary Send a Message + * @param {string} token JWT token or API key for authorization + * @param {string} body Message text, UTF-8 or UTF-16 string with emoji + * @param {string} [quotedMsgId] Message ID to quote/reply to (Cloud API wamid) + * @param {string} [chatId] Recipient chat ID: phone@c.us, group@g.us, or BSUID@lid + * @param {number} [phone] Phone number starting with country code (alternative to chatId) + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendMessageRaw(requestParameters: SendMessageRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Send a message to an existing chat. (Only if the dialogue has an Open Session). The message will be added to the queue for sending and delivered even if the phone is disconnected from the Internet or authorization is not passed. Only one of two parameters is needed to determine the destination - chatId or phone. + * Send a Message + */ + sendMessage(token: string, body: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for sendOrderDetails without sending the request + * @param {string} token JWT token or API key for authorization + * @param {SendOrderDetailsRequest} sendOrderDetailsRequest + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendOrderDetailsRequestOpts(requestParameters: SendOrderDetailsOperationRequest): Promise; + + /** + * Send a WhatsApp **order details** payment / invoice message using a pre-approved **Utility** template that has an `ORDER_DETAILS` button. **India only** (WhatsApp Payments India). Requires: - India WhatsApp Business number - Commerce enabled on the channel (`GET`/`POST /commerce`) - Approved template with an `ORDER_DETAILS` button Use this method when you need structured fields (`order`, `referenceId`, `currency`, `paymentSettings`). The API appends a template button `sub_type: order_details` and sends via the same path as `POST /sendTemplate`. Works **outside the 24-hour session window** (template message). You can also send the same payload yourself with `POST /sendTemplate` by including a button component in `params`: ```json { \"type\": \"button\", \"sub_type\": \"order_details\", \"index\": 0, \"parameters\": [{ \"type\": \"action\", \"action\": { \"order_details\": { \"reference_id\": \"order-123\", \"currency\": \"INR\", \"order\": { \"status\": \"pending\", \"items\": [], \"subtotal\": { \"offset\": 100, \"value\": 50000 } } } } }] } ``` + * @summary Send order details (India payments template) + * @param {string} token JWT token or API key for authorization + * @param {SendOrderDetailsRequest} sendOrderDetailsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendOrderDetailsRaw(requestParameters: SendOrderDetailsOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Send a WhatsApp **order details** payment / invoice message using a pre-approved **Utility** template that has an `ORDER_DETAILS` button. **India only** (WhatsApp Payments India). Requires: - India WhatsApp Business number - Commerce enabled on the channel (`GET`/`POST /commerce`) - Approved template with an `ORDER_DETAILS` button Use this method when you need structured fields (`order`, `referenceId`, `currency`, `paymentSettings`). The API appends a template button `sub_type: order_details` and sends via the same path as `POST /sendTemplate`. Works **outside the 24-hour session window** (template message). You can also send the same payload yourself with `POST /sendTemplate` by including a button component in `params`: ```json { \"type\": \"button\", \"sub_type\": \"order_details\", \"index\": 0, \"parameters\": [{ \"type\": \"action\", \"action\": { \"order_details\": { \"reference_id\": \"order-123\", \"currency\": \"INR\", \"order\": { \"status\": \"pending\", \"items\": [], \"subtotal\": { \"offset\": 100, \"value\": 50000 } } } } }] } ``` + * Send order details (India payments template) + */ + sendOrderDetails(token: string, sendOrderDetailsRequest: SendOrderDetailsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for sendPaymentRequest without sending the request + * @param {string} token JWT token or API key for authorization + * @param {SendPaymentRequestRequest} sendPaymentRequestRequest + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendPaymentRequestRequestOpts(requestParameters: SendPaymentRequestOperationRequest): Promise; + + /** + * Send a regional payment request interactive message (beta scaffold). `region` must be IN, SG, or BR. Payload shape follows Meta regional payments docs; verify on stage before production use. Full regional builders are not implemented yet. + * @summary Send payment request (regional) + * @param {string} token JWT token or API key for authorization + * @param {SendPaymentRequestRequest} sendPaymentRequestRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendPaymentRequestRaw(requestParameters: SendPaymentRequestOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Send a regional payment request interactive message (beta scaffold). `region` must be IN, SG, or BR. Payload shape follows Meta regional payments docs; verify on stage before production use. Full regional builders are not implemented yet. + * Send payment request (regional) + */ + sendPaymentRequest(token: string, sendPaymentRequestRequest: SendPaymentRequestRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for sendProduct without sending the request + * @param {string} token JWT token or API key for authorization + * @param {SendProductRequest} sendProductRequest + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendProductRequestOpts(requestParameters: SendProductOperationRequest): Promise; + + /** + * Send a single catalog product or a product list. Destination is `chatId` or `phone`. `action` is required: - single product: `{ \"catalog_id\": \"...\", \"product_retailer_id\": \"...\" }` - product list: `{ \"catalog_id\": \"...\", \"sections\": [{ \"title\": \"...\", \"product_items\": [{ \"product_retailer_id\": \"...\" }] }] }` + * @summary Send a Product + * @param {string} token JWT token or API key for authorization + * @param {SendProductRequest} sendProductRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendProductRaw(requestParameters: SendProductOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Send a single catalog product or a product list. Destination is `chatId` or `phone`. `action` is required: - single product: `{ \"catalog_id\": \"...\", \"product_retailer_id\": \"...\" }` - product list: `{ \"catalog_id\": \"...\", \"sections\": [{ \"title\": \"...\", \"product_items\": [{ \"product_retailer_id\": \"...\" }] }] }` + * Send a Product + */ + sendProduct(token: string, sendProductRequest: SendProductRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for sendReaction without sending the request + * @param {string} token JWT token or API key for authorization + * @param {SendReactionRequest} [sendReactionRequest] + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendReactionRequestOpts(requestParameters: SendReactionOperationRequest): Promise; + + /** + * + * @summary Send Reaction + * @param {string} token JWT token or API key for authorization + * @param {SendReactionRequest} [sendReactionRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendReactionRaw(requestParameters: SendReactionOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Send Reaction + */ + sendReaction(token: string, sendReactionRequest?: SendReactionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for sendSticker without sending the request + * @param {string} token JWT token or API key for authorization + * @param {SendStickerRequest} sendStickerRequest + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendStickerRequestOpts(requestParameters: SendStickerOperationRequest): Promise; + + /** + * Send a WhatsApp sticker by mediaId or link URL. + * @summary Send sticker message + * @param {string} token JWT token or API key for authorization + * @param {SendStickerRequest} sendStickerRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof MessagingApiInterface + */ + sendStickerRaw(requestParameters: SendStickerOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Send a WhatsApp sticker by mediaId or link URL. + * Send sticker message + */ + sendSticker(token: string, sendStickerRequest: SendStickerRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + +} + +/** + * + */ +export class MessagingApi extends runtime.BaseAPI implements MessagingApiInterface { + + /** + * Creates request options for createReadMessage without sending the request + */ + async createReadMessageRequestOpts(requestParameters: CreateReadMessageRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling createReadMessage().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + const consumes: runtime.Consume[] = [ + { contentType: 'application/x-www-form-urlencoded' }, + { contentType: 'application/json' }, + ]; + // @ts-ignore: canConsumeForm may be unused + const canConsumeForm = runtime.canConsumeForm(consumes); + + let formParams: { append(param: string, value: any): any }; + let useForm = false; + if (useForm) { + formParams = new FormData(); + } else { + formParams = new URLSearchParams(); + } + + if (requestParameters['messageId'] != null) { + formParams.append('messageId', requestParameters['messageId'] as any); + } + + if (requestParameters['msgId'] != null) { + formParams.append('msgId', requestParameters['msgId'] as any); + } + + if (requestParameters['typingIndicator'] != null) { + formParams.append('typingIndicator', requestParameters['typingIndicator'] as any); + } + + + let urlPath = `/readMessage`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: formParams, + }; + } + + /** + * Mark message as read + */ + async createReadMessageRaw(requestParameters: CreateReadMessageRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.createReadMessageRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CreateReadMessage200ResponseFromJSON(jsonValue)); + } + + /** + * Mark message as read + */ + async createReadMessage(token: string, messageId?: string, msgId?: string, typingIndicator?: boolean, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createReadMessageRaw({ token: token, messageId: messageId, msgId: msgId, typingIndicator: typingIndicator }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for createUploadMedia without sending the request + */ + async createUploadMediaRequestOpts(requestParameters: CreateUploadMediaOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling createUploadMedia().' + ); + } + + if (requestParameters['createUploadMediaRequest'] == null) { + throw new runtime.RequiredError( + 'createUploadMediaRequest', + 'Required parameter "createUploadMediaRequest" was null or undefined when calling createUploadMedia().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/uploadMedia`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: CreateUploadMediaRequestToJSON(requestParameters['createUploadMediaRequest']), + }; + } + + /** + * Upload a file to WhatsApp media storage and get a numeric `mediaId` for later use with `send_file` / `send_sticker` (`mediaId` field, not `body`). Pass the file as `body` **or** `url` — an HTTP(S) URL or a base64 data URI. The `mediaId` in the response is a numeric string (keep it as a string). + * Upload media + */ + async createUploadMediaRaw(requestParameters: CreateUploadMediaOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.createUploadMediaRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CreateUploadMedia200ResponseFromJSON(jsonValue)); + } + + /** + * Upload a file to WhatsApp media storage and get a numeric `mediaId` for later use with `send_file` / `send_sticker` (`mediaId` field, not `body`). Pass the file as `body` **or** `url` — an HTTP(S) URL or a base64 data URI. The `mediaId` in the response is a numeric string (keep it as a string). + * Upload media + */ + async createUploadMedia(token: string, createUploadMediaRequest: CreateUploadMediaRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createUploadMediaRaw({ token: token, createUploadMediaRequest: createUploadMediaRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for deleteMedia without sending the request + */ + async deleteMediaRequestOpts(requestParameters: DeleteMediaRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling deleteMedia().' + ); + } + + if (requestParameters['mediaId'] == null) { + throw new runtime.RequiredError( + 'mediaId', + 'Required parameter "mediaId" was null or undefined when calling deleteMedia().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/media/{mediaId}`; + urlPath = urlPath.replace('{mediaId}', encodeURIComponent(String(requestParameters['mediaId']))); + + return { + path: urlPath, + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Delete previously uploaded media by numeric `mediaId` (from `/uploadMedia`). This is the canonical deletion endpoint and uses the REST `DELETE` verb on the media resource path. The older `POST /deleteMedia` is a deprecated alias. + * Delete media from WABA storage + */ + async deleteMediaRaw(requestParameters: DeleteMediaRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.deleteMediaRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => SuccessResponseFromJSON(jsonValue)); + } + + /** + * Delete previously uploaded media by numeric `mediaId` (from `/uploadMedia`). This is the canonical deletion endpoint and uses the REST `DELETE` verb on the media resource path. The older `POST /deleteMedia` is a deprecated alias. + * Delete media from WABA storage + */ + async deleteMedia(token: string, mediaId: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.deleteMediaRaw({ token: token, mediaId: mediaId }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for deleteMediaLegacy without sending the request + * @deprecated + */ + async deleteMediaLegacyRequestOpts(requestParameters: DeleteMediaLegacyOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling deleteMediaLegacy().' + ); + } + + if (requestParameters['deleteMediaLegacyRequest'] == null) { + throw new runtime.RequiredError( + 'deleteMediaLegacyRequest', + 'Required parameter "deleteMediaLegacyRequest" was null or undefined when calling deleteMediaLegacy().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/deleteMedia`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: DeleteMediaLegacyRequestToJSON(requestParameters['deleteMediaLegacyRequest']), + }; + } + + /** + * **Deprecated.** Use `DELETE /media/{mediaId}` instead. This POST alias is kept for backward compatibility with earlier integrations. New integrations should call `DELETE /media/{mediaId}`: 1msg follows REST conventions for resource deletion going forward (delete a resource with the `DELETE` verb on its resource path). + * Delete media from WABA storage (deprecated alias) + * @deprecated + */ + async deleteMediaLegacyRaw(requestParameters: DeleteMediaLegacyOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.deleteMediaLegacyRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => SuccessResponseFromJSON(jsonValue)); + } + + /** + * **Deprecated.** Use `DELETE /media/{mediaId}` instead. This POST alias is kept for backward compatibility with earlier integrations. New integrations should call `DELETE /media/{mediaId}`: 1msg follows REST conventions for resource deletion going forward (delete a resource with the `DELETE` verb on its resource path). + * Delete media from WABA storage (deprecated alias) + * @deprecated + */ + async deleteMediaLegacy(token: string, deleteMediaLegacyRequest: DeleteMediaLegacyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.deleteMediaLegacyRaw({ token: token, deleteMediaLegacyRequest: deleteMediaLegacyRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for getMmLiteStatus without sending the request + */ + async getMmLiteStatusRequestOpts(requestParameters: GetMmLiteStatusRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling getMmLiteStatus().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/mmLiteStatus`; + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Get MM Lite availability and status + */ + async getMmLiteStatusRaw(requestParameters: GetMmLiteStatusRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.getMmLiteStatusRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => GetMmLiteStatus200ResponseFromJSON(jsonValue)); + } + + /** + * Get MM Lite availability and status + */ + async getMmLiteStatus(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getMmLiteStatusRaw({ token: token }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for listMessages without sending the request + */ + async listMessagesRequestOpts(requestParameters: ListMessagesRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling listMessages().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + if (requestParameters['chatId'] != null) { + queryParameters['chatId'] = requestParameters['chatId']; + } + + if (requestParameters['limit'] != null) { + queryParameters['limit'] = requestParameters['limit']; + } + + if (requestParameters['last'] != null) { + queryParameters['last'] = requestParameters['last']; + } + + if (requestParameters['lastMessageNumber'] != null) { + queryParameters['lastMessageNumber'] = requestParameters['lastMessageNumber']; + } + + if (requestParameters['firstMessageNumber'] != null) { + queryParameters['firstMessageNumber'] = requestParameters['firstMessageNumber']; + } + + if (requestParameters['minTime'] != null) { + queryParameters['min_time'] = requestParameters['minTime']; + } + + if (requestParameters['maxTime'] != null) { + queryParameters['max_time'] = requestParameters['maxTime']; + } + + if (requestParameters['msgId'] != null) { + queryParameters['msgId'] = requestParameters['msgId']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/messages`; + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * List stored chat history for this channel (requires history storage). Filter with `chatId`, `limit`, `last`, message numbers, or time bounds. + * Get messages list + */ + async listMessagesRaw(requestParameters: ListMessagesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.listMessagesRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ListMessages200ResponseFromJSON(jsonValue)); + } + + /** + * List stored chat history for this channel (requires history storage). Filter with `chatId`, `limit`, `last`, message numbers, or time bounds. + * Get messages list + */ + async listMessages(token: string, chatId?: string, limit?: number, last?: boolean, lastMessageNumber?: number, firstMessageNumber?: number, minTime?: number, maxTime?: number, msgId?: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.listMessagesRaw({ token: token, chatId: chatId, limit: limit, last: last, lastMessageNumber: lastMessageNumber, firstMessageNumber: firstMessageNumber, minTime: minTime, maxTime: maxTime, msgId: msgId }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for retrieveMedia without sending the request + */ + async retrieveMediaRequestOpts(requestParameters: RetrieveMediaRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling retrieveMedia().' + ); + } + + if (requestParameters['mediaId'] == null) { + throw new runtime.RequiredError( + 'mediaId', + 'Required parameter "mediaId" was null or undefined when calling retrieveMedia().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + if (requestParameters['mediaId'] != null) { + queryParameters['mediaId'] = requestParameters['mediaId']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/retrieveMedia`; + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Get WABA media URL and metadata by mediaId (from uploadMedia). The returned `url` is temporary and typically expires within ~5 minutes. + * Retrieve uploaded media metadata + */ + async retrieveMediaRaw(requestParameters: RetrieveMediaRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.retrieveMediaRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => RetrieveMedia200ResponseFromJSON(jsonValue)); + } + + /** + * Get WABA media URL and metadata by mediaId (from uploadMedia). The returned `url` is temporary and typically expires within ~5 minutes. + * Retrieve uploaded media metadata + */ + async retrieveMedia(token: string, mediaId: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.retrieveMediaRaw({ token: token, mediaId: mediaId }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendAddressMessage without sending the request + */ + async sendAddressMessageRequestOpts(requestParameters: SendAddressMessageOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendAddressMessage().' + ); + } + + if (requestParameters['sendAddressMessageRequest'] == null) { + throw new runtime.RequiredError( + 'sendAddressMessageRequest', + 'Required parameter "sendAddressMessageRequest" was null or undefined when calling sendAddressMessage().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/sendAddressMessage`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: SendAddressMessageRequestToJSON(requestParameters['sendAddressMessageRequest']), + }; + } + + /** + * Request shipping address from the user (WhatsApp interactive `address_message`). **India and Singapore only.** Requires: - Business WhatsApp number registered in that country - Recipient phone matching the country (`+91` ↔ `IN`, `+65` ↔ `SG`) Pass `country: \"IN\"` or `country: \"SG\"`. Eligibility is validated upstream; mismatches (e.g. Singapore phone with `country: \"IN\"`) return errors such as `Unsupported Interactive Message type` (HTTP 200 with `sent: false`). Optional action parameters: `values`, `saved_addresses`, `validation_errors`. + * Send address request message + */ + async sendAddressMessageRaw(requestParameters: SendAddressMessageOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendAddressMessageRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => MessageSentResponseFromJSON(jsonValue)); + } + + /** + * Request shipping address from the user (WhatsApp interactive `address_message`). **India and Singapore only.** Requires: - Business WhatsApp number registered in that country - Recipient phone matching the country (`+91` ↔ `IN`, `+65` ↔ `SG`) Pass `country: \"IN\"` or `country: \"SG\"`. Eligibility is validated upstream; mismatches (e.g. Singapore phone with `country: \"IN\"`) return errors such as `Unsupported Interactive Message type` (HTTP 200 with `sent: false`). Optional action parameters: `values`, `saved_addresses`, `validation_errors`. + * Send address request message + */ + async sendAddressMessage(token: string, sendAddressMessageRequest: SendAddressMessageRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendAddressMessageRaw({ token: token, sendAddressMessageRequest: sendAddressMessageRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendButton without sending the request + */ + async sendButtonRequestOpts(requestParameters: SendButtonOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendButton().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/sendButton`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: SendButtonRequestToJSON(requestParameters['sendButtonRequest']), + }; + } + + /** + * Send Reply Buttons Message + */ + async sendButtonRaw(requestParameters: SendButtonOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendButtonRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => MessageSentResponseFromJSON(jsonValue)); + } + + /** + * Send Reply Buttons Message + */ + async sendButton(token: string, sendButtonRequest?: SendButtonRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendButtonRaw({ token: token, sendButtonRequest: sendButtonRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendCarousel without sending the request + */ + async sendCarouselRequestOpts(requestParameters: SendCarouselRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendCarousel().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + const consumes: runtime.Consume[] = [ + { contentType: 'application/x-www-form-urlencoded' }, + { contentType: 'application/json' }, + ]; + // @ts-ignore: canConsumeForm may be unused + const canConsumeForm = runtime.canConsumeForm(consumes); + + let formParams: { append(param: string, value: any): any }; + let useForm = false; + if (useForm) { + formParams = new FormData(); + } else { + formParams = new URLSearchParams(); + } + + if (requestParameters['body'] != null) { + formParams.append('body', requestParameters['body'] as any); + } + + if (requestParameters['cards'] != null) { + formParams.append('cards', requestParameters['cards']!.join(runtime.COLLECTION_FORMATS["csv"])); + } + + if (requestParameters['params'] != null) { + formParams.append('params', requestParameters['params']!.join(runtime.COLLECTION_FORMATS["csv"])); + } + + if (requestParameters['quotedMsgId'] != null) { + formParams.append('quotedMsgId', requestParameters['quotedMsgId'] as any); + } + + if (requestParameters['chatId'] != null) { + formParams.append('chatId', requestParameters['chatId'] as any); + } + + if (requestParameters['phone'] != null) { + formParams.append('phone', requestParameters['phone'] as any); + } + + + let urlPath = `/sendCarousel`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: formParams, + }; + } + + /** + * You can send product cards via Carousel in two ways: Template messages: do not require a 24-hour customer service window between you and the recipient. Use sendTemplate. Free-form messages: can be sent only when a customer service window is open between you and the recipient. Use sendCarousel. The message structure in /sendCarousel is largely similar to sending a template. However, in this case you must explicitly specify all elements that are created in advance when working with templates. This is because the message is sent without using a template. In /sendCarousel, for a Catalog Carousel there can be either 1 URL button or one or more quick reply buttons. Prefer the simple `cards` array (2–10 cards). Each card needs a header media/product plus a CTA URL or quick-reply buttons. Example: ```json { \"phone\": \"79001234567\", \"body\": \"Pick a product\", \"cards\": [ { \"header\": { \"type\": \"image\", \"image\": { \"link\": \"https://example.com/1.jpg\" } }, \"body\": { \"text\": \"Card one\" }, \"type\": \"cta_url\", \"action\": { \"name\": \"cta_url\", \"parameters\": { \"url\": \"https://example.com/p1\", \"display_text\": \"Open\" } } }, { \"header\": { \"type\": \"image\", \"image\": { \"link\": \"https://example.com/2.jpg\" } }, \"body\": { \"text\": \"Card two\" }, \"type\": \"cta_url\", \"action\": { \"name\": \"cta_url\", \"parameters\": { \"url\": \"https://example.com/p2\", \"display_text\": \"Open\" } } } ] } ``` `params` with a `CAROUSEL` component is the template-like alternative. + * Send Carousel + */ + async sendCarouselRaw(requestParameters: SendCarouselRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendCarouselRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => MessageSentResponseFromJSON(jsonValue)); + } + + /** + * You can send product cards via Carousel in two ways: Template messages: do not require a 24-hour customer service window between you and the recipient. Use sendTemplate. Free-form messages: can be sent only when a customer service window is open between you and the recipient. Use sendCarousel. The message structure in /sendCarousel is largely similar to sending a template. However, in this case you must explicitly specify all elements that are created in advance when working with templates. This is because the message is sent without using a template. In /sendCarousel, for a Catalog Carousel there can be either 1 URL button or one or more quick reply buttons. Prefer the simple `cards` array (2–10 cards). Each card needs a header media/product plus a CTA URL or quick-reply buttons. Example: ```json { \"phone\": \"79001234567\", \"body\": \"Pick a product\", \"cards\": [ { \"header\": { \"type\": \"image\", \"image\": { \"link\": \"https://example.com/1.jpg\" } }, \"body\": { \"text\": \"Card one\" }, \"type\": \"cta_url\", \"action\": { \"name\": \"cta_url\", \"parameters\": { \"url\": \"https://example.com/p1\", \"display_text\": \"Open\" } } }, { \"header\": { \"type\": \"image\", \"image\": { \"link\": \"https://example.com/2.jpg\" } }, \"body\": { \"text\": \"Card two\" }, \"type\": \"cta_url\", \"action\": { \"name\": \"cta_url\", \"parameters\": { \"url\": \"https://example.com/p2\", \"display_text\": \"Open\" } } } ] } ``` `params` with a `CAROUSEL` component is the template-like alternative. + * Send Carousel + */ + async sendCarousel(token: string, body?: string, cards?: Array<{ [key: string]: any; }>, params?: Array, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendCarouselRaw({ token: token, body: body, cards: cards, params: params, quotedMsgId: quotedMsgId, chatId: chatId, phone: phone }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendContact without sending the request + */ + async sendContactRequestOpts(requestParameters: SendContactOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendContact().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/sendContact`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: SendContactRequestToJSON(requestParameters['sendContactRequest']), + }; + } + + /** + * Send a WhatsApp contact card. Preferred simple body (legacy-compatible): ```json { \"phone\": \"79001234567\", \"contact\": { \"name\": \"Lida\", \"phone\": \"+79181976551\" } } ``` Cloud API shape also works: `contacts` is an array of objects with `name.formatted_name` and `phones[].phone` (E.164 string, **not** a timestamp). + * Send a Contact + */ + async sendContactRaw(requestParameters: SendContactOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendContactRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => MessageSentResponseFromJSON(jsonValue)); + } + + /** + * Send a WhatsApp contact card. Preferred simple body (legacy-compatible): ```json { \"phone\": \"79001234567\", \"contact\": { \"name\": \"Lida\", \"phone\": \"+79181976551\" } } ``` Cloud API shape also works: `contacts` is an array of objects with `name.formatted_name` and `phones[].phone` (E.164 string, **not** a timestamp). + * Send a Contact + */ + async sendContact(token: string, sendContactRequest?: SendContactRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendContactRaw({ token: token, sendContactRequest: sendContactRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendCtaUrl without sending the request + */ + async sendCtaUrlRequestOpts(requestParameters: SendCtaUrlOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendCtaUrl().' + ); + } + + if (requestParameters['sendCtaUrlRequest'] == null) { + throw new runtime.RequiredError( + 'sendCtaUrlRequest', + 'Required parameter "sendCtaUrlRequest" was null or undefined when calling sendCtaUrl().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/sendCtaUrl`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: SendCtaUrlRequestToJSON(requestParameters['sendCtaUrlRequest']), + }; + } + + /** + * Send an interactive message with a single call-to-action URL button. + * Send CTA URL interactive message + */ + async sendCtaUrlRaw(requestParameters: SendCtaUrlOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendCtaUrlRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => MessageSentResponseFromJSON(jsonValue)); + } + + /** + * Send an interactive message with a single call-to-action URL button. + * Send CTA URL interactive message + */ + async sendCtaUrl(token: string, sendCtaUrlRequest: SendCtaUrlRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendCtaUrlRaw({ token: token, sendCtaUrlRequest: sendCtaUrlRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendFile without sending the request + */ + async sendFileRequestOpts(requestParameters: SendFileRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendFile().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + const consumes: runtime.Consume[] = [ + { contentType: 'application/x-www-form-urlencoded' }, + { contentType: 'application/json' }, + ]; + // @ts-ignore: canConsumeForm may be unused + const canConsumeForm = runtime.canConsumeForm(consumes); + + let formParams: { append(param: string, value: any): any }; + let useForm = false; + if (useForm) { + formParams = new FormData(); + } else { + formParams = new URLSearchParams(); + } + + if (requestParameters['body'] != null) { + formParams.append('body', requestParameters['body'] as any); + } + + if (requestParameters['filename'] != null) { + formParams.append('filename', requestParameters['filename'] as any); + } + + if (requestParameters['mediaId'] != null) { + formParams.append('mediaId', requestParameters['mediaId'] as any); + } + + if (requestParameters['mediaType'] != null) { + formParams.append('mediaType', requestParameters['mediaType'] as any); + } + + if (requestParameters['voice'] != null) { + formParams.append('voice', requestParameters['voice'] as any); + } + + if (requestParameters['caption'] != null) { + formParams.append('caption', requestParameters['caption'] as any); + } + + if (requestParameters['quotedMsgId'] != null) { + formParams.append('quotedMsgId', requestParameters['quotedMsgId'] as any); + } + + if (requestParameters['chatId'] != null) { + formParams.append('chatId', requestParameters['chatId'] as any); + } + + if (requestParameters['phone'] != null) { + formParams.append('phone', requestParameters['phone'] as any); + } + + + let urlPath = `/sendFile`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: formParams, + }; + } + + /** + * Send a file to an existing chat. (Only if the dialogue has an Open Session). Only one of two parameters is needed to determine the destination - chatId or phone. + * Send a File + */ + async sendFileRaw(requestParameters: SendFileRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendFileRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => MessageSentResponseFromJSON(jsonValue)); + } + + /** + * Send a file to an existing chat. (Only if the dialogue has an Open Session). Only one of two parameters is needed to determine the destination - chatId or phone. + * Send a File + */ + async sendFile(token: string, body?: string, filename?: string, mediaId?: string, mediaType?: SendFileMediaTypeEnum, voice?: boolean, caption?: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendFileRaw({ token: token, body: body, filename: filename, mediaId: mediaId, mediaType: mediaType, voice: voice, caption: caption, quotedMsgId: quotedMsgId, chatId: chatId, phone: phone }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendFlow without sending the request + */ + async sendFlowRequestOpts(requestParameters: SendFlowRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendFlow().' + ); + } + + if (requestParameters['body'] == null) { + throw new runtime.RequiredError( + 'body', + 'Required parameter "body" was null or undefined when calling sendFlow().' + ); + } + + if (requestParameters['flowId'] == null) { + throw new runtime.RequiredError( + 'flowId', + 'Required parameter "flowId" was null or undefined when calling sendFlow().' + ); + } + + if (requestParameters['flowToken'] == null) { + throw new runtime.RequiredError( + 'flowToken', + 'Required parameter "flowToken" was null or undefined when calling sendFlow().' + ); + } + + if (requestParameters['flowCta'] == null) { + throw new runtime.RequiredError( + 'flowCta', + 'Required parameter "flowCta" was null or undefined when calling sendFlow().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + const consumes: runtime.Consume[] = [ + { contentType: 'application/x-www-form-urlencoded' }, + { contentType: 'application/json' }, + ]; + // @ts-ignore: canConsumeForm may be unused + const canConsumeForm = runtime.canConsumeForm(consumes); + + let formParams: { append(param: string, value: any): any }; + let useForm = false; + if (useForm) { + formParams = new FormData(); + } else { + formParams = new URLSearchParams(); + } + + if (requestParameters['body'] != null) { + formParams.append('body', requestParameters['body'] as any); + } + + if (requestParameters['header'] != null) { + formParams.append('header', new Blob([JSON.stringify(SendFlowRequestHeaderToJSON(requestParameters['header']))], { type: "application/json", })); + } + + if (requestParameters['footer'] != null) { + formParams.append('footer', requestParameters['footer'] as any); + } + + if (requestParameters['flowId'] != null) { + formParams.append('flowId', requestParameters['flowId'] as any); + } + + if (requestParameters['flowToken'] != null) { + formParams.append('flowToken', requestParameters['flowToken'] as any); + } + + if (requestParameters['flowCta'] != null) { + formParams.append('flowCta', requestParameters['flowCta'] as any); + } + + if (requestParameters['flowAction'] != null) { + formParams.append('flowAction', requestParameters['flowAction'] as any); + } + + if (requestParameters['flowActionPayload'] != null) { + formParams.append('flowActionPayload', new Blob([JSON.stringify(objectToJSON(requestParameters['flowActionPayload']))], { type: "application/json", })); + } + + if (requestParameters['flowMessageVersion'] != null) { + formParams.append('flowMessageVersion', requestParameters['flowMessageVersion'] as any); + } + + if (requestParameters['mode'] != null) { + formParams.append('mode', requestParameters['mode'] as any); + } + + if (requestParameters['flowActionData'] != null) { + formParams.append('flowActionData', new Blob([JSON.stringify(objectToJSON(requestParameters['flowActionData']))], { type: "application/json", })); + } + + if (requestParameters['flowActionScreen'] != null) { + formParams.append('flowActionScreen', requestParameters['flowActionScreen'] as any); + } + + if (requestParameters['quotedMsgId'] != null) { + formParams.append('quotedMsgId', requestParameters['quotedMsgId'] as any); + } + + if (requestParameters['chatId'] != null) { + formParams.append('chatId', requestParameters['chatId'] as any); + } + + if (requestParameters['phone'] != null) { + formParams.append('phone', requestParameters['phone'] as any); + } + + + let urlPath = `/sendFlow`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: formParams, + }; + } + + /** + * Send Interactive WhatsApp Flow message to an existing chat. (Only if the dialogue has an Open Session). Only one of two parameters is needed to determine the destination - chatId or phone. Use this method to send a published WhatsApp Flow as a service (interactive) message. If the 24-hour window is closed, send a template with a FLOW button via /sendTemplate. + * Send WhatsApp Flow Message + */ + async sendFlowRaw(requestParameters: SendFlowRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendFlowRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => MessageSentResponseFromJSON(jsonValue)); + } + + /** + * Send Interactive WhatsApp Flow message to an existing chat. (Only if the dialogue has an Open Session). Only one of two parameters is needed to determine the destination - chatId or phone. Use this method to send a published WhatsApp Flow as a service (interactive) message. If the 24-hour window is closed, send a template with a FLOW button via /sendTemplate. + * Send WhatsApp Flow Message + */ + async sendFlow(token: string, body: string, flowId: string, flowToken: string, flowCta: string, header?: SendFlowRequestHeader, footer?: string, flowAction?: SendFlowFlowActionEnum, flowActionPayload?: object, flowMessageVersion?: string, mode?: SendFlowModeEnum, flowActionData?: object, flowActionScreen?: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendFlowRaw({ token: token, body: body, flowId: flowId, flowToken: flowToken, flowCta: flowCta, header: header, footer: footer, flowAction: flowAction, flowActionPayload: flowActionPayload, flowMessageVersion: flowMessageVersion, mode: mode, flowActionData: flowActionData, flowActionScreen: flowActionScreen, quotedMsgId: quotedMsgId, chatId: chatId, phone: phone }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendList without sending the request + */ + async sendListRequestOpts(requestParameters: SendListOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendList().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/sendList`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: SendListRequestToJSON(requestParameters['sendListRequest']), + }; + } + + /** + * Send List Message + */ + async sendListRaw(requestParameters: SendListOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendListRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => MessageSentResponseFromJSON(jsonValue)); + } + + /** + * Send List Message + */ + async sendList(token: string, sendListRequest?: SendListRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendListRaw({ token: token, sendListRequest: sendListRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendLocation without sending the request + */ + async sendLocationRequestOpts(requestParameters: SendLocationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendLocation().' + ); + } + + if (requestParameters['lat'] == null) { + throw new runtime.RequiredError( + 'lat', + 'Required parameter "lat" was null or undefined when calling sendLocation().' + ); + } + + if (requestParameters['lng'] == null) { + throw new runtime.RequiredError( + 'lng', + 'Required parameter "lng" was null or undefined when calling sendLocation().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + const consumes: runtime.Consume[] = [ + { contentType: 'application/x-www-form-urlencoded' }, + { contentType: 'application/json' }, + ]; + // @ts-ignore: canConsumeForm may be unused + const canConsumeForm = runtime.canConsumeForm(consumes); + + let formParams: { append(param: string, value: any): any }; + let useForm = false; + if (useForm) { + formParams = new FormData(); + } else { + formParams = new URLSearchParams(); + } + + if (requestParameters['lat'] != null) { + formParams.append('lat', requestParameters['lat'] as any); + } + + if (requestParameters['lng'] != null) { + formParams.append('lng', requestParameters['lng'] as any); + } + + if (requestParameters['address'] != null) { + formParams.append('address', requestParameters['address'] as any); + } + + if (requestParameters['name'] != null) { + formParams.append('name', requestParameters['name'] as any); + } + + if (requestParameters['quotedMsgId'] != null) { + formParams.append('quotedMsgId', requestParameters['quotedMsgId'] as any); + } + + if (requestParameters['chatId'] != null) { + formParams.append('chatId', requestParameters['chatId'] as any); + } + + if (requestParameters['phone'] != null) { + formParams.append('phone', requestParameters['phone'] as any); + } + + + let urlPath = `/sendLocation`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: formParams, + }; + } + + /** + * Send a location to an existing chat. (Only if the dialogue has an Open Session). Only one of two parameters is needed to determine the destination - chatId or phone. + * Send a Location + */ + async sendLocationRaw(requestParameters: SendLocationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendLocationRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => MessageSentResponseFromJSON(jsonValue)); + } + + /** + * Send a location to an existing chat. (Only if the dialogue has an Open Session). Only one of two parameters is needed to determine the destination - chatId or phone. + * Send a Location + */ + async sendLocation(token: string, lat: string, lng: string, address?: string, name?: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendLocationRaw({ token: token, lat: lat, lng: lng, address: address, name: name, quotedMsgId: quotedMsgId, chatId: chatId, phone: phone }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendLocationRequest without sending the request + */ + async sendLocationRequestRequestOpts(requestParameters: SendLocationRequestOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendLocationRequest().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/sendLocationRequest`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: SendLocationRequestRequestToJSON(requestParameters['sendLocationRequestRequest']), + }; + } + + /** + * Send Location Request Message + */ + async sendLocationRequestRaw(requestParameters: SendLocationRequestOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendLocationRequestRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => MessageSentResponseFromJSON(jsonValue)); + } + + /** + * Send Location Request Message + */ + async sendLocationRequest(token: string, sendLocationRequestRequest?: SendLocationRequestRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendLocationRequestRaw({ token: token, sendLocationRequestRequest: sendLocationRequestRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendMessage without sending the request + */ + async sendMessageRequestOpts(requestParameters: SendMessageRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendMessage().' + ); + } + + if (requestParameters['body'] == null) { + throw new runtime.RequiredError( + 'body', + 'Required parameter "body" was null or undefined when calling sendMessage().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + const consumes: runtime.Consume[] = [ + { contentType: 'application/x-www-form-urlencoded' }, + { contentType: 'application/json' }, + ]; + // @ts-ignore: canConsumeForm may be unused + const canConsumeForm = runtime.canConsumeForm(consumes); + + let formParams: { append(param: string, value: any): any }; + let useForm = false; + if (useForm) { + formParams = new FormData(); + } else { + formParams = new URLSearchParams(); + } + + if (requestParameters['body'] != null) { + formParams.append('body', requestParameters['body'] as any); + } + + if (requestParameters['quotedMsgId'] != null) { + formParams.append('quotedMsgId', requestParameters['quotedMsgId'] as any); + } + + if (requestParameters['chatId'] != null) { + formParams.append('chatId', requestParameters['chatId'] as any); + } + + if (requestParameters['phone'] != null) { + formParams.append('phone', requestParameters['phone'] as any); + } + + + let urlPath = `/sendMessage`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: formParams, + }; + } + + /** + * Send a message to an existing chat. (Only if the dialogue has an Open Session). The message will be added to the queue for sending and delivered even if the phone is disconnected from the Internet or authorization is not passed. Only one of two parameters is needed to determine the destination - chatId or phone. + * Send a Message + */ + async sendMessageRaw(requestParameters: SendMessageRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendMessageRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => MessageSentResponseFromJSON(jsonValue)); + } + + /** + * Send a message to an existing chat. (Only if the dialogue has an Open Session). The message will be added to the queue for sending and delivered even if the phone is disconnected from the Internet or authorization is not passed. Only one of two parameters is needed to determine the destination - chatId or phone. + * Send a Message + */ + async sendMessage(token: string, body: string, quotedMsgId?: string, chatId?: string, phone?: number, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendMessageRaw({ token: token, body: body, quotedMsgId: quotedMsgId, chatId: chatId, phone: phone }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendOrderDetails without sending the request + */ + async sendOrderDetailsRequestOpts(requestParameters: SendOrderDetailsOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendOrderDetails().' + ); + } + + if (requestParameters['sendOrderDetailsRequest'] == null) { + throw new runtime.RequiredError( + 'sendOrderDetailsRequest', + 'Required parameter "sendOrderDetailsRequest" was null or undefined when calling sendOrderDetails().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/sendOrderDetails`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: SendOrderDetailsRequestToJSON(requestParameters['sendOrderDetailsRequest']), + }; + } + + /** + * Send a WhatsApp **order details** payment / invoice message using a pre-approved **Utility** template that has an `ORDER_DETAILS` button. **India only** (WhatsApp Payments India). Requires: - India WhatsApp Business number - Commerce enabled on the channel (`GET`/`POST /commerce`) - Approved template with an `ORDER_DETAILS` button Use this method when you need structured fields (`order`, `referenceId`, `currency`, `paymentSettings`). The API appends a template button `sub_type: order_details` and sends via the same path as `POST /sendTemplate`. Works **outside the 24-hour session window** (template message). You can also send the same payload yourself with `POST /sendTemplate` by including a button component in `params`: ```json { \"type\": \"button\", \"sub_type\": \"order_details\", \"index\": 0, \"parameters\": [{ \"type\": \"action\", \"action\": { \"order_details\": { \"reference_id\": \"order-123\", \"currency\": \"INR\", \"order\": { \"status\": \"pending\", \"items\": [], \"subtotal\": { \"offset\": 100, \"value\": 50000 } } } } }] } ``` + * Send order details (India payments template) + */ + async sendOrderDetailsRaw(requestParameters: SendOrderDetailsOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendOrderDetailsRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => MessageSentResponseFromJSON(jsonValue)); + } + + /** + * Send a WhatsApp **order details** payment / invoice message using a pre-approved **Utility** template that has an `ORDER_DETAILS` button. **India only** (WhatsApp Payments India). Requires: - India WhatsApp Business number - Commerce enabled on the channel (`GET`/`POST /commerce`) - Approved template with an `ORDER_DETAILS` button Use this method when you need structured fields (`order`, `referenceId`, `currency`, `paymentSettings`). The API appends a template button `sub_type: order_details` and sends via the same path as `POST /sendTemplate`. Works **outside the 24-hour session window** (template message). You can also send the same payload yourself with `POST /sendTemplate` by including a button component in `params`: ```json { \"type\": \"button\", \"sub_type\": \"order_details\", \"index\": 0, \"parameters\": [{ \"type\": \"action\", \"action\": { \"order_details\": { \"reference_id\": \"order-123\", \"currency\": \"INR\", \"order\": { \"status\": \"pending\", \"items\": [], \"subtotal\": { \"offset\": 100, \"value\": 50000 } } } } }] } ``` + * Send order details (India payments template) + */ + async sendOrderDetails(token: string, sendOrderDetailsRequest: SendOrderDetailsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendOrderDetailsRaw({ token: token, sendOrderDetailsRequest: sendOrderDetailsRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendPaymentRequest without sending the request + */ + async sendPaymentRequestRequestOpts(requestParameters: SendPaymentRequestOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendPaymentRequest().' + ); + } + + if (requestParameters['sendPaymentRequestRequest'] == null) { + throw new runtime.RequiredError( + 'sendPaymentRequestRequest', + 'Required parameter "sendPaymentRequestRequest" was null or undefined when calling sendPaymentRequest().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/sendPaymentRequest`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: SendPaymentRequestRequestToJSON(requestParameters['sendPaymentRequestRequest']), + }; + } + + /** + * Send a regional payment request interactive message (beta scaffold). `region` must be IN, SG, or BR. Payload shape follows Meta regional payments docs; verify on stage before production use. Full regional builders are not implemented yet. + * Send payment request (regional) + */ + async sendPaymentRequestRaw(requestParameters: SendPaymentRequestOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendPaymentRequestRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => MessageSentResponseFromJSON(jsonValue)); + } + + /** + * Send a regional payment request interactive message (beta scaffold). `region` must be IN, SG, or BR. Payload shape follows Meta regional payments docs; verify on stage before production use. Full regional builders are not implemented yet. + * Send payment request (regional) + */ + async sendPaymentRequest(token: string, sendPaymentRequestRequest: SendPaymentRequestRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendPaymentRequestRaw({ token: token, sendPaymentRequestRequest: sendPaymentRequestRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendProduct without sending the request + */ + async sendProductRequestOpts(requestParameters: SendProductOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendProduct().' + ); + } + + if (requestParameters['sendProductRequest'] == null) { + throw new runtime.RequiredError( + 'sendProductRequest', + 'Required parameter "sendProductRequest" was null or undefined when calling sendProduct().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/sendProduct`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: SendProductRequestToJSON(requestParameters['sendProductRequest']), + }; + } + + /** + * Send a single catalog product or a product list. Destination is `chatId` or `phone`. `action` is required: - single product: `{ \"catalog_id\": \"...\", \"product_retailer_id\": \"...\" }` - product list: `{ \"catalog_id\": \"...\", \"sections\": [{ \"title\": \"...\", \"product_items\": [{ \"product_retailer_id\": \"...\" }] }] }` + * Send a Product + */ + async sendProductRaw(requestParameters: SendProductOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendProductRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => MessageSentResponseFromJSON(jsonValue)); + } + + /** + * Send a single catalog product or a product list. Destination is `chatId` or `phone`. `action` is required: - single product: `{ \"catalog_id\": \"...\", \"product_retailer_id\": \"...\" }` - product list: `{ \"catalog_id\": \"...\", \"sections\": [{ \"title\": \"...\", \"product_items\": [{ \"product_retailer_id\": \"...\" }] }] }` + * Send a Product + */ + async sendProduct(token: string, sendProductRequest: SendProductRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendProductRaw({ token: token, sendProductRequest: sendProductRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendReaction without sending the request + */ + async sendReactionRequestOpts(requestParameters: SendReactionOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendReaction().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/sendReaction`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: SendReactionRequestToJSON(requestParameters['sendReactionRequest']), + }; + } + + /** + * Send Reaction + */ + async sendReactionRaw(requestParameters: SendReactionOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendReactionRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => MessageSentResponseFromJSON(jsonValue)); + } + + /** + * Send Reaction + */ + async sendReaction(token: string, sendReactionRequest?: SendReactionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendReactionRaw({ token: token, sendReactionRequest: sendReactionRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendSticker without sending the request + */ + async sendStickerRequestOpts(requestParameters: SendStickerOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendSticker().' + ); + } + + if (requestParameters['sendStickerRequest'] == null) { + throw new runtime.RequiredError( + 'sendStickerRequest', + 'Required parameter "sendStickerRequest" was null or undefined when calling sendSticker().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/sendSticker`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: SendStickerRequestToJSON(requestParameters['sendStickerRequest']), + }; + } + + /** + * Send a WhatsApp sticker by mediaId or link URL. + * Send sticker message + */ + async sendStickerRaw(requestParameters: SendStickerOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendStickerRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => MessageSentResponseFromJSON(jsonValue)); + } + + /** + * Send a WhatsApp sticker by mediaId or link URL. + * Send sticker message + */ + async sendSticker(token: string, sendStickerRequest: SendStickerRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendStickerRaw({ token: token, sendStickerRequest: sendStickerRequest }, initOverrides); + return await response.value(); + } + +} + +/** + * @export + */ +export const SendFileMediaTypeEnum = { + Image: 'image', + Video: 'video', + Audio: 'audio', + Document: 'document' +} as const; +export type SendFileMediaTypeEnum = typeof SendFileMediaTypeEnum[keyof typeof SendFileMediaTypeEnum]; +/** + * @export + */ +export const SendFlowFlowActionEnum = { + Navigate: 'navigate', + DataExchange: 'data_exchange' +} as const; +export type SendFlowFlowActionEnum = typeof SendFlowFlowActionEnum[keyof typeof SendFlowFlowActionEnum]; +/** + * @export + */ +export const SendFlowModeEnum = { + Draft: 'draft', + Published: 'published' +} as const; +export type SendFlowModeEnum = typeof SendFlowModeEnum[keyof typeof SendFlowModeEnum]; diff --git a/typescript/src/generated/src/apis/ProfileApi.ts b/typescript/src/generated/src/apis/ProfileApi.ts new file mode 100644 index 0000000..dddf5e4 --- /dev/null +++ b/typescript/src/generated/src/apis/ProfileApi.ts @@ -0,0 +1,228 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from '../runtime'; +import { + type ErrorResponse, + ErrorResponseFromJSON, + ErrorResponseToJSON, +} from '../models/ErrorResponse'; +import { + type ProfileInfo, + ProfileInfoFromJSON, + ProfileInfoToJSON, +} from '../models/ProfileInfo'; +import { + type UpdateMe200Response, + UpdateMe200ResponseFromJSON, + UpdateMe200ResponseToJSON, +} from '../models/UpdateMe200Response'; +import { + type UpdateMeRequest, + UpdateMeRequestFromJSON, + UpdateMeRequestToJSON, +} from '../models/UpdateMeRequest'; + +export interface GetMeRequest { + token: string; +} + +export interface UpdateMeOperationRequest { + token: string; + updateMeRequest: UpdateMeRequest; +} + +/** + * ProfileApi - interface + * + * @export + * @interface ProfileApiInterface + */ +export interface ProfileApiInterface { + /** + * Creates request options for getMe without sending the request + * @param {string} token JWT token or API key for authorization + * @throws {RequiredError} + * @memberof ProfileApiInterface + */ + getMeRequestOpts(requestParameters: GetMeRequest): Promise; + + /** + * Return the WhatsApp Business profile for this channel: About, address, description, email, phone, websites, industry (`vertical`), and profile photo URL. + * @summary Get Profile Info + * @param {string} token JWT token or API key for authorization + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ProfileApiInterface + */ + getMeRaw(requestParameters: GetMeRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Return the WhatsApp Business profile for this channel: About, address, description, email, phone, websites, industry (`vertical`), and profile photo URL. + * Get Profile Info + */ + getMe(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for updateMe without sending the request + * @param {string} token JWT token or API key for authorization + * @param {UpdateMeRequest} updateMeRequest + * @throws {RequiredError} + * @memberof ProfileApiInterface + */ + updateMeRequestOpts(requestParameters: UpdateMeOperationRequest): Promise; + + /** + * Update WhatsApp Business Account profile fields. At least one of about, description, email, photo, address, vertical, websites is required. Blocked when the channel subscription limit is exceeded. + * @summary Update profile info + * @param {string} token JWT token or API key for authorization + * @param {UpdateMeRequest} updateMeRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ProfileApiInterface + */ + updateMeRaw(requestParameters: UpdateMeOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Update WhatsApp Business Account profile fields. At least one of about, description, email, photo, address, vertical, websites is required. Blocked when the channel subscription limit is exceeded. + * Update profile info + */ + updateMe(token: string, updateMeRequest: UpdateMeRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + +} + +/** + * + */ +export class ProfileApi extends runtime.BaseAPI implements ProfileApiInterface { + + /** + * Creates request options for getMe without sending the request + */ + async getMeRequestOpts(requestParameters: GetMeRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling getMe().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/me`; + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Return the WhatsApp Business profile for this channel: About, address, description, email, phone, websites, industry (`vertical`), and profile photo URL. + * Get Profile Info + */ + async getMeRaw(requestParameters: GetMeRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.getMeRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ProfileInfoFromJSON(jsonValue)); + } + + /** + * Return the WhatsApp Business profile for this channel: About, address, description, email, phone, websites, industry (`vertical`), and profile photo URL. + * Get Profile Info + */ + async getMe(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getMeRaw({ token: token }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for updateMe without sending the request + */ + async updateMeRequestOpts(requestParameters: UpdateMeOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling updateMe().' + ); + } + + if (requestParameters['updateMeRequest'] == null) { + throw new runtime.RequiredError( + 'updateMeRequest', + 'Required parameter "updateMeRequest" was null or undefined when calling updateMe().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/me`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: UpdateMeRequestToJSON(requestParameters['updateMeRequest']), + }; + } + + /** + * Update WhatsApp Business Account profile fields. At least one of about, description, email, photo, address, vertical, websites is required. Blocked when the channel subscription limit is exceeded. + * Update profile info + */ + async updateMeRaw(requestParameters: UpdateMeOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.updateMeRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => UpdateMe200ResponseFromJSON(jsonValue)); + } + + /** + * Update WhatsApp Business Account profile fields. At least one of about, description, email, photo, address, vertical, websites is required. Blocked when the channel subscription limit is exceeded. + * Update profile info + */ + async updateMe(token: string, updateMeRequest: UpdateMeRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updateMeRaw({ token: token, updateMeRequest: updateMeRequest }, initOverrides); + return await response.value(); + } + +} diff --git a/typescript/src/generated/src/apis/TemplatesApi.ts b/typescript/src/generated/src/apis/TemplatesApi.ts new file mode 100644 index 0000000..698890e --- /dev/null +++ b/typescript/src/generated/src/apis/TemplatesApi.ts @@ -0,0 +1,445 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from '../runtime'; +import { + type AddTemplate200Response, + AddTemplate200ResponseFromJSON, + AddTemplate200ResponseToJSON, +} from '../models/AddTemplate200Response'; +import { + type AddTemplateRequest, + AddTemplateRequestFromJSON, + AddTemplateRequestToJSON, +} from '../models/AddTemplateRequest'; +import { + type ErrorResponse, + ErrorResponseFromJSON, + ErrorResponseToJSON, +} from '../models/ErrorResponse'; +import { + type ListTemplates200Response, + ListTemplates200ResponseFromJSON, + ListTemplates200ResponseToJSON, +} from '../models/ListTemplates200Response'; +import { + type RemoveTemplateRequest, + RemoveTemplateRequestFromJSON, + RemoveTemplateRequestToJSON, +} from '../models/RemoveTemplateRequest'; +import { + type SendTemplateRequest, + SendTemplateRequestFromJSON, + SendTemplateRequestToJSON, +} from '../models/SendTemplateRequest'; + +export interface AddTemplateOperationRequest { + token: string; + addTemplateRequest?: (AddTemplateRequest) | undefined; +} + +export interface ListTemplatesRequest { + token: string; + limit?: (number) | undefined; + offset?: (number) | undefined; + sort?: (ListTemplatesSortEnum) | undefined; +} + +export interface RemoveTemplateOperationRequest { + token: string; + removeTemplateRequest: RemoveTemplateRequest; +} + +export interface SendTemplateOperationRequest { + token: string; + sendTemplateRequest?: (SendTemplateRequest) | undefined; +} + +/** + * TemplatesApi - interface + * + * @export + * @interface TemplatesApiInterface + */ +export interface TemplatesApiInterface { + /** + * Creates request options for addTemplate without sending the request + * @param {string} token JWT token or API key for authorization + * @param {AddTemplateRequest} [addTemplateRequest] + * @throws {RequiredError} + * @memberof TemplatesApiInterface + */ + addTemplateRequestOpts(requestParameters: AddTemplateOperationRequest): Promise; + + /** + * Create a WABA message template (`name`, `category`, `language`, `components`). After create, Meta reviews the template; list it with `GET /templates`. + * @summary Create message template + * @param {string} token JWT token or API key for authorization + * @param {AddTemplateRequest} [addTemplateRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TemplatesApiInterface + */ + addTemplateRaw(requestParameters: AddTemplateOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Create a WABA message template (`name`, `category`, `language`, `components`). After create, Meta reviews the template; list it with `GET /templates`. + * Create message template + */ + addTemplate(token: string, addTemplateRequest?: AddTemplateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for listTemplates without sending the request + * @param {string} token JWT token or API key for authorization + * @param {number} [limit] + * @param {number} [offset] + * @param {'id' | 'name' | 'status'} [sort] Sort field (`id`, `name`, or `status`) + * @throws {RequiredError} + * @memberof TemplatesApiInterface + */ + listTemplatesRequestOpts(requestParameters: ListTemplatesRequest): Promise; + + /** + * List message templates. Paginate with `limit` / `offset`; sort by `id`, `name`, or `status`. + * @summary Get templates list + * @param {string} token JWT token or API key for authorization + * @param {number} [limit] + * @param {number} [offset] + * @param {'id' | 'name' | 'status'} [sort] Sort field (`id`, `name`, or `status`) + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TemplatesApiInterface + */ + listTemplatesRaw(requestParameters: ListTemplatesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * List message templates. Paginate with `limit` / `offset`; sort by `id`, `name`, or `status`. + * Get templates list + */ + listTemplates(token: string, limit?: number, offset?: number, sort?: ListTemplatesSortEnum, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for removeTemplate without sending the request + * @param {string} token JWT token or API key for authorization + * @param {RemoveTemplateRequest} removeTemplateRequest + * @throws {RequiredError} + * @memberof TemplatesApiInterface + */ + removeTemplateRequestOpts(requestParameters: RemoveTemplateOperationRequest): Promise; + + /** + * Delete a message template by `name` (all language versions of that name). + * @summary Remove message template + * @param {string} token JWT token or API key for authorization + * @param {RemoveTemplateRequest} removeTemplateRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TemplatesApiInterface + */ + removeTemplateRaw(requestParameters: RemoveTemplateOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Delete a message template by `name` (all language versions of that name). + * Remove message template + */ + removeTemplate(token: string, removeTemplateRequest: RemoveTemplateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>; + + /** + * Creates request options for sendTemplate without sending the request + * @param {string} token JWT token or API key for authorization + * @param {SendTemplateRequest} [sendTemplateRequest] + * @throws {RequiredError} + * @memberof TemplatesApiInterface + */ + sendTemplateRequestOpts(requestParameters: SendTemplateOperationRequest): Promise; + + /** + * Send a WhatsApp **template** message (works outside the 24-hour session window). Use this tool — not `send_message` — when the 24h session is closed. `params` MUST be Cloud API **component objects**, never a flat list of strings and never the old On-Prem `hsm` / `localizable_params` format. Example body variable `{{1}}`: ```json { \"type\": \"body\", \"parameters\": [{ \"type\": \"text\", \"text\": \"Ivan\" }] } ``` Do not send `\"type\": \"hsm\"` and do not send `params: [\"Ivan\", \"123\"]`. Supported `params` button `sub_type` values include: `url`, `quick_reply`, `copy_code` / `coupon_code`, `catalog`, `flow`, `limited_time_offer`, and **`order_details`** (WhatsApp Payments **India only** — requires an approved Utility template with an ORDER_DETAILS button). Convenience wrapper with structured fields: `POST /sendOrderDetails`. + * @summary Send Template Message + * @param {string} token JWT token or API key for authorization + * @param {SendTemplateRequest} [sendTemplateRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TemplatesApiInterface + */ + sendTemplateRaw(requestParameters: SendTemplateOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Send a WhatsApp **template** message (works outside the 24-hour session window). Use this tool — not `send_message` — when the 24h session is closed. `params` MUST be Cloud API **component objects**, never a flat list of strings and never the old On-Prem `hsm` / `localizable_params` format. Example body variable `{{1}}`: ```json { \"type\": \"body\", \"parameters\": [{ \"type\": \"text\", \"text\": \"Ivan\" }] } ``` Do not send `\"type\": \"hsm\"` and do not send `params: [\"Ivan\", \"123\"]`. Supported `params` button `sub_type` values include: `url`, `quick_reply`, `copy_code` / `coupon_code`, `catalog`, `flow`, `limited_time_offer`, and **`order_details`** (WhatsApp Payments **India only** — requires an approved Utility template with an ORDER_DETAILS button). Convenience wrapper with structured fields: `POST /sendOrderDetails`. + * Send Template Message + */ + sendTemplate(token: string, sendTemplateRequest?: SendTemplateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }>; + +} + +/** + * + */ +export class TemplatesApi extends runtime.BaseAPI implements TemplatesApiInterface { + + /** + * Creates request options for addTemplate without sending the request + */ + async addTemplateRequestOpts(requestParameters: AddTemplateOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling addTemplate().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/addTemplate`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: AddTemplateRequestToJSON(requestParameters['addTemplateRequest']), + }; + } + + /** + * Create a WABA message template (`name`, `category`, `language`, `components`). After create, Meta reviews the template; list it with `GET /templates`. + * Create message template + */ + async addTemplateRaw(requestParameters: AddTemplateOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.addTemplateRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AddTemplate200ResponseFromJSON(jsonValue)); + } + + /** + * Create a WABA message template (`name`, `category`, `language`, `components`). After create, Meta reviews the template; list it with `GET /templates`. + * Create message template + */ + async addTemplate(token: string, addTemplateRequest?: AddTemplateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.addTemplateRaw({ token: token, addTemplateRequest: addTemplateRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for listTemplates without sending the request + */ + async listTemplatesRequestOpts(requestParameters: ListTemplatesRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling listTemplates().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + if (requestParameters['limit'] != null) { + queryParameters['limit'] = requestParameters['limit']; + } + + if (requestParameters['offset'] != null) { + queryParameters['offset'] = requestParameters['offset']; + } + + if (requestParameters['sort'] != null) { + queryParameters['sort'] = requestParameters['sort']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/templates`; + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * List message templates. Paginate with `limit` / `offset`; sort by `id`, `name`, or `status`. + * Get templates list + */ + async listTemplatesRaw(requestParameters: ListTemplatesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.listTemplatesRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ListTemplates200ResponseFromJSON(jsonValue)); + } + + /** + * List message templates. Paginate with `limit` / `offset`; sort by `id`, `name`, or `status`. + * Get templates list + */ + async listTemplates(token: string, limit?: number, offset?: number, sort?: ListTemplatesSortEnum, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.listTemplatesRaw({ token: token, limit: limit, offset: offset, sort: sort }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for removeTemplate without sending the request + */ + async removeTemplateRequestOpts(requestParameters: RemoveTemplateOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling removeTemplate().' + ); + } + + if (requestParameters['removeTemplateRequest'] == null) { + throw new runtime.RequiredError( + 'removeTemplateRequest', + 'Required parameter "removeTemplateRequest" was null or undefined when calling removeTemplate().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/removeTemplate`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: RemoveTemplateRequestToJSON(requestParameters['removeTemplateRequest']), + }; + } + + /** + * Delete a message template by `name` (all language versions of that name). + * Remove message template + */ + async removeTemplateRaw(requestParameters: RemoveTemplateOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.removeTemplateRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + * Delete a message template by `name` (all language versions of that name). + * Remove message template + */ + async removeTemplate(token: string, removeTemplateRequest: RemoveTemplateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> { + const response = await this.removeTemplateRaw({ token: token, removeTemplateRequest: removeTemplateRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for sendTemplate without sending the request + */ + async sendTemplateRequestOpts(requestParameters: SendTemplateOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling sendTemplate().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/sendTemplate`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: SendTemplateRequestToJSON(requestParameters['sendTemplateRequest']), + }; + } + + /** + * Send a WhatsApp **template** message (works outside the 24-hour session window). Use this tool — not `send_message` — when the 24h session is closed. `params` MUST be Cloud API **component objects**, never a flat list of strings and never the old On-Prem `hsm` / `localizable_params` format. Example body variable `{{1}}`: ```json { \"type\": \"body\", \"parameters\": [{ \"type\": \"text\", \"text\": \"Ivan\" }] } ``` Do not send `\"type\": \"hsm\"` and do not send `params: [\"Ivan\", \"123\"]`. Supported `params` button `sub_type` values include: `url`, `quick_reply`, `copy_code` / `coupon_code`, `catalog`, `flow`, `limited_time_offer`, and **`order_details`** (WhatsApp Payments **India only** — requires an approved Utility template with an ORDER_DETAILS button). Convenience wrapper with structured fields: `POST /sendOrderDetails`. + * Send Template Message + */ + async sendTemplateRaw(requestParameters: SendTemplateOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.sendTemplateRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + * Send a WhatsApp **template** message (works outside the 24-hour session window). Use this tool — not `send_message` — when the 24h session is closed. `params` MUST be Cloud API **component objects**, never a flat list of strings and never the old On-Prem `hsm` / `localizable_params` format. Example body variable `{{1}}`: ```json { \"type\": \"body\", \"parameters\": [{ \"type\": \"text\", \"text\": \"Ivan\" }] } ``` Do not send `\"type\": \"hsm\"` and do not send `params: [\"Ivan\", \"123\"]`. Supported `params` button `sub_type` values include: `url`, `quick_reply`, `copy_code` / `coupon_code`, `catalog`, `flow`, `limited_time_offer`, and **`order_details`** (WhatsApp Payments **India only** — requires an approved Utility template with an ORDER_DETAILS button). Convenience wrapper with structured fields: `POST /sendOrderDetails`. + * Send Template Message + */ + async sendTemplate(token: string, sendTemplateRequest?: SendTemplateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: any; }> { + const response = await this.sendTemplateRaw({ token: token, sendTemplateRequest: sendTemplateRequest }, initOverrides); + return await response.value(); + } + +} + +/** + * @export + */ +export const ListTemplatesSortEnum = { + Id: 'id', + Name: 'name', + Status: 'status' +} as const; +export type ListTemplatesSortEnum = typeof ListTemplatesSortEnum[keyof typeof ListTemplatesSortEnum]; diff --git a/typescript/src/generated/src/apis/UsersApi.ts b/typescript/src/generated/src/apis/UsersApi.ts new file mode 100644 index 0000000..1e45232 --- /dev/null +++ b/typescript/src/generated/src/apis/UsersApi.ts @@ -0,0 +1,317 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from '../runtime'; +import { + type BlockUserRequest, + BlockUserRequestFromJSON, + BlockUserRequestToJSON, +} from '../models/BlockUserRequest'; +import { + type ErrorResponse, + ErrorResponseFromJSON, + ErrorResponseToJSON, +} from '../models/ErrorResponse'; +import { + type ListBlockedUsers200Response, + ListBlockedUsers200ResponseFromJSON, + ListBlockedUsers200ResponseToJSON, +} from '../models/ListBlockedUsers200Response'; +import { + type SuccessResponse, + SuccessResponseFromJSON, + SuccessResponseToJSON, +} from '../models/SuccessResponse'; + +export interface BlockUserOperationRequest { + token: string; + blockUserRequest: BlockUserRequest; +} + +export interface ListBlockedUsersRequest { + token: string; +} + +export interface UnblockUserRequest { + token: string; + blockUserRequest: BlockUserRequest; +} + +/** + * UsersApi - interface + * + * @export + * @interface UsersApiInterface + */ +export interface UsersApiInterface { + /** + * Creates request options for blockUser without sending the request + * @param {string} token JWT token or API key for authorization + * @param {BlockUserRequest} blockUserRequest + * @throws {RequiredError} + * @memberof UsersApiInterface + */ + blockUserRequestOpts(requestParameters: BlockUserOperationRequest): Promise; + + /** + * + * @summary Block WhatsApp user + * @param {string} token JWT token or API key for authorization + * @param {BlockUserRequest} blockUserRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UsersApiInterface + */ + blockUserRaw(requestParameters: BlockUserOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Block WhatsApp user + */ + blockUser(token: string, blockUserRequest: BlockUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for listBlockedUsers without sending the request + * @param {string} token JWT token or API key for authorization + * @throws {RequiredError} + * @memberof UsersApiInterface + */ + listBlockedUsersRequestOpts(requestParameters: ListBlockedUsersRequest): Promise; + + /** + * Returns users currently blocked on this WhatsApp channel (WABA `GET /block_users`). Same channel token auth as `blockUser` / `unblockUser`. + * @summary List blocked WhatsApp users + * @param {string} token JWT token or API key for authorization + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UsersApiInterface + */ + listBlockedUsersRaw(requestParameters: ListBlockedUsersRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Returns users currently blocked on this WhatsApp channel (WABA `GET /block_users`). Same channel token auth as `blockUser` / `unblockUser`. + * List blocked WhatsApp users + */ + listBlockedUsers(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for unblockUser without sending the request + * @param {string} token JWT token or API key for authorization + * @param {BlockUserRequest} blockUserRequest + * @throws {RequiredError} + * @memberof UsersApiInterface + */ + unblockUserRequestOpts(requestParameters: UnblockUserRequest): Promise; + + /** + * + * @summary Unblock WhatsApp user + * @param {string} token JWT token or API key for authorization + * @param {BlockUserRequest} blockUserRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UsersApiInterface + */ + unblockUserRaw(requestParameters: UnblockUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Unblock WhatsApp user + */ + unblockUser(token: string, blockUserRequest: BlockUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + +} + +/** + * + */ +export class UsersApi extends runtime.BaseAPI implements UsersApiInterface { + + /** + * Creates request options for blockUser without sending the request + */ + async blockUserRequestOpts(requestParameters: BlockUserOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling blockUser().' + ); + } + + if (requestParameters['blockUserRequest'] == null) { + throw new runtime.RequiredError( + 'blockUserRequest', + 'Required parameter "blockUserRequest" was null or undefined when calling blockUser().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/blockUser`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: BlockUserRequestToJSON(requestParameters['blockUserRequest']), + }; + } + + /** + * Block WhatsApp user + */ + async blockUserRaw(requestParameters: BlockUserOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.blockUserRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => SuccessResponseFromJSON(jsonValue)); + } + + /** + * Block WhatsApp user + */ + async blockUser(token: string, blockUserRequest: BlockUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.blockUserRaw({ token: token, blockUserRequest: blockUserRequest }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for listBlockedUsers without sending the request + */ + async listBlockedUsersRequestOpts(requestParameters: ListBlockedUsersRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling listBlockedUsers().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/blockedUsers`; + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Returns users currently blocked on this WhatsApp channel (WABA `GET /block_users`). Same channel token auth as `blockUser` / `unblockUser`. + * List blocked WhatsApp users + */ + async listBlockedUsersRaw(requestParameters: ListBlockedUsersRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.listBlockedUsersRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ListBlockedUsers200ResponseFromJSON(jsonValue)); + } + + /** + * Returns users currently blocked on this WhatsApp channel (WABA `GET /block_users`). Same channel token auth as `blockUser` / `unblockUser`. + * List blocked WhatsApp users + */ + async listBlockedUsers(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.listBlockedUsersRaw({ token: token }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for unblockUser without sending the request + */ + async unblockUserRequestOpts(requestParameters: UnblockUserRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling unblockUser().' + ); + } + + if (requestParameters['blockUserRequest'] == null) { + throw new runtime.RequiredError( + 'blockUserRequest', + 'Required parameter "blockUserRequest" was null or undefined when calling unblockUser().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/unblockUser`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: BlockUserRequestToJSON(requestParameters['blockUserRequest']), + }; + } + + /** + * Unblock WhatsApp user + */ + async unblockUserRaw(requestParameters: UnblockUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.unblockUserRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => SuccessResponseFromJSON(jsonValue)); + } + + /** + * Unblock WhatsApp user + */ + async unblockUser(token: string, blockUserRequest: BlockUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.unblockUserRaw({ token: token, blockUserRequest: blockUserRequest }, initOverrides); + return await response.value(); + } + +} diff --git a/typescript/src/generated/src/apis/WebhooksApi.ts b/typescript/src/generated/src/apis/WebhooksApi.ts new file mode 100644 index 0000000..5a1cea4 --- /dev/null +++ b/typescript/src/generated/src/apis/WebhooksApi.ts @@ -0,0 +1,228 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from '../runtime'; +import { + type ErrorResponse, + ErrorResponseFromJSON, + ErrorResponseToJSON, +} from '../models/ErrorResponse'; +import { + type GetWebhook200Response, + GetWebhook200ResponseFromJSON, + GetWebhook200ResponseToJSON, +} from '../models/GetWebhook200Response'; +import { + type SetWebhook200Response, + SetWebhook200ResponseFromJSON, + SetWebhook200ResponseToJSON, +} from '../models/SetWebhook200Response'; +import { + type SetWebhookRequest, + SetWebhookRequestFromJSON, + SetWebhookRequestToJSON, +} from '../models/SetWebhookRequest'; + +export interface GetWebhookRequest { + token: string; +} + +export interface SetWebhookOperationRequest { + token: string; + setWebhookRequest: SetWebhookRequest; +} + +/** + * WebhooksApi - interface + * + * @export + * @interface WebhooksApiInterface + */ +export interface WebhooksApiInterface { + /** + * Creates request options for getWebhook without sending the request + * @param {string} token JWT token or API key for authorization + * @throws {RequiredError} + * @memberof WebhooksApiInterface + */ + getWebhookRequestOpts(requestParameters: GetWebhookRequest): Promise; + + /** + * Return the webhook URL(s) currently configured for this channel, plus delivery status for each URL. `webhookUrl` is a string when a single URL is set, an array of strings when multiple URLs are configured, or `null` if none is set. **Prefer `webhookStatuses`.** The circuit breaker is per URL, not per channel. If 1 of 4 URLs is sticky-disabled, that URL is skipped; the other three still receive events. Send/receive are not affected. Channel-level `haveDisabledWebhooks`, `circuitState`, `reason`, `fails`, `trips`, and timestamps are a compatibility summary of **one** URL (the first sticky-disabled URL, else the first configured URL). They are not \"the channel is dead\". - `haveDisabledWebhooks` — `true` when **at least one** URL in `webhookUrl` is sticky auto-disabled. Live URLs still get events. - `circuitState` — compressed scalar for that same primary URL: `ok` | `degraded` | `open` | `half_open` | `disabled`. - `disabledWebhooks` — currently configured URLs that are sticky-disabled (subset of `webhookUrl`). - `webhookStatuses` — one row per currently configured URL. Use this array to see which endpoints are live vs skipped. - `fails` / `trips` / `firstFailAt` — **diagnostics for support**, not product UI. `fails` = failures in a rolling ~10 minute window (not lifetime). `trips` = failed recovery probes on the 15 min → 1 h → 6 h schedule (sticky disable after 3). Clients can ignore these and use `webhookStatuses` + `disabledWebhooks` only. Sticky disable skips delivery; it does not unconfigure the URL (it stays in `webhookUrl`). Re-enable with `POST /webhook` or `POST /settings`. Those endpoints **replace** the whole list — with multiple URLs, send the full array. + * @summary Get webhook URL + * @param {string} token JWT token or API key for authorization + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof WebhooksApiInterface + */ + getWebhookRaw(requestParameters: GetWebhookRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Return the webhook URL(s) currently configured for this channel, plus delivery status for each URL. `webhookUrl` is a string when a single URL is set, an array of strings when multiple URLs are configured, or `null` if none is set. **Prefer `webhookStatuses`.** The circuit breaker is per URL, not per channel. If 1 of 4 URLs is sticky-disabled, that URL is skipped; the other three still receive events. Send/receive are not affected. Channel-level `haveDisabledWebhooks`, `circuitState`, `reason`, `fails`, `trips`, and timestamps are a compatibility summary of **one** URL (the first sticky-disabled URL, else the first configured URL). They are not \"the channel is dead\". - `haveDisabledWebhooks` — `true` when **at least one** URL in `webhookUrl` is sticky auto-disabled. Live URLs still get events. - `circuitState` — compressed scalar for that same primary URL: `ok` | `degraded` | `open` | `half_open` | `disabled`. - `disabledWebhooks` — currently configured URLs that are sticky-disabled (subset of `webhookUrl`). - `webhookStatuses` — one row per currently configured URL. Use this array to see which endpoints are live vs skipped. - `fails` / `trips` / `firstFailAt` — **diagnostics for support**, not product UI. `fails` = failures in a rolling ~10 minute window (not lifetime). `trips` = failed recovery probes on the 15 min → 1 h → 6 h schedule (sticky disable after 3). Clients can ignore these and use `webhookStatuses` + `disabledWebhooks` only. Sticky disable skips delivery; it does not unconfigure the URL (it stays in `webhookUrl`). Re-enable with `POST /webhook` or `POST /settings`. Those endpoints **replace** the whole list — with multiple URLs, send the full array. + * Get webhook URL + */ + getWebhook(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Creates request options for setWebhook without sending the request + * @param {string} token JWT token or API key for authorization + * @param {SetWebhookRequest} setWebhookRequest + * @throws {RequiredError} + * @memberof WebhooksApiInterface + */ + setWebhookRequestOpts(requestParameters: SetWebhookOperationRequest): Promise; + + /** + * Set the client webhook URL that receives inbound events for this channel. **Replaces** the stored webhook list (it does not append). To deliver the same events to several endpoints, pass an array in `webhookUrl` (max 5) or use `POST /settings`. With several URLs already configured, posting only the disabled URL **drops the others** — send the complete array to re-enable one of many. Incoming payloads include messages, delivery ACKs, group updates, coexistence echoes, and calling events. WhatsApp Calling payloads (`type: \"calls\"`) are documented under the **Calling** tag. Call permission replies arrive on the normal messages path (`call_permission_reply`). Repeating `POST /webhook` with the same URL(s) clears an auto-disable (self-serve re-enable). Send/receive are not affected by webhook auto-disable. + * @summary Set webhook URL + * @param {string} token JWT token or API key for authorization + * @param {SetWebhookRequest} setWebhookRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof WebhooksApiInterface + */ + setWebhookRaw(requestParameters: SetWebhookOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Set the client webhook URL that receives inbound events for this channel. **Replaces** the stored webhook list (it does not append). To deliver the same events to several endpoints, pass an array in `webhookUrl` (max 5) or use `POST /settings`. With several URLs already configured, posting only the disabled URL **drops the others** — send the complete array to re-enable one of many. Incoming payloads include messages, delivery ACKs, group updates, coexistence echoes, and calling events. WhatsApp Calling payloads (`type: \"calls\"`) are documented under the **Calling** tag. Call permission replies arrive on the normal messages path (`call_permission_reply`). Repeating `POST /webhook` with the same URL(s) clears an auto-disable (self-serve re-enable). Send/receive are not affected by webhook auto-disable. + * Set webhook URL + */ + setWebhook(token: string, setWebhookRequest: SetWebhookRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + +} + +/** + * + */ +export class WebhooksApi extends runtime.BaseAPI implements WebhooksApiInterface { + + /** + * Creates request options for getWebhook without sending the request + */ + async getWebhookRequestOpts(requestParameters: GetWebhookRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling getWebhook().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/webhook`; + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Return the webhook URL(s) currently configured for this channel, plus delivery status for each URL. `webhookUrl` is a string when a single URL is set, an array of strings when multiple URLs are configured, or `null` if none is set. **Prefer `webhookStatuses`.** The circuit breaker is per URL, not per channel. If 1 of 4 URLs is sticky-disabled, that URL is skipped; the other three still receive events. Send/receive are not affected. Channel-level `haveDisabledWebhooks`, `circuitState`, `reason`, `fails`, `trips`, and timestamps are a compatibility summary of **one** URL (the first sticky-disabled URL, else the first configured URL). They are not \"the channel is dead\". - `haveDisabledWebhooks` — `true` when **at least one** URL in `webhookUrl` is sticky auto-disabled. Live URLs still get events. - `circuitState` — compressed scalar for that same primary URL: `ok` | `degraded` | `open` | `half_open` | `disabled`. - `disabledWebhooks` — currently configured URLs that are sticky-disabled (subset of `webhookUrl`). - `webhookStatuses` — one row per currently configured URL. Use this array to see which endpoints are live vs skipped. - `fails` / `trips` / `firstFailAt` — **diagnostics for support**, not product UI. `fails` = failures in a rolling ~10 minute window (not lifetime). `trips` = failed recovery probes on the 15 min → 1 h → 6 h schedule (sticky disable after 3). Clients can ignore these and use `webhookStatuses` + `disabledWebhooks` only. Sticky disable skips delivery; it does not unconfigure the URL (it stays in `webhookUrl`). Re-enable with `POST /webhook` or `POST /settings`. Those endpoints **replace** the whole list — with multiple URLs, send the full array. + * Get webhook URL + */ + async getWebhookRaw(requestParameters: GetWebhookRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.getWebhookRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => GetWebhook200ResponseFromJSON(jsonValue)); + } + + /** + * Return the webhook URL(s) currently configured for this channel, plus delivery status for each URL. `webhookUrl` is a string when a single URL is set, an array of strings when multiple URLs are configured, or `null` if none is set. **Prefer `webhookStatuses`.** The circuit breaker is per URL, not per channel. If 1 of 4 URLs is sticky-disabled, that URL is skipped; the other three still receive events. Send/receive are not affected. Channel-level `haveDisabledWebhooks`, `circuitState`, `reason`, `fails`, `trips`, and timestamps are a compatibility summary of **one** URL (the first sticky-disabled URL, else the first configured URL). They are not \"the channel is dead\". - `haveDisabledWebhooks` — `true` when **at least one** URL in `webhookUrl` is sticky auto-disabled. Live URLs still get events. - `circuitState` — compressed scalar for that same primary URL: `ok` | `degraded` | `open` | `half_open` | `disabled`. - `disabledWebhooks` — currently configured URLs that are sticky-disabled (subset of `webhookUrl`). - `webhookStatuses` — one row per currently configured URL. Use this array to see which endpoints are live vs skipped. - `fails` / `trips` / `firstFailAt` — **diagnostics for support**, not product UI. `fails` = failures in a rolling ~10 minute window (not lifetime). `trips` = failed recovery probes on the 15 min → 1 h → 6 h schedule (sticky disable after 3). Clients can ignore these and use `webhookStatuses` + `disabledWebhooks` only. Sticky disable skips delivery; it does not unconfigure the URL (it stays in `webhookUrl`). Re-enable with `POST /webhook` or `POST /settings`. Those endpoints **replace** the whole list — with multiple URLs, send the full array. + * Get webhook URL + */ + async getWebhook(token: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getWebhookRaw({ token: token }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for setWebhook without sending the request + */ + async setWebhookRequestOpts(requestParameters: SetWebhookOperationRequest): Promise { + if (requestParameters['token'] == null) { + throw new runtime.RequiredError( + 'token', + 'Required parameter "token" was null or undefined when calling setWebhook().' + ); + } + + if (requestParameters['setWebhookRequest'] == null) { + throw new runtime.RequiredError( + 'setWebhookRequest', + 'Required parameter "setWebhookRequest" was null or undefined when calling setWebhook().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + queryParameters["token"] = await this.configuration.apiKey("token"); // tokenAuth authentication + } + + + let urlPath = `/webhook`; + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: SetWebhookRequestToJSON(requestParameters['setWebhookRequest']), + }; + } + + /** + * Set the client webhook URL that receives inbound events for this channel. **Replaces** the stored webhook list (it does not append). To deliver the same events to several endpoints, pass an array in `webhookUrl` (max 5) or use `POST /settings`. With several URLs already configured, posting only the disabled URL **drops the others** — send the complete array to re-enable one of many. Incoming payloads include messages, delivery ACKs, group updates, coexistence echoes, and calling events. WhatsApp Calling payloads (`type: \"calls\"`) are documented under the **Calling** tag. Call permission replies arrive on the normal messages path (`call_permission_reply`). Repeating `POST /webhook` with the same URL(s) clears an auto-disable (self-serve re-enable). Send/receive are not affected by webhook auto-disable. + * Set webhook URL + */ + async setWebhookRaw(requestParameters: SetWebhookOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.setWebhookRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => SetWebhook200ResponseFromJSON(jsonValue)); + } + + /** + * Set the client webhook URL that receives inbound events for this channel. **Replaces** the stored webhook list (it does not append). To deliver the same events to several endpoints, pass an array in `webhookUrl` (max 5) or use `POST /settings`. With several URLs already configured, posting only the disabled URL **drops the others** — send the complete array to re-enable one of many. Incoming payloads include messages, delivery ACKs, group updates, coexistence echoes, and calling events. WhatsApp Calling payloads (`type: \"calls\"`) are documented under the **Calling** tag. Call permission replies arrive on the normal messages path (`call_permission_reply`). Repeating `POST /webhook` with the same URL(s) clears an auto-disable (self-serve re-enable). Send/receive are not affected by webhook auto-disable. + * Set webhook URL + */ + async setWebhook(token: string, setWebhookRequest: SetWebhookRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.setWebhookRaw({ token: token, setWebhookRequest: setWebhookRequest }, initOverrides); + return await response.value(); + } + +} diff --git a/typescript/src/generated/src/apis/index.ts b/typescript/src/generated/src/apis/index.ts new file mode 100644 index 0000000..3d22236 --- /dev/null +++ b/typescript/src/generated/src/apis/index.ts @@ -0,0 +1,12 @@ +/* tslint:disable */ +/* eslint-disable */ +export { CallingApi } from './CallingApi'; +export { CatalogApi } from './CatalogApi'; +export { ChannelApi } from './ChannelApi'; +export { FlowsApi } from './FlowsApi'; +export { GroupsApi } from './GroupsApi'; +export { MessagingApi } from './MessagingApi'; +export { ProfileApi } from './ProfileApi'; +export { TemplatesApi } from './TemplatesApi'; +export { UsersApi } from './UsersApi'; +export { WebhooksApi } from './WebhooksApi'; diff --git a/typescript/src/generated/src/index.ts b/typescript/src/generated/src/index.ts new file mode 100644 index 0000000..bebe8bb --- /dev/null +++ b/typescript/src/generated/src/index.ts @@ -0,0 +1,5 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './runtime'; +export * from './apis/index'; +export * from './models/index'; diff --git a/typescript/src/generated/src/models/AddTemplate200Response.ts b/typescript/src/generated/src/models/AddTemplate200Response.ts new file mode 100644 index 0000000..02ef663 --- /dev/null +++ b/typescript/src/generated/src/models/AddTemplate200Response.ts @@ -0,0 +1,68 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface AddTemplate200Response + */ +export interface AddTemplate200Response { + [key: string]: any | any; + /** + * Upstream create-template payload + * @type {{ [key: string]: any; }} + * @memberof AddTemplate200Response + */ + response?: ({ [key: string]: any; }) | undefined; +} + +/** + * Check if a given object implements the AddTemplate200Response interface. + */ +export function instanceOfAddTemplate200Response(value: object): value is AddTemplate200Response { + return true; +} + +export function AddTemplate200ResponseFromJSON(json: any): AddTemplate200Response { + return AddTemplate200ResponseFromJSONTyped(json, false); +} + +export function AddTemplate200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): AddTemplate200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'response': json['response'] == null ? undefined : json['response'], + }; +} + +export function AddTemplate200ResponseToJSON(json: any): AddTemplate200Response { + return AddTemplate200ResponseToJSONTyped(json, false); +} + +export function AddTemplate200ResponseToJSONTyped(value?: AddTemplate200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'response': value['response'], + }; +} + diff --git a/typescript/src/generated/src/models/AddTemplateRequest.ts b/typescript/src/generated/src/models/AddTemplateRequest.ts new file mode 100644 index 0000000..5700f4d --- /dev/null +++ b/typescript/src/generated/src/models/AddTemplateRequest.ts @@ -0,0 +1,92 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface AddTemplateRequest + */ +export interface AddTemplateRequest { + [key: string]: any | any; + /** + * Template name + * @type {string} + * @memberof AddTemplateRequest + */ + name?: (string) | undefined; + /** + * MARKETING, UTILITY, or AUTHENTICATION + * @type {string} + * @memberof AddTemplateRequest + */ + category?: (string) | undefined; + /** + * Template language code (e.g. en_US) + * @type {string} + * @memberof AddTemplateRequest + */ + language?: (string) | undefined; + /** + * Template components (HEADER, BODY, FOOTER, BUTTONS, CAROUSEL) + * @type {Array<{ [key: string]: any; }>} + * @memberof AddTemplateRequest + */ + components?: (Array<{ [key: string]: any; }>) | undefined; +} + +/** + * Check if a given object implements the AddTemplateRequest interface. + */ +export function instanceOfAddTemplateRequest(value: object): value is AddTemplateRequest { + return true; +} + +export function AddTemplateRequestFromJSON(json: any): AddTemplateRequest { + return AddTemplateRequestFromJSONTyped(json, false); +} + +export function AddTemplateRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): AddTemplateRequest { + if (json == null) { + return json; + } + return { + + ...json, + 'name': json['name'] == null ? undefined : json['name'], + 'category': json['category'] == null ? undefined : json['category'], + 'language': json['language'] == null ? undefined : json['language'], + 'components': json['components'] == null ? undefined : json['components'], + }; +} + +export function AddTemplateRequestToJSON(json: any): AddTemplateRequest { + return AddTemplateRequestToJSONTyped(json, false); +} + +export function AddTemplateRequestToJSONTyped(value?: AddTemplateRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'name': value['name'], + 'category': value['category'], + 'language': value['language'], + 'components': value['components'], + }; +} + diff --git a/typescript/src/generated/src/models/BlockUserRequest.ts b/typescript/src/generated/src/models/BlockUserRequest.ts new file mode 100644 index 0000000..ba05a77 --- /dev/null +++ b/typescript/src/generated/src/models/BlockUserRequest.ts @@ -0,0 +1,69 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface BlockUserRequest + */ +export interface BlockUserRequest { + [key: string]: any | any; + /** + * + * @type {number} + * @memberof BlockUserRequest + */ + phone: number; +} + +/** + * Check if a given object implements the BlockUserRequest interface. + */ +export function instanceOfBlockUserRequest(value: object): value is BlockUserRequest { + if (!('phone' in value) || value['phone'] === undefined) return false; + return true; +} + +export function BlockUserRequestFromJSON(json: any): BlockUserRequest { + return BlockUserRequestFromJSONTyped(json, false); +} + +export function BlockUserRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): BlockUserRequest { + if (json == null) { + return json; + } + return { + + ...json, + 'phone': json['phone'], + }; +} + +export function BlockUserRequestToJSON(json: any): BlockUserRequest { + return BlockUserRequestToJSONTyped(json, false); +} + +export function BlockUserRequestToJSONTyped(value?: BlockUserRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'phone': value['phone'], + }; +} + diff --git a/typescript/src/generated/src/models/CallingSettings.ts b/typescript/src/generated/src/models/CallingSettings.ts new file mode 100644 index 0000000..69f9632 --- /dev/null +++ b/typescript/src/generated/src/models/CallingSettings.ts @@ -0,0 +1,79 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { CallingSettingsCalling } from './CallingSettingsCalling'; +import { + CallingSettingsCallingFromJSON, + CallingSettingsCallingFromJSONTyped, + CallingSettingsCallingToJSON, + CallingSettingsCallingToJSONTyped, +} from './CallingSettingsCalling'; + +/** + * Calling settings payload for GET/POST `/callingSettings`. + * Proxies upstream `GET|POST /calling/settings`. + * Extra Meta fields may appear on GET responses; document core fields below. + * + * @export + * @interface CallingSettings + */ +export interface CallingSettings { + [key: string]: any | any; + /** + * + * @type {CallingSettingsCalling} + * @memberof CallingSettings + */ + calling?: (CallingSettingsCalling) | undefined; +} + +/** + * Check if a given object implements the CallingSettings interface. + */ +export function instanceOfCallingSettings(value: object): value is CallingSettings { + return true; +} + +export function CallingSettingsFromJSON(json: any): CallingSettings { + return CallingSettingsFromJSONTyped(json, false); +} + +export function CallingSettingsFromJSONTyped(json: any, ignoreDiscriminator: boolean): CallingSettings { + if (json == null) { + return json; + } + return { + + ...json, + 'calling': json['calling'] == null ? undefined : CallingSettingsCallingFromJSON(json['calling']), + }; +} + +export function CallingSettingsToJSON(json: any): CallingSettings { + return CallingSettingsToJSONTyped(json, false); +} + +export function CallingSettingsToJSONTyped(value?: CallingSettings | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'calling': CallingSettingsCallingToJSON(value['calling']), + }; +} + diff --git a/typescript/src/generated/src/models/CallingSettingsCalling.ts b/typescript/src/generated/src/models/CallingSettingsCalling.ts new file mode 100644 index 0000000..93d54f1 --- /dev/null +++ b/typescript/src/generated/src/models/CallingSettingsCalling.ts @@ -0,0 +1,219 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { CallingSettingsCallingSip } from './CallingSettingsCallingSip'; +import { + CallingSettingsCallingSipFromJSON, + CallingSettingsCallingSipFromJSONTyped, + CallingSettingsCallingSipToJSON, + CallingSettingsCallingSipToJSONTyped, +} from './CallingSettingsCallingSip'; +import type { CallingSettingsCallingAudio } from './CallingSettingsCallingAudio'; +import { + CallingSettingsCallingAudioFromJSON, + CallingSettingsCallingAudioFromJSONTyped, + CallingSettingsCallingAudioToJSON, + CallingSettingsCallingAudioToJSONTyped, +} from './CallingSettingsCallingAudio'; +import type { CallingSettingsCallingCallHours } from './CallingSettingsCallingCallHours'; +import { + CallingSettingsCallingCallHoursFromJSON, + CallingSettingsCallingCallHoursFromJSONTyped, + CallingSettingsCallingCallHoursToJSON, + CallingSettingsCallingCallHoursToJSONTyped, +} from './CallingSettingsCallingCallHours'; +import type { CallingSettingsCallingVideo } from './CallingSettingsCallingVideo'; +import { + CallingSettingsCallingVideoFromJSON, + CallingSettingsCallingVideoFromJSONTyped, + CallingSettingsCallingVideoToJSON, + CallingSettingsCallingVideoToJSONTyped, +} from './CallingSettingsCallingVideo'; + +/** + * Calling feature configuration for the business phone number + * @export + * @interface CallingSettingsCalling + */ +export interface CallingSettingsCalling { + [key: string]: any | any; + /** + * Enable or disable Calling API on this number + * @type {CallingSettingsCallingStatusEnum} + * @memberof CallingSettingsCalling + */ + status?: (CallingSettingsCallingStatusEnum) | undefined; + /** + * Controls call icon visibility in the WhatsApp client + * @type {CallingSettingsCallingCallIconVisibilityEnum} + * @memberof CallingSettingsCalling + */ + callIconVisibility?: (CallingSettingsCallingCallIconVisibilityEnum) | undefined; + /** + * When ENABLED, a user who calls your business automatically grants + * call permission for business-initiated callbacks (subject to Meta rules). + * + * @type {CallingSettingsCallingCallbackPermissionStatusEnum} + * @memberof CallingSettingsCalling + */ + callbackPermissionStatus?: (CallingSettingsCallingCallbackPermissionStatusEnum) | undefined; + /** + * SRTP key exchange. DTLS is default/recommended. + * SDES is only valid when SIP signaling is enabled. + * + * @type {CallingSettingsCallingSrtpKeyExchangeProtocolEnum} + * @memberof CallingSettingsCalling + */ + srtpKeyExchangeProtocol?: (CallingSettingsCallingSrtpKeyExchangeProtocolEnum) | undefined; + /** + * + * @type {CallingSettingsCallingCallHours} + * @memberof CallingSettingsCalling + */ + callHours?: (CallingSettingsCallingCallHours) | undefined; + /** + * + * @type {CallingSettingsCallingSip} + * @memberof CallingSettingsCalling + */ + sip?: (CallingSettingsCallingSip) | undefined; + /** + * + * @type {CallingSettingsCallingVideo} + * @memberof CallingSettingsCalling + */ + video?: (CallingSettingsCallingVideo) | undefined; + /** + * + * @type {CallingSettingsCallingAudio} + * @memberof CallingSettingsCalling + */ + audio?: (CallingSettingsCallingAudio) | undefined; + /** + * Calling restrictions (response-only) + * @type {{ [key: string]: any; }} + * @memberof CallingSettingsCalling + */ + restrictions?: ({ [key: string]: any; }) | undefined; + /** + * Meta media IP ranges (response-only) + * @type {{ [key: string]: any; }} + * @memberof CallingSettingsCalling + */ + ipAddresses?: ({ [key: string]: any; }) | undefined; + /** + * Call icon country restrictions (response-only) + * @type {{ [key: string]: any; }} + * @memberof CallingSettingsCalling + */ + callIcons?: ({ [key: string]: any; }) | undefined; +} + + +/** + * @export + */ +export const CallingSettingsCallingStatusEnum = { + Enabled: 'ENABLED', + Disabled: 'DISABLED' +} as const; +export type CallingSettingsCallingStatusEnum = typeof CallingSettingsCallingStatusEnum[keyof typeof CallingSettingsCallingStatusEnum]; + +/** + * @export + */ +export const CallingSettingsCallingCallIconVisibilityEnum = { + Default: 'DEFAULT', + DisableAll: 'DISABLE_ALL' +} as const; +export type CallingSettingsCallingCallIconVisibilityEnum = typeof CallingSettingsCallingCallIconVisibilityEnum[keyof typeof CallingSettingsCallingCallIconVisibilityEnum]; + +/** + * @export + */ +export const CallingSettingsCallingCallbackPermissionStatusEnum = { + Enabled: 'ENABLED', + Disabled: 'DISABLED' +} as const; +export type CallingSettingsCallingCallbackPermissionStatusEnum = typeof CallingSettingsCallingCallbackPermissionStatusEnum[keyof typeof CallingSettingsCallingCallbackPermissionStatusEnum]; + +/** + * @export + */ +export const CallingSettingsCallingSrtpKeyExchangeProtocolEnum = { + Dtls: 'DTLS', + Sdes: 'SDES' +} as const; +export type CallingSettingsCallingSrtpKeyExchangeProtocolEnum = typeof CallingSettingsCallingSrtpKeyExchangeProtocolEnum[keyof typeof CallingSettingsCallingSrtpKeyExchangeProtocolEnum]; + + +/** + * Check if a given object implements the CallingSettingsCalling interface. + */ +export function instanceOfCallingSettingsCalling(value: object): value is CallingSettingsCalling { + return true; +} + +export function CallingSettingsCallingFromJSON(json: any): CallingSettingsCalling { + return CallingSettingsCallingFromJSONTyped(json, false); +} + +export function CallingSettingsCallingFromJSONTyped(json: any, ignoreDiscriminator: boolean): CallingSettingsCalling { + if (json == null) { + return json; + } + return { + + ...json, + 'status': json['status'] == null ? undefined : json['status'], + 'callIconVisibility': json['call_icon_visibility'] == null ? undefined : json['call_icon_visibility'], + 'callbackPermissionStatus': json['callback_permission_status'] == null ? undefined : json['callback_permission_status'], + 'srtpKeyExchangeProtocol': json['srtp_key_exchange_protocol'] == null ? undefined : json['srtp_key_exchange_protocol'], + 'callHours': json['call_hours'] == null ? undefined : CallingSettingsCallingCallHoursFromJSON(json['call_hours']), + 'sip': json['sip'] == null ? undefined : CallingSettingsCallingSipFromJSON(json['sip']), + 'video': json['video'] == null ? undefined : CallingSettingsCallingVideoFromJSON(json['video']), + 'audio': json['audio'] == null ? undefined : CallingSettingsCallingAudioFromJSON(json['audio']), + 'restrictions': json['restrictions'] == null ? undefined : json['restrictions'], + 'ipAddresses': json['ip_addresses'] == null ? undefined : json['ip_addresses'], + 'callIcons': json['call_icons'] == null ? undefined : json['call_icons'], + }; +} + +export function CallingSettingsCallingToJSON(json: any): CallingSettingsCalling { + return CallingSettingsCallingToJSONTyped(json, false); +} + +export function CallingSettingsCallingToJSONTyped(value?: CallingSettingsCalling | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'status': value['status'], + 'call_icon_visibility': value['callIconVisibility'], + 'callback_permission_status': value['callbackPermissionStatus'], + 'srtp_key_exchange_protocol': value['srtpKeyExchangeProtocol'], + 'call_hours': CallingSettingsCallingCallHoursToJSON(value['callHours']), + 'sip': CallingSettingsCallingSipToJSON(value['sip']), + 'video': CallingSettingsCallingVideoToJSON(value['video']), + 'audio': CallingSettingsCallingAudioToJSON(value['audio']), + 'restrictions': value['restrictions'], + 'ip_addresses': value['ipAddresses'], + 'call_icons': value['callIcons'], + }; +} + diff --git a/typescript/src/generated/src/models/CallingSettingsCallingAudio.ts b/typescript/src/generated/src/models/CallingSettingsCallingAudio.ts new file mode 100644 index 0000000..e910125 --- /dev/null +++ b/typescript/src/generated/src/models/CallingSettingsCallingAudio.ts @@ -0,0 +1,68 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * Audio settings (typically response-only) + * @export + * @interface CallingSettingsCallingAudio + */ +export interface CallingSettingsCallingAudio { + [key: string]: any | any; + /** + * + * @type {string} + * @memberof CallingSettingsCallingAudio + */ + status?: (string) | undefined; +} + +/** + * Check if a given object implements the CallingSettingsCallingAudio interface. + */ +export function instanceOfCallingSettingsCallingAudio(value: object): value is CallingSettingsCallingAudio { + return true; +} + +export function CallingSettingsCallingAudioFromJSON(json: any): CallingSettingsCallingAudio { + return CallingSettingsCallingAudioFromJSONTyped(json, false); +} + +export function CallingSettingsCallingAudioFromJSONTyped(json: any, ignoreDiscriminator: boolean): CallingSettingsCallingAudio { + if (json == null) { + return json; + } + return { + + ...json, + 'status': json['status'] == null ? undefined : json['status'], + }; +} + +export function CallingSettingsCallingAudioToJSON(json: any): CallingSettingsCallingAudio { + return CallingSettingsCallingAudioToJSONTyped(json, false); +} + +export function CallingSettingsCallingAudioToJSONTyped(value?: CallingSettingsCallingAudio | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'status': value['status'], + }; +} + diff --git a/typescript/src/generated/src/models/CallingSettingsCallingCallHours.ts b/typescript/src/generated/src/models/CallingSettingsCallingCallHours.ts new file mode 100644 index 0000000..5cd94b2 --- /dev/null +++ b/typescript/src/generated/src/models/CallingSettingsCallingCallHours.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * Optional call hours / timezone configuration (Meta shape) + * @export + * @interface CallingSettingsCallingCallHours + */ +export interface CallingSettingsCallingCallHours { + [key: string]: any | any; + /** + * + * @type {string} + * @memberof CallingSettingsCallingCallHours + */ + status?: (string) | undefined; + /** + * + * @type {string} + * @memberof CallingSettingsCallingCallHours + */ + timezone?: (string) | undefined; + /** + * + * @type {string} + * @memberof CallingSettingsCallingCallHours + */ + dayOfWeekStart?: (string) | undefined; +} + +/** + * Check if a given object implements the CallingSettingsCallingCallHours interface. + */ +export function instanceOfCallingSettingsCallingCallHours(value: object): value is CallingSettingsCallingCallHours { + return true; +} + +export function CallingSettingsCallingCallHoursFromJSON(json: any): CallingSettingsCallingCallHours { + return CallingSettingsCallingCallHoursFromJSONTyped(json, false); +} + +export function CallingSettingsCallingCallHoursFromJSONTyped(json: any, ignoreDiscriminator: boolean): CallingSettingsCallingCallHours { + if (json == null) { + return json; + } + return { + + ...json, + 'status': json['status'] == null ? undefined : json['status'], + 'timezone': json['timezone'] == null ? undefined : json['timezone'], + 'dayOfWeekStart': json['day_of_week_start'] == null ? undefined : json['day_of_week_start'], + }; +} + +export function CallingSettingsCallingCallHoursToJSON(json: any): CallingSettingsCallingCallHours { + return CallingSettingsCallingCallHoursToJSONTyped(json, false); +} + +export function CallingSettingsCallingCallHoursToJSONTyped(value?: CallingSettingsCallingCallHours | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'status': value['status'], + 'timezone': value['timezone'], + 'day_of_week_start': value['dayOfWeekStart'], + }; +} + diff --git a/typescript/src/generated/src/models/CallingSettingsCallingSip.ts b/typescript/src/generated/src/models/CallingSettingsCallingSip.ts new file mode 100644 index 0000000..0b509f4 --- /dev/null +++ b/typescript/src/generated/src/models/CallingSettingsCallingSip.ts @@ -0,0 +1,97 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { CallingSettingsCallingSipServersInner } from './CallingSettingsCallingSipServersInner'; +import { + CallingSettingsCallingSipServersInnerFromJSON, + CallingSettingsCallingSipServersInnerFromJSONTyped, + CallingSettingsCallingSipServersInnerToJSON, + CallingSettingsCallingSipServersInnerToJSONTyped, +} from './CallingSettingsCallingSipServersInner'; + +/** + * SIP trunk settings. When SIP is ENABLED, Graph call actions and + * calling webhooks are not used — Meta dials your SIP server directly. + * + * @export + * @interface CallingSettingsCallingSip + */ +export interface CallingSettingsCallingSip { + [key: string]: any | any; + /** + * + * @type {CallingSettingsCallingSipStatusEnum} + * @memberof CallingSettingsCallingSip + */ + status?: (CallingSettingsCallingSipStatusEnum) | undefined; + /** + * + * @type {Array} + * @memberof CallingSettingsCallingSip + */ + servers?: (Array) | undefined; +} + + +/** + * @export + */ +export const CallingSettingsCallingSipStatusEnum = { + Enabled: 'ENABLED', + Disabled: 'DISABLED' +} as const; +export type CallingSettingsCallingSipStatusEnum = typeof CallingSettingsCallingSipStatusEnum[keyof typeof CallingSettingsCallingSipStatusEnum]; + + +/** + * Check if a given object implements the CallingSettingsCallingSip interface. + */ +export function instanceOfCallingSettingsCallingSip(value: object): value is CallingSettingsCallingSip { + return true; +} + +export function CallingSettingsCallingSipFromJSON(json: any): CallingSettingsCallingSip { + return CallingSettingsCallingSipFromJSONTyped(json, false); +} + +export function CallingSettingsCallingSipFromJSONTyped(json: any, ignoreDiscriminator: boolean): CallingSettingsCallingSip { + if (json == null) { + return json; + } + return { + + ...json, + 'status': json['status'] == null ? undefined : json['status'], + 'servers': json['servers'] == null ? undefined : ((json['servers'] as Array).map(CallingSettingsCallingSipServersInnerFromJSON)), + }; +} + +export function CallingSettingsCallingSipToJSON(json: any): CallingSettingsCallingSip { + return CallingSettingsCallingSipToJSONTyped(json, false); +} + +export function CallingSettingsCallingSipToJSONTyped(value?: CallingSettingsCallingSip | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'status': value['status'], + 'servers': value['servers'] == null ? undefined : ((value['servers'] as Array).map(CallingSettingsCallingSipServersInnerToJSON)), + }; +} + diff --git a/typescript/src/generated/src/models/CallingSettingsCallingSipServersInner.ts b/typescript/src/generated/src/models/CallingSettingsCallingSipServersInner.ts new file mode 100644 index 0000000..310f8b3 --- /dev/null +++ b/typescript/src/generated/src/models/CallingSettingsCallingSipServersInner.ts @@ -0,0 +1,108 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface CallingSettingsCallingSipServersInner + */ +export interface CallingSettingsCallingSipServersInner { + [key: string]: any | any; + /** + * + * @type {string} + * @memberof CallingSettingsCallingSipServersInner + */ + hostname?: (string) | undefined; + /** + * + * @type {number} + * @memberof CallingSettingsCallingSipServersInner + */ + port?: (number) | undefined; + /** + * + * @type {{ [key: string]: string; }} + * @memberof CallingSettingsCallingSipServersInner + */ + requestUriUserParams?: ({ [key: string]: string; }) | undefined; + /** + * Present on GET when SIP credentials are returned by Meta + * @type {string} + * @memberof CallingSettingsCallingSipServersInner + */ + sipUserPassword?: (string) | undefined; + /** + * Alternate password field name from some Meta responses + * @type {string} + * @memberof CallingSettingsCallingSipServersInner + */ + password?: (string) | undefined; + /** + * + * @type {string} + * @memberof CallingSettingsCallingSipServersInner + */ + appId?: (string) | undefined; +} + +/** + * Check if a given object implements the CallingSettingsCallingSipServersInner interface. + */ +export function instanceOfCallingSettingsCallingSipServersInner(value: object): value is CallingSettingsCallingSipServersInner { + return true; +} + +export function CallingSettingsCallingSipServersInnerFromJSON(json: any): CallingSettingsCallingSipServersInner { + return CallingSettingsCallingSipServersInnerFromJSONTyped(json, false); +} + +export function CallingSettingsCallingSipServersInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): CallingSettingsCallingSipServersInner { + if (json == null) { + return json; + } + return { + + ...json, + 'hostname': json['hostname'] == null ? undefined : json['hostname'], + 'port': json['port'] == null ? undefined : json['port'], + 'requestUriUserParams': json['request_uri_user_params'] == null ? undefined : json['request_uri_user_params'], + 'sipUserPassword': json['sip_user_password'] == null ? undefined : json['sip_user_password'], + 'password': json['password'] == null ? undefined : json['password'], + 'appId': json['app_id'] == null ? undefined : json['app_id'], + }; +} + +export function CallingSettingsCallingSipServersInnerToJSON(json: any): CallingSettingsCallingSipServersInner { + return CallingSettingsCallingSipServersInnerToJSONTyped(json, false); +} + +export function CallingSettingsCallingSipServersInnerToJSONTyped(value?: CallingSettingsCallingSipServersInner | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'hostname': value['hostname'], + 'port': value['port'], + 'request_uri_user_params': value['requestUriUserParams'], + 'sip_user_password': value['sipUserPassword'], + 'password': value['password'], + 'app_id': value['appId'], + }; +} + diff --git a/typescript/src/generated/src/models/CallingSettingsCallingVideo.ts b/typescript/src/generated/src/models/CallingSettingsCallingVideo.ts new file mode 100644 index 0000000..13336c5 --- /dev/null +++ b/typescript/src/generated/src/models/CallingSettingsCallingVideo.ts @@ -0,0 +1,79 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * Video calling toggle when supported + * @export + * @interface CallingSettingsCallingVideo + */ +export interface CallingSettingsCallingVideo { + [key: string]: any | any; + /** + * + * @type {CallingSettingsCallingVideoStatusEnum} + * @memberof CallingSettingsCallingVideo + */ + status?: (CallingSettingsCallingVideoStatusEnum) | undefined; +} + + +/** + * @export + */ +export const CallingSettingsCallingVideoStatusEnum = { + Enabled: 'ENABLED', + Disabled: 'DISABLED' +} as const; +export type CallingSettingsCallingVideoStatusEnum = typeof CallingSettingsCallingVideoStatusEnum[keyof typeof CallingSettingsCallingVideoStatusEnum]; + + +/** + * Check if a given object implements the CallingSettingsCallingVideo interface. + */ +export function instanceOfCallingSettingsCallingVideo(value: object): value is CallingSettingsCallingVideo { + return true; +} + +export function CallingSettingsCallingVideoFromJSON(json: any): CallingSettingsCallingVideo { + return CallingSettingsCallingVideoFromJSONTyped(json, false); +} + +export function CallingSettingsCallingVideoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CallingSettingsCallingVideo { + if (json == null) { + return json; + } + return { + + ...json, + 'status': json['status'] == null ? undefined : json['status'], + }; +} + +export function CallingSettingsCallingVideoToJSON(json: any): CallingSettingsCallingVideo { + return CallingSettingsCallingVideoToJSONTyped(json, false); +} + +export function CallingSettingsCallingVideoToJSONTyped(value?: CallingSettingsCallingVideo | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'status': value['status'], + }; +} + diff --git a/typescript/src/generated/src/models/ConversationalAutomation.ts b/typescript/src/generated/src/models/ConversationalAutomation.ts new file mode 100644 index 0000000..f0f7e14 --- /dev/null +++ b/typescript/src/generated/src/models/ConversationalAutomation.ts @@ -0,0 +1,92 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { ConversationalAutomationCommandsInner } from './ConversationalAutomationCommandsInner'; +import { + ConversationalAutomationCommandsInnerFromJSON, + ConversationalAutomationCommandsInnerFromJSONTyped, + ConversationalAutomationCommandsInnerToJSON, + ConversationalAutomationCommandsInnerToJSONTyped, +} from './ConversationalAutomationCommandsInner'; + +/** + * + * @export + * @interface ConversationalAutomation + */ +export interface ConversationalAutomation { + [key: string]: any | any; + /** + * Enable the automatic welcome message for new conversations + * @type {boolean} + * @memberof ConversationalAutomation + */ + enableWelcomeMessage?: (boolean) | undefined; + /** + * Ice-breaker prompt strings (max 4, each ≤ 80 characters) + * @type {Array} + * @memberof ConversationalAutomation + */ + prompts?: (Array) | undefined; + /** + * Slash commands shown in WhatsApp + * @type {Array} + * @memberof ConversationalAutomation + */ + commands?: (Array) | undefined; +} + +/** + * Check if a given object implements the ConversationalAutomation interface. + */ +export function instanceOfConversationalAutomation(value: object): value is ConversationalAutomation { + return true; +} + +export function ConversationalAutomationFromJSON(json: any): ConversationalAutomation { + return ConversationalAutomationFromJSONTyped(json, false); +} + +export function ConversationalAutomationFromJSONTyped(json: any, ignoreDiscriminator: boolean): ConversationalAutomation { + if (json == null) { + return json; + } + return { + + ...json, + 'enableWelcomeMessage': json['enable_welcome_message'] == null ? undefined : json['enable_welcome_message'], + 'prompts': json['prompts'] == null ? undefined : json['prompts'], + 'commands': json['commands'] == null ? undefined : ((json['commands'] as Array).map(ConversationalAutomationCommandsInnerFromJSON)), + }; +} + +export function ConversationalAutomationToJSON(json: any): ConversationalAutomation { + return ConversationalAutomationToJSONTyped(json, false); +} + +export function ConversationalAutomationToJSONTyped(value?: ConversationalAutomation | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'enable_welcome_message': value['enableWelcomeMessage'], + 'prompts': value['prompts'], + 'commands': value['commands'] == null ? undefined : ((value['commands'] as Array).map(ConversationalAutomationCommandsInnerToJSON)), + }; +} + diff --git a/typescript/src/generated/src/models/ConversationalAutomationCommandsInner.ts b/typescript/src/generated/src/models/ConversationalAutomationCommandsInner.ts new file mode 100644 index 0000000..f7e5293 --- /dev/null +++ b/typescript/src/generated/src/models/ConversationalAutomationCommandsInner.ts @@ -0,0 +1,78 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface ConversationalAutomationCommandsInner + */ +export interface ConversationalAutomationCommandsInner { + [key: string]: any | any; + /** + * + * @type {string} + * @memberof ConversationalAutomationCommandsInner + */ + commandName: string; + /** + * + * @type {string} + * @memberof ConversationalAutomationCommandsInner + */ + commandDescription: string; +} + +/** + * Check if a given object implements the ConversationalAutomationCommandsInner interface. + */ +export function instanceOfConversationalAutomationCommandsInner(value: object): value is ConversationalAutomationCommandsInner { + if (!('commandName' in value) || value['commandName'] === undefined) return false; + if (!('commandDescription' in value) || value['commandDescription'] === undefined) return false; + return true; +} + +export function ConversationalAutomationCommandsInnerFromJSON(json: any): ConversationalAutomationCommandsInner { + return ConversationalAutomationCommandsInnerFromJSONTyped(json, false); +} + +export function ConversationalAutomationCommandsInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): ConversationalAutomationCommandsInner { + if (json == null) { + return json; + } + return { + + ...json, + 'commandName': json['command_name'], + 'commandDescription': json['command_description'], + }; +} + +export function ConversationalAutomationCommandsInnerToJSON(json: any): ConversationalAutomationCommandsInner { + return ConversationalAutomationCommandsInnerToJSONTyped(json, false); +} + +export function ConversationalAutomationCommandsInnerToJSONTyped(value?: ConversationalAutomationCommandsInner | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'command_name': value['commandName'], + 'command_description': value['commandDescription'], + }; +} + diff --git a/typescript/src/generated/src/models/CreateCommerce200Response.ts b/typescript/src/generated/src/models/CreateCommerce200Response.ts new file mode 100644 index 0000000..3091f47 --- /dev/null +++ b/typescript/src/generated/src/models/CreateCommerce200Response.ts @@ -0,0 +1,68 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateCommerce200Response + */ +export interface CreateCommerce200Response { + [key: string]: any | any; + /** + * + * @type {boolean} + * @memberof CreateCommerce200Response + */ + success?: (boolean) | undefined; +} + +/** + * Check if a given object implements the CreateCommerce200Response interface. + */ +export function instanceOfCreateCommerce200Response(value: object): value is CreateCommerce200Response { + return true; +} + +export function CreateCommerce200ResponseFromJSON(json: any): CreateCommerce200Response { + return CreateCommerce200ResponseFromJSONTyped(json, false); +} + +export function CreateCommerce200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateCommerce200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'success': json['success'] == null ? undefined : json['success'], + }; +} + +export function CreateCommerce200ResponseToJSON(json: any): CreateCommerce200Response { + return CreateCommerce200ResponseToJSONTyped(json, false); +} + +export function CreateCommerce200ResponseToJSONTyped(value?: CreateCommerce200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'success': value['success'], + }; +} + diff --git a/typescript/src/generated/src/models/CreateCommerceRequest.ts b/typescript/src/generated/src/models/CreateCommerceRequest.ts new file mode 100644 index 0000000..8ee2d18 --- /dev/null +++ b/typescript/src/generated/src/models/CreateCommerceRequest.ts @@ -0,0 +1,77 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { CreateCommerceRequestParams } from './CreateCommerceRequestParams'; +import { + CreateCommerceRequestParamsFromJSON, + CreateCommerceRequestParamsFromJSONTyped, + CreateCommerceRequestParamsToJSON, + CreateCommerceRequestParamsToJSONTyped, +} from './CreateCommerceRequestParams'; + +/** + * + * @export + * @interface CreateCommerceRequest + */ +export interface CreateCommerceRequest { + [key: string]: any | any; + /** + * + * @type {CreateCommerceRequestParams} + * @memberof CreateCommerceRequest + */ + params: CreateCommerceRequestParams; +} + +/** + * Check if a given object implements the CreateCommerceRequest interface. + */ +export function instanceOfCreateCommerceRequest(value: object): value is CreateCommerceRequest { + if (!('params' in value) || value['params'] === undefined) return false; + return true; +} + +export function CreateCommerceRequestFromJSON(json: any): CreateCommerceRequest { + return CreateCommerceRequestFromJSONTyped(json, false); +} + +export function CreateCommerceRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateCommerceRequest { + if (json == null) { + return json; + } + return { + + ...json, + 'params': CreateCommerceRequestParamsFromJSON(json['params']), + }; +} + +export function CreateCommerceRequestToJSON(json: any): CreateCommerceRequest { + return CreateCommerceRequestToJSONTyped(json, false); +} + +export function CreateCommerceRequestToJSONTyped(value?: CreateCommerceRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'params': CreateCommerceRequestParamsToJSON(value['params']), + }; +} + diff --git a/typescript/src/generated/src/models/CreateCommerceRequestParams.ts b/typescript/src/generated/src/models/CreateCommerceRequestParams.ts new file mode 100644 index 0000000..cd2a823 --- /dev/null +++ b/typescript/src/generated/src/models/CreateCommerceRequestParams.ts @@ -0,0 +1,78 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateCommerceRequestParams + */ +export interface CreateCommerceRequestParams { + [key: string]: any | any; + /** + * Enable cart + * @type {boolean} + * @memberof CreateCommerceRequestParams + */ + isCartEnabled: boolean; + /** + * Show catalog storefront icon + * @type {boolean} + * @memberof CreateCommerceRequestParams + */ + isCatalogVisible: boolean; +} + +/** + * Check if a given object implements the CreateCommerceRequestParams interface. + */ +export function instanceOfCreateCommerceRequestParams(value: object): value is CreateCommerceRequestParams { + if (!('isCartEnabled' in value) || value['isCartEnabled'] === undefined) return false; + if (!('isCatalogVisible' in value) || value['isCatalogVisible'] === undefined) return false; + return true; +} + +export function CreateCommerceRequestParamsFromJSON(json: any): CreateCommerceRequestParams { + return CreateCommerceRequestParamsFromJSONTyped(json, false); +} + +export function CreateCommerceRequestParamsFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateCommerceRequestParams { + if (json == null) { + return json; + } + return { + + ...json, + 'isCartEnabled': json['is_cart_enabled'], + 'isCatalogVisible': json['is_catalog_visible'], + }; +} + +export function CreateCommerceRequestParamsToJSON(json: any): CreateCommerceRequestParams { + return CreateCommerceRequestParamsToJSONTyped(json, false); +} + +export function CreateCommerceRequestParamsToJSONTyped(value?: CreateCommerceRequestParams | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'is_cart_enabled': value['isCartEnabled'], + 'is_catalog_visible': value['isCatalogVisible'], + }; +} + diff --git a/typescript/src/generated/src/models/CreateFlowsRequest.ts b/typescript/src/generated/src/models/CreateFlowsRequest.ts new file mode 100644 index 0000000..2c10e25 --- /dev/null +++ b/typescript/src/generated/src/models/CreateFlowsRequest.ts @@ -0,0 +1,116 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateFlowsRequest + */ +export interface CreateFlowsRequest { + /** + * Flow name + * @type {string} + * @memberof CreateFlowsRequest + */ + name: string; + /** + * One or more Flow categories + * @type {Array} + * @memberof CreateFlowsRequest + */ + categories: Array; + /** + * HTTPS endpoint for the Flow data channel + * @type {string} + * @memberof CreateFlowsRequest + */ + endpointUri?: (string) | undefined; + /** + * Publish immediately after create + * @type {boolean} + * @memberof CreateFlowsRequest + */ + publish?: (boolean) | undefined; + /** + * Optional Flow JSON document + * @type {{ [key: string]: any; }} + * @memberof CreateFlowsRequest + */ + flowJson?: ({ [key: string]: any; }) | undefined; +} + + +/** + * @export + */ +export const CreateFlowsRequestCategoriesEnum = { + SignUp: 'SIGN_UP', + SignIn: 'SIGN_IN', + AppointmentBooking: 'APPOINTMENT_BOOKING', + LeadGeneration: 'LEAD_GENERATION', + ContactUs: 'CONTACT_US', + CustomerSupport: 'CUSTOMER_SUPPORT', + Survey: 'SURVEY', + Other: 'OTHER' +} as const; +export type CreateFlowsRequestCategoriesEnum = typeof CreateFlowsRequestCategoriesEnum[keyof typeof CreateFlowsRequestCategoriesEnum]; + + +/** + * Check if a given object implements the CreateFlowsRequest interface. + */ +export function instanceOfCreateFlowsRequest(value: object): value is CreateFlowsRequest { + if (!('name' in value) || value['name'] === undefined) return false; + if (!('categories' in value) || value['categories'] === undefined) return false; + return true; +} + +export function CreateFlowsRequestFromJSON(json: any): CreateFlowsRequest { + return CreateFlowsRequestFromJSONTyped(json, false); +} + +export function CreateFlowsRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateFlowsRequest { + if (json == null) { + return json; + } + return { + + 'name': json['name'], + 'categories': json['categories'], + 'endpointUri': json['endpointUri'] == null ? undefined : json['endpointUri'], + 'publish': json['publish'] == null ? undefined : json['publish'], + 'flowJson': json['flowJson'] == null ? undefined : json['flowJson'], + }; +} + +export function CreateFlowsRequestToJSON(json: any): CreateFlowsRequest { + return CreateFlowsRequestToJSONTyped(json, false); +} + +export function CreateFlowsRequestToJSONTyped(value?: CreateFlowsRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'name': value['name'], + 'categories': value['categories'], + 'endpointUri': value['endpointUri'], + 'publish': value['publish'], + 'flowJson': value['flowJson'], + }; +} + diff --git a/typescript/src/generated/src/models/CreateGroups200Response.ts b/typescript/src/generated/src/models/CreateGroups200Response.ts new file mode 100644 index 0000000..be584d0 --- /dev/null +++ b/typescript/src/generated/src/models/CreateGroups200Response.ts @@ -0,0 +1,68 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateGroups200Response + */ +export interface CreateGroups200Response { + [key: string]: any | any; + /** + * Error details returned by the provider. May be a string or a JSON object. + * @type {any} + * @memberof CreateGroups200Response + */ + error?: (any | null) | undefined; +} + +/** + * Check if a given object implements the CreateGroups200Response interface. + */ +export function instanceOfCreateGroups200Response(value: object): value is CreateGroups200Response { + return true; +} + +export function CreateGroups200ResponseFromJSON(json: any): CreateGroups200Response { + return CreateGroups200ResponseFromJSONTyped(json, false); +} + +export function CreateGroups200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateGroups200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'error': json['error'] == null ? undefined : json['error'], + }; +} + +export function CreateGroups200ResponseToJSON(json: any): CreateGroups200Response { + return CreateGroups200ResponseToJSONTyped(json, false); +} + +export function CreateGroups200ResponseToJSONTyped(value?: CreateGroups200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'error': value['error'], + }; +} + diff --git a/typescript/src/generated/src/models/CreateGroupsGroupIdRequest.ts b/typescript/src/generated/src/models/CreateGroupsGroupIdRequest.ts new file mode 100644 index 0000000..081b4fc --- /dev/null +++ b/typescript/src/generated/src/models/CreateGroupsGroupIdRequest.ts @@ -0,0 +1,81 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateGroupsGroupIdRequest + */ +export interface CreateGroupsGroupIdRequest { + /** + * New group subject / name + * @type {string} + * @memberof CreateGroupsGroupIdRequest + */ + subject?: (string) | undefined; + /** + * New group description + * @type {string} + * @memberof CreateGroupsGroupIdRequest + */ + description?: (string) | undefined; + /** + * Image URL or base64 data URI for the group profile picture + * @type {string} + * @memberof CreateGroupsGroupIdRequest + */ + profilePictureFile?: (string) | undefined; +} + +/** + * Check if a given object implements the CreateGroupsGroupIdRequest interface. + */ +export function instanceOfCreateGroupsGroupIdRequest(value: object): value is CreateGroupsGroupIdRequest { + return true; +} + +export function CreateGroupsGroupIdRequestFromJSON(json: any): CreateGroupsGroupIdRequest { + return CreateGroupsGroupIdRequestFromJSONTyped(json, false); +} + +export function CreateGroupsGroupIdRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateGroupsGroupIdRequest { + if (json == null) { + return json; + } + return { + + 'subject': json['subject'] == null ? undefined : json['subject'], + 'description': json['description'] == null ? undefined : json['description'], + 'profilePictureFile': json['profile_picture_file'] == null ? undefined : json['profile_picture_file'], + }; +} + +export function CreateGroupsGroupIdRequestToJSON(json: any): CreateGroupsGroupIdRequest { + return CreateGroupsGroupIdRequestToJSONTyped(json, false); +} + +export function CreateGroupsGroupIdRequestToJSONTyped(value?: CreateGroupsGroupIdRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'subject': value['subject'], + 'description': value['description'], + 'profile_picture_file': value['profilePictureFile'], + }; +} + diff --git a/typescript/src/generated/src/models/CreateGroupsRequest.ts b/typescript/src/generated/src/models/CreateGroupsRequest.ts new file mode 100644 index 0000000..dde03a3 --- /dev/null +++ b/typescript/src/generated/src/models/CreateGroupsRequest.ts @@ -0,0 +1,74 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateGroupsRequest + */ +export interface CreateGroupsRequest { + /** + * Group subject / name + * @type {string} + * @memberof CreateGroupsRequest + */ + groupName: string; + /** + * Optional group description + * @type {string} + * @memberof CreateGroupsRequest + */ + description?: (string) | undefined; +} + +/** + * Check if a given object implements the CreateGroupsRequest interface. + */ +export function instanceOfCreateGroupsRequest(value: object): value is CreateGroupsRequest { + if (!('groupName' in value) || value['groupName'] === undefined) return false; + return true; +} + +export function CreateGroupsRequestFromJSON(json: any): CreateGroupsRequest { + return CreateGroupsRequestFromJSONTyped(json, false); +} + +export function CreateGroupsRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateGroupsRequest { + if (json == null) { + return json; + } + return { + + 'groupName': json['groupName'], + 'description': json['description'] == null ? undefined : json['description'], + }; +} + +export function CreateGroupsRequestToJSON(json: any): CreateGroupsRequest { + return CreateGroupsRequestToJSONTyped(json, false); +} + +export function CreateGroupsRequestToJSONTyped(value?: CreateGroupsRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'groupName': value['groupName'], + 'description': value['description'], + }; +} + diff --git a/typescript/src/generated/src/models/CreateReadMessage200Response.ts b/typescript/src/generated/src/models/CreateReadMessage200Response.ts new file mode 100644 index 0000000..2ffc0c8 --- /dev/null +++ b/typescript/src/generated/src/models/CreateReadMessage200Response.ts @@ -0,0 +1,68 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateReadMessage200Response + */ +export interface CreateReadMessage200Response { + [key: string]: any | any; + /** + * + * @type {string} + * @memberof CreateReadMessage200Response + */ + result?: (string) | undefined; +} + +/** + * Check if a given object implements the CreateReadMessage200Response interface. + */ +export function instanceOfCreateReadMessage200Response(value: object): value is CreateReadMessage200Response { + return true; +} + +export function CreateReadMessage200ResponseFromJSON(json: any): CreateReadMessage200Response { + return CreateReadMessage200ResponseFromJSONTyped(json, false); +} + +export function CreateReadMessage200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateReadMessage200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'result': json['result'] == null ? undefined : json['result'], + }; +} + +export function CreateReadMessage200ResponseToJSON(json: any): CreateReadMessage200Response { + return CreateReadMessage200ResponseToJSONTyped(json, false); +} + +export function CreateReadMessage200ResponseToJSONTyped(value?: CreateReadMessage200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'result': value['result'], + }; +} + diff --git a/typescript/src/generated/src/models/CreateReadMessage401Response.ts b/typescript/src/generated/src/models/CreateReadMessage401Response.ts new file mode 100644 index 0000000..c8f5099 --- /dev/null +++ b/typescript/src/generated/src/models/CreateReadMessage401Response.ts @@ -0,0 +1,65 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateReadMessage401Response + */ +export interface CreateReadMessage401Response { + /** + * + * @type {string} + * @memberof CreateReadMessage401Response + */ + error?: (string) | undefined; +} + +/** + * Check if a given object implements the CreateReadMessage401Response interface. + */ +export function instanceOfCreateReadMessage401Response(value: object): value is CreateReadMessage401Response { + return true; +} + +export function CreateReadMessage401ResponseFromJSON(json: any): CreateReadMessage401Response { + return CreateReadMessage401ResponseFromJSONTyped(json, false); +} + +export function CreateReadMessage401ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateReadMessage401Response { + if (json == null) { + return json; + } + return { + + 'error': json['error'] == null ? undefined : json['error'], + }; +} + +export function CreateReadMessage401ResponseToJSON(json: any): CreateReadMessage401Response { + return CreateReadMessage401ResponseToJSONTyped(json, false); +} + +export function CreateReadMessage401ResponseToJSONTyped(value?: CreateReadMessage401Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'error': value['error'], + }; +} + diff --git a/typescript/src/generated/src/models/CreateReadMessageRequest.ts b/typescript/src/generated/src/models/CreateReadMessageRequest.ts new file mode 100644 index 0000000..3252d77 --- /dev/null +++ b/typescript/src/generated/src/models/CreateReadMessageRequest.ts @@ -0,0 +1,81 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateReadMessageRequest + */ +export interface CreateReadMessageRequest { + /** + * + * @type {string} + * @memberof CreateReadMessageRequest + */ + messageId?: (string) | undefined; + /** + * + * @type {string} + * @memberof CreateReadMessageRequest + */ + msgId?: (string) | undefined; + /** + * Show WhatsApp typing indicator (max 25s or until reply) + * @type {boolean} + * @memberof CreateReadMessageRequest + */ + typingIndicator?: (boolean) | undefined; +} + +/** + * Check if a given object implements the CreateReadMessageRequest interface. + */ +export function instanceOfCreateReadMessageRequest(value: object): value is CreateReadMessageRequest { + return true; +} + +export function CreateReadMessageRequestFromJSON(json: any): CreateReadMessageRequest { + return CreateReadMessageRequestFromJSONTyped(json, false); +} + +export function CreateReadMessageRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateReadMessageRequest { + if (json == null) { + return json; + } + return { + + 'messageId': json['messageId'] == null ? undefined : json['messageId'], + 'msgId': json['msgId'] == null ? undefined : json['msgId'], + 'typingIndicator': json['typingIndicator'] == null ? undefined : json['typingIndicator'], + }; +} + +export function CreateReadMessageRequestToJSON(json: any): CreateReadMessageRequest { + return CreateReadMessageRequestToJSONTyped(json, false); +} + +export function CreateReadMessageRequestToJSONTyped(value?: CreateReadMessageRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'messageId': value['messageId'], + 'msgId': value['msgId'], + 'typingIndicator': value['typingIndicator'], + }; +} + diff --git a/typescript/src/generated/src/models/CreateSettingsRequest.ts b/typescript/src/generated/src/models/CreateSettingsRequest.ts new file mode 100644 index 0000000..ff61bcc --- /dev/null +++ b/typescript/src/generated/src/models/CreateSettingsRequest.ts @@ -0,0 +1,116 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { CreateSettingsRequestWebhookUrl } from './CreateSettingsRequestWebhookUrl'; +import { + CreateSettingsRequestWebhookUrlFromJSON, + CreateSettingsRequestWebhookUrlFromJSONTyped, + CreateSettingsRequestWebhookUrlToJSON, + CreateSettingsRequestWebhookUrlToJSONTyped, +} from './CreateSettingsRequestWebhookUrl'; + +/** + * + * @export + * @interface CreateSettingsRequest + */ +export interface CreateSettingsRequest { + [key: string]: any | any; + /** + * + * @type {CreateSettingsRequestWebhookUrl} + * @memberof CreateSettingsRequest + */ + webhookUrl?: (CreateSettingsRequestWebhookUrl) | undefined; + /** + * + * @type {boolean} + * @memberof CreateSettingsRequest + */ + guaranteedHooks?: (boolean) | undefined; + /** + * + * @type {boolean} + * @memberof CreateSettingsRequest + */ + ackNotificationsOn?: (boolean) | undefined; + /** + * + * @type {boolean} + * @memberof CreateSettingsRequest + */ + rawHooks?: (boolean) | undefined; + /** + * + * @type {boolean} + * @memberof CreateSettingsRequest + */ + templateAnalyticsEnabled?: (boolean) | undefined; + /** + * + * @type {boolean} + * @memberof CreateSettingsRequest + */ + ctaUrlLinkTrackingOptedOut?: (boolean) | undefined; +} + +/** + * Check if a given object implements the CreateSettingsRequest interface. + */ +export function instanceOfCreateSettingsRequest(value: object): value is CreateSettingsRequest { + return true; +} + +export function CreateSettingsRequestFromJSON(json: any): CreateSettingsRequest { + return CreateSettingsRequestFromJSONTyped(json, false); +} + +export function CreateSettingsRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateSettingsRequest { + if (json == null) { + return json; + } + return { + + ...json, + 'webhookUrl': json['webhookUrl'] == null ? undefined : CreateSettingsRequestWebhookUrlFromJSON(json['webhookUrl']), + 'guaranteedHooks': json['guaranteedHooks'] == null ? undefined : json['guaranteedHooks'], + 'ackNotificationsOn': json['ackNotificationsOn'] == null ? undefined : json['ackNotificationsOn'], + 'rawHooks': json['rawHooks'] == null ? undefined : json['rawHooks'], + 'templateAnalyticsEnabled': json['template_analytics_enabled'] == null ? undefined : json['template_analytics_enabled'], + 'ctaUrlLinkTrackingOptedOut': json['cta_url_link_tracking_opted_out'] == null ? undefined : json['cta_url_link_tracking_opted_out'], + }; +} + +export function CreateSettingsRequestToJSON(json: any): CreateSettingsRequest { + return CreateSettingsRequestToJSONTyped(json, false); +} + +export function CreateSettingsRequestToJSONTyped(value?: CreateSettingsRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'webhookUrl': CreateSettingsRequestWebhookUrlToJSON(value['webhookUrl']), + 'guaranteedHooks': value['guaranteedHooks'], + 'ackNotificationsOn': value['ackNotificationsOn'], + 'rawHooks': value['rawHooks'], + 'template_analytics_enabled': value['templateAnalyticsEnabled'], + 'cta_url_link_tracking_opted_out': value['ctaUrlLinkTrackingOptedOut'], + }; +} + diff --git a/typescript/src/generated/src/models/CreateSettingsRequestWebhookUrl.ts b/typescript/src/generated/src/models/CreateSettingsRequestWebhookUrl.ts new file mode 100644 index 0000000..d1e6b60 --- /dev/null +++ b/typescript/src/generated/src/models/CreateSettingsRequestWebhookUrl.ts @@ -0,0 +1,59 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +/** + * @type CreateSettingsRequestWebhookUrl + * Replacement webhook URL, or array of URLs (max 5) + * @export + */ +export type CreateSettingsRequestWebhookUrl = Array | string; + +export function CreateSettingsRequestWebhookUrlFromJSON(json: any): CreateSettingsRequestWebhookUrl { + return CreateSettingsRequestWebhookUrlFromJSONTyped(json, false); +} + +export function CreateSettingsRequestWebhookUrlFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateSettingsRequestWebhookUrl { + if (json == null) { + return json; + } + if (Array.isArray(json)) { + if (json.every(item => typeof item === 'string')) { + return json; + } + } + if (typeof json === 'string') { + return json; + } + return {} as any; +} + +export function CreateSettingsRequestWebhookUrlToJSON(json: any): any { + return CreateSettingsRequestWebhookUrlToJSONTyped(json, false); +} + +export function CreateSettingsRequestWebhookUrlToJSONTyped(value?: CreateSettingsRequestWebhookUrl | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + if (Array.isArray(value)) { + if (value.every(item => typeof item === 'string')) { + return value; + } + } + if (typeof value === 'string') { + return value; + } + return {}; +} + diff --git a/typescript/src/generated/src/models/CreateUploadMedia200Response.ts b/typescript/src/generated/src/models/CreateUploadMedia200Response.ts new file mode 100644 index 0000000..da752c1 --- /dev/null +++ b/typescript/src/generated/src/models/CreateUploadMedia200Response.ts @@ -0,0 +1,68 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateUploadMedia200Response + */ +export interface CreateUploadMedia200Response { + [key: string]: any | any; + /** + * + * @type {string} + * @memberof CreateUploadMedia200Response + */ + mediaId?: (string) | undefined; +} + +/** + * Check if a given object implements the CreateUploadMedia200Response interface. + */ +export function instanceOfCreateUploadMedia200Response(value: object): value is CreateUploadMedia200Response { + return true; +} + +export function CreateUploadMedia200ResponseFromJSON(json: any): CreateUploadMedia200Response { + return CreateUploadMedia200ResponseFromJSONTyped(json, false); +} + +export function CreateUploadMedia200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateUploadMedia200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'mediaId': json['mediaId'] == null ? undefined : json['mediaId'], + }; +} + +export function CreateUploadMedia200ResponseToJSON(json: any): CreateUploadMedia200Response { + return CreateUploadMedia200ResponseToJSONTyped(json, false); +} + +export function CreateUploadMedia200ResponseToJSONTyped(value?: CreateUploadMedia200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'mediaId': value['mediaId'], + }; +} + diff --git a/typescript/src/generated/src/models/CreateUploadMediaRequest.ts b/typescript/src/generated/src/models/CreateUploadMediaRequest.ts new file mode 100644 index 0000000..66331b1 --- /dev/null +++ b/typescript/src/generated/src/models/CreateUploadMediaRequest.ts @@ -0,0 +1,73 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateUploadMediaRequest + */ +export interface CreateUploadMediaRequest { + /** + * File HTTP(S) URL or base64 data URI (`data:;base64,...`) + * @type {string} + * @memberof CreateUploadMediaRequest + */ + body?: (string) | undefined; + /** + * Alias for `body` — public HTTP(S) URL of the file to upload + * @type {string} + * @memberof CreateUploadMediaRequest + */ + url?: (string) | undefined; +} + +/** + * Check if a given object implements the CreateUploadMediaRequest interface. + */ +export function instanceOfCreateUploadMediaRequest(value: object): value is CreateUploadMediaRequest { + return true; +} + +export function CreateUploadMediaRequestFromJSON(json: any): CreateUploadMediaRequest { + return CreateUploadMediaRequestFromJSONTyped(json, false); +} + +export function CreateUploadMediaRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateUploadMediaRequest { + if (json == null) { + return json; + } + return { + + 'body': json['body'] == null ? undefined : json['body'], + 'url': json['url'] == null ? undefined : json['url'], + }; +} + +export function CreateUploadMediaRequestToJSON(json: any): CreateUploadMediaRequest { + return CreateUploadMediaRequestToJSONTyped(json, false); +} + +export function CreateUploadMediaRequestToJSONTyped(value?: CreateUploadMediaRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'body': value['body'], + 'url': value['url'], + }; +} + diff --git a/typescript/src/generated/src/models/DeleteFlowsFlowId200Response.ts b/typescript/src/generated/src/models/DeleteFlowsFlowId200Response.ts new file mode 100644 index 0000000..35eeb47 --- /dev/null +++ b/typescript/src/generated/src/models/DeleteFlowsFlowId200Response.ts @@ -0,0 +1,76 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface DeleteFlowsFlowId200Response + */ +export interface DeleteFlowsFlowId200Response { + [key: string]: any | any; + /** + * + * @type {boolean} + * @memberof DeleteFlowsFlowId200Response + */ + success?: (boolean) | undefined; + /** + * Error details returned by the provider. May be a string or a JSON object. + * @type {any} + * @memberof DeleteFlowsFlowId200Response + */ + error?: (any | null) | undefined; +} + +/** + * Check if a given object implements the DeleteFlowsFlowId200Response interface. + */ +export function instanceOfDeleteFlowsFlowId200Response(value: object): value is DeleteFlowsFlowId200Response { + return true; +} + +export function DeleteFlowsFlowId200ResponseFromJSON(json: any): DeleteFlowsFlowId200Response { + return DeleteFlowsFlowId200ResponseFromJSONTyped(json, false); +} + +export function DeleteFlowsFlowId200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): DeleteFlowsFlowId200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'success': json['success'] == null ? undefined : json['success'], + 'error': json['error'] == null ? undefined : json['error'], + }; +} + +export function DeleteFlowsFlowId200ResponseToJSON(json: any): DeleteFlowsFlowId200Response { + return DeleteFlowsFlowId200ResponseToJSONTyped(json, false); +} + +export function DeleteFlowsFlowId200ResponseToJSONTyped(value?: DeleteFlowsFlowId200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'success': value['success'], + 'error': value['error'], + }; +} + diff --git a/typescript/src/generated/src/models/DeleteGroupsGroupId200Response.ts b/typescript/src/generated/src/models/DeleteGroupsGroupId200Response.ts new file mode 100644 index 0000000..8f867ce --- /dev/null +++ b/typescript/src/generated/src/models/DeleteGroupsGroupId200Response.ts @@ -0,0 +1,76 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface DeleteGroupsGroupId200Response + */ +export interface DeleteGroupsGroupId200Response { + [key: string]: any | any; + /** + * + * @type {boolean} + * @memberof DeleteGroupsGroupId200Response + */ + success?: (boolean) | undefined; + /** + * + * @type {{ [key: string]: any; }} + * @memberof DeleteGroupsGroupId200Response + */ + response?: ({ [key: string]: any; }) | undefined; +} + +/** + * Check if a given object implements the DeleteGroupsGroupId200Response interface. + */ +export function instanceOfDeleteGroupsGroupId200Response(value: object): value is DeleteGroupsGroupId200Response { + return true; +} + +export function DeleteGroupsGroupId200ResponseFromJSON(json: any): DeleteGroupsGroupId200Response { + return DeleteGroupsGroupId200ResponseFromJSONTyped(json, false); +} + +export function DeleteGroupsGroupId200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): DeleteGroupsGroupId200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'success': json['success'] == null ? undefined : json['success'], + 'response': json['response'] == null ? undefined : json['response'], + }; +} + +export function DeleteGroupsGroupId200ResponseToJSON(json: any): DeleteGroupsGroupId200Response { + return DeleteGroupsGroupId200ResponseToJSONTyped(json, false); +} + +export function DeleteGroupsGroupId200ResponseToJSONTyped(value?: DeleteGroupsGroupId200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'success': value['success'], + 'response': value['response'], + }; +} + diff --git a/typescript/src/generated/src/models/DeleteMediaLegacyRequest.ts b/typescript/src/generated/src/models/DeleteMediaLegacyRequest.ts new file mode 100644 index 0000000..b605bf4 --- /dev/null +++ b/typescript/src/generated/src/models/DeleteMediaLegacyRequest.ts @@ -0,0 +1,69 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface DeleteMediaLegacyRequest + */ +export interface DeleteMediaLegacyRequest { + [key: string]: any | any; + /** + * Numeric WABA media id + * @type {string} + * @memberof DeleteMediaLegacyRequest + */ + mediaId: string; +} + +/** + * Check if a given object implements the DeleteMediaLegacyRequest interface. + */ +export function instanceOfDeleteMediaLegacyRequest(value: object): value is DeleteMediaLegacyRequest { + if (!('mediaId' in value) || value['mediaId'] === undefined) return false; + return true; +} + +export function DeleteMediaLegacyRequestFromJSON(json: any): DeleteMediaLegacyRequest { + return DeleteMediaLegacyRequestFromJSONTyped(json, false); +} + +export function DeleteMediaLegacyRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): DeleteMediaLegacyRequest { + if (json == null) { + return json; + } + return { + + ...json, + 'mediaId': json['mediaId'], + }; +} + +export function DeleteMediaLegacyRequestToJSON(json: any): DeleteMediaLegacyRequest { + return DeleteMediaLegacyRequestToJSONTyped(json, false); +} + +export function DeleteMediaLegacyRequestToJSONTyped(value?: DeleteMediaLegacyRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'mediaId': value['mediaId'], + }; +} + diff --git a/typescript/src/generated/src/models/ErrorResponse.ts b/typescript/src/generated/src/models/ErrorResponse.ts new file mode 100644 index 0000000..ca380b9 --- /dev/null +++ b/typescript/src/generated/src/models/ErrorResponse.ts @@ -0,0 +1,65 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * Standard error response + * @export + * @interface ErrorResponse + */ +export interface ErrorResponse { + /** + * Error message + * @type {string} + * @memberof ErrorResponse + */ + error?: (string) | undefined; +} + +/** + * Check if a given object implements the ErrorResponse interface. + */ +export function instanceOfErrorResponse(value: object): value is ErrorResponse { + return true; +} + +export function ErrorResponseFromJSON(json: any): ErrorResponse { + return ErrorResponseFromJSONTyped(json, false); +} + +export function ErrorResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): ErrorResponse { + if (json == null) { + return json; + } + return { + + 'error': json['error'] == null ? undefined : json['error'], + }; +} + +export function ErrorResponseToJSON(json: any): ErrorResponse { + return ErrorResponseToJSONTyped(json, false); +} + +export function ErrorResponseToJSONTyped(value?: ErrorResponse | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'error': value['error'], + }; +} + diff --git a/typescript/src/generated/src/models/GetCommerce200ResponseInner.ts b/typescript/src/generated/src/models/GetCommerce200ResponseInner.ts new file mode 100644 index 0000000..feecaf6 --- /dev/null +++ b/typescript/src/generated/src/models/GetCommerce200ResponseInner.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface GetCommerce200ResponseInner + */ +export interface GetCommerce200ResponseInner { + [key: string]: any | any; + /** + * Catalog id + * @type {string} + * @memberof GetCommerce200ResponseInner + */ + id?: (string) | undefined; + /** + * Whether the cart is enabled + * @type {boolean} + * @memberof GetCommerce200ResponseInner + */ + isCartEnabled?: (boolean) | undefined; + /** + * Whether the catalog storefront icon is shown + * @type {boolean} + * @memberof GetCommerce200ResponseInner + */ + isCatalogVisible?: (boolean) | undefined; +} + +/** + * Check if a given object implements the GetCommerce200ResponseInner interface. + */ +export function instanceOfGetCommerce200ResponseInner(value: object): value is GetCommerce200ResponseInner { + return true; +} + +export function GetCommerce200ResponseInnerFromJSON(json: any): GetCommerce200ResponseInner { + return GetCommerce200ResponseInnerFromJSONTyped(json, false); +} + +export function GetCommerce200ResponseInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): GetCommerce200ResponseInner { + if (json == null) { + return json; + } + return { + + ...json, + 'id': json['id'] == null ? undefined : json['id'], + 'isCartEnabled': json['is_cart_enabled'] == null ? undefined : json['is_cart_enabled'], + 'isCatalogVisible': json['is_catalog_visible'] == null ? undefined : json['is_catalog_visible'], + }; +} + +export function GetCommerce200ResponseInnerToJSON(json: any): GetCommerce200ResponseInner { + return GetCommerce200ResponseInnerToJSONTyped(json, false); +} + +export function GetCommerce200ResponseInnerToJSONTyped(value?: GetCommerce200ResponseInner | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'id': value['id'], + 'is_cart_enabled': value['isCartEnabled'], + 'is_catalog_visible': value['isCatalogVisible'], + }; +} + diff --git a/typescript/src/generated/src/models/GetMmLiteStatus200Response.ts b/typescript/src/generated/src/models/GetMmLiteStatus200Response.ts new file mode 100644 index 0000000..e822e68 --- /dev/null +++ b/typescript/src/generated/src/models/GetMmLiteStatus200Response.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface GetMmLiteStatus200Response + */ +export interface GetMmLiteStatus200Response { + [key: string]: any | any; + /** + * + * @type {boolean} + * @memberof GetMmLiteStatus200Response + */ + available?: (boolean) | undefined; + /** + * + * @type {string} + * @memberof GetMmLiteStatus200Response + */ + status?: (string) | undefined; + /** + * + * @type {string} + * @memberof GetMmLiteStatus200Response + */ + message?: (string) | undefined; +} + +/** + * Check if a given object implements the GetMmLiteStatus200Response interface. + */ +export function instanceOfGetMmLiteStatus200Response(value: object): value is GetMmLiteStatus200Response { + return true; +} + +export function GetMmLiteStatus200ResponseFromJSON(json: any): GetMmLiteStatus200Response { + return GetMmLiteStatus200ResponseFromJSONTyped(json, false); +} + +export function GetMmLiteStatus200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): GetMmLiteStatus200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'available': json['available'] == null ? undefined : json['available'], + 'status': json['status'] == null ? undefined : json['status'], + 'message': json['message'] == null ? undefined : json['message'], + }; +} + +export function GetMmLiteStatus200ResponseToJSON(json: any): GetMmLiteStatus200Response { + return GetMmLiteStatus200ResponseToJSONTyped(json, false); +} + +export function GetMmLiteStatus200ResponseToJSONTyped(value?: GetMmLiteStatus200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'available': value['available'], + 'status': value['status'], + 'message': value['message'], + }; +} + diff --git a/typescript/src/generated/src/models/GetStatus200Response.ts b/typescript/src/generated/src/models/GetStatus200Response.ts new file mode 100644 index 0000000..1ab0a28 --- /dev/null +++ b/typescript/src/generated/src/models/GetStatus200Response.ts @@ -0,0 +1,100 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface GetStatus200Response + */ +export interface GetStatus200Response { + [key: string]: any | any; + /** + * + * @type {boolean} + * @memberof GetStatus200Response + */ + isCloud?: (boolean) | undefined; + /** + * typically `connected` when the number can send + * @type {string} + * @memberof GetStatus200Response + */ + status?: (string) | undefined; + /** + * + * @type {string} + * @memberof GetStatus200Response + */ + accountStatus?: (string) | undefined; + /** + * + * @type {boolean} + * @memberof GetStatus200Response + */ + mmLiteAvailable?: (boolean) | undefined; + /** + * Optional soft-fail warning when Meta Graph health_status could not be loaded. Never includes internal provider names. + * @type {string} + * @memberof GetStatus200Response + */ + healthStatusWarning?: (string) | undefined; +} + +/** + * Check if a given object implements the GetStatus200Response interface. + */ +export function instanceOfGetStatus200Response(value: object): value is GetStatus200Response { + return true; +} + +export function GetStatus200ResponseFromJSON(json: any): GetStatus200Response { + return GetStatus200ResponseFromJSONTyped(json, false); +} + +export function GetStatus200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): GetStatus200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'isCloud': json['isCloud'] == null ? undefined : json['isCloud'], + 'status': json['status'] == null ? undefined : json['status'], + 'accountStatus': json['accountStatus'] == null ? undefined : json['accountStatus'], + 'mmLiteAvailable': json['mm_lite_available'] == null ? undefined : json['mm_lite_available'], + 'healthStatusWarning': json['health_status_warning'] == null ? undefined : json['health_status_warning'], + }; +} + +export function GetStatus200ResponseToJSON(json: any): GetStatus200Response { + return GetStatus200ResponseToJSONTyped(json, false); +} + +export function GetStatus200ResponseToJSONTyped(value?: GetStatus200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'isCloud': value['isCloud'], + 'status': value['status'], + 'accountStatus': value['accountStatus'], + 'mm_lite_available': value['mmLiteAvailable'], + 'health_status_warning': value['healthStatusWarning'], + }; +} + diff --git a/typescript/src/generated/src/models/GetWebhook200Response.ts b/typescript/src/generated/src/models/GetWebhook200Response.ts new file mode 100644 index 0000000..c1f6cbf --- /dev/null +++ b/typescript/src/generated/src/models/GetWebhook200Response.ts @@ -0,0 +1,201 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { WebhookUrlStatus } from './WebhookUrlStatus'; +import { + WebhookUrlStatusFromJSON, + WebhookUrlStatusFromJSONTyped, + WebhookUrlStatusToJSON, + WebhookUrlStatusToJSONTyped, +} from './WebhookUrlStatus'; +import type { GetWebhook200ResponseWebhookUrl } from './GetWebhook200ResponseWebhookUrl'; +import { + GetWebhook200ResponseWebhookUrlFromJSON, + GetWebhook200ResponseWebhookUrlFromJSONTyped, + GetWebhook200ResponseWebhookUrlToJSON, + GetWebhook200ResponseWebhookUrlToJSONTyped, +} from './GetWebhook200ResponseWebhookUrl'; + +/** + * + * @export + * @interface GetWebhook200Response + */ +export interface GetWebhook200Response { + [key: string]: any | any; + /** + * + * @type {GetWebhook200ResponseWebhookUrl} + * @memberof GetWebhook200Response + */ + webhookUrl?: (GetWebhook200ResponseWebhookUrl | null) | undefined; + /** + * `true` when at least one URL in `webhookUrl` is sticky auto-disabled. + * Not "the channel is dead": other configured URLs still receive events. + * Send/receive are unaffected. + * + * @type {boolean} + * @memberof GetWebhook200Response + */ + haveDisabledWebhooks?: (boolean) | undefined; + /** + * Compatibility scalar for **one** URL (first sticky-disabled, else first + * configured). Not the channel as a whole. Prefer `webhookStatuses[].circuitState`. + * + * @type {GetWebhook200ResponseCircuitStateEnum} + * @memberof GetWebhook200Response + */ + circuitState?: (GetWebhook200ResponseCircuitStateEnum) | undefined; + /** + * Last qualifying fail reason of the summary URL (same URL as `circuitState`) + * @type {string} + * @memberof GetWebhook200Response + */ + reason?: (string) | undefined; + /** + * Diagnostic only (summary URL). Qualifying failures in the rolling + * ~10 minute breaker window — not lifetime and not customer retries. + * Prefer `webhookStatuses` / `disabledWebhooks`. + * + * @type {number} + * @memberof GetWebhook200Response + */ + fails?: (number) | undefined; + /** + * Diagnostic only (summary URL). Failed recovery probes (≈15 min → + * 1 h → 6 h). Sticky disable after 3. Not a blind unblock timer. + * + * @type {number} + * @memberof GetWebhook200Response + */ + trips?: (number) | undefined; + /** + * Epoch milliseconds when the summary URL became sticky-disabled + * @type {number} + * @memberof GetWebhook200Response + */ + disabledAt?: (number) | undefined; + /** + * Diagnostic only (summary URL). Epoch ms of the first fail in the + * current ~10 minute window (pairs with `fails`). + * + * @type {number} + * @memberof GetWebhook200Response + */ + firstFailAt?: (number) | undefined; + /** + * Last HTTP status from the summary URL, when known + * @type {number} + * @memberof GetWebhook200Response + */ + lastStatus?: (number) | undefined; + /** + * Epoch milliseconds of the next half-open probe for the summary URL, if any + * @type {number} + * @memberof GetWebhook200Response + */ + nextProbeAt?: (number) | undefined; + /** + * Currently configured URLs that are sticky auto-disabled (subset of `webhookUrl`). + * Does not include leftover URLs that are no longer configured. + * + * @type {Array<{ [key: string]: any; }>} + * @memberof GetWebhook200Response + */ + disabledWebhooks?: (Array<{ [key: string]: any; }>) | undefined; + /** + * One entry per currently configured URL. Prefer this over top-level + * `haveDisabledWebhooks` / `circuitState` when more than one webhook is set. + * + * @type {Array} + * @memberof GetWebhook200Response + */ + webhookStatuses?: (Array) | undefined; +} + + +/** + * @export + */ +export const GetWebhook200ResponseCircuitStateEnum = { + Ok: 'ok', + Degraded: 'degraded', + Open: 'open', + HalfOpen: 'half_open', + Disabled: 'disabled' +} as const; +export type GetWebhook200ResponseCircuitStateEnum = typeof GetWebhook200ResponseCircuitStateEnum[keyof typeof GetWebhook200ResponseCircuitStateEnum]; + + +/** + * Check if a given object implements the GetWebhook200Response interface. + */ +export function instanceOfGetWebhook200Response(value: object): value is GetWebhook200Response { + return true; +} + +export function GetWebhook200ResponseFromJSON(json: any): GetWebhook200Response { + return GetWebhook200ResponseFromJSONTyped(json, false); +} + +export function GetWebhook200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): GetWebhook200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'webhookUrl': json['webhookUrl'] == null ? undefined : GetWebhook200ResponseWebhookUrlFromJSON(json['webhookUrl']), + 'haveDisabledWebhooks': json['haveDisabledWebhooks'] == null ? undefined : json['haveDisabledWebhooks'], + 'circuitState': json['circuitState'] == null ? undefined : json['circuitState'], + 'reason': json['reason'] == null ? undefined : json['reason'], + 'fails': json['fails'] == null ? undefined : json['fails'], + 'trips': json['trips'] == null ? undefined : json['trips'], + 'disabledAt': json['disabledAt'] == null ? undefined : json['disabledAt'], + 'firstFailAt': json['firstFailAt'] == null ? undefined : json['firstFailAt'], + 'lastStatus': json['lastStatus'] == null ? undefined : json['lastStatus'], + 'nextProbeAt': json['nextProbeAt'] == null ? undefined : json['nextProbeAt'], + 'disabledWebhooks': json['disabledWebhooks'] == null ? undefined : json['disabledWebhooks'], + 'webhookStatuses': json['webhookStatuses'] == null ? undefined : ((json['webhookStatuses'] as Array).map(WebhookUrlStatusFromJSON)), + }; +} + +export function GetWebhook200ResponseToJSON(json: any): GetWebhook200Response { + return GetWebhook200ResponseToJSONTyped(json, false); +} + +export function GetWebhook200ResponseToJSONTyped(value?: GetWebhook200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'webhookUrl': GetWebhook200ResponseWebhookUrlToJSON(value['webhookUrl']), + 'haveDisabledWebhooks': value['haveDisabledWebhooks'], + 'circuitState': value['circuitState'], + 'reason': value['reason'], + 'fails': value['fails'], + 'trips': value['trips'], + 'disabledAt': value['disabledAt'], + 'firstFailAt': value['firstFailAt'], + 'lastStatus': value['lastStatus'], + 'nextProbeAt': value['nextProbeAt'], + 'disabledWebhooks': value['disabledWebhooks'], + 'webhookStatuses': value['webhookStatuses'] == null ? undefined : ((value['webhookStatuses'] as Array).map(WebhookUrlStatusToJSON)), + }; +} + diff --git a/typescript/src/generated/src/models/GetWebhook200ResponseWebhookUrl.ts b/typescript/src/generated/src/models/GetWebhook200ResponseWebhookUrl.ts new file mode 100644 index 0000000..7479faa --- /dev/null +++ b/typescript/src/generated/src/models/GetWebhook200ResponseWebhookUrl.ts @@ -0,0 +1,59 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +/** + * @type GetWebhook200ResponseWebhookUrl + * Configured webhook URL, array of URLs, or null when none is set + * @export + */ +export type GetWebhook200ResponseWebhookUrl = Array | string; + +export function GetWebhook200ResponseWebhookUrlFromJSON(json: any): GetWebhook200ResponseWebhookUrl { + return GetWebhook200ResponseWebhookUrlFromJSONTyped(json, false); +} + +export function GetWebhook200ResponseWebhookUrlFromJSONTyped(json: any, ignoreDiscriminator: boolean): GetWebhook200ResponseWebhookUrl { + if (json == null) { + return json; + } + if (typeof json === 'string') { + return json; + } + if (Array.isArray(json)) { + if (json.every(item => typeof item === 'string')) { + return json; + } + } + return {} as any; +} + +export function GetWebhook200ResponseWebhookUrlToJSON(json: any): any { + return GetWebhook200ResponseWebhookUrlToJSONTyped(json, false); +} + +export function GetWebhook200ResponseWebhookUrlToJSONTyped(value?: GetWebhook200ResponseWebhookUrl | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + if (typeof value === 'string') { + return value; + } + if (Array.isArray(value)) { + if (value.every(item => typeof item === 'string')) { + return value; + } + } + return {}; +} + diff --git a/typescript/src/generated/src/models/GetWhatsappBusinessEncryption200Response.ts b/typescript/src/generated/src/models/GetWhatsappBusinessEncryption200Response.ts new file mode 100644 index 0000000..42e0506 --- /dev/null +++ b/typescript/src/generated/src/models/GetWhatsappBusinessEncryption200Response.ts @@ -0,0 +1,95 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface GetWhatsappBusinessEncryption200Response + */ +export interface GetWhatsappBusinessEncryption200Response { + [key: string]: any | any; + /** + * Stored 2048-bit RSA public key (PEM) + * @type {string} + * @memberof GetWhatsappBusinessEncryption200Response + */ + businessPublicKey?: (string) | undefined; + /** + * + * @type {GetWhatsappBusinessEncryption200ResponseBusinessPublicKeySignatureStatusEnum} + * @memberof GetWhatsappBusinessEncryption200Response + */ + businessPublicKeySignatureStatus?: (GetWhatsappBusinessEncryption200ResponseBusinessPublicKeySignatureStatusEnum) | undefined; + /** + * + * @type {Array<{ [key: string]: any; }>} + * @memberof GetWhatsappBusinessEncryption200Response + */ + data?: (Array<{ [key: string]: any; }>) | undefined; +} + + +/** + * @export + */ +export const GetWhatsappBusinessEncryption200ResponseBusinessPublicKeySignatureStatusEnum = { + Valid: 'VALID', + Mismatch: 'MISMATCH' +} as const; +export type GetWhatsappBusinessEncryption200ResponseBusinessPublicKeySignatureStatusEnum = typeof GetWhatsappBusinessEncryption200ResponseBusinessPublicKeySignatureStatusEnum[keyof typeof GetWhatsappBusinessEncryption200ResponseBusinessPublicKeySignatureStatusEnum]; + + +/** + * Check if a given object implements the GetWhatsappBusinessEncryption200Response interface. + */ +export function instanceOfGetWhatsappBusinessEncryption200Response(value: object): value is GetWhatsappBusinessEncryption200Response { + return true; +} + +export function GetWhatsappBusinessEncryption200ResponseFromJSON(json: any): GetWhatsappBusinessEncryption200Response { + return GetWhatsappBusinessEncryption200ResponseFromJSONTyped(json, false); +} + +export function GetWhatsappBusinessEncryption200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): GetWhatsappBusinessEncryption200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'businessPublicKey': json['business_public_key'] == null ? undefined : json['business_public_key'], + 'businessPublicKeySignatureStatus': json['business_public_key_signature_status'] == null ? undefined : json['business_public_key_signature_status'], + 'data': json['data'] == null ? undefined : json['data'], + }; +} + +export function GetWhatsappBusinessEncryption200ResponseToJSON(json: any): GetWhatsappBusinessEncryption200Response { + return GetWhatsappBusinessEncryption200ResponseToJSONTyped(json, false); +} + +export function GetWhatsappBusinessEncryption200ResponseToJSONTyped(value?: GetWhatsappBusinessEncryption200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'business_public_key': value['businessPublicKey'], + 'business_public_key_signature_status': value['businessPublicKeySignatureStatus'], + 'data': value['data'], + }; +} + diff --git a/typescript/src/generated/src/models/InitiateCallRequest.ts b/typescript/src/generated/src/models/InitiateCallRequest.ts new file mode 100644 index 0000000..0ddda7f --- /dev/null +++ b/typescript/src/generated/src/models/InitiateCallRequest.ts @@ -0,0 +1,162 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { InitiateCallRequestSession } from './InitiateCallRequestSession'; +import { + InitiateCallRequestSessionFromJSON, + InitiateCallRequestSessionFromJSONTyped, + InitiateCallRequestSessionToJSON, + InitiateCallRequestSessionToJSONTyped, +} from './InitiateCallRequestSession'; + +/** + * Call action payload for `POST /initiateCall` (proxies upstream `POST /calling/calls`). + * + * Despite the path name, this endpoint handles **all** call actions — not only + * outbound connect. + * + * ## Required fields by `action` + * + * | action | Required | `session` | + * |--------|----------|-----------| + * | `connect` (outbound) | `messaging_product`, `to`, `action` | `sdp_type: offer` + business WebRTC SDP | + * | `pre_accept` | `messaging_product`, `call_id`, `action` | `sdp_type: answer` (WebRTC-generated) | + * | `accept` | `messaging_product`, `call_id`, `action` | `sdp_type: answer` (WebRTC-generated) | + * | `reject` | `messaging_product`, `call_id`, `action` | none | + * | `terminate` | `messaging_product`, `call_id`, `action` | none | + * + * **Critical:** For `pre_accept` / `accept`, `session.sdp` must be a + * **WebRTC-generated SDP answer**. Do not echo Meta's offer SDP back. + * Postman alone cannot establish real media — you need a WebRTC (or SIP) stack. + * + * @export + * @interface InitiateCallRequest + */ +export interface InitiateCallRequest { + [key: string]: any | any; + /** + * Must be `whatsapp` + * @type {InitiateCallRequestMessagingProductEnum} + * @memberof InitiateCallRequest + */ + messagingProduct: InitiateCallRequestMessagingProductEnum; + /** + * Call control action + * @type {InitiateCallRequestActionEnum} + * @memberof InitiateCallRequest + */ + action: InitiateCallRequestActionEnum; + /** + * WhatsApp call id from the inbound/outbound calls webhook (`calls[].id`). + * Required for `pre_accept`, `accept`, `reject`, `terminate`. + * + * @type {string} + * @memberof InitiateCallRequest + */ + callId?: (string) | undefined; + /** + * Recipient WhatsApp user phone (digits, country code, no +). + * Required for outbound `connect`. + * + * @type {string} + * @memberof InitiateCallRequest + */ + to?: (string) | undefined; + /** + * Optional opaque string echoed on later call webhooks for correlation + * @type {string} + * @memberof InitiateCallRequest + */ + bizOpaqueCallbackData?: (string) | undefined; + /** + * + * @type {InitiateCallRequestSession} + * @memberof InitiateCallRequest + */ + session?: (InitiateCallRequestSession) | undefined; +} + + +/** + * @export + */ +export const InitiateCallRequestMessagingProductEnum = { + Whatsapp: 'whatsapp' +} as const; +export type InitiateCallRequestMessagingProductEnum = typeof InitiateCallRequestMessagingProductEnum[keyof typeof InitiateCallRequestMessagingProductEnum]; + +/** + * @export + */ +export const InitiateCallRequestActionEnum = { + Connect: 'connect', + PreAccept: 'pre_accept', + Accept: 'accept', + Reject: 'reject', + Terminate: 'terminate' +} as const; +export type InitiateCallRequestActionEnum = typeof InitiateCallRequestActionEnum[keyof typeof InitiateCallRequestActionEnum]; + + +/** + * Check if a given object implements the InitiateCallRequest interface. + */ +export function instanceOfInitiateCallRequest(value: object): value is InitiateCallRequest { + if (!('messagingProduct' in value) || value['messagingProduct'] === undefined) return false; + if (!('action' in value) || value['action'] === undefined) return false; + return true; +} + +export function InitiateCallRequestFromJSON(json: any): InitiateCallRequest { + return InitiateCallRequestFromJSONTyped(json, false); +} + +export function InitiateCallRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): InitiateCallRequest { + if (json == null) { + return json; + } + return { + + ...json, + 'messagingProduct': json['messaging_product'], + 'action': json['action'], + 'callId': json['call_id'] == null ? undefined : json['call_id'], + 'to': json['to'] == null ? undefined : json['to'], + 'bizOpaqueCallbackData': json['biz_opaque_callback_data'] == null ? undefined : json['biz_opaque_callback_data'], + 'session': json['session'] == null ? undefined : InitiateCallRequestSessionFromJSON(json['session']), + }; +} + +export function InitiateCallRequestToJSON(json: any): InitiateCallRequest { + return InitiateCallRequestToJSONTyped(json, false); +} + +export function InitiateCallRequestToJSONTyped(value?: InitiateCallRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'messaging_product': value['messagingProduct'], + 'action': value['action'], + 'call_id': value['callId'], + 'to': value['to'], + 'biz_opaque_callback_data': value['bizOpaqueCallbackData'], + 'session': InitiateCallRequestSessionToJSON(value['session']), + }; +} + diff --git a/typescript/src/generated/src/models/InitiateCallRequestSession.ts b/typescript/src/generated/src/models/InitiateCallRequestSession.ts new file mode 100644 index 0000000..22d4b94 --- /dev/null +++ b/typescript/src/generated/src/models/InitiateCallRequestSession.ts @@ -0,0 +1,91 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * WebRTC SDP session (required for connect / pre_accept / accept) + * @export + * @interface InitiateCallRequestSession + */ +export interface InitiateCallRequestSession { + [key: string]: any | any; + /** + * offer for outbound connect; answer for pre_accept/accept + * @type {InitiateCallRequestSessionSdpTypeEnum} + * @memberof InitiateCallRequestSession + */ + sdpType: InitiateCallRequestSessionSdpTypeEnum; + /** + * Full SDP (RFC 8866). Replace placeholders with SDP from your WebRTC stack. + * Must negotiate ICE, DTLS-SRTP, and OPUS for WhatsApp media. + * + * @type {string} + * @memberof InitiateCallRequestSession + */ + sdp: string; +} + + +/** + * @export + */ +export const InitiateCallRequestSessionSdpTypeEnum = { + Offer: 'offer', + Answer: 'answer' +} as const; +export type InitiateCallRequestSessionSdpTypeEnum = typeof InitiateCallRequestSessionSdpTypeEnum[keyof typeof InitiateCallRequestSessionSdpTypeEnum]; + + +/** + * Check if a given object implements the InitiateCallRequestSession interface. + */ +export function instanceOfInitiateCallRequestSession(value: object): value is InitiateCallRequestSession { + if (!('sdpType' in value) || value['sdpType'] === undefined) return false; + if (!('sdp' in value) || value['sdp'] === undefined) return false; + return true; +} + +export function InitiateCallRequestSessionFromJSON(json: any): InitiateCallRequestSession { + return InitiateCallRequestSessionFromJSONTyped(json, false); +} + +export function InitiateCallRequestSessionFromJSONTyped(json: any, ignoreDiscriminator: boolean): InitiateCallRequestSession { + if (json == null) { + return json; + } + return { + + ...json, + 'sdpType': json['sdp_type'], + 'sdp': json['sdp'], + }; +} + +export function InitiateCallRequestSessionToJSON(json: any): InitiateCallRequestSession { + return InitiateCallRequestSessionToJSONTyped(json, false); +} + +export function InitiateCallRequestSessionToJSONTyped(value?: InitiateCallRequestSession | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'sdp_type': value['sdpType'], + 'sdp': value['sdp'], + }; +} + diff --git a/typescript/src/generated/src/models/InitiateCallResponse.ts b/typescript/src/generated/src/models/InitiateCallResponse.ts new file mode 100644 index 0000000..3de05a9 --- /dev/null +++ b/typescript/src/generated/src/models/InitiateCallResponse.ts @@ -0,0 +1,118 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { InitiateCallResponseCallsInner } from './InitiateCallResponseCallsInner'; +import { + InitiateCallResponseCallsInnerFromJSON, + InitiateCallResponseCallsInnerFromJSONTyped, + InitiateCallResponseCallsInnerToJSON, + InitiateCallResponseCallsInnerToJSONTyped, +} from './InitiateCallResponseCallsInner'; +import type { InitiateCallResponseResponse } from './InitiateCallResponseResponse'; +import { + InitiateCallResponseResponseFromJSON, + InitiateCallResponseResponseFromJSONTyped, + InitiateCallResponseResponseToJSON, + InitiateCallResponseResponseToJSONTyped, +} from './InitiateCallResponseResponse'; + +/** + * Successful call action response from upstream, returned as-is. + * On empty upstream body, 1msg may return `{ "result": "success" }`. + * Upstream failures are often wrapped as HTTP 200 `{ "response": { "error": "..." } }`. + * + * @export + * @interface InitiateCallResponse + */ +export interface InitiateCallResponse { + [key: string]: any | any; + /** + * + * @type {string} + * @memberof InitiateCallResponse + */ + messagingProduct?: (string) | undefined; + /** + * + * @type {boolean} + * @memberof InitiateCallResponse + */ + success?: (boolean) | undefined; + /** + * Present on outbound `connect` — contains the new call id + * @type {Array} + * @memberof InitiateCallResponse + */ + calls?: (Array) | undefined; + /** + * Legacy success marker when upstream returns an empty body + * @type {string} + * @memberof InitiateCallResponse + */ + result?: (string) | undefined; + /** + * + * @type {InitiateCallResponseResponse} + * @memberof InitiateCallResponse + */ + response?: (InitiateCallResponseResponse) | undefined; +} + +/** + * Check if a given object implements the InitiateCallResponse interface. + */ +export function instanceOfInitiateCallResponse(value: object): value is InitiateCallResponse { + return true; +} + +export function InitiateCallResponseFromJSON(json: any): InitiateCallResponse { + return InitiateCallResponseFromJSONTyped(json, false); +} + +export function InitiateCallResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): InitiateCallResponse { + if (json == null) { + return json; + } + return { + + ...json, + 'messagingProduct': json['messaging_product'] == null ? undefined : json['messaging_product'], + 'success': json['success'] == null ? undefined : json['success'], + 'calls': json['calls'] == null ? undefined : ((json['calls'] as Array).map(InitiateCallResponseCallsInnerFromJSON)), + 'result': json['result'] == null ? undefined : json['result'], + 'response': json['response'] == null ? undefined : InitiateCallResponseResponseFromJSON(json['response']), + }; +} + +export function InitiateCallResponseToJSON(json: any): InitiateCallResponse { + return InitiateCallResponseToJSONTyped(json, false); +} + +export function InitiateCallResponseToJSONTyped(value?: InitiateCallResponse | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'messaging_product': value['messagingProduct'], + 'success': value['success'], + 'calls': value['calls'] == null ? undefined : ((value['calls'] as Array).map(InitiateCallResponseCallsInnerToJSON)), + 'result': value['result'], + 'response': InitiateCallResponseResponseToJSON(value['response']), + }; +} + diff --git a/typescript/src/generated/src/models/InitiateCallResponseCallsInner.ts b/typescript/src/generated/src/models/InitiateCallResponseCallsInner.ts new file mode 100644 index 0000000..f946211 --- /dev/null +++ b/typescript/src/generated/src/models/InitiateCallResponseCallsInner.ts @@ -0,0 +1,68 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface InitiateCallResponseCallsInner + */ +export interface InitiateCallResponseCallsInner { + [key: string]: any | any; + /** + * + * @type {string} + * @memberof InitiateCallResponseCallsInner + */ + id?: (string) | undefined; +} + +/** + * Check if a given object implements the InitiateCallResponseCallsInner interface. + */ +export function instanceOfInitiateCallResponseCallsInner(value: object): value is InitiateCallResponseCallsInner { + return true; +} + +export function InitiateCallResponseCallsInnerFromJSON(json: any): InitiateCallResponseCallsInner { + return InitiateCallResponseCallsInnerFromJSONTyped(json, false); +} + +export function InitiateCallResponseCallsInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): InitiateCallResponseCallsInner { + if (json == null) { + return json; + } + return { + + ...json, + 'id': json['id'] == null ? undefined : json['id'], + }; +} + +export function InitiateCallResponseCallsInnerToJSON(json: any): InitiateCallResponseCallsInner { + return InitiateCallResponseCallsInnerToJSONTyped(json, false); +} + +export function InitiateCallResponseCallsInnerToJSONTyped(value?: InitiateCallResponseCallsInner | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'id': value['id'], + }; +} + diff --git a/typescript/src/generated/src/models/InitiateCallResponseResponse.ts b/typescript/src/generated/src/models/InitiateCallResponseResponse.ts new file mode 100644 index 0000000..7d76cd9 --- /dev/null +++ b/typescript/src/generated/src/models/InitiateCallResponseResponse.ts @@ -0,0 +1,68 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * Present when 1msg wraps an upstream error + * @export + * @interface InitiateCallResponseResponse + */ +export interface InitiateCallResponseResponse { + [key: string]: any | any; + /** + * + * @type {string} + * @memberof InitiateCallResponseResponse + */ + error?: (string) | undefined; +} + +/** + * Check if a given object implements the InitiateCallResponseResponse interface. + */ +export function instanceOfInitiateCallResponseResponse(value: object): value is InitiateCallResponseResponse { + return true; +} + +export function InitiateCallResponseResponseFromJSON(json: any): InitiateCallResponseResponse { + return InitiateCallResponseResponseFromJSONTyped(json, false); +} + +export function InitiateCallResponseResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): InitiateCallResponseResponse { + if (json == null) { + return json; + } + return { + + ...json, + 'error': json['error'] == null ? undefined : json['error'], + }; +} + +export function InitiateCallResponseResponseToJSON(json: any): InitiateCallResponseResponse { + return InitiateCallResponseResponseToJSONTyped(json, false); +} + +export function InitiateCallResponseResponseToJSONTyped(value?: InitiateCallResponseResponse | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'error': value['error'], + }; +} + diff --git a/typescript/src/generated/src/models/ListBlockedUsers200Response.ts b/typescript/src/generated/src/models/ListBlockedUsers200Response.ts new file mode 100644 index 0000000..8347f58 --- /dev/null +++ b/typescript/src/generated/src/models/ListBlockedUsers200Response.ts @@ -0,0 +1,68 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface ListBlockedUsers200Response + */ +export interface ListBlockedUsers200Response { + [key: string]: any | any; + /** + * + * @type {Array<{ [key: string]: any; }>} + * @memberof ListBlockedUsers200Response + */ + blockedUsers?: (Array<{ [key: string]: any; }>) | undefined; +} + +/** + * Check if a given object implements the ListBlockedUsers200Response interface. + */ +export function instanceOfListBlockedUsers200Response(value: object): value is ListBlockedUsers200Response { + return true; +} + +export function ListBlockedUsers200ResponseFromJSON(json: any): ListBlockedUsers200Response { + return ListBlockedUsers200ResponseFromJSONTyped(json, false); +} + +export function ListBlockedUsers200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): ListBlockedUsers200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'blockedUsers': json['blockedUsers'] == null ? undefined : json['blockedUsers'], + }; +} + +export function ListBlockedUsers200ResponseToJSON(json: any): ListBlockedUsers200Response { + return ListBlockedUsers200ResponseToJSONTyped(json, false); +} + +export function ListBlockedUsers200ResponseToJSONTyped(value?: ListBlockedUsers200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'blockedUsers': value['blockedUsers'], + }; +} + diff --git a/typescript/src/generated/src/models/ListFlows200Response.ts b/typescript/src/generated/src/models/ListFlows200Response.ts new file mode 100644 index 0000000..5a99ae4 --- /dev/null +++ b/typescript/src/generated/src/models/ListFlows200Response.ts @@ -0,0 +1,100 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface ListFlows200Response + */ +export interface ListFlows200Response { + [key: string]: any | any; + /** + * + * @type {Array<{ [key: string]: any; }>} + * @memberof ListFlows200Response + */ + items?: (Array<{ [key: string]: any; }>) | undefined; + /** + * + * @type {{ [key: string]: any; }} + * @memberof ListFlows200Response + */ + paging?: ({ [key: string]: any; }) | undefined; + /** + * + * @type {number} + * @memberof ListFlows200Response + */ + count?: (number) | undefined; + /** + * + * @type {number} + * @memberof ListFlows200Response + */ + total?: (number) | undefined; + /** + * Error details returned by the provider. May be a string or a JSON object. + * @type {any} + * @memberof ListFlows200Response + */ + error?: (any | null) | undefined; +} + +/** + * Check if a given object implements the ListFlows200Response interface. + */ +export function instanceOfListFlows200Response(value: object): value is ListFlows200Response { + return true; +} + +export function ListFlows200ResponseFromJSON(json: any): ListFlows200Response { + return ListFlows200ResponseFromJSONTyped(json, false); +} + +export function ListFlows200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): ListFlows200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'items': json['items'] == null ? undefined : json['items'], + 'paging': json['paging'] == null ? undefined : json['paging'], + 'count': json['count'] == null ? undefined : json['count'], + 'total': json['total'] == null ? undefined : json['total'], + 'error': json['error'] == null ? undefined : json['error'], + }; +} + +export function ListFlows200ResponseToJSON(json: any): ListFlows200Response { + return ListFlows200ResponseToJSONTyped(json, false); +} + +export function ListFlows200ResponseToJSONTyped(value?: ListFlows200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'items': value['items'], + 'paging': value['paging'], + 'count': value['count'], + 'total': value['total'], + 'error': value['error'], + }; +} + diff --git a/typescript/src/generated/src/models/ListMessages200Response.ts b/typescript/src/generated/src/models/ListMessages200Response.ts new file mode 100644 index 0000000..003ec48 --- /dev/null +++ b/typescript/src/generated/src/models/ListMessages200Response.ts @@ -0,0 +1,76 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface ListMessages200Response + */ +export interface ListMessages200Response { + [key: string]: any | any; + /** + * + * @type {string} + * @memberof ListMessages200Response + */ + notice?: (string) | undefined; + /** + * + * @type {Array<{ [key: string]: any; }>} + * @memberof ListMessages200Response + */ + messages?: (Array<{ [key: string]: any; }>) | undefined; +} + +/** + * Check if a given object implements the ListMessages200Response interface. + */ +export function instanceOfListMessages200Response(value: object): value is ListMessages200Response { + return true; +} + +export function ListMessages200ResponseFromJSON(json: any): ListMessages200Response { + return ListMessages200ResponseFromJSONTyped(json, false); +} + +export function ListMessages200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): ListMessages200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'notice': json['notice'] == null ? undefined : json['notice'], + 'messages': json['messages'] == null ? undefined : json['messages'], + }; +} + +export function ListMessages200ResponseToJSON(json: any): ListMessages200Response { + return ListMessages200ResponseToJSONTyped(json, false); +} + +export function ListMessages200ResponseToJSONTyped(value?: ListMessages200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'notice': value['notice'], + 'messages': value['messages'], + }; +} + diff --git a/typescript/src/generated/src/models/ListSettings200Response.ts b/typescript/src/generated/src/models/ListSettings200Response.ts new file mode 100644 index 0000000..ed7778c --- /dev/null +++ b/typescript/src/generated/src/models/ListSettings200Response.ts @@ -0,0 +1,243 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { WebhookUrlStatus } from './WebhookUrlStatus'; +import { + WebhookUrlStatusFromJSON, + WebhookUrlStatusFromJSONTyped, + WebhookUrlStatusToJSON, + WebhookUrlStatusToJSONTyped, +} from './WebhookUrlStatus'; +import type { ListSettings200ResponseWebhookUrl } from './ListSettings200ResponseWebhookUrl'; +import { + ListSettings200ResponseWebhookUrlFromJSON, + ListSettings200ResponseWebhookUrlFromJSONTyped, + ListSettings200ResponseWebhookUrlToJSON, + ListSettings200ResponseWebhookUrlToJSONTyped, +} from './ListSettings200ResponseWebhookUrl'; + +/** + * + * @export + * @interface ListSettings200Response + */ +export interface ListSettings200Response { + [key: string]: any | any; + /** + * + * @type {ListSettings200ResponseWebhookUrl} + * @memberof ListSettings200Response + */ + webhookUrl?: (ListSettings200ResponseWebhookUrl) | undefined; + /** + * Retry webhooks until acknowledged + * @type {boolean} + * @memberof ListSettings200Response + */ + guaranteedHooks?: (boolean) | undefined; + /** + * Include message ACK / status events in webhooks + * @type {boolean} + * @memberof ListSettings200Response + */ + ackNotificationsOn?: (boolean) | undefined; + /** + * Forward raw provider webhook payloads + * @type {boolean} + * @memberof ListSettings200Response + */ + rawHooks?: (boolean) | undefined; + /** + * + * @type {boolean} + * @memberof ListSettings200Response + */ + mmLiteEnabled?: (boolean) | undefined; + /** + * + * @type {boolean} + * @memberof ListSettings200Response + */ + templateAnalyticsEnabled?: (boolean) | undefined; + /** + * + * @type {boolean} + * @memberof ListSettings200Response + */ + ctaUrlLinkTrackingOptedOut?: (boolean) | undefined; + /** + * `true` when at least one URL in `webhookUrl` is sticky auto-disabled. + * Not "the channel is dead": other configured URLs still receive events. + * + * @type {boolean} + * @memberof ListSettings200Response + */ + haveDisabledWebhooks?: (boolean) | undefined; + /** + * Compatibility scalar for **one** URL (first sticky-disabled, else first + * configured). Prefer `webhookStatuses[].circuitState`. + * + * @type {ListSettings200ResponseCircuitStateEnum} + * @memberof ListSettings200Response + */ + circuitState?: (ListSettings200ResponseCircuitStateEnum) | undefined; + /** + * Last qualifying fail reason of the summary URL + * @type {string} + * @memberof ListSettings200Response + */ + reason?: (string) | undefined; + /** + * Diagnostic only (summary URL). Qualifying failures in the rolling + * ~10 minute breaker window — not lifetime. Prefer `webhookStatuses`. + * + * @type {number} + * @memberof ListSettings200Response + */ + fails?: (number) | undefined; + /** + * Diagnostic only (summary URL). Failed recovery probes (≈15 min → + * 1 h → 6 h). Sticky disable after 3. Not a blind unblock timer. + * + * @type {number} + * @memberof ListSettings200Response + */ + trips?: (number) | undefined; + /** + * Epoch milliseconds when the summary URL became sticky-disabled + * @type {number} + * @memberof ListSettings200Response + */ + disabledAt?: (number) | undefined; + /** + * Diagnostic only (summary URL). Epoch ms of the first fail in the + * current ~10 minute window (pairs with `fails`). + * + * @type {number} + * @memberof ListSettings200Response + */ + firstFailAt?: (number) | undefined; + /** + * Last HTTP status from the summary URL, when known + * @type {number} + * @memberof ListSettings200Response + */ + lastStatus?: (number) | undefined; + /** + * Epoch milliseconds of the next half-open probe for the summary URL, if any + * @type {number} + * @memberof ListSettings200Response + */ + nextProbeAt?: (number) | undefined; + /** + * Currently configured URLs that are sticky auto-disabled (subset of `webhookUrl`) + * @type {Array<{ [key: string]: any; }>} + * @memberof ListSettings200Response + */ + disabledWebhooks?: (Array<{ [key: string]: any; }>) | undefined; + /** + * One entry per currently configured URL. Prefer this over top-level `haveDisabledWebhooks` / `circuitState`. + * @type {Array} + * @memberof ListSettings200Response + */ + webhookStatuses?: (Array) | undefined; +} + + +/** + * @export + */ +export const ListSettings200ResponseCircuitStateEnum = { + Ok: 'ok', + Degraded: 'degraded', + Open: 'open', + HalfOpen: 'half_open', + Disabled: 'disabled' +} as const; +export type ListSettings200ResponseCircuitStateEnum = typeof ListSettings200ResponseCircuitStateEnum[keyof typeof ListSettings200ResponseCircuitStateEnum]; + + +/** + * Check if a given object implements the ListSettings200Response interface. + */ +export function instanceOfListSettings200Response(value: object): value is ListSettings200Response { + return true; +} + +export function ListSettings200ResponseFromJSON(json: any): ListSettings200Response { + return ListSettings200ResponseFromJSONTyped(json, false); +} + +export function ListSettings200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): ListSettings200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'webhookUrl': json['webhookUrl'] == null ? undefined : ListSettings200ResponseWebhookUrlFromJSON(json['webhookUrl']), + 'guaranteedHooks': json['guaranteedHooks'] == null ? undefined : json['guaranteedHooks'], + 'ackNotificationsOn': json['ackNotificationsOn'] == null ? undefined : json['ackNotificationsOn'], + 'rawHooks': json['rawHooks'] == null ? undefined : json['rawHooks'], + 'mmLiteEnabled': json['mm_lite_enabled'] == null ? undefined : json['mm_lite_enabled'], + 'templateAnalyticsEnabled': json['template_analytics_enabled'] == null ? undefined : json['template_analytics_enabled'], + 'ctaUrlLinkTrackingOptedOut': json['cta_url_link_tracking_opted_out'] == null ? undefined : json['cta_url_link_tracking_opted_out'], + 'haveDisabledWebhooks': json['haveDisabledWebhooks'] == null ? undefined : json['haveDisabledWebhooks'], + 'circuitState': json['circuitState'] == null ? undefined : json['circuitState'], + 'reason': json['reason'] == null ? undefined : json['reason'], + 'fails': json['fails'] == null ? undefined : json['fails'], + 'trips': json['trips'] == null ? undefined : json['trips'], + 'disabledAt': json['disabledAt'] == null ? undefined : json['disabledAt'], + 'firstFailAt': json['firstFailAt'] == null ? undefined : json['firstFailAt'], + 'lastStatus': json['lastStatus'] == null ? undefined : json['lastStatus'], + 'nextProbeAt': json['nextProbeAt'] == null ? undefined : json['nextProbeAt'], + 'disabledWebhooks': json['disabledWebhooks'] == null ? undefined : json['disabledWebhooks'], + 'webhookStatuses': json['webhookStatuses'] == null ? undefined : ((json['webhookStatuses'] as Array).map(WebhookUrlStatusFromJSON)), + }; +} + +export function ListSettings200ResponseToJSON(json: any): ListSettings200Response { + return ListSettings200ResponseToJSONTyped(json, false); +} + +export function ListSettings200ResponseToJSONTyped(value?: ListSettings200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'webhookUrl': ListSettings200ResponseWebhookUrlToJSON(value['webhookUrl']), + 'guaranteedHooks': value['guaranteedHooks'], + 'ackNotificationsOn': value['ackNotificationsOn'], + 'rawHooks': value['rawHooks'], + 'mm_lite_enabled': value['mmLiteEnabled'], + 'template_analytics_enabled': value['templateAnalyticsEnabled'], + 'cta_url_link_tracking_opted_out': value['ctaUrlLinkTrackingOptedOut'], + 'haveDisabledWebhooks': value['haveDisabledWebhooks'], + 'circuitState': value['circuitState'], + 'reason': value['reason'], + 'fails': value['fails'], + 'trips': value['trips'], + 'disabledAt': value['disabledAt'], + 'firstFailAt': value['firstFailAt'], + 'lastStatus': value['lastStatus'], + 'nextProbeAt': value['nextProbeAt'], + 'disabledWebhooks': value['disabledWebhooks'], + 'webhookStatuses': value['webhookStatuses'] == null ? undefined : ((value['webhookStatuses'] as Array).map(WebhookUrlStatusToJSON)), + }; +} + diff --git a/typescript/src/generated/src/models/ListSettings200ResponseWebhookUrl.ts b/typescript/src/generated/src/models/ListSettings200ResponseWebhookUrl.ts new file mode 100644 index 0000000..1cdacdb --- /dev/null +++ b/typescript/src/generated/src/models/ListSettings200ResponseWebhookUrl.ts @@ -0,0 +1,59 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +/** + * @type ListSettings200ResponseWebhookUrl + * One URL, or several if multiple webhooks are configured + * @export + */ +export type ListSettings200ResponseWebhookUrl = Array | string; + +export function ListSettings200ResponseWebhookUrlFromJSON(json: any): ListSettings200ResponseWebhookUrl { + return ListSettings200ResponseWebhookUrlFromJSONTyped(json, false); +} + +export function ListSettings200ResponseWebhookUrlFromJSONTyped(json: any, ignoreDiscriminator: boolean): ListSettings200ResponseWebhookUrl { + if (json == null) { + return json; + } + if (Array.isArray(json)) { + if (json.every(item => typeof item === 'string')) { + return json; + } + } + if (typeof json === 'string') { + return json; + } + return {} as any; +} + +export function ListSettings200ResponseWebhookUrlToJSON(json: any): any { + return ListSettings200ResponseWebhookUrlToJSONTyped(json, false); +} + +export function ListSettings200ResponseWebhookUrlToJSONTyped(value?: ListSettings200ResponseWebhookUrl | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + if (Array.isArray(value)) { + if (value.every(item => typeof item === 'string')) { + return value; + } + } + if (typeof value === 'string') { + return value; + } + return {}; +} + diff --git a/typescript/src/generated/src/models/ListTemplates200Response.ts b/typescript/src/generated/src/models/ListTemplates200Response.ts new file mode 100644 index 0000000..566d3eb --- /dev/null +++ b/typescript/src/generated/src/models/ListTemplates200Response.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface ListTemplates200Response + */ +export interface ListTemplates200Response { + [key: string]: any | any; + /** + * + * @type {number} + * @memberof ListTemplates200Response + */ + total?: (number) | undefined; + /** + * + * @type {Array<{ [key: string]: any; }>} + * @memberof ListTemplates200Response + */ + templates?: (Array<{ [key: string]: any; }>) | undefined; + /** + * + * @type {{ [key: string]: any; }} + * @memberof ListTemplates200Response + */ + error?: ({ [key: string]: any; }) | undefined; +} + +/** + * Check if a given object implements the ListTemplates200Response interface. + */ +export function instanceOfListTemplates200Response(value: object): value is ListTemplates200Response { + return true; +} + +export function ListTemplates200ResponseFromJSON(json: any): ListTemplates200Response { + return ListTemplates200ResponseFromJSONTyped(json, false); +} + +export function ListTemplates200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): ListTemplates200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'total': json['total'] == null ? undefined : json['total'], + 'templates': json['templates'] == null ? undefined : json['templates'], + 'error': json['error'] == null ? undefined : json['error'], + }; +} + +export function ListTemplates200ResponseToJSON(json: any): ListTemplates200Response { + return ListTemplates200ResponseToJSONTyped(json, false); +} + +export function ListTemplates200ResponseToJSONTyped(value?: ListTemplates200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'total': value['total'], + 'templates': value['templates'], + 'error': value['error'], + }; +} + diff --git a/typescript/src/generated/src/models/MessageSentResponse.ts b/typescript/src/generated/src/models/MessageSentResponse.ts new file mode 100644 index 0000000..67bade8 --- /dev/null +++ b/typescript/src/generated/src/models/MessageSentResponse.ts @@ -0,0 +1,92 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * Response for successfully sent message + * @export + * @interface MessageSentResponse + */ +export interface MessageSentResponse { + [key: string]: any | any; + /** + * Whether the message was successfully queued for sending + * @type {boolean} + * @memberof MessageSentResponse + */ + sent?: (boolean) | undefined; + /** + * Message ID + * @type {string} + * @memberof MessageSentResponse + */ + id?: (string) | undefined; + /** + * Status message + * @type {string} + * @memberof MessageSentResponse + */ + message?: (string) | undefined; + /** + * Detailed description + * @type {string} + * @memberof MessageSentResponse + */ + description?: (string) | undefined; +} + +/** + * Check if a given object implements the MessageSentResponse interface. + */ +export function instanceOfMessageSentResponse(value: object): value is MessageSentResponse { + return true; +} + +export function MessageSentResponseFromJSON(json: any): MessageSentResponse { + return MessageSentResponseFromJSONTyped(json, false); +} + +export function MessageSentResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): MessageSentResponse { + if (json == null) { + return json; + } + return { + + ...json, + 'sent': json['sent'] == null ? undefined : json['sent'], + 'id': json['id'] == null ? undefined : json['id'], + 'message': json['message'] == null ? undefined : json['message'], + 'description': json['description'] == null ? undefined : json['description'], + }; +} + +export function MessageSentResponseToJSON(json: any): MessageSentResponse { + return MessageSentResponseToJSONTyped(json, false); +} + +export function MessageSentResponseToJSONTyped(value?: MessageSentResponse | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'sent': value['sent'], + 'id': value['id'], + 'message': value['message'], + 'description': value['description'], + }; +} + diff --git a/typescript/src/generated/src/models/PatchFlowsFlowIdAssets200Response.ts b/typescript/src/generated/src/models/PatchFlowsFlowIdAssets200Response.ts new file mode 100644 index 0000000..1e76005 --- /dev/null +++ b/typescript/src/generated/src/models/PatchFlowsFlowIdAssets200Response.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface PatchFlowsFlowIdAssets200Response + */ +export interface PatchFlowsFlowIdAssets200Response { + [key: string]: any | any; + /** + * + * @type {boolean} + * @memberof PatchFlowsFlowIdAssets200Response + */ + success?: (boolean) | undefined; + /** + * + * @type {Array<{ [key: string]: any; }>} + * @memberof PatchFlowsFlowIdAssets200Response + */ + validationErrors?: (Array<{ [key: string]: any; }>) | undefined; + /** + * Error details returned by the provider. May be a string or a JSON object. + * @type {any} + * @memberof PatchFlowsFlowIdAssets200Response + */ + error?: (any | null) | undefined; +} + +/** + * Check if a given object implements the PatchFlowsFlowIdAssets200Response interface. + */ +export function instanceOfPatchFlowsFlowIdAssets200Response(value: object): value is PatchFlowsFlowIdAssets200Response { + return true; +} + +export function PatchFlowsFlowIdAssets200ResponseFromJSON(json: any): PatchFlowsFlowIdAssets200Response { + return PatchFlowsFlowIdAssets200ResponseFromJSONTyped(json, false); +} + +export function PatchFlowsFlowIdAssets200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): PatchFlowsFlowIdAssets200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'success': json['success'] == null ? undefined : json['success'], + 'validationErrors': json['validationErrors'] == null ? undefined : json['validationErrors'], + 'error': json['error'] == null ? undefined : json['error'], + }; +} + +export function PatchFlowsFlowIdAssets200ResponseToJSON(json: any): PatchFlowsFlowIdAssets200Response { + return PatchFlowsFlowIdAssets200ResponseToJSONTyped(json, false); +} + +export function PatchFlowsFlowIdAssets200ResponseToJSONTyped(value?: PatchFlowsFlowIdAssets200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'success': value['success'], + 'validationErrors': value['validationErrors'], + 'error': value['error'], + }; +} + diff --git a/typescript/src/generated/src/models/PatchFlowsFlowIdAssetsRequest.ts b/typescript/src/generated/src/models/PatchFlowsFlowIdAssetsRequest.ts new file mode 100644 index 0000000..327e1a9 --- /dev/null +++ b/typescript/src/generated/src/models/PatchFlowsFlowIdAssetsRequest.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface PatchFlowsFlowIdAssetsRequest + */ +export interface PatchFlowsFlowIdAssetsRequest { + /** + * WhatsApp Flow JSON document + * @type {{ [key: string]: any; }} + * @memberof PatchFlowsFlowIdAssetsRequest + */ + flowJson: { [key: string]: any; }; +} + +/** + * Check if a given object implements the PatchFlowsFlowIdAssetsRequest interface. + */ +export function instanceOfPatchFlowsFlowIdAssetsRequest(value: object): value is PatchFlowsFlowIdAssetsRequest { + if (!('flowJson' in value) || value['flowJson'] === undefined) return false; + return true; +} + +export function PatchFlowsFlowIdAssetsRequestFromJSON(json: any): PatchFlowsFlowIdAssetsRequest { + return PatchFlowsFlowIdAssetsRequestFromJSONTyped(json, false); +} + +export function PatchFlowsFlowIdAssetsRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): PatchFlowsFlowIdAssetsRequest { + if (json == null) { + return json; + } + return { + + 'flowJson': json['flowJson'], + }; +} + +export function PatchFlowsFlowIdAssetsRequestToJSON(json: any): PatchFlowsFlowIdAssetsRequest { + return PatchFlowsFlowIdAssetsRequestToJSONTyped(json, false); +} + +export function PatchFlowsFlowIdAssetsRequestToJSONTyped(value?: PatchFlowsFlowIdAssetsRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'flowJson': value['flowJson'], + }; +} + diff --git a/typescript/src/generated/src/models/PatchFlowsFlowIdMetadataRequest.ts b/typescript/src/generated/src/models/PatchFlowsFlowIdMetadataRequest.ts new file mode 100644 index 0000000..0947ce3 --- /dev/null +++ b/typescript/src/generated/src/models/PatchFlowsFlowIdMetadataRequest.ts @@ -0,0 +1,98 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface PatchFlowsFlowIdMetadataRequest + */ +export interface PatchFlowsFlowIdMetadataRequest { + /** + * + * @type {string} + * @memberof PatchFlowsFlowIdMetadataRequest + */ + name?: (string) | undefined; + /** + * + * @type {Array} + * @memberof PatchFlowsFlowIdMetadataRequest + */ + categories?: (Array) | undefined; + /** + * HTTPS endpoint for the Flow data channel + * @type {string} + * @memberof PatchFlowsFlowIdMetadataRequest + */ + endpointUri?: (string) | undefined; +} + + +/** + * @export + */ +export const PatchFlowsFlowIdMetadataRequestCategoriesEnum = { + SignUp: 'SIGN_UP', + SignIn: 'SIGN_IN', + AppointmentBooking: 'APPOINTMENT_BOOKING', + LeadGeneration: 'LEAD_GENERATION', + ContactUs: 'CONTACT_US', + CustomerSupport: 'CUSTOMER_SUPPORT', + Survey: 'SURVEY', + Other: 'OTHER' +} as const; +export type PatchFlowsFlowIdMetadataRequestCategoriesEnum = typeof PatchFlowsFlowIdMetadataRequestCategoriesEnum[keyof typeof PatchFlowsFlowIdMetadataRequestCategoriesEnum]; + + +/** + * Check if a given object implements the PatchFlowsFlowIdMetadataRequest interface. + */ +export function instanceOfPatchFlowsFlowIdMetadataRequest(value: object): value is PatchFlowsFlowIdMetadataRequest { + return true; +} + +export function PatchFlowsFlowIdMetadataRequestFromJSON(json: any): PatchFlowsFlowIdMetadataRequest { + return PatchFlowsFlowIdMetadataRequestFromJSONTyped(json, false); +} + +export function PatchFlowsFlowIdMetadataRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): PatchFlowsFlowIdMetadataRequest { + if (json == null) { + return json; + } + return { + + 'name': json['name'] == null ? undefined : json['name'], + 'categories': json['categories'] == null ? undefined : json['categories'], + 'endpointUri': json['endpointUri'] == null ? undefined : json['endpointUri'], + }; +} + +export function PatchFlowsFlowIdMetadataRequestToJSON(json: any): PatchFlowsFlowIdMetadataRequest { + return PatchFlowsFlowIdMetadataRequestToJSONTyped(json, false); +} + +export function PatchFlowsFlowIdMetadataRequestToJSONTyped(value?: PatchFlowsFlowIdMetadataRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'name': value['name'], + 'categories': value['categories'], + 'endpointUri': value['endpointUri'], + }; +} + diff --git a/typescript/src/generated/src/models/ProfileInfo.ts b/typescript/src/generated/src/models/ProfileInfo.ts new file mode 100644 index 0000000..e97703c --- /dev/null +++ b/typescript/src/generated/src/models/ProfileInfo.ts @@ -0,0 +1,150 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * WhatsApp Business profile information + * @export + * @interface ProfileInfo + */ +export interface ProfileInfo { + [key: string]: any | any; + /** + * Profile's About section + * @type {string} + * @memberof ProfileInfo + */ + about?: (string) | undefined; + /** + * Address of the business + * @type {string} + * @memberof ProfileInfo + */ + address?: (string) | undefined; + /** + * Description of the business + * @type {string} + * @memberof ProfileInfo + */ + description?: (string) | undefined; + /** + * Business email + * @type {string} + * @memberof ProfileInfo + */ + email?: (string) | undefined; + /** + * Linked phone number + * @type {string} + * @memberof ProfileInfo + */ + phone?: (string) | undefined; + /** + * Industry of the business + * @type {ProfileInfoVerticalEnum} + * @memberof ProfileInfo + */ + vertical?: (ProfileInfoVerticalEnum) | undefined; + /** + * Profile photo URL + * @type {string} + * @memberof ProfileInfo + */ + photo?: (string) | undefined; + /** + * + * @type {Array} + * @memberof ProfileInfo + */ + websites?: (Array) | undefined; +} + + +/** + * @export + */ +export const ProfileInfoVerticalEnum = { + Automotive: 'Automotive', + BeautySpaAndSalon: 'Beauty, Spa and Salon', + ClothingAndApparel: 'Clothing and Apparel', + Education: 'Education', + Entertainment: 'Entertainment', + EventPlanningAndService: 'Event Planning and Service', + FinanceAndBanking: 'Finance and Banking', + FoodAndGrocery: 'Food and Grocery', + PublicService: 'Public Service', + HotelAndLodging: 'Hotel and Lodging', + MedicalAndHealth: 'Medical and Health', + NonProfit: 'Non-profit', + ProfessionalServices: 'Professional Services', + ShoppingAndRetail: 'Shopping and Retail', + TravelAndTransportation: 'Travel and Transportation', + Restaurant: 'Restaurant', + Other: 'Other' +} as const; +export type ProfileInfoVerticalEnum = typeof ProfileInfoVerticalEnum[keyof typeof ProfileInfoVerticalEnum]; + + +/** + * Check if a given object implements the ProfileInfo interface. + */ +export function instanceOfProfileInfo(value: object): value is ProfileInfo { + return true; +} + +export function ProfileInfoFromJSON(json: any): ProfileInfo { + return ProfileInfoFromJSONTyped(json, false); +} + +export function ProfileInfoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ProfileInfo { + if (json == null) { + return json; + } + return { + + ...json, + 'about': json['about'] == null ? undefined : json['about'], + 'address': json['address'] == null ? undefined : json['address'], + 'description': json['description'] == null ? undefined : json['description'], + 'email': json['email'] == null ? undefined : json['email'], + 'phone': json['phone'] == null ? undefined : json['phone'], + 'vertical': json['vertical'] == null ? undefined : json['vertical'], + 'photo': json['photo'] == null ? undefined : json['photo'], + 'websites': json['websites'] == null ? undefined : json['websites'], + }; +} + +export function ProfileInfoToJSON(json: any): ProfileInfo { + return ProfileInfoToJSONTyped(json, false); +} + +export function ProfileInfoToJSONTyped(value?: ProfileInfo | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'about': value['about'], + 'address': value['address'], + 'description': value['description'], + 'email': value['email'], + 'phone': value['phone'], + 'vertical': value['vertical'], + 'photo': value['photo'], + 'websites': value['websites'], + }; +} + diff --git a/typescript/src/generated/src/models/RemoveTemplateRequest.ts b/typescript/src/generated/src/models/RemoveTemplateRequest.ts new file mode 100644 index 0000000..1168752 --- /dev/null +++ b/typescript/src/generated/src/models/RemoveTemplateRequest.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface RemoveTemplateRequest + */ +export interface RemoveTemplateRequest { + /** + * Template name to delete + * @type {string} + * @memberof RemoveTemplateRequest + */ + name: string; +} + +/** + * Check if a given object implements the RemoveTemplateRequest interface. + */ +export function instanceOfRemoveTemplateRequest(value: object): value is RemoveTemplateRequest { + if (!('name' in value) || value['name'] === undefined) return false; + return true; +} + +export function RemoveTemplateRequestFromJSON(json: any): RemoveTemplateRequest { + return RemoveTemplateRequestFromJSONTyped(json, false); +} + +export function RemoveTemplateRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): RemoveTemplateRequest { + if (json == null) { + return json; + } + return { + + 'name': json['name'], + }; +} + +export function RemoveTemplateRequestToJSON(json: any): RemoveTemplateRequest { + return RemoveTemplateRequestToJSONTyped(json, false); +} + +export function RemoveTemplateRequestToJSONTyped(value?: RemoveTemplateRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'name': value['name'], + }; +} + diff --git a/typescript/src/generated/src/models/RetrieveMedia200Response.ts b/typescript/src/generated/src/models/RetrieveMedia200Response.ts new file mode 100644 index 0000000..7c12551 --- /dev/null +++ b/typescript/src/generated/src/models/RetrieveMedia200Response.ts @@ -0,0 +1,100 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface RetrieveMedia200Response + */ +export interface RetrieveMedia200Response { + [key: string]: any | any; + /** + * + * @type {string} + * @memberof RetrieveMedia200Response + */ + url?: (string) | undefined; + /** + * + * @type {string} + * @memberof RetrieveMedia200Response + */ + mimeType?: (string) | undefined; + /** + * + * @type {string} + * @memberof RetrieveMedia200Response + */ + sha256?: (string) | undefined; + /** + * + * @type {number} + * @memberof RetrieveMedia200Response + */ + fileSize?: (number) | undefined; + /** + * + * @type {string} + * @memberof RetrieveMedia200Response + */ + id?: (string) | undefined; +} + +/** + * Check if a given object implements the RetrieveMedia200Response interface. + */ +export function instanceOfRetrieveMedia200Response(value: object): value is RetrieveMedia200Response { + return true; +} + +export function RetrieveMedia200ResponseFromJSON(json: any): RetrieveMedia200Response { + return RetrieveMedia200ResponseFromJSONTyped(json, false); +} + +export function RetrieveMedia200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): RetrieveMedia200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'url': json['url'] == null ? undefined : json['url'], + 'mimeType': json['mimeType'] == null ? undefined : json['mimeType'], + 'sha256': json['sha256'] == null ? undefined : json['sha256'], + 'fileSize': json['fileSize'] == null ? undefined : json['fileSize'], + 'id': json['id'] == null ? undefined : json['id'], + }; +} + +export function RetrieveMedia200ResponseToJSON(json: any): RetrieveMedia200Response { + return RetrieveMedia200ResponseToJSONTyped(json, false); +} + +export function RetrieveMedia200ResponseToJSONTyped(value?: RetrieveMedia200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'url': value['url'], + 'mimeType': value['mimeType'], + 'sha256': value['sha256'], + 'fileSize': value['fileSize'], + 'id': value['id'], + }; +} + diff --git a/typescript/src/generated/src/models/SendAddressMessageRequest.ts b/typescript/src/generated/src/models/SendAddressMessageRequest.ts new file mode 100644 index 0000000..9c8380d --- /dev/null +++ b/typescript/src/generated/src/models/SendAddressMessageRequest.ts @@ -0,0 +1,136 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SendAddressMessageRequest + */ +export interface SendAddressMessageRequest { + [key: string]: any | any; + /** + * Recipient phone (E.164 digits, no +). Must match country. + * @type {number} + * @memberof SendAddressMessageRequest + */ + phone?: (number) | undefined; + /** + * + * @type {string} + * @memberof SendAddressMessageRequest + */ + chatId?: (string) | undefined; + /** + * Body text shown with the address request + * @type {string} + * @memberof SendAddressMessageRequest + */ + body: string; + /** + * Address form country. Defaults to IN if omitted. + * @type {SendAddressMessageRequestCountryEnum} + * @memberof SendAddressMessageRequest + */ + country?: (SendAddressMessageRequestCountryEnum) | undefined; + /** + * Optional prefilled address fields + * @type {{ [key: string]: any; }} + * @memberof SendAddressMessageRequest + */ + values?: ({ [key: string]: any; }) | undefined; + /** + * Optional previously saved addresses for the user + * @type {Array<{ [key: string]: any; }>} + * @memberof SendAddressMessageRequest + */ + savedAddresses?: (Array<{ [key: string]: any; }>) | undefined; + /** + * Optional field validation errors when re-prompting + * @type {{ [key: string]: any; }} + * @memberof SendAddressMessageRequest + */ + validationErrors?: ({ [key: string]: any; }) | undefined; + /** + * + * @type {string} + * @memberof SendAddressMessageRequest + */ + quotedMsgId?: (string) | undefined; +} + + +/** + * @export + */ +export const SendAddressMessageRequestCountryEnum = { + In: 'IN', + Sg: 'SG' +} as const; +export type SendAddressMessageRequestCountryEnum = typeof SendAddressMessageRequestCountryEnum[keyof typeof SendAddressMessageRequestCountryEnum]; + + +/** + * Check if a given object implements the SendAddressMessageRequest interface. + */ +export function instanceOfSendAddressMessageRequest(value: object): value is SendAddressMessageRequest { + if (!('body' in value) || value['body'] === undefined) return false; + return true; +} + +export function SendAddressMessageRequestFromJSON(json: any): SendAddressMessageRequest { + return SendAddressMessageRequestFromJSONTyped(json, false); +} + +export function SendAddressMessageRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendAddressMessageRequest { + if (json == null) { + return json; + } + return { + + ...json, + 'phone': json['phone'] == null ? undefined : json['phone'], + 'chatId': json['chatId'] == null ? undefined : json['chatId'], + 'body': json['body'], + 'country': json['country'] == null ? undefined : json['country'], + 'values': json['values'] == null ? undefined : json['values'], + 'savedAddresses': json['saved_addresses'] == null ? undefined : json['saved_addresses'], + 'validationErrors': json['validation_errors'] == null ? undefined : json['validation_errors'], + 'quotedMsgId': json['quotedMsgId'] == null ? undefined : json['quotedMsgId'], + }; +} + +export function SendAddressMessageRequestToJSON(json: any): SendAddressMessageRequest { + return SendAddressMessageRequestToJSONTyped(json, false); +} + +export function SendAddressMessageRequestToJSONTyped(value?: SendAddressMessageRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'phone': value['phone'], + 'chatId': value['chatId'], + 'body': value['body'], + 'country': value['country'], + 'values': value['values'], + 'saved_addresses': value['savedAddresses'], + 'validation_errors': value['validationErrors'], + 'quotedMsgId': value['quotedMsgId'], + }; +} + diff --git a/typescript/src/generated/src/models/SendButtonRequest.ts b/typescript/src/generated/src/models/SendButtonRequest.ts new file mode 100644 index 0000000..295e73a --- /dev/null +++ b/typescript/src/generated/src/models/SendButtonRequest.ts @@ -0,0 +1,129 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { SendButtonRequestSectionsInner } from './SendButtonRequestSectionsInner'; +import { + SendButtonRequestSectionsInnerFromJSON, + SendButtonRequestSectionsInnerFromJSONTyped, + SendButtonRequestSectionsInnerToJSON, + SendButtonRequestSectionsInnerToJSONTyped, +} from './SendButtonRequestSectionsInner'; + +/** + * + * @export + * @interface SendButtonRequest + */ +export interface SendButtonRequest { + /** + * Recipient phone with country code. Use phone or chatId. + * @type {string} + * @memberof SendButtonRequest + */ + phone?: (string) | undefined; + /** + * Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. + * @type {string} + * @memberof SendButtonRequest + */ + chatId?: (string) | undefined; + /** + * Optional Cloud API wamid to quote + * @type {string} + * @memberof SendButtonRequest + */ + quotedMsgId?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendButtonRequest + */ + body?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendButtonRequest + */ + footer?: (string) | undefined; + /** + * Optional interactive header (text/image/video/document) + * @type {{ [key: string]: any; }} + * @memberof SendButtonRequest + */ + header?: ({ [key: string]: any; }) | undefined; + /** + * Legacy alias for sections (`[{id,title}]`) + * @type {Array} + * @memberof SendButtonRequest + */ + buttons?: (Array) | undefined; + /** + * + * @type {Array} + * @memberof SendButtonRequest + */ + sections?: (Array) | undefined; +} + +/** + * Check if a given object implements the SendButtonRequest interface. + */ +export function instanceOfSendButtonRequest(value: object): value is SendButtonRequest { + return true; +} + +export function SendButtonRequestFromJSON(json: any): SendButtonRequest { + return SendButtonRequestFromJSONTyped(json, false); +} + +export function SendButtonRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendButtonRequest { + if (json == null) { + return json; + } + return { + + 'phone': json['phone'] == null ? undefined : json['phone'], + 'chatId': json['chatId'] == null ? undefined : json['chatId'], + 'quotedMsgId': json['quotedMsgId'] == null ? undefined : json['quotedMsgId'], + 'body': json['body'] == null ? undefined : json['body'], + 'footer': json['footer'] == null ? undefined : json['footer'], + 'header': json['header'] == null ? undefined : json['header'], + 'buttons': json['buttons'] == null ? undefined : json['buttons'], + 'sections': json['sections'] == null ? undefined : ((json['sections'] as Array).map(SendButtonRequestSectionsInnerFromJSON)), + }; +} + +export function SendButtonRequestToJSON(json: any): SendButtonRequest { + return SendButtonRequestToJSONTyped(json, false); +} + +export function SendButtonRequestToJSONTyped(value?: SendButtonRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'phone': value['phone'], + 'chatId': value['chatId'], + 'quotedMsgId': value['quotedMsgId'], + 'body': value['body'], + 'footer': value['footer'], + 'header': value['header'], + 'buttons': value['buttons'], + 'sections': value['sections'] == null ? undefined : ((value['sections'] as Array).map(SendButtonRequestSectionsInnerToJSON)), + }; +} + diff --git a/typescript/src/generated/src/models/SendButtonRequestSectionsInner.ts b/typescript/src/generated/src/models/SendButtonRequestSectionsInner.ts new file mode 100644 index 0000000..a7c3fd5 --- /dev/null +++ b/typescript/src/generated/src/models/SendButtonRequestSectionsInner.ts @@ -0,0 +1,81 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { SendButtonRequestSectionsInnerReply } from './SendButtonRequestSectionsInnerReply'; +import { + SendButtonRequestSectionsInnerReplyFromJSON, + SendButtonRequestSectionsInnerReplyFromJSONTyped, + SendButtonRequestSectionsInnerReplyToJSON, + SendButtonRequestSectionsInnerReplyToJSONTyped, +} from './SendButtonRequestSectionsInnerReply'; + +/** + * + * @export + * @interface SendButtonRequestSectionsInner + */ +export interface SendButtonRequestSectionsInner { + /** + * + * @type {string} + * @memberof SendButtonRequestSectionsInner + */ + type?: (string) | undefined; + /** + * + * @type {SendButtonRequestSectionsInnerReply} + * @memberof SendButtonRequestSectionsInner + */ + reply?: (SendButtonRequestSectionsInnerReply) | undefined; +} + +/** + * Check if a given object implements the SendButtonRequestSectionsInner interface. + */ +export function instanceOfSendButtonRequestSectionsInner(value: object): value is SendButtonRequestSectionsInner { + return true; +} + +export function SendButtonRequestSectionsInnerFromJSON(json: any): SendButtonRequestSectionsInner { + return SendButtonRequestSectionsInnerFromJSONTyped(json, false); +} + +export function SendButtonRequestSectionsInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendButtonRequestSectionsInner { + if (json == null) { + return json; + } + return { + + 'type': json['type'] == null ? undefined : json['type'], + 'reply': json['reply'] == null ? undefined : SendButtonRequestSectionsInnerReplyFromJSON(json['reply']), + }; +} + +export function SendButtonRequestSectionsInnerToJSON(json: any): SendButtonRequestSectionsInner { + return SendButtonRequestSectionsInnerToJSONTyped(json, false); +} + +export function SendButtonRequestSectionsInnerToJSONTyped(value?: SendButtonRequestSectionsInner | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'type': value['type'], + 'reply': SendButtonRequestSectionsInnerReplyToJSON(value['reply']), + }; +} + diff --git a/typescript/src/generated/src/models/SendButtonRequestSectionsInnerReply.ts b/typescript/src/generated/src/models/SendButtonRequestSectionsInnerReply.ts new file mode 100644 index 0000000..b9ce956 --- /dev/null +++ b/typescript/src/generated/src/models/SendButtonRequestSectionsInnerReply.ts @@ -0,0 +1,73 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SendButtonRequestSectionsInnerReply + */ +export interface SendButtonRequestSectionsInnerReply { + /** + * + * @type {string} + * @memberof SendButtonRequestSectionsInnerReply + */ + id?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendButtonRequestSectionsInnerReply + */ + title?: (string) | undefined; +} + +/** + * Check if a given object implements the SendButtonRequestSectionsInnerReply interface. + */ +export function instanceOfSendButtonRequestSectionsInnerReply(value: object): value is SendButtonRequestSectionsInnerReply { + return true; +} + +export function SendButtonRequestSectionsInnerReplyFromJSON(json: any): SendButtonRequestSectionsInnerReply { + return SendButtonRequestSectionsInnerReplyFromJSONTyped(json, false); +} + +export function SendButtonRequestSectionsInnerReplyFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendButtonRequestSectionsInnerReply { + if (json == null) { + return json; + } + return { + + 'id': json['id'] == null ? undefined : json['id'], + 'title': json['title'] == null ? undefined : json['title'], + }; +} + +export function SendButtonRequestSectionsInnerReplyToJSON(json: any): SendButtonRequestSectionsInnerReply { + return SendButtonRequestSectionsInnerReplyToJSONTyped(json, false); +} + +export function SendButtonRequestSectionsInnerReplyToJSONTyped(value?: SendButtonRequestSectionsInnerReply | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'id': value['id'], + 'title': value['title'], + }; +} + diff --git a/typescript/src/generated/src/models/SendCarouselRequest1.ts b/typescript/src/generated/src/models/SendCarouselRequest1.ts new file mode 100644 index 0000000..a7a77ac --- /dev/null +++ b/typescript/src/generated/src/models/SendCarouselRequest1.ts @@ -0,0 +1,105 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SendCarouselRequest1 + */ +export interface SendCarouselRequest1 { + /** + * Text shown above the carousel + * @type {string} + * @memberof SendCarouselRequest1 + */ + body?: (string) | undefined; + /** + * Preferred. 2–10 carousel cards. + * @type {Array<{ [key: string]: any; }>} + * @memberof SendCarouselRequest1 + */ + cards?: (Array<{ [key: string]: any; }>) | undefined; + /** + * Template-like alternative — include a CAROUSEL component with cards + * @type {Array} + * @memberof SendCarouselRequest1 + */ + params?: (Array) | undefined; + /** + * + * @type {string} + * @memberof SendCarouselRequest1 + */ + quotedMsgId?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendCarouselRequest1 + */ + chatId?: (string) | undefined; + /** + * + * @type {number} + * @memberof SendCarouselRequest1 + */ + phone?: (number) | undefined; +} + +/** + * Check if a given object implements the SendCarouselRequest1 interface. + */ +export function instanceOfSendCarouselRequest1(value: object): value is SendCarouselRequest1 { + return true; +} + +export function SendCarouselRequest1FromJSON(json: any): SendCarouselRequest1 { + return SendCarouselRequest1FromJSONTyped(json, false); +} + +export function SendCarouselRequest1FromJSONTyped(json: any, ignoreDiscriminator: boolean): SendCarouselRequest1 { + if (json == null) { + return json; + } + return { + + 'body': json['body'] == null ? undefined : json['body'], + 'cards': json['cards'] == null ? undefined : json['cards'], + 'params': json['params'] == null ? undefined : json['params'], + 'quotedMsgId': json['quotedMsgId'] == null ? undefined : json['quotedMsgId'], + 'chatId': json['chatId'] == null ? undefined : json['chatId'], + 'phone': json['phone'] == null ? undefined : json['phone'], + }; +} + +export function SendCarouselRequest1ToJSON(json: any): SendCarouselRequest1 { + return SendCarouselRequest1ToJSONTyped(json, false); +} + +export function SendCarouselRequest1ToJSONTyped(value?: SendCarouselRequest1 | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'body': value['body'], + 'cards': value['cards'], + 'params': value['params'], + 'quotedMsgId': value['quotedMsgId'], + 'chatId': value['chatId'], + 'phone': value['phone'], + }; +} + diff --git a/typescript/src/generated/src/models/SendContactRequest.ts b/typescript/src/generated/src/models/SendContactRequest.ts new file mode 100644 index 0000000..bc7ec8a --- /dev/null +++ b/typescript/src/generated/src/models/SendContactRequest.ts @@ -0,0 +1,112 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { SendContactRequestContactsInner } from './SendContactRequestContactsInner'; +import { + SendContactRequestContactsInnerFromJSON, + SendContactRequestContactsInnerFromJSONTyped, + SendContactRequestContactsInnerToJSON, + SendContactRequestContactsInnerToJSONTyped, +} from './SendContactRequestContactsInner'; +import type { SendContactRequestContact } from './SendContactRequestContact'; +import { + SendContactRequestContactFromJSON, + SendContactRequestContactFromJSONTyped, + SendContactRequestContactToJSON, + SendContactRequestContactToJSONTyped, +} from './SendContactRequestContact'; + +/** + * + * @export + * @interface SendContactRequest + */ +export interface SendContactRequest { + /** + * Recipient phone with country code. Use phone or chatId. + * @type {string} + * @memberof SendContactRequest + */ + phone?: (string) | undefined; + /** + * Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. + * @type {string} + * @memberof SendContactRequest + */ + chatId?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendContactRequest + */ + quotedMsgId?: (string) | undefined; + /** + * + * @type {SendContactRequestContact} + * @memberof SendContactRequest + */ + contact?: (SendContactRequestContact) | undefined; + /** + * + * @type {Array} + * @memberof SendContactRequest + */ + contacts?: (Array) | undefined; +} + +/** + * Check if a given object implements the SendContactRequest interface. + */ +export function instanceOfSendContactRequest(value: object): value is SendContactRequest { + return true; +} + +export function SendContactRequestFromJSON(json: any): SendContactRequest { + return SendContactRequestFromJSONTyped(json, false); +} + +export function SendContactRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendContactRequest { + if (json == null) { + return json; + } + return { + + 'phone': json['phone'] == null ? undefined : json['phone'], + 'chatId': json['chatId'] == null ? undefined : json['chatId'], + 'quotedMsgId': json['quotedMsgId'] == null ? undefined : json['quotedMsgId'], + 'contact': json['contact'] == null ? undefined : SendContactRequestContactFromJSON(json['contact']), + 'contacts': json['contacts'] == null ? undefined : ((json['contacts'] as Array).map(SendContactRequestContactsInnerFromJSON)), + }; +} + +export function SendContactRequestToJSON(json: any): SendContactRequest { + return SendContactRequestToJSONTyped(json, false); +} + +export function SendContactRequestToJSONTyped(value?: SendContactRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'phone': value['phone'], + 'chatId': value['chatId'], + 'quotedMsgId': value['quotedMsgId'], + 'contact': SendContactRequestContactToJSON(value['contact']), + 'contacts': value['contacts'] == null ? undefined : ((value['contacts'] as Array).map(SendContactRequestContactsInnerToJSON)), + }; +} + diff --git a/typescript/src/generated/src/models/SendContactRequestContact.ts b/typescript/src/generated/src/models/SendContactRequestContact.ts new file mode 100644 index 0000000..e0625f4 --- /dev/null +++ b/typescript/src/generated/src/models/SendContactRequestContact.ts @@ -0,0 +1,107 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { SendContactRequestContactName } from './SendContactRequestContactName'; +import { + SendContactRequestContactNameFromJSON, + SendContactRequestContactNameFromJSONTyped, + SendContactRequestContactNameToJSON, + SendContactRequestContactNameToJSONTyped, +} from './SendContactRequestContactName'; + +/** + * Simple contact card. Use this or `contacts`. + * @export + * @interface SendContactRequestContact + */ +export interface SendContactRequestContact { + /** + * + * @type {SendContactRequestContactName} + * @memberof SendContactRequestContact + */ + name: SendContactRequestContactName; + /** + * Contact phone in E.164 (`+79181976551`), not a timestamp + * @type {string} + * @memberof SendContactRequestContact + */ + phone: string; + /** + * + * @type {string} + * @memberof SendContactRequestContact + */ + email?: (string) | undefined; + /** + * + * @type {{ [key: string]: any; }} + * @memberof SendContactRequestContact + */ + org?: ({ [key: string]: any; }) | undefined; + /** + * + * @type {string} + * @memberof SendContactRequestContact + */ + url?: (string) | undefined; +} + +/** + * Check if a given object implements the SendContactRequestContact interface. + */ +export function instanceOfSendContactRequestContact(value: object): value is SendContactRequestContact { + if (!('name' in value) || value['name'] === undefined) return false; + if (!('phone' in value) || value['phone'] === undefined) return false; + return true; +} + +export function SendContactRequestContactFromJSON(json: any): SendContactRequestContact { + return SendContactRequestContactFromJSONTyped(json, false); +} + +export function SendContactRequestContactFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendContactRequestContact { + if (json == null) { + return json; + } + return { + + 'name': SendContactRequestContactNameFromJSON(json['name']), + 'phone': json['phone'], + 'email': json['email'] == null ? undefined : json['email'], + 'org': json['org'] == null ? undefined : json['org'], + 'url': json['url'] == null ? undefined : json['url'], + }; +} + +export function SendContactRequestContactToJSON(json: any): SendContactRequestContact { + return SendContactRequestContactToJSONTyped(json, false); +} + +export function SendContactRequestContactToJSONTyped(value?: SendContactRequestContact | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'name': SendContactRequestContactNameToJSON(value['name']), + 'phone': value['phone'], + 'email': value['email'], + 'org': value['org'], + 'url': value['url'], + }; +} + diff --git a/typescript/src/generated/src/models/SendContactRequestContactName.ts b/typescript/src/generated/src/models/SendContactRequestContactName.ts new file mode 100644 index 0000000..58af0ad --- /dev/null +++ b/typescript/src/generated/src/models/SendContactRequestContactName.ts @@ -0,0 +1,49 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +/** + * @type SendContactRequestContactName + * Display name (string) or Cloud API name object + * @export + */ +export type SendContactRequestContactName = string | { [key: string]: any; }; + +export function SendContactRequestContactNameFromJSON(json: any): SendContactRequestContactName { + return SendContactRequestContactNameFromJSONTyped(json, false); +} + +export function SendContactRequestContactNameFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendContactRequestContactName { + if (json == null) { + return json; + } + if (typeof json === 'string') { + return json; + } + return {} as any; +} + +export function SendContactRequestContactNameToJSON(json: any): any { + return SendContactRequestContactNameToJSONTyped(json, false); +} + +export function SendContactRequestContactNameToJSONTyped(value?: SendContactRequestContactName | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + if (typeof value === 'string') { + return value; + } + return {}; +} + diff --git a/typescript/src/generated/src/models/SendContactRequestContactsInner.ts b/typescript/src/generated/src/models/SendContactRequestContactsInner.ts new file mode 100644 index 0000000..91f59d4 --- /dev/null +++ b/typescript/src/generated/src/models/SendContactRequestContactsInner.ts @@ -0,0 +1,135 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { SendContactRequestContactsInnerOrg } from './SendContactRequestContactsInnerOrg'; +import { + SendContactRequestContactsInnerOrgFromJSON, + SendContactRequestContactsInnerOrgFromJSONTyped, + SendContactRequestContactsInnerOrgToJSON, + SendContactRequestContactsInnerOrgToJSONTyped, +} from './SendContactRequestContactsInnerOrg'; +import type { SendContactRequestContactsInnerPhonesInner } from './SendContactRequestContactsInnerPhonesInner'; +import { + SendContactRequestContactsInnerPhonesInnerFromJSON, + SendContactRequestContactsInnerPhonesInnerFromJSONTyped, + SendContactRequestContactsInnerPhonesInnerToJSON, + SendContactRequestContactsInnerPhonesInnerToJSONTyped, +} from './SendContactRequestContactsInnerPhonesInner'; +import type { SendContactRequestContactsInnerName } from './SendContactRequestContactsInnerName'; +import { + SendContactRequestContactsInnerNameFromJSON, + SendContactRequestContactsInnerNameFromJSONTyped, + SendContactRequestContactsInnerNameToJSON, + SendContactRequestContactsInnerNameToJSONTyped, +} from './SendContactRequestContactsInnerName'; + +/** + * + * @export + * @interface SendContactRequestContactsInner + */ +export interface SendContactRequestContactsInner { + /** + * + * @type {SendContactRequestContactsInnerName} + * @memberof SendContactRequestContactsInner + */ + name?: (SendContactRequestContactsInnerName) | undefined; + /** + * + * @type {string} + * @memberof SendContactRequestContactsInner + */ + birthday?: (string) | undefined; + /** + * + * @type {Array<{ [key: string]: any; }>} + * @memberof SendContactRequestContactsInner + */ + addresses?: (Array<{ [key: string]: any; }>) | undefined; + /** + * + * @type {Array<{ [key: string]: any; }>} + * @memberof SendContactRequestContactsInner + */ + emails?: (Array<{ [key: string]: any; }>) | undefined; + /** + * + * @type {SendContactRequestContactsInnerOrg} + * @memberof SendContactRequestContactsInner + */ + org?: (SendContactRequestContactsInnerOrg) | undefined; + /** + * + * @type {Array} + * @memberof SendContactRequestContactsInner + */ + phones?: (Array) | undefined; + /** + * + * @type {Array<{ [key: string]: any; }>} + * @memberof SendContactRequestContactsInner + */ + urls?: (Array<{ [key: string]: any; }>) | undefined; +} + +/** + * Check if a given object implements the SendContactRequestContactsInner interface. + */ +export function instanceOfSendContactRequestContactsInner(value: object): value is SendContactRequestContactsInner { + return true; +} + +export function SendContactRequestContactsInnerFromJSON(json: any): SendContactRequestContactsInner { + return SendContactRequestContactsInnerFromJSONTyped(json, false); +} + +export function SendContactRequestContactsInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendContactRequestContactsInner { + if (json == null) { + return json; + } + return { + + 'name': json['name'] == null ? undefined : SendContactRequestContactsInnerNameFromJSON(json['name']), + 'birthday': json['birthday'] == null ? undefined : json['birthday'], + 'addresses': json['addresses'] == null ? undefined : json['addresses'], + 'emails': json['emails'] == null ? undefined : json['emails'], + 'org': json['org'] == null ? undefined : SendContactRequestContactsInnerOrgFromJSON(json['org']), + 'phones': json['phones'] == null ? undefined : ((json['phones'] as Array).map(SendContactRequestContactsInnerPhonesInnerFromJSON)), + 'urls': json['urls'] == null ? undefined : json['urls'], + }; +} + +export function SendContactRequestContactsInnerToJSON(json: any): SendContactRequestContactsInner { + return SendContactRequestContactsInnerToJSONTyped(json, false); +} + +export function SendContactRequestContactsInnerToJSONTyped(value?: SendContactRequestContactsInner | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'name': SendContactRequestContactsInnerNameToJSON(value['name']), + 'birthday': value['birthday'], + 'addresses': value['addresses'], + 'emails': value['emails'], + 'org': SendContactRequestContactsInnerOrgToJSON(value['org']), + 'phones': value['phones'] == null ? undefined : ((value['phones'] as Array).map(SendContactRequestContactsInnerPhonesInnerToJSON)), + 'urls': value['urls'], + }; +} + diff --git a/typescript/src/generated/src/models/SendContactRequestContactsInnerName.ts b/typescript/src/generated/src/models/SendContactRequestContactsInnerName.ts new file mode 100644 index 0000000..36c0b3d --- /dev/null +++ b/typescript/src/generated/src/models/SendContactRequestContactsInnerName.ts @@ -0,0 +1,105 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SendContactRequestContactsInnerName + */ +export interface SendContactRequestContactsInnerName { + /** + * + * @type {string} + * @memberof SendContactRequestContactsInnerName + */ + formattedName?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendContactRequestContactsInnerName + */ + firstName?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendContactRequestContactsInnerName + */ + lastName?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendContactRequestContactsInnerName + */ + middleName?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendContactRequestContactsInnerName + */ + suffix?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendContactRequestContactsInnerName + */ + prefix?: (string) | undefined; +} + +/** + * Check if a given object implements the SendContactRequestContactsInnerName interface. + */ +export function instanceOfSendContactRequestContactsInnerName(value: object): value is SendContactRequestContactsInnerName { + return true; +} + +export function SendContactRequestContactsInnerNameFromJSON(json: any): SendContactRequestContactsInnerName { + return SendContactRequestContactsInnerNameFromJSONTyped(json, false); +} + +export function SendContactRequestContactsInnerNameFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendContactRequestContactsInnerName { + if (json == null) { + return json; + } + return { + + 'formattedName': json['formatted_name'] == null ? undefined : json['formatted_name'], + 'firstName': json['first_name'] == null ? undefined : json['first_name'], + 'lastName': json['last_name'] == null ? undefined : json['last_name'], + 'middleName': json['middle_name'] == null ? undefined : json['middle_name'], + 'suffix': json['suffix'] == null ? undefined : json['suffix'], + 'prefix': json['prefix'] == null ? undefined : json['prefix'], + }; +} + +export function SendContactRequestContactsInnerNameToJSON(json: any): SendContactRequestContactsInnerName { + return SendContactRequestContactsInnerNameToJSONTyped(json, false); +} + +export function SendContactRequestContactsInnerNameToJSONTyped(value?: SendContactRequestContactsInnerName | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'formatted_name': value['formattedName'], + 'first_name': value['firstName'], + 'last_name': value['lastName'], + 'middle_name': value['middleName'], + 'suffix': value['suffix'], + 'prefix': value['prefix'], + }; +} + diff --git a/typescript/src/generated/src/models/SendContactRequestContactsInnerOrg.ts b/typescript/src/generated/src/models/SendContactRequestContactsInnerOrg.ts new file mode 100644 index 0000000..1dec223 --- /dev/null +++ b/typescript/src/generated/src/models/SendContactRequestContactsInnerOrg.ts @@ -0,0 +1,81 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SendContactRequestContactsInnerOrg + */ +export interface SendContactRequestContactsInnerOrg { + /** + * + * @type {string} + * @memberof SendContactRequestContactsInnerOrg + */ + company?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendContactRequestContactsInnerOrg + */ + department?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendContactRequestContactsInnerOrg + */ + title?: (string) | undefined; +} + +/** + * Check if a given object implements the SendContactRequestContactsInnerOrg interface. + */ +export function instanceOfSendContactRequestContactsInnerOrg(value: object): value is SendContactRequestContactsInnerOrg { + return true; +} + +export function SendContactRequestContactsInnerOrgFromJSON(json: any): SendContactRequestContactsInnerOrg { + return SendContactRequestContactsInnerOrgFromJSONTyped(json, false); +} + +export function SendContactRequestContactsInnerOrgFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendContactRequestContactsInnerOrg { + if (json == null) { + return json; + } + return { + + 'company': json['company'] == null ? undefined : json['company'], + 'department': json['department'] == null ? undefined : json['department'], + 'title': json['title'] == null ? undefined : json['title'], + }; +} + +export function SendContactRequestContactsInnerOrgToJSON(json: any): SendContactRequestContactsInnerOrg { + return SendContactRequestContactsInnerOrgToJSONTyped(json, false); +} + +export function SendContactRequestContactsInnerOrgToJSONTyped(value?: SendContactRequestContactsInnerOrg | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'company': value['company'], + 'department': value['department'], + 'title': value['title'], + }; +} + diff --git a/typescript/src/generated/src/models/SendContactRequestContactsInnerPhonesInner.ts b/typescript/src/generated/src/models/SendContactRequestContactsInnerPhonesInner.ts new file mode 100644 index 0000000..b3d784f --- /dev/null +++ b/typescript/src/generated/src/models/SendContactRequestContactsInnerPhonesInner.ts @@ -0,0 +1,81 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SendContactRequestContactsInnerPhonesInner + */ +export interface SendContactRequestContactsInnerPhonesInner { + /** + * E.164 phone (`+79181976551`). Not a timestamp. + * @type {string} + * @memberof SendContactRequestContactsInnerPhonesInner + */ + phone?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendContactRequestContactsInnerPhonesInner + */ + type?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendContactRequestContactsInnerPhonesInner + */ + waId?: (string) | undefined; +} + +/** + * Check if a given object implements the SendContactRequestContactsInnerPhonesInner interface. + */ +export function instanceOfSendContactRequestContactsInnerPhonesInner(value: object): value is SendContactRequestContactsInnerPhonesInner { + return true; +} + +export function SendContactRequestContactsInnerPhonesInnerFromJSON(json: any): SendContactRequestContactsInnerPhonesInner { + return SendContactRequestContactsInnerPhonesInnerFromJSONTyped(json, false); +} + +export function SendContactRequestContactsInnerPhonesInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendContactRequestContactsInnerPhonesInner { + if (json == null) { + return json; + } + return { + + 'phone': json['phone'] == null ? undefined : json['phone'], + 'type': json['type'] == null ? undefined : json['type'], + 'waId': json['wa_id'] == null ? undefined : json['wa_id'], + }; +} + +export function SendContactRequestContactsInnerPhonesInnerToJSON(json: any): SendContactRequestContactsInnerPhonesInner { + return SendContactRequestContactsInnerPhonesInnerToJSONTyped(json, false); +} + +export function SendContactRequestContactsInnerPhonesInnerToJSONTyped(value?: SendContactRequestContactsInnerPhonesInner | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'phone': value['phone'], + 'type': value['type'], + 'wa_id': value['waId'], + }; +} + diff --git a/typescript/src/generated/src/models/SendCtaUrlRequest.ts b/typescript/src/generated/src/models/SendCtaUrlRequest.ts new file mode 100644 index 0000000..2dcc7ae --- /dev/null +++ b/typescript/src/generated/src/models/SendCtaUrlRequest.ts @@ -0,0 +1,127 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SendCtaUrlRequest + */ +export interface SendCtaUrlRequest { + [key: string]: any | any; + /** + * + * @type {number} + * @memberof SendCtaUrlRequest + */ + phone?: (number) | undefined; + /** + * + * @type {string} + * @memberof SendCtaUrlRequest + */ + chatId?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendCtaUrlRequest + */ + body: string; + /** + * Button label + * @type {string} + * @memberof SendCtaUrlRequest + */ + displayText: string; + /** + * + * @type {string} + * @memberof SendCtaUrlRequest + */ + url: string; + /** + * + * @type {{ [key: string]: any; }} + * @memberof SendCtaUrlRequest + */ + header?: ({ [key: string]: any; }) | undefined; + /** + * + * @type {string} + * @memberof SendCtaUrlRequest + */ + footer?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendCtaUrlRequest + */ + quotedMsgId?: (string) | undefined; +} + +/** + * Check if a given object implements the SendCtaUrlRequest interface. + */ +export function instanceOfSendCtaUrlRequest(value: object): value is SendCtaUrlRequest { + if (!('body' in value) || value['body'] === undefined) return false; + if (!('displayText' in value) || value['displayText'] === undefined) return false; + if (!('url' in value) || value['url'] === undefined) return false; + return true; +} + +export function SendCtaUrlRequestFromJSON(json: any): SendCtaUrlRequest { + return SendCtaUrlRequestFromJSONTyped(json, false); +} + +export function SendCtaUrlRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendCtaUrlRequest { + if (json == null) { + return json; + } + return { + + ...json, + 'phone': json['phone'] == null ? undefined : json['phone'], + 'chatId': json['chatId'] == null ? undefined : json['chatId'], + 'body': json['body'], + 'displayText': json['displayText'], + 'url': json['url'], + 'header': json['header'] == null ? undefined : json['header'], + 'footer': json['footer'] == null ? undefined : json['footer'], + 'quotedMsgId': json['quotedMsgId'] == null ? undefined : json['quotedMsgId'], + }; +} + +export function SendCtaUrlRequestToJSON(json: any): SendCtaUrlRequest { + return SendCtaUrlRequestToJSONTyped(json, false); +} + +export function SendCtaUrlRequestToJSONTyped(value?: SendCtaUrlRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'phone': value['phone'], + 'chatId': value['chatId'], + 'body': value['body'], + 'displayText': value['displayText'], + 'url': value['url'], + 'header': value['header'], + 'footer': value['footer'], + 'quotedMsgId': value['quotedMsgId'], + }; +} + diff --git a/typescript/src/generated/src/models/SendFileRequest.ts b/typescript/src/generated/src/models/SendFileRequest.ts new file mode 100644 index 0000000..906c757 --- /dev/null +++ b/typescript/src/generated/src/models/SendFileRequest.ts @@ -0,0 +1,148 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * Send file by URL/base64 or by mediaId + * @export + * @interface SendFileRequest + */ +export interface SendFileRequest { + [key: string]: any | any; + /** + * File source (required unless mediaId is set): + * - HTTP/HTTPS URL + * - Base64 data URI + * + * @type {string} + * @memberof SendFileRequest + */ + body?: (string) | undefined; + /** + * File name with extension (required with body, not with mediaId) + * @type {string} + * @memberof SendFileRequest + */ + filename?: (string) | undefined; + /** + * WABA media id from uploadMedia (alternative to body) + * @type {string} + * @memberof SendFileRequest + */ + mediaId?: (string) | undefined; + /** + * Required when using mediaId + * @type {SendFileRequestMediaTypeEnum} + * @memberof SendFileRequest + */ + mediaType?: (SendFileRequestMediaTypeEnum) | undefined; + /** + * Native WhatsApp voice note (audio/ogg only) + * @type {boolean} + * @memberof SendFileRequest + */ + voice?: (boolean) | undefined; + /** + * + * @type {string} + * @memberof SendFileRequest + */ + caption?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendFileRequest + */ + quotedMsgId?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendFileRequest + */ + chatId?: (string) | undefined; + /** + * + * @type {number} + * @memberof SendFileRequest + */ + phone?: (number) | undefined; +} + + +/** + * @export + */ +export const SendFileRequestMediaTypeEnum = { + Image: 'image', + Video: 'video', + Audio: 'audio', + Document: 'document' +} as const; +export type SendFileRequestMediaTypeEnum = typeof SendFileRequestMediaTypeEnum[keyof typeof SendFileRequestMediaTypeEnum]; + + +/** + * Check if a given object implements the SendFileRequest interface. + */ +export function instanceOfSendFileRequest(value: object): value is SendFileRequest { + return true; +} + +export function SendFileRequestFromJSON(json: any): SendFileRequest { + return SendFileRequestFromJSONTyped(json, false); +} + +export function SendFileRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendFileRequest { + if (json == null) { + return json; + } + return { + + ...json, + 'body': json['body'] == null ? undefined : json['body'], + 'filename': json['filename'] == null ? undefined : json['filename'], + 'mediaId': json['mediaId'] == null ? undefined : json['mediaId'], + 'mediaType': json['mediaType'] == null ? undefined : json['mediaType'], + 'voice': json['voice'] == null ? undefined : json['voice'], + 'caption': json['caption'] == null ? undefined : json['caption'], + 'quotedMsgId': json['quotedMsgId'] == null ? undefined : json['quotedMsgId'], + 'chatId': json['chatId'] == null ? undefined : json['chatId'], + 'phone': json['phone'] == null ? undefined : json['phone'], + }; +} + +export function SendFileRequestToJSON(json: any): SendFileRequest { + return SendFileRequestToJSONTyped(json, false); +} + +export function SendFileRequestToJSONTyped(value?: SendFileRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'body': value['body'], + 'filename': value['filename'], + 'mediaId': value['mediaId'], + 'mediaType': value['mediaType'], + 'voice': value['voice'], + 'caption': value['caption'], + 'quotedMsgId': value['quotedMsgId'], + 'chatId': value['chatId'], + 'phone': value['phone'], + }; +} + diff --git a/typescript/src/generated/src/models/SendFlowRequest1.ts b/typescript/src/generated/src/models/SendFlowRequest1.ts new file mode 100644 index 0000000..feef363 --- /dev/null +++ b/typescript/src/generated/src/models/SendFlowRequest1.ts @@ -0,0 +1,209 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { SendFlowRequest1Header } from './SendFlowRequest1Header'; +import { + SendFlowRequest1HeaderFromJSON, + SendFlowRequest1HeaderFromJSONTyped, + SendFlowRequest1HeaderToJSON, + SendFlowRequest1HeaderToJSONTyped, +} from './SendFlowRequest1Header'; + +/** + * + * @export + * @interface SendFlowRequest1 + */ +export interface SendFlowRequest1 { + /** + * + * @type {string} + * @memberof SendFlowRequest1 + */ + body: string; + /** + * + * @type {SendFlowRequest1Header} + * @memberof SendFlowRequest1 + */ + header?: (SendFlowRequest1Header) | undefined; + /** + * + * @type {string} + * @memberof SendFlowRequest1 + */ + footer?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendFlowRequest1 + */ + flowId: string; + /** + * + * @type {string} + * @memberof SendFlowRequest1 + */ + flowToken: string; + /** + * + * @type {string} + * @memberof SendFlowRequest1 + */ + flowCta: string; + /** + * + * @type {SendFlowRequest1FlowActionEnum} + * @memberof SendFlowRequest1 + */ + flowAction?: (SendFlowRequest1FlowActionEnum) | undefined; + /** + * + * @type {object} + * @memberof SendFlowRequest1 + */ + flowActionPayload?: (object) | undefined; + /** + * + * @type {string} + * @memberof SendFlowRequest1 + */ + flowMessageVersion?: (string) | undefined; + /** + * + * @type {SendFlowRequest1ModeEnum} + * @memberof SendFlowRequest1 + */ + mode?: (SendFlowRequest1ModeEnum) | undefined; + /** + * + * @type {object} + * @memberof SendFlowRequest1 + */ + flowActionData?: (object) | undefined; + /** + * + * @type {string} + * @memberof SendFlowRequest1 + */ + flowActionScreen?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendFlowRequest1 + */ + quotedMsgId?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendFlowRequest1 + */ + chatId?: (string) | undefined; + /** + * + * @type {number} + * @memberof SendFlowRequest1 + */ + phone?: (number) | undefined; +} + + +/** + * @export + */ +export const SendFlowRequest1FlowActionEnum = { + Navigate: 'navigate', + DataExchange: 'data_exchange' +} as const; +export type SendFlowRequest1FlowActionEnum = typeof SendFlowRequest1FlowActionEnum[keyof typeof SendFlowRequest1FlowActionEnum]; + +/** + * @export + */ +export const SendFlowRequest1ModeEnum = { + Draft: 'draft', + Published: 'published' +} as const; +export type SendFlowRequest1ModeEnum = typeof SendFlowRequest1ModeEnum[keyof typeof SendFlowRequest1ModeEnum]; + + +/** + * Check if a given object implements the SendFlowRequest1 interface. + */ +export function instanceOfSendFlowRequest1(value: object): value is SendFlowRequest1 { + if (!('body' in value) || value['body'] === undefined) return false; + if (!('flowId' in value) || value['flowId'] === undefined) return false; + if (!('flowToken' in value) || value['flowToken'] === undefined) return false; + if (!('flowCta' in value) || value['flowCta'] === undefined) return false; + return true; +} + +export function SendFlowRequest1FromJSON(json: any): SendFlowRequest1 { + return SendFlowRequest1FromJSONTyped(json, false); +} + +export function SendFlowRequest1FromJSONTyped(json: any, ignoreDiscriminator: boolean): SendFlowRequest1 { + if (json == null) { + return json; + } + return { + + 'body': json['body'], + 'header': json['header'] == null ? undefined : SendFlowRequest1HeaderFromJSON(json['header']), + 'footer': json['footer'] == null ? undefined : json['footer'], + 'flowId': json['flowId'], + 'flowToken': json['flowToken'], + 'flowCta': json['flowCta'], + 'flowAction': json['flowAction'] == null ? undefined : json['flowAction'], + 'flowActionPayload': json['flowActionPayload'] == null ? undefined : json['flowActionPayload'], + 'flowMessageVersion': json['flowMessageVersion'] == null ? undefined : json['flowMessageVersion'], + 'mode': json['mode'] == null ? undefined : json['mode'], + 'flowActionData': json['flowActionData'] == null ? undefined : json['flowActionData'], + 'flowActionScreen': json['flowActionScreen'] == null ? undefined : json['flowActionScreen'], + 'quotedMsgId': json['quotedMsgId'] == null ? undefined : json['quotedMsgId'], + 'chatId': json['chatId'] == null ? undefined : json['chatId'], + 'phone': json['phone'] == null ? undefined : json['phone'], + }; +} + +export function SendFlowRequest1ToJSON(json: any): SendFlowRequest1 { + return SendFlowRequest1ToJSONTyped(json, false); +} + +export function SendFlowRequest1ToJSONTyped(value?: SendFlowRequest1 | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'body': value['body'], + 'header': SendFlowRequest1HeaderToJSON(value['header']), + 'footer': value['footer'], + 'flowId': value['flowId'], + 'flowToken': value['flowToken'], + 'flowCta': value['flowCta'], + 'flowAction': value['flowAction'], + 'flowActionPayload': value['flowActionPayload'], + 'flowMessageVersion': value['flowMessageVersion'], + 'mode': value['mode'], + 'flowActionData': value['flowActionData'], + 'flowActionScreen': value['flowActionScreen'], + 'quotedMsgId': value['quotedMsgId'], + 'chatId': value['chatId'], + 'phone': value['phone'], + }; +} + diff --git a/typescript/src/generated/src/models/SendFlowRequest1Header.ts b/typescript/src/generated/src/models/SendFlowRequest1Header.ts new file mode 100644 index 0000000..ac14716 --- /dev/null +++ b/typescript/src/generated/src/models/SendFlowRequest1Header.ts @@ -0,0 +1,49 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +/** + * @type SendFlowRequest1Header + * + * @export + */ +export type SendFlowRequest1Header = object | string; + +export function SendFlowRequest1HeaderFromJSON(json: any): SendFlowRequest1Header { + return SendFlowRequest1HeaderFromJSONTyped(json, false); +} + +export function SendFlowRequest1HeaderFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendFlowRequest1Header { + if (json == null) { + return json; + } + if (typeof json === 'string') { + return json; + } + return {} as any; +} + +export function SendFlowRequest1HeaderToJSON(json: any): any { + return SendFlowRequest1HeaderToJSONTyped(json, false); +} + +export function SendFlowRequest1HeaderToJSONTyped(value?: SendFlowRequest1Header | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + if (typeof value === 'string') { + return value; + } + return {}; +} + diff --git a/typescript/src/generated/src/models/SendFlowRequestHeader.ts b/typescript/src/generated/src/models/SendFlowRequestHeader.ts new file mode 100644 index 0000000..210bfc4 --- /dev/null +++ b/typescript/src/generated/src/models/SendFlowRequestHeader.ts @@ -0,0 +1,49 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +/** + * @type SendFlowRequestHeader + * Flow header (string or text header object) + * @export + */ +export type SendFlowRequestHeader = object | string; + +export function SendFlowRequestHeaderFromJSON(json: any): SendFlowRequestHeader { + return SendFlowRequestHeaderFromJSONTyped(json, false); +} + +export function SendFlowRequestHeaderFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendFlowRequestHeader { + if (json == null) { + return json; + } + if (typeof json === 'string') { + return json; + } + return {} as any; +} + +export function SendFlowRequestHeaderToJSON(json: any): any { + return SendFlowRequestHeaderToJSONTyped(json, false); +} + +export function SendFlowRequestHeaderToJSONTyped(value?: SendFlowRequestHeader | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + if (typeof value === 'string') { + return value; + } + return {}; +} + diff --git a/typescript/src/generated/src/models/SendListRequest.ts b/typescript/src/generated/src/models/SendListRequest.ts new file mode 100644 index 0000000..74f2a16 --- /dev/null +++ b/typescript/src/generated/src/models/SendListRequest.ts @@ -0,0 +1,121 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { SendListRequestSectionsInner } from './SendListRequestSectionsInner'; +import { + SendListRequestSectionsInnerFromJSON, + SendListRequestSectionsInnerFromJSONTyped, + SendListRequestSectionsInnerToJSON, + SendListRequestSectionsInnerToJSONTyped, +} from './SendListRequestSectionsInner'; + +/** + * + * @export + * @interface SendListRequest + */ +export interface SendListRequest { + /** + * Recipient phone with country code. Use phone or chatId. + * @type {string} + * @memberof SendListRequest + */ + phone?: (string) | undefined; + /** + * Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. + * @type {string} + * @memberof SendListRequest + */ + chatId?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendListRequest + */ + quotedMsgId?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendListRequest + */ + body?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendListRequest + */ + buttonText?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendListRequest + */ + action?: (string) | undefined; + /** + * + * @type {Array} + * @memberof SendListRequest + */ + sections?: (Array) | undefined; +} + +/** + * Check if a given object implements the SendListRequest interface. + */ +export function instanceOfSendListRequest(value: object): value is SendListRequest { + return true; +} + +export function SendListRequestFromJSON(json: any): SendListRequest { + return SendListRequestFromJSONTyped(json, false); +} + +export function SendListRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendListRequest { + if (json == null) { + return json; + } + return { + + 'phone': json['phone'] == null ? undefined : json['phone'], + 'chatId': json['chatId'] == null ? undefined : json['chatId'], + 'quotedMsgId': json['quotedMsgId'] == null ? undefined : json['quotedMsgId'], + 'body': json['body'] == null ? undefined : json['body'], + 'buttonText': json['buttonText'] == null ? undefined : json['buttonText'], + 'action': json['action'] == null ? undefined : json['action'], + 'sections': json['sections'] == null ? undefined : ((json['sections'] as Array).map(SendListRequestSectionsInnerFromJSON)), + }; +} + +export function SendListRequestToJSON(json: any): SendListRequest { + return SendListRequestToJSONTyped(json, false); +} + +export function SendListRequestToJSONTyped(value?: SendListRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'phone': value['phone'], + 'chatId': value['chatId'], + 'quotedMsgId': value['quotedMsgId'], + 'body': value['body'], + 'buttonText': value['buttonText'], + 'action': value['action'], + 'sections': value['sections'] == null ? undefined : ((value['sections'] as Array).map(SendListRequestSectionsInnerToJSON)), + }; +} + diff --git a/typescript/src/generated/src/models/SendListRequestSectionsInner.ts b/typescript/src/generated/src/models/SendListRequestSectionsInner.ts new file mode 100644 index 0000000..c5f9d80 --- /dev/null +++ b/typescript/src/generated/src/models/SendListRequestSectionsInner.ts @@ -0,0 +1,81 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { SendListRequestSectionsInnerRowsInner } from './SendListRequestSectionsInnerRowsInner'; +import { + SendListRequestSectionsInnerRowsInnerFromJSON, + SendListRequestSectionsInnerRowsInnerFromJSONTyped, + SendListRequestSectionsInnerRowsInnerToJSON, + SendListRequestSectionsInnerRowsInnerToJSONTyped, +} from './SendListRequestSectionsInnerRowsInner'; + +/** + * + * @export + * @interface SendListRequestSectionsInner + */ +export interface SendListRequestSectionsInner { + /** + * + * @type {string} + * @memberof SendListRequestSectionsInner + */ + title?: (string) | undefined; + /** + * + * @type {Array} + * @memberof SendListRequestSectionsInner + */ + rows?: (Array) | undefined; +} + +/** + * Check if a given object implements the SendListRequestSectionsInner interface. + */ +export function instanceOfSendListRequestSectionsInner(value: object): value is SendListRequestSectionsInner { + return true; +} + +export function SendListRequestSectionsInnerFromJSON(json: any): SendListRequestSectionsInner { + return SendListRequestSectionsInnerFromJSONTyped(json, false); +} + +export function SendListRequestSectionsInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendListRequestSectionsInner { + if (json == null) { + return json; + } + return { + + 'title': json['title'] == null ? undefined : json['title'], + 'rows': json['rows'] == null ? undefined : ((json['rows'] as Array).map(SendListRequestSectionsInnerRowsInnerFromJSON)), + }; +} + +export function SendListRequestSectionsInnerToJSON(json: any): SendListRequestSectionsInner { + return SendListRequestSectionsInnerToJSONTyped(json, false); +} + +export function SendListRequestSectionsInnerToJSONTyped(value?: SendListRequestSectionsInner | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'title': value['title'], + 'rows': value['rows'] == null ? undefined : ((value['rows'] as Array).map(SendListRequestSectionsInnerRowsInnerToJSON)), + }; +} + diff --git a/typescript/src/generated/src/models/SendListRequestSectionsInnerRowsInner.ts b/typescript/src/generated/src/models/SendListRequestSectionsInnerRowsInner.ts new file mode 100644 index 0000000..0ae06f3 --- /dev/null +++ b/typescript/src/generated/src/models/SendListRequestSectionsInnerRowsInner.ts @@ -0,0 +1,81 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SendListRequestSectionsInnerRowsInner + */ +export interface SendListRequestSectionsInnerRowsInner { + /** + * + * @type {string} + * @memberof SendListRequestSectionsInnerRowsInner + */ + id?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendListRequestSectionsInnerRowsInner + */ + title?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendListRequestSectionsInnerRowsInner + */ + description?: (string) | undefined; +} + +/** + * Check if a given object implements the SendListRequestSectionsInnerRowsInner interface. + */ +export function instanceOfSendListRequestSectionsInnerRowsInner(value: object): value is SendListRequestSectionsInnerRowsInner { + return true; +} + +export function SendListRequestSectionsInnerRowsInnerFromJSON(json: any): SendListRequestSectionsInnerRowsInner { + return SendListRequestSectionsInnerRowsInnerFromJSONTyped(json, false); +} + +export function SendListRequestSectionsInnerRowsInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendListRequestSectionsInnerRowsInner { + if (json == null) { + return json; + } + return { + + 'id': json['id'] == null ? undefined : json['id'], + 'title': json['title'] == null ? undefined : json['title'], + 'description': json['description'] == null ? undefined : json['description'], + }; +} + +export function SendListRequestSectionsInnerRowsInnerToJSON(json: any): SendListRequestSectionsInnerRowsInner { + return SendListRequestSectionsInnerRowsInnerToJSONTyped(json, false); +} + +export function SendListRequestSectionsInnerRowsInnerToJSONTyped(value?: SendListRequestSectionsInnerRowsInner | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'id': value['id'], + 'title': value['title'], + 'description': value['description'], + }; +} + diff --git a/typescript/src/generated/src/models/SendLocationRequest1.ts b/typescript/src/generated/src/models/SendLocationRequest1.ts new file mode 100644 index 0000000..f7d50a4 --- /dev/null +++ b/typescript/src/generated/src/models/SendLocationRequest1.ts @@ -0,0 +1,115 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SendLocationRequest1 + */ +export interface SendLocationRequest1 { + /** + * + * @type {string} + * @memberof SendLocationRequest1 + */ + lat: string; + /** + * + * @type {string} + * @memberof SendLocationRequest1 + */ + lng: string; + /** + * + * @type {string} + * @memberof SendLocationRequest1 + */ + address?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendLocationRequest1 + */ + name?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendLocationRequest1 + */ + quotedMsgId?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendLocationRequest1 + */ + chatId?: (string) | undefined; + /** + * + * @type {number} + * @memberof SendLocationRequest1 + */ + phone?: (number) | undefined; +} + +/** + * Check if a given object implements the SendLocationRequest1 interface. + */ +export function instanceOfSendLocationRequest1(value: object): value is SendLocationRequest1 { + if (!('lat' in value) || value['lat'] === undefined) return false; + if (!('lng' in value) || value['lng'] === undefined) return false; + return true; +} + +export function SendLocationRequest1FromJSON(json: any): SendLocationRequest1 { + return SendLocationRequest1FromJSONTyped(json, false); +} + +export function SendLocationRequest1FromJSONTyped(json: any, ignoreDiscriminator: boolean): SendLocationRequest1 { + if (json == null) { + return json; + } + return { + + 'lat': json['lat'], + 'lng': json['lng'], + 'address': json['address'] == null ? undefined : json['address'], + 'name': json['name'] == null ? undefined : json['name'], + 'quotedMsgId': json['quotedMsgId'] == null ? undefined : json['quotedMsgId'], + 'chatId': json['chatId'] == null ? undefined : json['chatId'], + 'phone': json['phone'] == null ? undefined : json['phone'], + }; +} + +export function SendLocationRequest1ToJSON(json: any): SendLocationRequest1 { + return SendLocationRequest1ToJSONTyped(json, false); +} + +export function SendLocationRequest1ToJSONTyped(value?: SendLocationRequest1 | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'lat': value['lat'], + 'lng': value['lng'], + 'address': value['address'], + 'name': value['name'], + 'quotedMsgId': value['quotedMsgId'], + 'chatId': value['chatId'], + 'phone': value['phone'], + }; +} + diff --git a/typescript/src/generated/src/models/SendLocationRequestRequest.ts b/typescript/src/generated/src/models/SendLocationRequestRequest.ts new file mode 100644 index 0000000..8e758fd --- /dev/null +++ b/typescript/src/generated/src/models/SendLocationRequestRequest.ts @@ -0,0 +1,89 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SendLocationRequestRequest + */ +export interface SendLocationRequestRequest { + /** + * Recipient phone with country code. Use phone or chatId. + * @type {string} + * @memberof SendLocationRequestRequest + */ + phone?: (string) | undefined; + /** + * Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. + * @type {string} + * @memberof SendLocationRequestRequest + */ + chatId?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendLocationRequestRequest + */ + quotedMsgId?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendLocationRequestRequest + */ + body?: (string) | undefined; +} + +/** + * Check if a given object implements the SendLocationRequestRequest interface. + */ +export function instanceOfSendLocationRequestRequest(value: object): value is SendLocationRequestRequest { + return true; +} + +export function SendLocationRequestRequestFromJSON(json: any): SendLocationRequestRequest { + return SendLocationRequestRequestFromJSONTyped(json, false); +} + +export function SendLocationRequestRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendLocationRequestRequest { + if (json == null) { + return json; + } + return { + + 'phone': json['phone'] == null ? undefined : json['phone'], + 'chatId': json['chatId'] == null ? undefined : json['chatId'], + 'quotedMsgId': json['quotedMsgId'] == null ? undefined : json['quotedMsgId'], + 'body': json['body'] == null ? undefined : json['body'], + }; +} + +export function SendLocationRequestRequestToJSON(json: any): SendLocationRequestRequest { + return SendLocationRequestRequestToJSONTyped(json, false); +} + +export function SendLocationRequestRequestToJSONTyped(value?: SendLocationRequestRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'phone': value['phone'], + 'chatId': value['chatId'], + 'quotedMsgId': value['quotedMsgId'], + 'body': value['body'], + }; +} + diff --git a/typescript/src/generated/src/models/SendMessageRequest.ts b/typescript/src/generated/src/models/SendMessageRequest.ts new file mode 100644 index 0000000..ca7a5da --- /dev/null +++ b/typescript/src/generated/src/models/SendMessageRequest.ts @@ -0,0 +1,90 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * Request body for sending a text message + * @export + * @interface SendMessageRequest + */ +export interface SendMessageRequest { + /** + * Message text, UTF-8 or UTF-16 string with emoji + * @type {string} + * @memberof SendMessageRequest + */ + body: string; + /** + * Message ID to quote/reply to (Cloud API wamid) + * @type {string} + * @memberof SendMessageRequest + */ + quotedMsgId?: (string) | undefined; + /** + * Recipient chat ID: phone@c.us, group@g.us, or BSUID@lid + * @type {string} + * @memberof SendMessageRequest + */ + chatId?: (string) | undefined; + /** + * Phone number starting with country code (alternative to chatId) + * @type {number} + * @memberof SendMessageRequest + */ + phone?: (number) | undefined; +} + +/** + * Check if a given object implements the SendMessageRequest interface. + */ +export function instanceOfSendMessageRequest(value: object): value is SendMessageRequest { + if (!('body' in value) || value['body'] === undefined) return false; + return true; +} + +export function SendMessageRequestFromJSON(json: any): SendMessageRequest { + return SendMessageRequestFromJSONTyped(json, false); +} + +export function SendMessageRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendMessageRequest { + if (json == null) { + return json; + } + return { + + 'body': json['body'], + 'quotedMsgId': json['quotedMsgId'] == null ? undefined : json['quotedMsgId'], + 'chatId': json['chatId'] == null ? undefined : json['chatId'], + 'phone': json['phone'] == null ? undefined : json['phone'], + }; +} + +export function SendMessageRequestToJSON(json: any): SendMessageRequest { + return SendMessageRequestToJSONTyped(json, false); +} + +export function SendMessageRequestToJSONTyped(value?: SendMessageRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'body': value['body'], + 'quotedMsgId': value['quotedMsgId'], + 'chatId': value['chatId'], + 'phone': value['phone'], + }; +} + diff --git a/typescript/src/generated/src/models/SendOrderDetailsRequest.ts b/typescript/src/generated/src/models/SendOrderDetailsRequest.ts new file mode 100644 index 0000000..5a7e100 --- /dev/null +++ b/typescript/src/generated/src/models/SendOrderDetailsRequest.ts @@ -0,0 +1,161 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { SendOrderDetailsRequestOrder } from './SendOrderDetailsRequestOrder'; +import { + SendOrderDetailsRequestOrderFromJSON, + SendOrderDetailsRequestOrderFromJSONTyped, + SendOrderDetailsRequestOrderToJSON, + SendOrderDetailsRequestOrderToJSONTyped, +} from './SendOrderDetailsRequestOrder'; +import type { SendOrderDetailsRequestLanguage } from './SendOrderDetailsRequestLanguage'; +import { + SendOrderDetailsRequestLanguageFromJSON, + SendOrderDetailsRequestLanguageFromJSONTyped, + SendOrderDetailsRequestLanguageToJSON, + SendOrderDetailsRequestLanguageToJSONTyped, +} from './SendOrderDetailsRequestLanguage'; + +/** + * + * @export + * @interface SendOrderDetailsRequest + */ +export interface SendOrderDetailsRequest { + [key: string]: any | any; + /** + * Recipient phone (India E.164 digits, no +). Use phone or chatId. + * @type {number} + * @memberof SendOrderDetailsRequest + */ + phone?: (number) | undefined; + /** + * Recipient chatId (e.g. phone@c.us). Use phone or chatId. + * @type {string} + * @memberof SendOrderDetailsRequest + */ + chatId?: (string) | undefined; + /** + * Approved Utility template name that includes an ORDER_DETAILS button + * @type {string} + * @memberof SendOrderDetailsRequest + */ + template: string; + /** + * Template namespace from the channel / template list + * @type {string} + * @memberof SendOrderDetailsRequest + */ + namespace: string; + /** + * + * @type {SendOrderDetailsRequestLanguage} + * @memberof SendOrderDetailsRequest + */ + language: SendOrderDetailsRequestLanguage; + /** + * Extra template components (HEADER / BODY / etc.). If an order_details button is missing, the API appends one from order / referenceId / currency / paymentSettings. + * + * @type {Array<{ [key: string]: any; }>} + * @memberof SendOrderDetailsRequest + */ + params?: (Array<{ [key: string]: any; }>) | undefined; + /** + * Unique order / payment reference id (maps to reference_id) + * @type {string} + * @memberof SendOrderDetailsRequest + */ + referenceId?: (string) | undefined; + /** + * Currency code for India payments + * @type {string} + * @memberof SendOrderDetailsRequest + */ + currency?: (string) | undefined; + /** + * Optional payment settings (UPI / payment gateway / payment link). Forwarded as payment_settings on the order_details action. + * + * @type {{ [key: string]: any; }} + * @memberof SendOrderDetailsRequest + */ + paymentSettings?: ({ [key: string]: any; }) | undefined; + /** + * + * @type {SendOrderDetailsRequestOrder} + * @memberof SendOrderDetailsRequest + */ + order: SendOrderDetailsRequestOrder; +} + +/** + * Check if a given object implements the SendOrderDetailsRequest interface. + */ +export function instanceOfSendOrderDetailsRequest(value: object): value is SendOrderDetailsRequest { + if (!('template' in value) || value['template'] === undefined) return false; + if (!('namespace' in value) || value['namespace'] === undefined) return false; + if (!('language' in value) || value['language'] === undefined) return false; + if (!('order' in value) || value['order'] === undefined) return false; + return true; +} + +export function SendOrderDetailsRequestFromJSON(json: any): SendOrderDetailsRequest { + return SendOrderDetailsRequestFromJSONTyped(json, false); +} + +export function SendOrderDetailsRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendOrderDetailsRequest { + if (json == null) { + return json; + } + return { + + ...json, + 'phone': json['phone'] == null ? undefined : json['phone'], + 'chatId': json['chatId'] == null ? undefined : json['chatId'], + 'template': json['template'], + 'namespace': json['namespace'], + 'language': SendOrderDetailsRequestLanguageFromJSON(json['language']), + 'params': json['params'] == null ? undefined : json['params'], + 'referenceId': json['referenceId'] == null ? undefined : json['referenceId'], + 'currency': json['currency'] == null ? undefined : json['currency'], + 'paymentSettings': json['paymentSettings'] == null ? undefined : json['paymentSettings'], + 'order': SendOrderDetailsRequestOrderFromJSON(json['order']), + }; +} + +export function SendOrderDetailsRequestToJSON(json: any): SendOrderDetailsRequest { + return SendOrderDetailsRequestToJSONTyped(json, false); +} + +export function SendOrderDetailsRequestToJSONTyped(value?: SendOrderDetailsRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'phone': value['phone'], + 'chatId': value['chatId'], + 'template': value['template'], + 'namespace': value['namespace'], + 'language': SendOrderDetailsRequestLanguageToJSON(value['language']), + 'params': value['params'], + 'referenceId': value['referenceId'], + 'currency': value['currency'], + 'paymentSettings': value['paymentSettings'], + 'order': SendOrderDetailsRequestOrderToJSON(value['order']), + }; +} + diff --git a/typescript/src/generated/src/models/SendOrderDetailsRequestLanguage.ts b/typescript/src/generated/src/models/SendOrderDetailsRequestLanguage.ts new file mode 100644 index 0000000..84a00ce --- /dev/null +++ b/typescript/src/generated/src/models/SendOrderDetailsRequestLanguage.ts @@ -0,0 +1,77 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * Template language + * @export + * @interface SendOrderDetailsRequestLanguage + */ +export interface SendOrderDetailsRequestLanguage { + [key: string]: any | any; + /** + * Language code + * @type {string} + * @memberof SendOrderDetailsRequestLanguage + */ + code: string; + /** + * Optional language policy + * @type {string} + * @memberof SendOrderDetailsRequestLanguage + */ + policy?: (string) | undefined; +} + +/** + * Check if a given object implements the SendOrderDetailsRequestLanguage interface. + */ +export function instanceOfSendOrderDetailsRequestLanguage(value: object): value is SendOrderDetailsRequestLanguage { + if (!('code' in value) || value['code'] === undefined) return false; + return true; +} + +export function SendOrderDetailsRequestLanguageFromJSON(json: any): SendOrderDetailsRequestLanguage { + return SendOrderDetailsRequestLanguageFromJSONTyped(json, false); +} + +export function SendOrderDetailsRequestLanguageFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendOrderDetailsRequestLanguage { + if (json == null) { + return json; + } + return { + + ...json, + 'code': json['code'], + 'policy': json['policy'] == null ? undefined : json['policy'], + }; +} + +export function SendOrderDetailsRequestLanguageToJSON(json: any): SendOrderDetailsRequestLanguage { + return SendOrderDetailsRequestLanguageToJSONTyped(json, false); +} + +export function SendOrderDetailsRequestLanguageToJSONTyped(value?: SendOrderDetailsRequestLanguage | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'code': value['code'], + 'policy': value['policy'], + }; +} + diff --git a/typescript/src/generated/src/models/SendOrderDetailsRequestOrder.ts b/typescript/src/generated/src/models/SendOrderDetailsRequestOrder.ts new file mode 100644 index 0000000..e2a7182 --- /dev/null +++ b/typescript/src/generated/src/models/SendOrderDetailsRequestOrder.ts @@ -0,0 +1,125 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { SendOrderDetailsRequestOrderItemsInnerAmount } from './SendOrderDetailsRequestOrderItemsInnerAmount'; +import { + SendOrderDetailsRequestOrderItemsInnerAmountFromJSON, + SendOrderDetailsRequestOrderItemsInnerAmountFromJSONTyped, + SendOrderDetailsRequestOrderItemsInnerAmountToJSON, + SendOrderDetailsRequestOrderItemsInnerAmountToJSONTyped, +} from './SendOrderDetailsRequestOrderItemsInnerAmount'; +import type { SendOrderDetailsRequestOrderItemsInner } from './SendOrderDetailsRequestOrderItemsInner'; +import { + SendOrderDetailsRequestOrderItemsInnerFromJSON, + SendOrderDetailsRequestOrderItemsInnerFromJSONTyped, + SendOrderDetailsRequestOrderItemsInnerToJSON, + SendOrderDetailsRequestOrderItemsInnerToJSONTyped, +} from './SendOrderDetailsRequestOrderItemsInner'; + +/** + * Order payload for the ORDER_DETAILS button. Typical fields: status, items[], subtotal, tax, shipping, discount. Amount objects use `{ "offset": 100, "value": }` (e.g. value 50000 with offset 100 = ₹500.00). + * + * @export + * @interface SendOrderDetailsRequestOrder + */ +export interface SendOrderDetailsRequestOrder { + [key: string]: any | any; + /** + * Order status + * @type {string} + * @memberof SendOrderDetailsRequestOrder + */ + status?: (string) | undefined; + /** + * Line items + * @type {Array} + * @memberof SendOrderDetailsRequestOrder + */ + items: Array; + /** + * + * @type {SendOrderDetailsRequestOrderItemsInnerAmount} + * @memberof SendOrderDetailsRequestOrder + */ + subtotal?: (SendOrderDetailsRequestOrderItemsInnerAmount) | undefined; + /** + * + * @type {{ [key: string]: any; }} + * @memberof SendOrderDetailsRequestOrder + */ + tax?: ({ [key: string]: any; }) | undefined; + /** + * + * @type {{ [key: string]: any; }} + * @memberof SendOrderDetailsRequestOrder + */ + shipping?: ({ [key: string]: any; }) | undefined; + /** + * + * @type {{ [key: string]: any; }} + * @memberof SendOrderDetailsRequestOrder + */ + discount?: ({ [key: string]: any; }) | undefined; +} + +/** + * Check if a given object implements the SendOrderDetailsRequestOrder interface. + */ +export function instanceOfSendOrderDetailsRequestOrder(value: object): value is SendOrderDetailsRequestOrder { + if (!('items' in value) || value['items'] === undefined) return false; + return true; +} + +export function SendOrderDetailsRequestOrderFromJSON(json: any): SendOrderDetailsRequestOrder { + return SendOrderDetailsRequestOrderFromJSONTyped(json, false); +} + +export function SendOrderDetailsRequestOrderFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendOrderDetailsRequestOrder { + if (json == null) { + return json; + } + return { + + ...json, + 'status': json['status'] == null ? undefined : json['status'], + 'items': ((json['items'] as Array).map(SendOrderDetailsRequestOrderItemsInnerFromJSON)), + 'subtotal': json['subtotal'] == null ? undefined : SendOrderDetailsRequestOrderItemsInnerAmountFromJSON(json['subtotal']), + 'tax': json['tax'] == null ? undefined : json['tax'], + 'shipping': json['shipping'] == null ? undefined : json['shipping'], + 'discount': json['discount'] == null ? undefined : json['discount'], + }; +} + +export function SendOrderDetailsRequestOrderToJSON(json: any): SendOrderDetailsRequestOrder { + return SendOrderDetailsRequestOrderToJSONTyped(json, false); +} + +export function SendOrderDetailsRequestOrderToJSONTyped(value?: SendOrderDetailsRequestOrder | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'status': value['status'], + 'items': ((value['items'] as Array).map(SendOrderDetailsRequestOrderItemsInnerToJSON)), + 'subtotal': SendOrderDetailsRequestOrderItemsInnerAmountToJSON(value['subtotal']), + 'tax': value['tax'], + 'shipping': value['shipping'], + 'discount': value['discount'], + }; +} + diff --git a/typescript/src/generated/src/models/SendOrderDetailsRequestOrderItemsInner.ts b/typescript/src/generated/src/models/SendOrderDetailsRequestOrderItemsInner.ts new file mode 100644 index 0000000..fba21c0 --- /dev/null +++ b/typescript/src/generated/src/models/SendOrderDetailsRequestOrderItemsInner.ts @@ -0,0 +1,100 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { SendOrderDetailsRequestOrderItemsInnerAmount } from './SendOrderDetailsRequestOrderItemsInnerAmount'; +import { + SendOrderDetailsRequestOrderItemsInnerAmountFromJSON, + SendOrderDetailsRequestOrderItemsInnerAmountFromJSONTyped, + SendOrderDetailsRequestOrderItemsInnerAmountToJSON, + SendOrderDetailsRequestOrderItemsInnerAmountToJSONTyped, +} from './SendOrderDetailsRequestOrderItemsInnerAmount'; + +/** + * + * @export + * @interface SendOrderDetailsRequestOrderItemsInner + */ +export interface SendOrderDetailsRequestOrderItemsInner { + [key: string]: any | any; + /** + * + * @type {string} + * @memberof SendOrderDetailsRequestOrderItemsInner + */ + retailerId?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendOrderDetailsRequestOrderItemsInner + */ + name?: (string) | undefined; + /** + * + * @type {number} + * @memberof SendOrderDetailsRequestOrderItemsInner + */ + quantity?: (number) | undefined; + /** + * + * @type {SendOrderDetailsRequestOrderItemsInnerAmount} + * @memberof SendOrderDetailsRequestOrderItemsInner + */ + amount?: (SendOrderDetailsRequestOrderItemsInnerAmount) | undefined; +} + +/** + * Check if a given object implements the SendOrderDetailsRequestOrderItemsInner interface. + */ +export function instanceOfSendOrderDetailsRequestOrderItemsInner(value: object): value is SendOrderDetailsRequestOrderItemsInner { + return true; +} + +export function SendOrderDetailsRequestOrderItemsInnerFromJSON(json: any): SendOrderDetailsRequestOrderItemsInner { + return SendOrderDetailsRequestOrderItemsInnerFromJSONTyped(json, false); +} + +export function SendOrderDetailsRequestOrderItemsInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendOrderDetailsRequestOrderItemsInner { + if (json == null) { + return json; + } + return { + + ...json, + 'retailerId': json['retailer_id'] == null ? undefined : json['retailer_id'], + 'name': json['name'] == null ? undefined : json['name'], + 'quantity': json['quantity'] == null ? undefined : json['quantity'], + 'amount': json['amount'] == null ? undefined : SendOrderDetailsRequestOrderItemsInnerAmountFromJSON(json['amount']), + }; +} + +export function SendOrderDetailsRequestOrderItemsInnerToJSON(json: any): SendOrderDetailsRequestOrderItemsInner { + return SendOrderDetailsRequestOrderItemsInnerToJSONTyped(json, false); +} + +export function SendOrderDetailsRequestOrderItemsInnerToJSONTyped(value?: SendOrderDetailsRequestOrderItemsInner | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'retailer_id': value['retailerId'], + 'name': value['name'], + 'quantity': value['quantity'], + 'amount': SendOrderDetailsRequestOrderItemsInnerAmountToJSON(value['amount']), + }; +} + diff --git a/typescript/src/generated/src/models/SendOrderDetailsRequestOrderItemsInnerAmount.ts b/typescript/src/generated/src/models/SendOrderDetailsRequestOrderItemsInnerAmount.ts new file mode 100644 index 0000000..34b1972 --- /dev/null +++ b/typescript/src/generated/src/models/SendOrderDetailsRequestOrderItemsInnerAmount.ts @@ -0,0 +1,76 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SendOrderDetailsRequestOrderItemsInnerAmount + */ +export interface SendOrderDetailsRequestOrderItemsInnerAmount { + [key: string]: any | any; + /** + * + * @type {number} + * @memberof SendOrderDetailsRequestOrderItemsInnerAmount + */ + offset?: (number) | undefined; + /** + * + * @type {number} + * @memberof SendOrderDetailsRequestOrderItemsInnerAmount + */ + value?: (number) | undefined; +} + +/** + * Check if a given object implements the SendOrderDetailsRequestOrderItemsInnerAmount interface. + */ +export function instanceOfSendOrderDetailsRequestOrderItemsInnerAmount(value: object): value is SendOrderDetailsRequestOrderItemsInnerAmount { + return true; +} + +export function SendOrderDetailsRequestOrderItemsInnerAmountFromJSON(json: any): SendOrderDetailsRequestOrderItemsInnerAmount { + return SendOrderDetailsRequestOrderItemsInnerAmountFromJSONTyped(json, false); +} + +export function SendOrderDetailsRequestOrderItemsInnerAmountFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendOrderDetailsRequestOrderItemsInnerAmount { + if (json == null) { + return json; + } + return { + + ...json, + 'offset': json['offset'] == null ? undefined : json['offset'], + 'value': json['value'] == null ? undefined : json['value'], + }; +} + +export function SendOrderDetailsRequestOrderItemsInnerAmountToJSON(json: any): SendOrderDetailsRequestOrderItemsInnerAmount { + return SendOrderDetailsRequestOrderItemsInnerAmountToJSONTyped(json, false); +} + +export function SendOrderDetailsRequestOrderItemsInnerAmountToJSONTyped(value?: SendOrderDetailsRequestOrderItemsInnerAmount | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'offset': value['offset'], + 'value': value['value'], + }; +} + diff --git a/typescript/src/generated/src/models/SendPaymentRequestRequest.ts b/typescript/src/generated/src/models/SendPaymentRequestRequest.ts new file mode 100644 index 0000000..89c9b9e --- /dev/null +++ b/typescript/src/generated/src/models/SendPaymentRequestRequest.ts @@ -0,0 +1,114 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SendPaymentRequestRequest + */ +export interface SendPaymentRequestRequest { + [key: string]: any | any; + /** + * + * @type {number} + * @memberof SendPaymentRequestRequest + */ + phone: number; + /** + * + * @type {SendPaymentRequestRequestRegionEnum} + * @memberof SendPaymentRequestRequest + */ + region: SendPaymentRequestRequestRegionEnum; + /** + * + * @type {string} + * @memberof SendPaymentRequestRequest + */ + body?: (string) | undefined; + /** + * + * @type {{ [key: string]: any; }} + * @memberof SendPaymentRequestRequest + */ + interactive?: ({ [key: string]: any; }) | undefined; + /** + * + * @type {{ [key: string]: any; }} + * @memberof SendPaymentRequestRequest + */ + action?: ({ [key: string]: any; }) | undefined; +} + + +/** + * @export + */ +export const SendPaymentRequestRequestRegionEnum = { + In: 'IN', + Sg: 'SG', + Br: 'BR' +} as const; +export type SendPaymentRequestRequestRegionEnum = typeof SendPaymentRequestRequestRegionEnum[keyof typeof SendPaymentRequestRequestRegionEnum]; + + +/** + * Check if a given object implements the SendPaymentRequestRequest interface. + */ +export function instanceOfSendPaymentRequestRequest(value: object): value is SendPaymentRequestRequest { + if (!('phone' in value) || value['phone'] === undefined) return false; + if (!('region' in value) || value['region'] === undefined) return false; + return true; +} + +export function SendPaymentRequestRequestFromJSON(json: any): SendPaymentRequestRequest { + return SendPaymentRequestRequestFromJSONTyped(json, false); +} + +export function SendPaymentRequestRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendPaymentRequestRequest { + if (json == null) { + return json; + } + return { + + ...json, + 'phone': json['phone'], + 'region': json['region'], + 'body': json['body'] == null ? undefined : json['body'], + 'interactive': json['interactive'] == null ? undefined : json['interactive'], + 'action': json['action'] == null ? undefined : json['action'], + }; +} + +export function SendPaymentRequestRequestToJSON(json: any): SendPaymentRequestRequest { + return SendPaymentRequestRequestToJSONTyped(json, false); +} + +export function SendPaymentRequestRequestToJSONTyped(value?: SendPaymentRequestRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'phone': value['phone'], + 'region': value['region'], + 'body': value['body'], + 'interactive': value['interactive'], + 'action': value['action'], + }; +} + diff --git a/typescript/src/generated/src/models/SendProductRequest.ts b/typescript/src/generated/src/models/SendProductRequest.ts new file mode 100644 index 0000000..0866f50 --- /dev/null +++ b/typescript/src/generated/src/models/SendProductRequest.ts @@ -0,0 +1,117 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SendProductRequest + */ +export interface SendProductRequest { + [key: string]: any | any; + /** + * Recipient phone with country code. Use phone or chatId. + * @type {string} + * @memberof SendProductRequest + */ + phone?: (string) | undefined; + /** + * Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. + * @type {string} + * @memberof SendProductRequest + */ + chatId?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendProductRequest + */ + quotedMsgId?: (string) | undefined; + /** + * Optional message text shown with the product + * @type {string} + * @memberof SendProductRequest + */ + body?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendProductRequest + */ + footer?: (string) | undefined; + /** + * Text header (product list only) + * @type {string} + * @memberof SendProductRequest + */ + header?: (string) | undefined; + /** + * Catalog action (`catalog_id` + `product_retailer_id`, or `sections` for a list) + * @type {{ [key: string]: any; }} + * @memberof SendProductRequest + */ + action: { [key: string]: any; }; +} + +/** + * Check if a given object implements the SendProductRequest interface. + */ +export function instanceOfSendProductRequest(value: object): value is SendProductRequest { + if (!('action' in value) || value['action'] === undefined) return false; + return true; +} + +export function SendProductRequestFromJSON(json: any): SendProductRequest { + return SendProductRequestFromJSONTyped(json, false); +} + +export function SendProductRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendProductRequest { + if (json == null) { + return json; + } + return { + + ...json, + 'phone': json['phone'] == null ? undefined : json['phone'], + 'chatId': json['chatId'] == null ? undefined : json['chatId'], + 'quotedMsgId': json['quotedMsgId'] == null ? undefined : json['quotedMsgId'], + 'body': json['body'] == null ? undefined : json['body'], + 'footer': json['footer'] == null ? undefined : json['footer'], + 'header': json['header'] == null ? undefined : json['header'], + 'action': json['action'], + }; +} + +export function SendProductRequestToJSON(json: any): SendProductRequest { + return SendProductRequestToJSONTyped(json, false); +} + +export function SendProductRequestToJSONTyped(value?: SendProductRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'phone': value['phone'], + 'chatId': value['chatId'], + 'quotedMsgId': value['quotedMsgId'], + 'body': value['body'], + 'footer': value['footer'], + 'header': value['header'], + 'action': value['action'], + }; +} + diff --git a/typescript/src/generated/src/models/SendReactionRequest.ts b/typescript/src/generated/src/models/SendReactionRequest.ts new file mode 100644 index 0000000..27f3195 --- /dev/null +++ b/typescript/src/generated/src/models/SendReactionRequest.ts @@ -0,0 +1,89 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SendReactionRequest + */ +export interface SendReactionRequest { + /** + * Recipient phone with country code. Use phone or chatId. + * @type {string} + * @memberof SendReactionRequest + */ + phone?: (string) | undefined; + /** + * Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. + * @type {string} + * @memberof SendReactionRequest + */ + chatId?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendReactionRequest + */ + body?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendReactionRequest + */ + quotedMsgId?: (string) | undefined; +} + +/** + * Check if a given object implements the SendReactionRequest interface. + */ +export function instanceOfSendReactionRequest(value: object): value is SendReactionRequest { + return true; +} + +export function SendReactionRequestFromJSON(json: any): SendReactionRequest { + return SendReactionRequestFromJSONTyped(json, false); +} + +export function SendReactionRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendReactionRequest { + if (json == null) { + return json; + } + return { + + 'phone': json['phone'] == null ? undefined : json['phone'], + 'chatId': json['chatId'] == null ? undefined : json['chatId'], + 'body': json['body'] == null ? undefined : json['body'], + 'quotedMsgId': json['quotedMsgId'] == null ? undefined : json['quotedMsgId'], + }; +} + +export function SendReactionRequestToJSON(json: any): SendReactionRequest { + return SendReactionRequestToJSONTyped(json, false); +} + +export function SendReactionRequestToJSONTyped(value?: SendReactionRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'phone': value['phone'], + 'chatId': value['chatId'], + 'body': value['body'], + 'quotedMsgId': value['quotedMsgId'], + }; +} + diff --git a/typescript/src/generated/src/models/SendStickerRequest.ts b/typescript/src/generated/src/models/SendStickerRequest.ts new file mode 100644 index 0000000..a0720df --- /dev/null +++ b/typescript/src/generated/src/models/SendStickerRequest.ts @@ -0,0 +1,100 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SendStickerRequest + */ +export interface SendStickerRequest { + [key: string]: any | any; + /** + * + * @type {number} + * @memberof SendStickerRequest + */ + phone?: (number) | undefined; + /** + * + * @type {string} + * @memberof SendStickerRequest + */ + chatId?: (string) | undefined; + /** + * WABA media id from uploadMedia + * @type {string} + * @memberof SendStickerRequest + */ + mediaId?: (string) | undefined; + /** + * Public URL to webp sticker + * @type {string} + * @memberof SendStickerRequest + */ + link?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendStickerRequest + */ + quotedMsgId?: (string) | undefined; +} + +/** + * Check if a given object implements the SendStickerRequest interface. + */ +export function instanceOfSendStickerRequest(value: object): value is SendStickerRequest { + return true; +} + +export function SendStickerRequestFromJSON(json: any): SendStickerRequest { + return SendStickerRequestFromJSONTyped(json, false); +} + +export function SendStickerRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendStickerRequest { + if (json == null) { + return json; + } + return { + + ...json, + 'phone': json['phone'] == null ? undefined : json['phone'], + 'chatId': json['chatId'] == null ? undefined : json['chatId'], + 'mediaId': json['mediaId'] == null ? undefined : json['mediaId'], + 'link': json['link'] == null ? undefined : json['link'], + 'quotedMsgId': json['quotedMsgId'] == null ? undefined : json['quotedMsgId'], + }; +} + +export function SendStickerRequestToJSON(json: any): SendStickerRequest { + return SendStickerRequestToJSONTyped(json, false); +} + +export function SendStickerRequestToJSONTyped(value?: SendStickerRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'phone': value['phone'], + 'chatId': value['chatId'], + 'mediaId': value['mediaId'], + 'link': value['link'], + 'quotedMsgId': value['quotedMsgId'], + }; +} + diff --git a/typescript/src/generated/src/models/SendTemplateRequest.ts b/typescript/src/generated/src/models/SendTemplateRequest.ts new file mode 100644 index 0000000..4d619ad --- /dev/null +++ b/typescript/src/generated/src/models/SendTemplateRequest.ts @@ -0,0 +1,157 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { SendTemplateRequestLanguage } from './SendTemplateRequestLanguage'; +import { + SendTemplateRequestLanguageFromJSON, + SendTemplateRequestLanguageFromJSONTyped, + SendTemplateRequestLanguageToJSON, + SendTemplateRequestLanguageToJSONTyped, +} from './SendTemplateRequestLanguage'; + +/** + * + * @export + * @interface SendTemplateRequest + */ +export interface SendTemplateRequest { + /** + * Approved template name (template `name`, not the old HSM `element_name`) + * @type {string} + * @memberof SendTemplateRequest + */ + template?: (string) | undefined; + /** + * + * @type {SendTemplateRequestLanguage} + * @memberof SendTemplateRequest + */ + language?: (SendTemplateRequestLanguage) | undefined; + /** + * Template namespace from `list_templates` + * @type {string} + * @memberof SendTemplateRequest + */ + namespace?: (string) | undefined; + /** + * Template components in WhatsApp Cloud API format. + * Each item is an object with `type` (`body`, `header`, `button`) + * and `parameters` (objects with `type` + `text` / media / action). + * Never a list of strings. Never HSM `localizable_params`. + * + * @type {Array<{ [key: string]: any; }>} + * @memberof SendTemplateRequest + */ + params?: (Array<{ [key: string]: any; }>) | undefined; + /** + * Recipient phone with country code (use phone or chatId) + * @type {string} + * @memberof SendTemplateRequest + */ + phone?: (string) | undefined; + /** + * Recipient chat ID (`phone@c.us`, group `@g.us`, or BSUID `@lid`). Use phone or chatId. + * @type {string} + * @memberof SendTemplateRequest + */ + chatId?: (string) | undefined; + /** + * Optional Cloud API wamid to quote + * @type {string} + * @memberof SendTemplateRequest + */ + quotedMsgId?: (string) | undefined; + /** + * Force Marketing Messages API (POST marketing_messages). + * If omitted: auto for MARKETING category when channel has mm_lite_enabled + * and mm_lite_available service settings. + * + * @type {boolean} + * @memberof SendTemplateRequest + */ + useMMlite?: (boolean) | undefined; + /** + * Sets message_activity_sharing on WABA payload. Enables click tracking webhooks. + * Requires MM Lite path. Ignored on Cloud API fallback. + * + * @type {boolean} + * @memberof SendTemplateRequest + */ + messageActivitySharing?: (boolean) | undefined; + /** + * Template message TTL in seconds (message_send_ttl_seconds). + * MARKETING via MM Lite: 43200–2592000. AUTHENTICATION: 30–900. + * UTILITY: 30–43200. AUTH/UTILITY also accept -1 (30-day custom TTL). + * + * @type {number} + * @memberof SendTemplateRequest + */ + messageSendTtlSeconds?: (number) | undefined; +} + +/** + * Check if a given object implements the SendTemplateRequest interface. + */ +export function instanceOfSendTemplateRequest(value: object): value is SendTemplateRequest { + return true; +} + +export function SendTemplateRequestFromJSON(json: any): SendTemplateRequest { + return SendTemplateRequestFromJSONTyped(json, false); +} + +export function SendTemplateRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendTemplateRequest { + if (json == null) { + return json; + } + return { + + 'template': json['template'] == null ? undefined : json['template'], + 'language': json['language'] == null ? undefined : SendTemplateRequestLanguageFromJSON(json['language']), + 'namespace': json['namespace'] == null ? undefined : json['namespace'], + 'params': json['params'] == null ? undefined : json['params'], + 'phone': json['phone'] == null ? undefined : json['phone'], + 'chatId': json['chatId'] == null ? undefined : json['chatId'], + 'quotedMsgId': json['quotedMsgId'] == null ? undefined : json['quotedMsgId'], + 'useMMlite': json['useMMlite'] == null ? undefined : json['useMMlite'], + 'messageActivitySharing': json['messageActivitySharing'] == null ? undefined : json['messageActivitySharing'], + 'messageSendTtlSeconds': json['messageSendTtlSeconds'] == null ? undefined : json['messageSendTtlSeconds'], + }; +} + +export function SendTemplateRequestToJSON(json: any): SendTemplateRequest { + return SendTemplateRequestToJSONTyped(json, false); +} + +export function SendTemplateRequestToJSONTyped(value?: SendTemplateRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'template': value['template'], + 'language': SendTemplateRequestLanguageToJSON(value['language']), + 'namespace': value['namespace'], + 'params': value['params'], + 'phone': value['phone'], + 'chatId': value['chatId'], + 'quotedMsgId': value['quotedMsgId'], + 'useMMlite': value['useMMlite'], + 'messageActivitySharing': value['messageActivitySharing'], + 'messageSendTtlSeconds': value['messageSendTtlSeconds'], + }; +} + diff --git a/typescript/src/generated/src/models/SendTemplateRequestLanguage.ts b/typescript/src/generated/src/models/SendTemplateRequestLanguage.ts new file mode 100644 index 0000000..2e25df5 --- /dev/null +++ b/typescript/src/generated/src/models/SendTemplateRequestLanguage.ts @@ -0,0 +1,73 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * Template language. Always set `policy` to `deterministic`. + * @export + * @interface SendTemplateRequestLanguage + */ +export interface SendTemplateRequestLanguage { + /** + * Must be `deterministic` + * @type {string} + * @memberof SendTemplateRequestLanguage + */ + policy?: (string) | undefined; + /** + * + * @type {string} + * @memberof SendTemplateRequestLanguage + */ + code?: (string) | undefined; +} + +/** + * Check if a given object implements the SendTemplateRequestLanguage interface. + */ +export function instanceOfSendTemplateRequestLanguage(value: object): value is SendTemplateRequestLanguage { + return true; +} + +export function SendTemplateRequestLanguageFromJSON(json: any): SendTemplateRequestLanguage { + return SendTemplateRequestLanguageFromJSONTyped(json, false); +} + +export function SendTemplateRequestLanguageFromJSONTyped(json: any, ignoreDiscriminator: boolean): SendTemplateRequestLanguage { + if (json == null) { + return json; + } + return { + + 'policy': json['policy'] == null ? undefined : json['policy'], + 'code': json['code'] == null ? undefined : json['code'], + }; +} + +export function SendTemplateRequestLanguageToJSON(json: any): SendTemplateRequestLanguage { + return SendTemplateRequestLanguageToJSONTyped(json, false); +} + +export function SendTemplateRequestLanguageToJSONTyped(value?: SendTemplateRequestLanguage | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'policy': value['policy'], + 'code': value['code'], + }; +} + diff --git a/typescript/src/generated/src/models/SetWebhook200Response.ts b/typescript/src/generated/src/models/SetWebhook200Response.ts new file mode 100644 index 0000000..6bbc0bd --- /dev/null +++ b/typescript/src/generated/src/models/SetWebhook200Response.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { SetWebhook200ResponseWebhookUrl } from './SetWebhook200ResponseWebhookUrl'; +import { + SetWebhook200ResponseWebhookUrlFromJSON, + SetWebhook200ResponseWebhookUrlFromJSONTyped, + SetWebhook200ResponseWebhookUrlToJSON, + SetWebhook200ResponseWebhookUrlToJSONTyped, +} from './SetWebhook200ResponseWebhookUrl'; + +/** + * + * @export + * @interface SetWebhook200Response + */ +export interface SetWebhook200Response { + [key: string]: any | any; + /** + * True when the stored webhook URL(s) match the request + * @type {boolean} + * @memberof SetWebhook200Response + */ + set?: (boolean) | undefined; + /** + * + * @type {SetWebhook200ResponseWebhookUrl} + * @memberof SetWebhook200Response + */ + webhookUrl?: (SetWebhook200ResponseWebhookUrl) | undefined; +} + +/** + * Check if a given object implements the SetWebhook200Response interface. + */ +export function instanceOfSetWebhook200Response(value: object): value is SetWebhook200Response { + return true; +} + +export function SetWebhook200ResponseFromJSON(json: any): SetWebhook200Response { + return SetWebhook200ResponseFromJSONTyped(json, false); +} + +export function SetWebhook200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): SetWebhook200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'set': json['set'] == null ? undefined : json['set'], + 'webhookUrl': json['webhookUrl'] == null ? undefined : SetWebhook200ResponseWebhookUrlFromJSON(json['webhookUrl']), + }; +} + +export function SetWebhook200ResponseToJSON(json: any): SetWebhook200Response { + return SetWebhook200ResponseToJSONTyped(json, false); +} + +export function SetWebhook200ResponseToJSONTyped(value?: SetWebhook200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'set': value['set'], + 'webhookUrl': SetWebhook200ResponseWebhookUrlToJSON(value['webhookUrl']), + }; +} + diff --git a/typescript/src/generated/src/models/SetWebhook200ResponseWebhookUrl.ts b/typescript/src/generated/src/models/SetWebhook200ResponseWebhookUrl.ts new file mode 100644 index 0000000..24a2348 --- /dev/null +++ b/typescript/src/generated/src/models/SetWebhook200ResponseWebhookUrl.ts @@ -0,0 +1,59 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +/** + * @type SetWebhook200ResponseWebhookUrl + * Currently stored webhook URL or list + * @export + */ +export type SetWebhook200ResponseWebhookUrl = Array | string; + +export function SetWebhook200ResponseWebhookUrlFromJSON(json: any): SetWebhook200ResponseWebhookUrl { + return SetWebhook200ResponseWebhookUrlFromJSONTyped(json, false); +} + +export function SetWebhook200ResponseWebhookUrlFromJSONTyped(json: any, ignoreDiscriminator: boolean): SetWebhook200ResponseWebhookUrl { + if (json == null) { + return json; + } + if (Array.isArray(json)) { + if (json.every(item => typeof item === 'string')) { + return json; + } + } + if (typeof json === 'string') { + return json; + } + return {} as any; +} + +export function SetWebhook200ResponseWebhookUrlToJSON(json: any): any { + return SetWebhook200ResponseWebhookUrlToJSONTyped(json, false); +} + +export function SetWebhook200ResponseWebhookUrlToJSONTyped(value?: SetWebhook200ResponseWebhookUrl | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + if (Array.isArray(value)) { + if (value.every(item => typeof item === 'string')) { + return value; + } + } + if (typeof value === 'string') { + return value; + } + return {}; +} + diff --git a/typescript/src/generated/src/models/SetWebhookRequest.ts b/typescript/src/generated/src/models/SetWebhookRequest.ts new file mode 100644 index 0000000..2f9df4d --- /dev/null +++ b/typescript/src/generated/src/models/SetWebhookRequest.ts @@ -0,0 +1,77 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { SetWebhookRequestWebhookUrl } from './SetWebhookRequestWebhookUrl'; +import { + SetWebhookRequestWebhookUrlFromJSON, + SetWebhookRequestWebhookUrlFromJSONTyped, + SetWebhookRequestWebhookUrlToJSON, + SetWebhookRequestWebhookUrlToJSONTyped, +} from './SetWebhookRequestWebhookUrl'; + +/** + * + * @export + * @interface SetWebhookRequest + */ +export interface SetWebhookRequest { + [key: string]: any | any; + /** + * + * @type {SetWebhookRequestWebhookUrl} + * @memberof SetWebhookRequest + */ + webhookUrl: SetWebhookRequestWebhookUrl; +} + +/** + * Check if a given object implements the SetWebhookRequest interface. + */ +export function instanceOfSetWebhookRequest(value: object): value is SetWebhookRequest { + if (!('webhookUrl' in value) || value['webhookUrl'] === undefined) return false; + return true; +} + +export function SetWebhookRequestFromJSON(json: any): SetWebhookRequest { + return SetWebhookRequestFromJSONTyped(json, false); +} + +export function SetWebhookRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SetWebhookRequest { + if (json == null) { + return json; + } + return { + + ...json, + 'webhookUrl': SetWebhookRequestWebhookUrlFromJSON(json['webhookUrl']), + }; +} + +export function SetWebhookRequestToJSON(json: any): SetWebhookRequest { + return SetWebhookRequestToJSONTyped(json, false); +} + +export function SetWebhookRequestToJSONTyped(value?: SetWebhookRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'webhookUrl': SetWebhookRequestWebhookUrlToJSON(value['webhookUrl']), + }; +} + diff --git a/typescript/src/generated/src/models/SetWebhookRequestWebhookUrl.ts b/typescript/src/generated/src/models/SetWebhookRequestWebhookUrl.ts new file mode 100644 index 0000000..9dd4ae1 --- /dev/null +++ b/typescript/src/generated/src/models/SetWebhookRequestWebhookUrl.ts @@ -0,0 +1,61 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +/** + * @type SetWebhookRequestWebhookUrl + * HTTP or HTTPS URL, or array of URLs (max 5). Replaces the stored list. + * Empty values are rejected — clear webhooks with `POST /settings`. + * + * @export + */ +export type SetWebhookRequestWebhookUrl = Array | string; + +export function SetWebhookRequestWebhookUrlFromJSON(json: any): SetWebhookRequestWebhookUrl { + return SetWebhookRequestWebhookUrlFromJSONTyped(json, false); +} + +export function SetWebhookRequestWebhookUrlFromJSONTyped(json: any, ignoreDiscriminator: boolean): SetWebhookRequestWebhookUrl { + if (json == null) { + return json; + } + if (Array.isArray(json)) { + if (json.every(item => typeof item === 'string')) { + return json; + } + } + if (typeof json === 'string') { + return json; + } + return {} as any; +} + +export function SetWebhookRequestWebhookUrlToJSON(json: any): any { + return SetWebhookRequestWebhookUrlToJSONTyped(json, false); +} + +export function SetWebhookRequestWebhookUrlToJSONTyped(value?: SetWebhookRequestWebhookUrl | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + if (Array.isArray(value)) { + if (value.every(item => typeof item === 'string')) { + return value; + } + } + if (typeof value === 'string') { + return value; + } + return {}; +} + diff --git a/typescript/src/generated/src/models/SetWhatsappBusinessEncryptionRequest.ts b/typescript/src/generated/src/models/SetWhatsappBusinessEncryptionRequest.ts new file mode 100644 index 0000000..9b2e78a --- /dev/null +++ b/typescript/src/generated/src/models/SetWhatsappBusinessEncryptionRequest.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SetWhatsappBusinessEncryptionRequest + */ +export interface SetWhatsappBusinessEncryptionRequest { + /** + * 2048-bit RSA public key in PEM format + * @type {string} + * @memberof SetWhatsappBusinessEncryptionRequest + */ + businessPublicKey: string; +} + +/** + * Check if a given object implements the SetWhatsappBusinessEncryptionRequest interface. + */ +export function instanceOfSetWhatsappBusinessEncryptionRequest(value: object): value is SetWhatsappBusinessEncryptionRequest { + if (!('businessPublicKey' in value) || value['businessPublicKey'] === undefined) return false; + return true; +} + +export function SetWhatsappBusinessEncryptionRequestFromJSON(json: any): SetWhatsappBusinessEncryptionRequest { + return SetWhatsappBusinessEncryptionRequestFromJSONTyped(json, false); +} + +export function SetWhatsappBusinessEncryptionRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SetWhatsappBusinessEncryptionRequest { + if (json == null) { + return json; + } + return { + + 'businessPublicKey': json['business_public_key'], + }; +} + +export function SetWhatsappBusinessEncryptionRequestToJSON(json: any): SetWhatsappBusinessEncryptionRequest { + return SetWhatsappBusinessEncryptionRequestToJSONTyped(json, false); +} + +export function SetWhatsappBusinessEncryptionRequestToJSONTyped(value?: SetWhatsappBusinessEncryptionRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'business_public_key': value['businessPublicKey'], + }; +} + diff --git a/typescript/src/generated/src/models/SuccessResponse.ts b/typescript/src/generated/src/models/SuccessResponse.ts new file mode 100644 index 0000000..fdc4377 --- /dev/null +++ b/typescript/src/generated/src/models/SuccessResponse.ts @@ -0,0 +1,68 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * Generic success response + * @export + * @interface SuccessResponse + */ +export interface SuccessResponse { + [key: string]: any | any; + /** + * Operation result + * @type {string} + * @memberof SuccessResponse + */ + result?: (string) | undefined; +} + +/** + * Check if a given object implements the SuccessResponse interface. + */ +export function instanceOfSuccessResponse(value: object): value is SuccessResponse { + return true; +} + +export function SuccessResponseFromJSON(json: any): SuccessResponse { + return SuccessResponseFromJSONTyped(json, false); +} + +export function SuccessResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): SuccessResponse { + if (json == null) { + return json; + } + return { + + ...json, + 'result': json['result'] == null ? undefined : json['result'], + }; +} + +export function SuccessResponseToJSON(json: any): SuccessResponse { + return SuccessResponseToJSONTyped(json, false); +} + +export function SuccessResponseToJSONTyped(value?: SuccessResponse | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'result': value['result'], + }; +} + diff --git a/typescript/src/generated/src/models/UpdateCallingSettings200Response.ts b/typescript/src/generated/src/models/UpdateCallingSettings200Response.ts new file mode 100644 index 0000000..3e8909a --- /dev/null +++ b/typescript/src/generated/src/models/UpdateCallingSettings200Response.ts @@ -0,0 +1,92 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { UpdateCallingSettings200ResponseResponse } from './UpdateCallingSettings200ResponseResponse'; +import { + UpdateCallingSettings200ResponseResponseFromJSON, + UpdateCallingSettings200ResponseResponseFromJSONTyped, + UpdateCallingSettings200ResponseResponseToJSON, + UpdateCallingSettings200ResponseResponseToJSONTyped, +} from './UpdateCallingSettings200ResponseResponse'; + +/** + * + * @export + * @interface UpdateCallingSettings200Response + */ +export interface UpdateCallingSettings200Response { + [key: string]: any | any; + /** + * + * @type {boolean} + * @memberof UpdateCallingSettings200Response + */ + success?: (boolean) | undefined; + /** + * + * @type {string} + * @memberof UpdateCallingSettings200Response + */ + result?: (string) | undefined; + /** + * + * @type {UpdateCallingSettings200ResponseResponse} + * @memberof UpdateCallingSettings200Response + */ + response?: (UpdateCallingSettings200ResponseResponse) | undefined; +} + +/** + * Check if a given object implements the UpdateCallingSettings200Response interface. + */ +export function instanceOfUpdateCallingSettings200Response(value: object): value is UpdateCallingSettings200Response { + return true; +} + +export function UpdateCallingSettings200ResponseFromJSON(json: any): UpdateCallingSettings200Response { + return UpdateCallingSettings200ResponseFromJSONTyped(json, false); +} + +export function UpdateCallingSettings200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateCallingSettings200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'success': json['success'] == null ? undefined : json['success'], + 'result': json['result'] == null ? undefined : json['result'], + 'response': json['response'] == null ? undefined : UpdateCallingSettings200ResponseResponseFromJSON(json['response']), + }; +} + +export function UpdateCallingSettings200ResponseToJSON(json: any): UpdateCallingSettings200Response { + return UpdateCallingSettings200ResponseToJSONTyped(json, false); +} + +export function UpdateCallingSettings200ResponseToJSONTyped(value?: UpdateCallingSettings200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'success': value['success'], + 'result': value['result'], + 'response': UpdateCallingSettings200ResponseResponseToJSON(value['response']), + }; +} + diff --git a/typescript/src/generated/src/models/UpdateCallingSettings200ResponseResponse.ts b/typescript/src/generated/src/models/UpdateCallingSettings200ResponseResponse.ts new file mode 100644 index 0000000..47f0419 --- /dev/null +++ b/typescript/src/generated/src/models/UpdateCallingSettings200ResponseResponse.ts @@ -0,0 +1,68 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface UpdateCallingSettings200ResponseResponse + */ +export interface UpdateCallingSettings200ResponseResponse { + [key: string]: any | any; + /** + * + * @type {string} + * @memberof UpdateCallingSettings200ResponseResponse + */ + error?: (string) | undefined; +} + +/** + * Check if a given object implements the UpdateCallingSettings200ResponseResponse interface. + */ +export function instanceOfUpdateCallingSettings200ResponseResponse(value: object): value is UpdateCallingSettings200ResponseResponse { + return true; +} + +export function UpdateCallingSettings200ResponseResponseFromJSON(json: any): UpdateCallingSettings200ResponseResponse { + return UpdateCallingSettings200ResponseResponseFromJSONTyped(json, false); +} + +export function UpdateCallingSettings200ResponseResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateCallingSettings200ResponseResponse { + if (json == null) { + return json; + } + return { + + ...json, + 'error': json['error'] == null ? undefined : json['error'], + }; +} + +export function UpdateCallingSettings200ResponseResponseToJSON(json: any): UpdateCallingSettings200ResponseResponse { + return UpdateCallingSettings200ResponseResponseToJSONTyped(json, false); +} + +export function UpdateCallingSettings200ResponseResponseToJSONTyped(value?: UpdateCallingSettings200ResponseResponse | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'error': value['error'], + }; +} + diff --git a/typescript/src/generated/src/models/UpdateMe200Response.ts b/typescript/src/generated/src/models/UpdateMe200Response.ts new file mode 100644 index 0000000..ea7d3c9 --- /dev/null +++ b/typescript/src/generated/src/models/UpdateMe200Response.ts @@ -0,0 +1,68 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface UpdateMe200Response + */ +export interface UpdateMe200Response { + [key: string]: any | any; + /** + * + * @type {string} + * @memberof UpdateMe200Response + */ + result?: (string) | undefined; +} + +/** + * Check if a given object implements the UpdateMe200Response interface. + */ +export function instanceOfUpdateMe200Response(value: object): value is UpdateMe200Response { + return true; +} + +export function UpdateMe200ResponseFromJSON(json: any): UpdateMe200Response { + return UpdateMe200ResponseFromJSONTyped(json, false); +} + +export function UpdateMe200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateMe200Response { + if (json == null) { + return json; + } + return { + + ...json, + 'result': json['result'] == null ? undefined : json['result'], + }; +} + +export function UpdateMe200ResponseToJSON(json: any): UpdateMe200Response { + return UpdateMe200ResponseToJSONTyped(json, false); +} + +export function UpdateMe200ResponseToJSONTyped(value?: UpdateMe200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'result': value['result'], + }; +} + diff --git a/typescript/src/generated/src/models/UpdateMeRequest.ts b/typescript/src/generated/src/models/UpdateMeRequest.ts new file mode 100644 index 0000000..462e5aa --- /dev/null +++ b/typescript/src/generated/src/models/UpdateMeRequest.ts @@ -0,0 +1,116 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface UpdateMeRequest + */ +export interface UpdateMeRequest { + [key: string]: any | any; + /** + * Profile About section (WhatsApp status text) + * @type {string} + * @memberof UpdateMeRequest + */ + about?: (string) | undefined; + /** + * Business address shown on the profile + * @type {string} + * @memberof UpdateMeRequest + */ + address?: (string) | undefined; + /** + * Business description (max 256 characters) + * @type {string} + * @memberof UpdateMeRequest + */ + description?: (string) | undefined; + /** + * Business email shown on the profile + * @type {string} + * @memberof UpdateMeRequest + */ + email?: (string) | undefined; + /** + * Industry of the business + * @type {string} + * @memberof UpdateMeRequest + */ + vertical?: (string) | undefined; + /** + * HTTPS URL or data:image/...;base64,... payload + * @type {string} + * @memberof UpdateMeRequest + */ + photo?: (string) | undefined; + /** + * Business website URLs + * @type {Array} + * @memberof UpdateMeRequest + */ + websites?: (Array) | undefined; +} + +/** + * Check if a given object implements the UpdateMeRequest interface. + */ +export function instanceOfUpdateMeRequest(value: object): value is UpdateMeRequest { + return true; +} + +export function UpdateMeRequestFromJSON(json: any): UpdateMeRequest { + return UpdateMeRequestFromJSONTyped(json, false); +} + +export function UpdateMeRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateMeRequest { + if (json == null) { + return json; + } + return { + + ...json, + 'about': json['about'] == null ? undefined : json['about'], + 'address': json['address'] == null ? undefined : json['address'], + 'description': json['description'] == null ? undefined : json['description'], + 'email': json['email'] == null ? undefined : json['email'], + 'vertical': json['vertical'] == null ? undefined : json['vertical'], + 'photo': json['photo'] == null ? undefined : json['photo'], + 'websites': json['websites'] == null ? undefined : json['websites'], + }; +} + +export function UpdateMeRequestToJSON(json: any): UpdateMeRequest { + return UpdateMeRequestToJSONTyped(json, false); +} + +export function UpdateMeRequestToJSONTyped(value?: UpdateMeRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'about': value['about'], + 'address': value['address'], + 'description': value['description'], + 'email': value['email'], + 'vertical': value['vertical'], + 'photo': value['photo'], + 'websites': value['websites'], + }; +} + diff --git a/typescript/src/generated/src/models/WebhookUrlStatus.ts b/typescript/src/generated/src/models/WebhookUrlStatus.ts new file mode 100644 index 0000000..f8a7323 --- /dev/null +++ b/typescript/src/generated/src/models/WebhookUrlStatus.ts @@ -0,0 +1,160 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * Circuit / auto-disable status for one configured webhook URL. + * The breaker is per URL (`instanceId` + URL hash), not per channel. + * + * @export + * @interface WebhookUrlStatus + */ +export interface WebhookUrlStatus { + [key: string]: any | any; + /** + * This webhook URL (same string as in `webhookUrl`) + * @type {string} + * @memberof WebhookUrlStatus + */ + url: string; + /** + * Delivery state for this URL only. `ok` delivering; `degraded` recent qualifying fails (still delivering, warning email on the 2nd fail); `open` skipping most deliveries pending a probe; `half_open` probe in flight (resume only on HTTP 2xx); `disabled` sticky auto-disabled until self-serve re-enable (`POST /webhook` / `POST /settings` with this URL) or a successful probe before sticky disable. + * + * @type {WebhookUrlStatusCircuitStateEnum} + * @memberof WebhookUrlStatus + */ + circuitState: WebhookUrlStatusCircuitStateEnum; + /** + * Last qualifying fail reason, e.g. `http_404` or `timeout_or_network` + * @type {string} + * @memberof WebhookUrlStatus + */ + reason?: (string) | undefined; + /** + * Diagnostic only — safe for clients to ignore. Number of qualifying delivery + * failures in the rolling ~10 minute breaker window (not lifetime, not "how many + * times the customer retried"). Prefer `circuitState` / `disabledWebhooks`. + * + * @type {number} + * @memberof WebhookUrlStatus + */ + fails?: (number) | undefined; + /** + * Diagnostic only — safe for clients to ignore. How many recovery probes already + * failed for this URL. Probes run on a schedule (≈15 min → 1 h → 6 h); sticky + * disable after 3 failed probes. The 6 h step is the last probe, not a blind + * "unblock in 6 hours" timer. + * + * @type {number} + * @memberof WebhookUrlStatus + */ + trips?: (number) | undefined; + /** + * Epoch milliseconds when this URL became sticky-disabled + * @type {number} + * @memberof WebhookUrlStatus + */ + disabledAt?: (number) | undefined; + /** + * Diagnostic only. Epoch ms of the first fail in the current ~10 minute window + * (pairs with `fails`; not a customer-facing period). + * + * @type {number} + * @memberof WebhookUrlStatus + */ + firstFailAt?: (number) | undefined; + /** + * Last HTTP status from this URL, when known + * @type {number} + * @memberof WebhookUrlStatus + */ + lastStatus?: (number) | undefined; + /** + * Epoch milliseconds of the next half-open probe, if any + * @type {number} + * @memberof WebhookUrlStatus + */ + nextProbeAt?: (number) | undefined; +} + + +/** + * @export + */ +export const WebhookUrlStatusCircuitStateEnum = { + Ok: 'ok', + Degraded: 'degraded', + Open: 'open', + HalfOpen: 'half_open', + Disabled: 'disabled' +} as const; +export type WebhookUrlStatusCircuitStateEnum = typeof WebhookUrlStatusCircuitStateEnum[keyof typeof WebhookUrlStatusCircuitStateEnum]; + + +/** + * Check if a given object implements the WebhookUrlStatus interface. + */ +export function instanceOfWebhookUrlStatus(value: object): value is WebhookUrlStatus { + if (!('url' in value) || value['url'] === undefined) return false; + if (!('circuitState' in value) || value['circuitState'] === undefined) return false; + return true; +} + +export function WebhookUrlStatusFromJSON(json: any): WebhookUrlStatus { + return WebhookUrlStatusFromJSONTyped(json, false); +} + +export function WebhookUrlStatusFromJSONTyped(json: any, ignoreDiscriminator: boolean): WebhookUrlStatus { + if (json == null) { + return json; + } + return { + + ...json, + 'url': json['url'], + 'circuitState': json['circuitState'], + 'reason': json['reason'] == null ? undefined : json['reason'], + 'fails': json['fails'] == null ? undefined : json['fails'], + 'trips': json['trips'] == null ? undefined : json['trips'], + 'disabledAt': json['disabledAt'] == null ? undefined : json['disabledAt'], + 'firstFailAt': json['firstFailAt'] == null ? undefined : json['firstFailAt'], + 'lastStatus': json['lastStatus'] == null ? undefined : json['lastStatus'], + 'nextProbeAt': json['nextProbeAt'] == null ? undefined : json['nextProbeAt'], + }; +} + +export function WebhookUrlStatusToJSON(json: any): WebhookUrlStatus { + return WebhookUrlStatusToJSONTyped(json, false); +} + +export function WebhookUrlStatusToJSONTyped(value?: WebhookUrlStatus | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + ...value, + 'url': value['url'], + 'circuitState': value['circuitState'], + 'reason': value['reason'], + 'fails': value['fails'], + 'trips': value['trips'], + 'disabledAt': value['disabledAt'], + 'firstFailAt': value['firstFailAt'], + 'lastStatus': value['lastStatus'], + 'nextProbeAt': value['nextProbeAt'], + }; +} + diff --git a/typescript/src/generated/src/models/index.ts b/typescript/src/generated/src/models/index.ts new file mode 100644 index 0000000..7f9cc0b --- /dev/null +++ b/typescript/src/generated/src/models/index.ts @@ -0,0 +1,101 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './AddTemplate200Response'; +export * from './AddTemplateRequest'; +export * from './BlockUserRequest'; +export * from './CallingSettings'; +export * from './CallingSettingsCalling'; +export * from './CallingSettingsCallingAudio'; +export * from './CallingSettingsCallingCallHours'; +export * from './CallingSettingsCallingSip'; +export * from './CallingSettingsCallingSipServersInner'; +export * from './CallingSettingsCallingVideo'; +export * from './ConversationalAutomation'; +export * from './ConversationalAutomationCommandsInner'; +export * from './CreateCommerce200Response'; +export * from './CreateCommerceRequest'; +export * from './CreateCommerceRequestParams'; +export * from './CreateFlowsRequest'; +export * from './CreateGroups200Response'; +export * from './CreateGroupsGroupIdRequest'; +export * from './CreateGroupsRequest'; +export * from './CreateReadMessage200Response'; +export * from './CreateReadMessage401Response'; +export * from './CreateReadMessageRequest'; +export * from './CreateSettingsRequest'; +export * from './CreateSettingsRequestWebhookUrl'; +export * from './CreateUploadMedia200Response'; +export * from './CreateUploadMediaRequest'; +export * from './DeleteFlowsFlowId200Response'; +export * from './DeleteGroupsGroupId200Response'; +export * from './DeleteMediaLegacyRequest'; +export * from './ErrorResponse'; +export * from './GetCommerce200ResponseInner'; +export * from './GetMmLiteStatus200Response'; +export * from './GetStatus200Response'; +export * from './GetWebhook200Response'; +export * from './GetWebhook200ResponseWebhookUrl'; +export * from './GetWhatsappBusinessEncryption200Response'; +export * from './InitiateCallRequest'; +export * from './InitiateCallRequestSession'; +export * from './InitiateCallResponse'; +export * from './InitiateCallResponseCallsInner'; +export * from './InitiateCallResponseResponse'; +export * from './ListBlockedUsers200Response'; +export * from './ListFlows200Response'; +export * from './ListMessages200Response'; +export * from './ListSettings200Response'; +export * from './ListSettings200ResponseWebhookUrl'; +export * from './ListTemplates200Response'; +export * from './MessageSentResponse'; +export * from './PatchFlowsFlowIdAssets200Response'; +export * from './PatchFlowsFlowIdAssetsRequest'; +export * from './PatchFlowsFlowIdMetadataRequest'; +export * from './ProfileInfo'; +export * from './RemoveTemplateRequest'; +export * from './RetrieveMedia200Response'; +export * from './SendAddressMessageRequest'; +export * from './SendButtonRequest'; +export * from './SendButtonRequestSectionsInner'; +export * from './SendButtonRequestSectionsInnerReply'; +export * from './SendCarouselRequest1'; +export * from './SendContactRequest'; +export * from './SendContactRequestContact'; +export * from './SendContactRequestContactName'; +export * from './SendContactRequestContactsInner'; +export * from './SendContactRequestContactsInnerName'; +export * from './SendContactRequestContactsInnerOrg'; +export * from './SendContactRequestContactsInnerPhonesInner'; +export * from './SendCtaUrlRequest'; +export * from './SendFileRequest'; +export * from './SendFlowRequest1'; +export * from './SendFlowRequest1Header'; +export * from './SendFlowRequestHeader'; +export * from './SendListRequest'; +export * from './SendListRequestSectionsInner'; +export * from './SendListRequestSectionsInnerRowsInner'; +export * from './SendLocationRequest1'; +export * from './SendLocationRequestRequest'; +export * from './SendMessageRequest'; +export * from './SendOrderDetailsRequest'; +export * from './SendOrderDetailsRequestLanguage'; +export * from './SendOrderDetailsRequestOrder'; +export * from './SendOrderDetailsRequestOrderItemsInner'; +export * from './SendOrderDetailsRequestOrderItemsInnerAmount'; +export * from './SendPaymentRequestRequest'; +export * from './SendProductRequest'; +export * from './SendReactionRequest'; +export * from './SendStickerRequest'; +export * from './SendTemplateRequest'; +export * from './SendTemplateRequestLanguage'; +export * from './SetWebhook200Response'; +export * from './SetWebhook200ResponseWebhookUrl'; +export * from './SetWebhookRequest'; +export * from './SetWebhookRequestWebhookUrl'; +export * from './SetWhatsappBusinessEncryptionRequest'; +export * from './SuccessResponse'; +export * from './UpdateCallingSettings200Response'; +export * from './UpdateCallingSettings200ResponseResponse'; +export * from './UpdateMe200Response'; +export * from './UpdateMeRequest'; +export * from './WebhookUrlStatus'; diff --git a/typescript/src/generated/src/runtime.ts b/typescript/src/generated/src/runtime.ts new file mode 100644 index 0000000..8ccec0a --- /dev/null +++ b/typescript/src/generated/src/runtime.ts @@ -0,0 +1,453 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * 1MSG WhatsApp Business API (Public) + * Public client API for sending messages, managing groups, flows, and templates. This is the API exposed to end customers via platform.1msg.io **Authentication:** Pass the channel token in **one** place. The API checks JSON body (`token`), then query string (`?token=`), then `Authorization: Bearer` header (preferred in production). **Documentation:** https://help.1msg.io/platform-1msg/getting-start/quick-start **API Docs:** https://docs.1msg.io/ + * + * The version of the OpenAPI document: 1.0.0 + * Contact: support@1msg.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +export const BASE_PATH = "https://api.1msg.io".replace(/\/+$/, ""); + +export interface ConfigurationParameters { + basePath?: (string) | undefined; // override base path + fetchApi?: (FetchAPI) | undefined; // override for fetch implementation + middleware?: (Middleware[]) | undefined; // middleware to apply before/after fetch requests + queryParamsStringify?: ((params: HTTPQuery) => string) | undefined; // stringify function for query strings + username?: (string) | undefined; // parameter for basic security + password?: (string) | undefined; // parameter for basic security + apiKey?: (string | Promise | ((name: string) => string | Promise)) | undefined; // parameter for apiKey security + accessToken?: (string | Promise | ((name?: string, scopes?: string[]) => string | Promise)) | undefined; // parameter for oauth2 security + headers?: (HTTPHeaders) | undefined; //header params we want to use on every request + credentials?: (RequestCredentials) | undefined; //value for the credentials param we want to use on each request +} + +export class Configuration { + constructor(private configuration: ConfigurationParameters = {}) {} + + set config(configuration: Configuration) { + this.configuration = configuration; + } + + get basePath(): string { + return this.configuration.basePath != null ? this.configuration.basePath : BASE_PATH; + } + + get fetchApi(): FetchAPI | undefined { + return this.configuration.fetchApi; + } + + get middleware(): Middleware[] { + return this.configuration.middleware || []; + } + + get queryParamsStringify(): (params: HTTPQuery) => string { + return this.configuration.queryParamsStringify || querystring; + } + + get username(): string | undefined { + return this.configuration.username; + } + + get password(): string | undefined { + return this.configuration.password; + } + + get apiKey(): ((name: string) => string | Promise) | undefined { + const apiKey = this.configuration.apiKey; + if (apiKey) { + return typeof apiKey === 'function' ? apiKey : () => apiKey; + } + return undefined; + } + + get accessToken(): ((name?: string, scopes?: string[]) => string | Promise) | undefined { + const accessToken = this.configuration.accessToken; + if (accessToken) { + return typeof accessToken === 'function' ? accessToken : async () => accessToken; + } + return undefined; + } + + get headers(): HTTPHeaders | undefined { + return this.configuration.headers; + } + + get credentials(): RequestCredentials | undefined { + return this.configuration.credentials; + } +} + +export const DefaultConfig = new Configuration(); + +/** + * This is the base class for all generated API classes. + */ +export class BaseAPI { + + private static readonly jsonRegex = /^(:?application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(:?;.*)?$/i; + private middleware: Middleware[]; + + constructor(protected configuration = DefaultConfig) { + this.middleware = configuration.middleware; + } + + withMiddleware(this: T, ...middlewares: Middleware[]) { + const next = this.clone(); + next.middleware = next.middleware.concat(...middlewares); + return next; + } + + withPreMiddleware(this: T, ...preMiddlewares: Array) { + const middlewares = preMiddlewares.map((pre) => ({ pre })); + return this.withMiddleware(...middlewares); + } + + withPostMiddleware(this: T, ...postMiddlewares: Array) { + const middlewares = postMiddlewares.map((post) => ({ post })); + return this.withMiddleware(...middlewares); + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + protected isJsonMime(mime: string | null | undefined): boolean { + if (!mime) { + return false; + } + return BaseAPI.jsonRegex.test(mime); + } + + protected async request(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction): Promise { + const { url, init } = await this.createFetchParams(context, initOverrides); + const response = await this.fetchApi(url, init); + if (response && (response.status >= 200 && response.status < 300)) { + return response; + } + throw new ResponseError(response, 'Response returned an error code'); + } + + private async createFetchParams(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction) { + let url = this.configuration.basePath + context.path; + if (context.query !== undefined && Object.keys(context.query).length !== 0) { + // only add the querystring to the URL if there are query parameters. + // this is done to avoid urls ending with a "?" character which buggy webservers + // do not handle correctly sometimes. + url += '?' + this.configuration.queryParamsStringify(context.query); + } + + const headers = Object.assign({}, this.configuration.headers, context.headers); + Object.keys(headers).forEach(key => headers[key] === undefined ? delete headers[key] : {}); + + const initOverrideFn = + typeof initOverrides === "function" + ? initOverrides + : async () => initOverrides; + + const initParams = { + method: context.method, + headers, + body: context.body, + ...(this.configuration.credentials === undefined ? {} : { credentials: this.configuration.credentials }), + }; + + const overriddenInit: RequestInit = { + ...initParams, + ...(await initOverrideFn({ + init: initParams, + context, + })) + }; + + let body: any; + if (isFormData(overriddenInit.body) + || (overriddenInit.body instanceof URLSearchParams) + || isBlob(overriddenInit.body)) { + body = overriddenInit.body; + } else if (this.isJsonMime(headers['Content-Type'])) { + body = JSON.stringify(overriddenInit.body); + } else { + body = overriddenInit.body; + } + + const init: RequestInit = { + ...overriddenInit, + body + }; + + return { url, init }; + } + + private fetchApi = async (url: string, init: RequestInit) => { + let fetchParams = { url, init }; + for (const middleware of this.middleware) { + if (middleware.pre) { + fetchParams = await middleware.pre({ + fetch: this.fetchApi, + ...fetchParams, + }) || fetchParams; + } + } + let response: Response | undefined = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response === undefined) { + if (e instanceof Error) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } else { + throw e; + } + } + } + for (const middleware of this.middleware) { + if (middleware.post) { + response = await middleware.post({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + response: response.clone(), + }) || response; + } + } + return response; + } + + /** + * Create a shallow clone of `this` by constructing a new instance + * and then shallow cloning data members. + */ + private clone(this: T): T { + const constructor = this.constructor as any; + const next = new constructor(this.configuration); + next.middleware = this.middleware.slice(); + return next; + } +}; + +function isBlob(value: any): value is Blob { + return typeof Blob !== 'undefined' && value instanceof Blob; +} + +function isFormData(value: any): value is FormData { + return typeof FormData !== "undefined" && value instanceof FormData; +} + +export class ResponseError extends Error { + override name: "ResponseError" = "ResponseError"; + constructor(public response: Response, msg?: string) { + super(msg); + + // restore prototype chain + const actualProto = new.target.prototype; + if (Object.setPrototypeOf) { + Object.setPrototypeOf(this, actualProto); + } + } +} + +export class FetchError extends Error { + override name: "FetchError" = "FetchError"; + constructor(public cause: Error, msg?: string) { + super(msg); + + // restore prototype chain + const actualProto = new.target.prototype; + if (Object.setPrototypeOf) { + Object.setPrototypeOf(this, actualProto); + } + } +} + +export class RequiredError extends Error { + override name: "RequiredError" = "RequiredError"; + constructor(public field: string, msg?: string) { + super(msg); + + // restore prototype chain + const actualProto = new.target.prototype; + if (Object.setPrototypeOf) { + Object.setPrototypeOf(this, actualProto); + } + } +} + +export const COLLECTION_FORMATS = { + csv: ",", + ssv: " ", + tsv: "\t", + pipes: "|", +}; + +export type FetchAPI = WindowOrWorkerGlobalScope['fetch']; + +export type Json = any; +export type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD'; +export type HTTPHeaders = { [key: string]: string }; +export type HTTPQuery = { [key: string]: string | number | null | boolean | Array | Set | HTTPQuery }; +export type HTTPBody = Json | FormData | URLSearchParams; +export type HTTPRequestInit = { headers?: (HTTPHeaders) | undefined; method: HTTPMethod; credentials?: (RequestCredentials) | undefined; body?: (HTTPBody) | undefined }; +export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original'; + +export type InitOverrideFunction = (requestContext: { init: HTTPRequestInit, context: RequestOpts }) => Promise + +export interface FetchParams { + url: string; + init: RequestInit; +} + +export interface RequestOpts { + path: string; + method: HTTPMethod; + headers: HTTPHeaders; + query?: (HTTPQuery) | undefined; + body?: (HTTPBody) | undefined; +} + +export function querystring(params: HTTPQuery, prefix: string = ''): string { + return Object.keys(params) + .map(key => querystringSingleKey(key, params[key], prefix)) + .filter(part => part.length > 0) + .join('&'); +} + +function querystringSingleKey(key: string, value: string | number | null | undefined | boolean | Array | Set | HTTPQuery, keyPrefix: string = ''): string { + const fullKey = keyPrefix + (keyPrefix.length ? `[${key}]` : key); + if (value instanceof Array) { + const multiValue = value.map(singleValue => encodeURIComponent(String(singleValue))) + .join(`&${encodeURIComponent(fullKey)}=`); + return `${encodeURIComponent(fullKey)}=${multiValue}`; + } + if (value instanceof Set) { + const valueAsArray = Array.from(value); + return querystringSingleKey(key, valueAsArray, keyPrefix); + } + if (value instanceof Date) { + return `${encodeURIComponent(fullKey)}=${encodeURIComponent(value.toISOString())}`; + } + if (value instanceof Object) { + return querystring(value as HTTPQuery, fullKey); + } + return `${encodeURIComponent(fullKey)}=${encodeURIComponent(String(value))}`; +} + +export function exists(json: any, key: string) { + const value = json[key]; + return value !== null && value !== undefined; +} + +export function mapValues(data: any, fn: (item: any) => any) { + const result: { [key: string]: any } = {}; + for (const key of Object.keys(data)) { + result[key] = fn(data[key]); + } + return result; +} + +export function canConsumeForm(consumes: Consume[]): boolean { + for (const consume of consumes) { + if ('multipart/form-data' === consume.contentType) { + return true; + } + } + return false; +} + +export interface Consume { + contentType: string; +} + +export interface RequestContext { + fetch: FetchAPI; + url: string; + init: RequestInit; +} + +export interface ResponseContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + response: Response; +} + +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: (Response) | undefined; +} + +export interface Middleware { + pre?: ((context: RequestContext) => Promise) | undefined; + post?: ((context: ResponseContext) => Promise) | undefined; + onError?: ((context: ErrorContext) => Promise) | undefined; +} + +export interface ApiResponse { + raw: Response; + value(): Promise; +} + +export interface ResponseTransformer { + (json: any): T; +} + +export class JSONApiResponse { + constructor(public raw: Response, private transformer: ResponseTransformer = (jsonValue: any) => jsonValue) {} + + async value(): Promise { + return this.transformer(await this.raw.json()); + } +} + +export class VoidApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return undefined; + } +} + +export class BlobApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return await this.raw.blob(); + }; +} + +export class TextApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return await this.raw.text(); + }; +} + +export function objectToJSON(value: unknown): unknown { + return value; +} diff --git a/typescript/src/index.ts b/typescript/src/index.ts index 9f0558f..cabc485 100644 --- a/typescript/src/index.ts +++ b/typescript/src/index.ts @@ -1,14 +1,5 @@ -export { SDK_VERSION } from './version'; -export { - ClientConfig, - type ClientConfigOptions, -} from './client-config'; -export { - Client, - createClient, -} from './client'; - -export * from './generated/src/runtime'; +export { Client, createClient } from './client'; +export { ClientConfig, type ClientConfigOptions } from './client'; export { CallingApi, CatalogApi, @@ -21,8 +12,11 @@ export { UsersApi, WebhooksApi, } from './generated/src/apis'; -export * from './generated/src/models'; -export type { SendMessageRequest } from './generated/src/models/SendMessageRequest'; +export * from './generated/src/models'; export type { MessageSentResponse } from './generated/src/models/MessageSentResponse'; export type { ProfileInfo } from './generated/src/models/ProfileInfo'; + +export type { SendMessageRequest } from './generated/src/models/SendMessageRequest'; +export * from './generated/src/runtime'; +export { SDK_VERSION } from './version'; diff --git a/typescript/tsconfig.json b/typescript/tsconfig.json index 37281e7..2cb92ea 100644 --- a/typescript/tsconfig.json +++ b/typescript/tsconfig.json @@ -12,7 +12,10 @@ "forceConsistentCasingInFileNames": true, "moduleResolution": "node", "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + "noEmitOnError": true }, "include": ["src/**/*"], "exclude": ["node_modules", "dist", "src/**/__tests__/**"] diff --git a/typescript/tsconfig.quality.json b/typescript/tsconfig.quality.json new file mode 100644 index 0000000..a3ec451 --- /dev/null +++ b/typescript/tsconfig.quality.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": true, + "rootDir": ".", + "jsx": "preserve" + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.mts", "src/**/*.cts"], + "exclude": ["node_modules", "dist"] +}