agentmail-clone-v1 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +20 -0
- package/.github/workflows/docs-deploy.yml +37 -0
- package/.github/workflows/landing-preview.yml +43 -0
- package/.github/workflows/openapi-lint.yml +31 -0
- package/.github/workflows/sdk-generate-check.yml +66 -0
- package/.github/workflows/sdk-release.yml +62 -0
- package/CHANGELOG.md +10 -0
- package/README.md +208 -0
- package/RELEASING.md +43 -0
- package/docs/api-reference/api-keys.mdx +11 -0
- package/docs/api-reference/domains.mdx +13 -0
- package/docs/api-reference/emails.mdx +26 -0
- package/docs/api-reference/inboxes.mdx +13 -0
- package/docs/api-reference/metrics.mdx +10 -0
- package/docs/authentication.mdx +25 -0
- package/docs/docs.json +35 -0
- package/docs/errors.mdx +34 -0
- package/docs/favicon.svg +5 -0
- package/docs/idempotency.mdx +18 -0
- package/docs/index.mdx +24 -0
- package/docs/quickstart.mdx +134 -0
- package/landing/DEPLOYING.md +33 -0
- package/landing/favicon.svg +5 -0
- package/landing/index.html +129 -0
- package/landing/main.js +45 -0
- package/landing/privacy.html +29 -0
- package/landing/styles.css +356 -0
- package/landing/terms.html +29 -0
- package/netlify.toml +15 -0
- package/openapi/openapi.yaml +1016 -0
- package/package.json +34 -0
- package/render.yaml +48 -0
- package/scripts/generate-sdk-py.sh +16 -0
- package/scripts/generate-sdk-ts.sh +16 -0
- package/scripts/migrate.js +66 -0
- package/scripts/validate-docs.js +56 -0
- package/scripts/validate-landing.js +39 -0
- package/sdks/python/README.md +40 -0
- package/sdks/python/emailagent_sdk/__init__.py +157 -0
- package/sdks/python/generated/.openapi-generator/FILES +101 -0
- package/sdks/python/generated/.openapi-generator/VERSION +1 -0
- package/sdks/python/generated/.openapi-generator-ignore +23 -0
- package/sdks/python/generated/emailagent_sdk_generated/__init__.py +105 -0
- package/sdks/python/generated/emailagent_sdk_generated/api/__init__.py +9 -0
- package/sdks/python/generated/emailagent_sdk_generated/api/api_keys_api.py +1162 -0
- package/sdks/python/generated/emailagent_sdk_generated/api/domains_api.py +1168 -0
- package/sdks/python/generated/emailagent_sdk_generated/api/emails_api.py +1232 -0
- package/sdks/python/generated/emailagent_sdk_generated/api/inboxes_api.py +1191 -0
- package/sdks/python/generated/emailagent_sdk_generated/api/metrics_api.py +285 -0
- package/sdks/python/generated/emailagent_sdk_generated/api_client.py +801 -0
- package/sdks/python/generated/emailagent_sdk_generated/api_response.py +21 -0
- package/sdks/python/generated/emailagent_sdk_generated/configuration.py +586 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/APIKeysApi.md +334 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/ApiKeyCreated.md +35 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/ApiKeyCreatedResponse.md +29 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/ApiKeyListItem.md +35 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/ApiKeyListResponse.md +29 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/CreateApiKeyRequest.md +30 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/CreateApiKeyRequestScopes.md +29 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/CreateDomainRequest.md +29 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/CreateInboxRequest.md +31 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/Domain.md +37 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/DomainListResponse.md +29 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/DomainResponse.md +29 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/DomainsApi.md +336 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/Email.md +43 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/EmailListResponse.md +29 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/EmailResponse.md +29 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/EmailsApi.md +353 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/ErrorResponse.md +29 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/Inbox.md +38 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/InboxListResponse.md +29 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/InboxResponse.md +29 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/InboxesApi.md +337 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/MetricsApi.md +83 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/MetricsData.md +35 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/MetricsResponse.md +29 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/OkResponse.md +29 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/PlanLimits.md +32 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/SendEmailRequest.md +32 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/UpdateEmailReadRequest.md +29 -0
- package/sdks/python/generated/emailagent_sdk_generated/docs/UpdateInboxRequest.md +29 -0
- package/sdks/python/generated/emailagent_sdk_generated/exceptions.py +216 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/__init__.py +41 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/api_key_created.py +113 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/api_key_created_response.py +91 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/api_key_list_item.py +123 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/api_key_list_response.py +95 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/create_api_key_request.py +93 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/create_api_key_request_scopes.py +143 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/create_domain_request.py +87 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/create_inbox_request.py +91 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/domain.py +134 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/domain_list_response.py +95 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/domain_response.py +91 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/email.py +175 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/email_list_response.py +95 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/email_response.py +91 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/error_response.py +87 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/inbox.py +136 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/inbox_list_response.py +95 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/inbox_response.py +91 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/metrics_data.py +110 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/metrics_response.py +91 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/ok_response.py +87 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/plan_limits.py +93 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/send_email_request.py +93 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/update_email_read_request.py +87 -0
- package/sdks/python/generated/emailagent_sdk_generated/models/update_inbox_request.py +92 -0
- package/sdks/python/generated/emailagent_sdk_generated/rest.py +258 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/__init__.py +0 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_api_key_created.py +68 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_api_key_created_response.py +52 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_api_key_list_item.py +66 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_api_key_list_response.py +56 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_api_keys_api.py +59 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_create_api_key_request.py +53 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_create_api_key_request_scopes.py +50 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_create_domain_request.py +52 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_create_inbox_request.py +54 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_domain.py +70 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_domain_list_response.py +56 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_domain_response.py +52 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_domains_api.py +59 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_email.py +79 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_email_list_response.py +56 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_email_response.py +52 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_emails_api.py +59 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_error_response.py +52 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_inbox.py +68 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_inbox_list_response.py +56 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_inbox_response.py +52 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_inboxes_api.py +59 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_metrics_api.py +38 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_metrics_data.py +72 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_metrics_response.py +74 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_ok_response.py +52 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_plan_limits.py +58 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_send_email_request.py +56 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_update_email_read_request.py +52 -0
- package/sdks/python/generated/emailagent_sdk_generated/test/test_update_inbox_request.py +52 -0
- package/sdks/python/generated/emailagent_sdk_generated_README.md +140 -0
- package/sdks/python/openapitools.json +7 -0
- package/sdks/python/pyproject.toml +19 -0
- package/sdks/typescript/README.md +41 -0
- package/sdks/typescript/generated/.openapi-generator/FILES +41 -0
- package/sdks/typescript/generated/.openapi-generator/VERSION +1 -0
- package/sdks/typescript/generated/.openapi-generator-ignore +23 -0
- package/sdks/typescript/generated/package.json +21 -0
- package/sdks/typescript/generated/src/apis/APIKeysApi.ts +314 -0
- package/sdks/typescript/generated/src/apis/DomainsApi.ts +314 -0
- package/sdks/typescript/generated/src/apis/EmailsApi.ts +350 -0
- package/sdks/typescript/generated/src/apis/InboxesApi.ts +329 -0
- package/sdks/typescript/generated/src/apis/MetricsApi.ts +93 -0
- package/sdks/typescript/generated/src/apis/index.ts +7 -0
- package/sdks/typescript/generated/src/index.ts +5 -0
- package/sdks/typescript/generated/src/models/ApiKeyCreated.ts +123 -0
- package/sdks/typescript/generated/src/models/ApiKeyCreatedResponse.ts +74 -0
- package/sdks/typescript/generated/src/models/ApiKeyListItem.ts +121 -0
- package/sdks/typescript/generated/src/models/ApiKeyListResponse.ts +74 -0
- package/sdks/typescript/generated/src/models/CreateApiKeyRequest.ts +82 -0
- package/sdks/typescript/generated/src/models/CreateApiKeyRequestScopes.ts +45 -0
- package/sdks/typescript/generated/src/models/CreateDomainRequest.ts +66 -0
- package/sdks/typescript/generated/src/models/CreateInboxRequest.ts +82 -0
- package/sdks/typescript/generated/src/models/Domain.ts +152 -0
- package/sdks/typescript/generated/src/models/DomainListResponse.ts +74 -0
- package/sdks/typescript/generated/src/models/DomainResponse.ts +74 -0
- package/sdks/typescript/generated/src/models/Email.ts +222 -0
- package/sdks/typescript/generated/src/models/EmailListResponse.ts +74 -0
- package/sdks/typescript/generated/src/models/EmailResponse.ts +74 -0
- package/sdks/typescript/generated/src/models/ErrorResponse.ts +66 -0
- package/sdks/typescript/generated/src/models/Inbox.ts +159 -0
- package/sdks/typescript/generated/src/models/InboxListResponse.ts +74 -0
- package/sdks/typescript/generated/src/models/InboxResponse.ts +74 -0
- package/sdks/typescript/generated/src/models/MetricsData.ts +139 -0
- package/sdks/typescript/generated/src/models/MetricsResponse.ts +74 -0
- package/sdks/typescript/generated/src/models/OkResponse.ts +66 -0
- package/sdks/typescript/generated/src/models/PlanLimits.ts +93 -0
- package/sdks/typescript/generated/src/models/SendEmailRequest.ts +91 -0
- package/sdks/typescript/generated/src/models/UpdateEmailReadRequest.ts +66 -0
- package/sdks/typescript/generated/src/models/UpdateInboxRequest.ts +66 -0
- package/sdks/typescript/generated/src/models/index.ts +27 -0
- package/sdks/typescript/generated/src/runtime.ts +432 -0
- package/sdks/typescript/generated/tsconfig.esm.json +7 -0
- package/sdks/typescript/generated/tsconfig.json +16 -0
- package/sdks/typescript/openapitools.json +8 -0
- package/sdks/typescript/package.json +27 -0
- package/sdks/typescript/src/index.ts +138 -0
- package/sdks/typescript/tsconfig.json +14 -0
- package/sql/001_init.sql +143 -0
- package/sql/002_local_auth.sql +38 -0
- package/sql/003_domain_routes.sql +2 -0
- package/sql/004_reliability_primitives.sql +75 -0
- package/sql/005_auth_email_flows.sql +22 -0
- package/src/config.js +30 -0
- package/src/db.js +25 -0
- package/src/lib/api-auth.js +55 -0
- package/src/lib/auth.js +71 -0
- package/src/lib/csrf.js +46 -0
- package/src/lib/dodo.js +67 -0
- package/src/lib/email-templates.js +67 -0
- package/src/lib/idempotency.js +85 -0
- package/src/lib/mailgun.js +188 -0
- package/src/lib/plan.js +24 -0
- package/src/lib/rate-limit.js +43 -0
- package/src/lib/security.js +62 -0
- package/src/lib/session.js +21 -0
- package/src/lib/store.js +638 -0
- package/src/lib/transactional-mailer.js +54 -0
- package/src/lib/validation.js +30 -0
- package/src/routes/api.js +485 -0
- package/src/routes/app.js +699 -0
- package/src/routes/auth.js +404 -0
- package/src/routes/webhooks.js +257 -0
- package/src/server.js +79 -0
- package/src/views/pages/admin.ejs +58 -0
- package/src/views/pages/api-keys.ejs +56 -0
- package/src/views/pages/billing.ejs +71 -0
- package/src/views/pages/domains.ejs +106 -0
- package/src/views/pages/inboxes.ejs +127 -0
- package/src/views/pages/login.ejs +57 -0
- package/src/views/pages/metrics.ejs +34 -0
- package/src/views/pages/reset-password.ejs +19 -0
- package/src/views/partials/bottom.ejs +3 -0
- package/src/views/partials/csrf-field.ejs +3 -0
- package/src/views/partials/flash.ejs +3 -0
- package/src/views/partials/top.ejs +130 -0
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agentmail-clone-v1",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "API-first inbox SaaS for agents (V1)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/server.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"dev": "node --watch src/server.js",
|
|
9
|
+
"landing:dev": "npx --yes serve@14.2.4 landing -l 8080",
|
|
10
|
+
"start": "node src/server.js",
|
|
11
|
+
"migrate": "node scripts/migrate.js",
|
|
12
|
+
"lint:openapi": "npx --yes @redocly/cli@1.24.0 lint openapi/openapi.yaml",
|
|
13
|
+
"docs:validate": "node scripts/validate-docs.js",
|
|
14
|
+
"landing:validate": "node scripts/validate-landing.js",
|
|
15
|
+
"generate:sdk:ts": "./scripts/generate-sdk-ts.sh",
|
|
16
|
+
"generate:sdk:py": "./scripts/generate-sdk-py.sh",
|
|
17
|
+
"generate:sdks": "npm run generate:sdk:ts && npm run generate:sdk:py",
|
|
18
|
+
"check:sdk:drift": "git diff --exit-code"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@fastify/cookie": "^9.4.0",
|
|
22
|
+
"@fastify/formbody": "^7.4.0",
|
|
23
|
+
"@fastify/multipart": "^8.3.1",
|
|
24
|
+
"@fastify/session": "^10.9.0",
|
|
25
|
+
"@fastify/view": "^9.1.0",
|
|
26
|
+
"dodopayments": "^2.19.0",
|
|
27
|
+
"dotenv": "^16.4.5",
|
|
28
|
+
"ejs": "^3.1.10",
|
|
29
|
+
"fastify": "^4.28.1",
|
|
30
|
+
"fastify-raw-body": "^4.3.0",
|
|
31
|
+
"fastify-plugin": "^5.0.1",
|
|
32
|
+
"pg": "^8.13.1"
|
|
33
|
+
}
|
|
34
|
+
}
|
package/render.yaml
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
services:
|
|
2
|
+
- type: web
|
|
3
|
+
name: emailagent-app
|
|
4
|
+
runtime: node
|
|
5
|
+
plan: free
|
|
6
|
+
autoDeployTrigger: commit
|
|
7
|
+
healthCheckPath: /healthz
|
|
8
|
+
buildCommand: npm ci
|
|
9
|
+
startCommand: npm start
|
|
10
|
+
envVars:
|
|
11
|
+
- key: NODE_ENV
|
|
12
|
+
value: production
|
|
13
|
+
- key: NODE_VERSION
|
|
14
|
+
value: 22
|
|
15
|
+
- key: DATABASE_URL
|
|
16
|
+
fromDatabase:
|
|
17
|
+
name: emailagent-db
|
|
18
|
+
property: connectionString
|
|
19
|
+
- key: APP_BASE_URL
|
|
20
|
+
value: https://app.emailagent.dev
|
|
21
|
+
- key: APP_SHARED_DOMAIN
|
|
22
|
+
value: emailagent.dev
|
|
23
|
+
- key: ADMIN_EMAIL
|
|
24
|
+
value: jagan.ganti@gmail.com
|
|
25
|
+
- key: SESSION_SECRET
|
|
26
|
+
generateValue: true
|
|
27
|
+
- key: API_KEY_HASH_SECRET
|
|
28
|
+
generateValue: true
|
|
29
|
+
- key: MAILGUN_API_KEY
|
|
30
|
+
sync: false
|
|
31
|
+
- key: MAILGUN_REGION
|
|
32
|
+
value: us
|
|
33
|
+
- key: MAILGUN_WEBHOOK_SIGNING_KEY
|
|
34
|
+
sync: false
|
|
35
|
+
- key: MAILGUN_ACCOUNT_DOMAIN
|
|
36
|
+
value: emailagent.dev
|
|
37
|
+
- key: DODO_PAYMENTS_API_KEY
|
|
38
|
+
sync: false
|
|
39
|
+
- key: DODO_PAYMENTS_ENVIRONMENT
|
|
40
|
+
value: live_mode
|
|
41
|
+
- key: DODO_PAYMENTS_WEBHOOK_KEY
|
|
42
|
+
sync: false
|
|
43
|
+
- key: DODO_PAYMENTS_PRODUCT_ID_PAID
|
|
44
|
+
sync: false
|
|
45
|
+
|
|
46
|
+
databases:
|
|
47
|
+
- name: emailagent-db
|
|
48
|
+
plan: free
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
5
|
+
SPEC_PATH="$ROOT_DIR/openapi/openapi.yaml"
|
|
6
|
+
OUT_DIR="$ROOT_DIR/sdks/python/generated"
|
|
7
|
+
CONFIG_PATH="$ROOT_DIR/sdks/python/openapitools.json"
|
|
8
|
+
|
|
9
|
+
rm -rf "$OUT_DIR"
|
|
10
|
+
mkdir -p "$OUT_DIR"
|
|
11
|
+
|
|
12
|
+
npx --yes @openapitools/openapi-generator-cli@2.20.0 generate \
|
|
13
|
+
-g python \
|
|
14
|
+
-i "$SPEC_PATH" \
|
|
15
|
+
-o "$OUT_DIR" \
|
|
16
|
+
-c "$CONFIG_PATH"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
5
|
+
SPEC_PATH="$ROOT_DIR/openapi/openapi.yaml"
|
|
6
|
+
OUT_DIR="$ROOT_DIR/sdks/typescript/generated"
|
|
7
|
+
CONFIG_PATH="$ROOT_DIR/sdks/typescript/openapitools.json"
|
|
8
|
+
|
|
9
|
+
rm -rf "$OUT_DIR"
|
|
10
|
+
mkdir -p "$OUT_DIR"
|
|
11
|
+
|
|
12
|
+
npx --yes @openapitools/openapi-generator-cli@2.20.0 generate \
|
|
13
|
+
-g typescript-fetch \
|
|
14
|
+
-i "$SPEC_PATH" \
|
|
15
|
+
-o "$OUT_DIR" \
|
|
16
|
+
-c "$CONFIG_PATH"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import dotenv from 'dotenv';
|
|
5
|
+
import pg from 'pg';
|
|
6
|
+
|
|
7
|
+
dotenv.config();
|
|
8
|
+
|
|
9
|
+
const { Pool } = pg;
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = path.dirname(__filename);
|
|
12
|
+
const migrationsDir = path.resolve(__dirname, '../sql');
|
|
13
|
+
|
|
14
|
+
async function run() {
|
|
15
|
+
if (!process.env.DATABASE_URL) {
|
|
16
|
+
throw new Error('DATABASE_URL is required');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
20
|
+
const client = await pool.connect();
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
await client.query('BEGIN');
|
|
24
|
+
await client.query(`
|
|
25
|
+
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
26
|
+
id BIGSERIAL PRIMARY KEY,
|
|
27
|
+
filename TEXT UNIQUE NOT NULL,
|
|
28
|
+
executed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
29
|
+
)
|
|
30
|
+
`);
|
|
31
|
+
|
|
32
|
+
const files = (await fs.readdir(migrationsDir))
|
|
33
|
+
.filter((f) => f.endsWith('.sql'))
|
|
34
|
+
.sort();
|
|
35
|
+
|
|
36
|
+
for (const filename of files) {
|
|
37
|
+
const already = await client.query(
|
|
38
|
+
'SELECT 1 FROM schema_migrations WHERE filename = $1',
|
|
39
|
+
[filename]
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
if (already.rowCount > 0) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const sql = await fs.readFile(path.join(migrationsDir, filename), 'utf8');
|
|
47
|
+
await client.query(sql);
|
|
48
|
+
await client.query('INSERT INTO schema_migrations (filename) VALUES ($1)', [filename]);
|
|
49
|
+
console.log(`Applied ${filename}`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
await client.query('COMMIT');
|
|
53
|
+
console.log('Migrations complete');
|
|
54
|
+
} catch (err) {
|
|
55
|
+
await client.query('ROLLBACK');
|
|
56
|
+
throw err;
|
|
57
|
+
} finally {
|
|
58
|
+
client.release();
|
|
59
|
+
await pool.end();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
run().catch((err) => {
|
|
64
|
+
console.error(err);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
const root = process.cwd();
|
|
5
|
+
const docsDir = path.join(root, 'docs');
|
|
6
|
+
const docsConfigPath = path.join(docsDir, 'docs.json');
|
|
7
|
+
|
|
8
|
+
if (!fs.existsSync(docsConfigPath)) {
|
|
9
|
+
console.error('Missing docs/docs.json');
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const config = JSON.parse(fs.readFileSync(docsConfigPath, 'utf8'));
|
|
14
|
+
const missing = [];
|
|
15
|
+
|
|
16
|
+
function collectPages(node) {
|
|
17
|
+
if (!node) return [];
|
|
18
|
+
if (Array.isArray(node)) {
|
|
19
|
+
return node.flatMap(collectPages);
|
|
20
|
+
}
|
|
21
|
+
if (typeof node === 'string') {
|
|
22
|
+
return [node];
|
|
23
|
+
}
|
|
24
|
+
if (typeof node === 'object') {
|
|
25
|
+
if (Array.isArray(node.pages)) {
|
|
26
|
+
return node.pages.flatMap(collectPages);
|
|
27
|
+
}
|
|
28
|
+
return Object.values(node).flatMap(collectPages);
|
|
29
|
+
}
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const pages = [...new Set(collectPages(config.navigation))];
|
|
34
|
+
for (const page of pages) {
|
|
35
|
+
if (page.startsWith('http://') || page.startsWith('https://')) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const filePath = path.join(docsDir, `${page}.mdx`);
|
|
39
|
+
if (!fs.existsSync(filePath)) {
|
|
40
|
+
missing.push(filePath);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!fs.existsSync(path.join(root, 'openapi', 'openapi.yaml'))) {
|
|
45
|
+
missing.push(path.join(root, 'openapi', 'openapi.yaml'));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (missing.length > 0) {
|
|
49
|
+
console.error('Docs validation failed. Missing files:');
|
|
50
|
+
for (const item of missing) {
|
|
51
|
+
console.error(`- ${item}`);
|
|
52
|
+
}
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
console.log(`Docs validation passed (${pages.length} pages found).`);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
const root = process.cwd();
|
|
5
|
+
const landingDir = path.join(root, 'landing');
|
|
6
|
+
const requiredFiles = ['index.html', 'styles.css', 'main.js', 'privacy.html', 'terms.html', 'favicon.svg'];
|
|
7
|
+
const missing = requiredFiles.filter((file) => !fs.existsSync(path.join(landingDir, file)));
|
|
8
|
+
|
|
9
|
+
if (missing.length) {
|
|
10
|
+
console.error('Landing validation failed. Missing files:');
|
|
11
|
+
for (const file of missing) {
|
|
12
|
+
console.error(`- landing/${file}`);
|
|
13
|
+
}
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const indexHtml = fs.readFileSync(path.join(landingDir, 'index.html'), 'utf8');
|
|
18
|
+
|
|
19
|
+
const requiredMarkers = [
|
|
20
|
+
'Email infrastructure for AI agents',
|
|
21
|
+
'https://app.emailagent.dev/',
|
|
22
|
+
'https://docs.emailagent.dev',
|
|
23
|
+
'data-cta="start-free-hero"',
|
|
24
|
+
'data-cta="docs-hero"',
|
|
25
|
+
'/privacy.html',
|
|
26
|
+
'/terms.html',
|
|
27
|
+
'canonical" href="https://emailagent.dev"'
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
const missingMarkers = requiredMarkers.filter((marker) => !indexHtml.includes(marker));
|
|
31
|
+
if (missingMarkers.length) {
|
|
32
|
+
console.error('Landing validation failed. Missing required content markers:');
|
|
33
|
+
for (const marker of missingMarkers) {
|
|
34
|
+
console.error(`- ${marker}`);
|
|
35
|
+
}
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
console.log('Landing validation passed.');
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# emailagent-sdk (Python)
|
|
2
|
+
|
|
3
|
+
Official Python SDK for EmailAgent.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install emailagent-sdk==0.1.0
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from emailagent_sdk import EmailAgentClient
|
|
15
|
+
|
|
16
|
+
client = EmailAgentClient(
|
|
17
|
+
api_key="<api_key>",
|
|
18
|
+
base_url="https://api.emailagent.dev",
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
print(client.list_inboxes())
|
|
22
|
+
|
|
23
|
+
emails = client.list_emails(inbox_id="<inbox_uuid>")
|
|
24
|
+
print(emails)
|
|
25
|
+
|
|
26
|
+
client.update_email_read(
|
|
27
|
+
email_id="<email_uuid>",
|
|
28
|
+
is_read=True,
|
|
29
|
+
idempotency_key="mark-read-001",
|
|
30
|
+
)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Idempotency
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
client.create_inbox(
|
|
37
|
+
local_part="agent-1",
|
|
38
|
+
idempotency_key="create-inbox-agent-1",
|
|
39
|
+
)
|
|
40
|
+
```
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""Official Python SDK for EmailAgent."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import Any
|
|
7
|
+
from urllib.parse import quote
|
|
8
|
+
|
|
9
|
+
import requests
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class EmailAgentApiError(Exception):
|
|
14
|
+
status_code: int
|
|
15
|
+
payload: Any
|
|
16
|
+
|
|
17
|
+
def __str__(self) -> str:
|
|
18
|
+
if isinstance(self.payload, dict) and self.payload.get("error"):
|
|
19
|
+
return str(self.payload["error"])
|
|
20
|
+
return f"EmailAgent API error ({self.status_code})"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class EmailAgentClient:
|
|
24
|
+
def __init__(self, api_key: str, base_url: str = "https://api.emailagent.dev") -> None:
|
|
25
|
+
self.base_url = base_url.rstrip("/")
|
|
26
|
+
self.session = requests.Session()
|
|
27
|
+
self.session.headers.update({"Authorization": f"Bearer {api_key}"})
|
|
28
|
+
|
|
29
|
+
def _request(
|
|
30
|
+
self,
|
|
31
|
+
method: str,
|
|
32
|
+
path: str,
|
|
33
|
+
body: dict[str, Any] | None = None,
|
|
34
|
+
idempotency_key: str | None = None,
|
|
35
|
+
) -> Any:
|
|
36
|
+
headers: dict[str, str] = {}
|
|
37
|
+
if idempotency_key:
|
|
38
|
+
headers["Idempotency-Key"] = idempotency_key
|
|
39
|
+
|
|
40
|
+
response = self.session.request(
|
|
41
|
+
method=method,
|
|
42
|
+
url=f"{self.base_url}{path}",
|
|
43
|
+
json=body,
|
|
44
|
+
headers=headers or None,
|
|
45
|
+
timeout=30,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
payload: Any
|
|
49
|
+
try:
|
|
50
|
+
payload = response.json()
|
|
51
|
+
except ValueError:
|
|
52
|
+
payload = response.text
|
|
53
|
+
|
|
54
|
+
if response.status_code >= 400:
|
|
55
|
+
raise EmailAgentApiError(response.status_code, payload)
|
|
56
|
+
|
|
57
|
+
return payload
|
|
58
|
+
|
|
59
|
+
def list_inboxes(self) -> Any:
|
|
60
|
+
return self._request("GET", "/api/v1/inboxes")
|
|
61
|
+
|
|
62
|
+
def create_inbox(
|
|
63
|
+
self,
|
|
64
|
+
local_part: str,
|
|
65
|
+
display_name: str | None = None,
|
|
66
|
+
domain_name: str | None = None,
|
|
67
|
+
idempotency_key: str | None = None,
|
|
68
|
+
) -> Any:
|
|
69
|
+
body: dict[str, Any] = {"localPart": local_part}
|
|
70
|
+
if display_name is not None:
|
|
71
|
+
body["displayName"] = display_name
|
|
72
|
+
if domain_name is not None:
|
|
73
|
+
body["domainName"] = domain_name
|
|
74
|
+
return self._request("POST", "/api/v1/inboxes", body, idempotency_key)
|
|
75
|
+
|
|
76
|
+
def update_inbox(self, inbox_id: str, display_name: str, idempotency_key: str | None = None) -> Any:
|
|
77
|
+
return self._request(
|
|
78
|
+
"PATCH",
|
|
79
|
+
f"/api/v1/inboxes/{inbox_id}",
|
|
80
|
+
{"displayName": display_name},
|
|
81
|
+
idempotency_key,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
def delete_inbox(self, inbox_id: str, idempotency_key: str | None = None) -> Any:
|
|
85
|
+
return self._request("DELETE", f"/api/v1/inboxes/{inbox_id}", None, idempotency_key)
|
|
86
|
+
|
|
87
|
+
def send_email(
|
|
88
|
+
self,
|
|
89
|
+
inbox_id: str,
|
|
90
|
+
to: str,
|
|
91
|
+
subject: str | None = None,
|
|
92
|
+
text: str | None = None,
|
|
93
|
+
idempotency_key: str | None = None,
|
|
94
|
+
) -> Any:
|
|
95
|
+
body: dict[str, Any] = {"inboxId": inbox_id, "to": to}
|
|
96
|
+
if subject is not None:
|
|
97
|
+
body["subject"] = subject
|
|
98
|
+
if text is not None:
|
|
99
|
+
body["text"] = text
|
|
100
|
+
return self._request("POST", "/api/v1/emails/send", body, idempotency_key)
|
|
101
|
+
|
|
102
|
+
def list_emails(self, inbox_id: str | None = None) -> Any:
|
|
103
|
+
path = "/api/v1/emails"
|
|
104
|
+
if inbox_id:
|
|
105
|
+
path = f"{path}?inboxId={quote(inbox_id, safe='')}"
|
|
106
|
+
return self._request("GET", path)
|
|
107
|
+
|
|
108
|
+
def update_email_read(
|
|
109
|
+
self,
|
|
110
|
+
email_id: str,
|
|
111
|
+
is_read: bool,
|
|
112
|
+
idempotency_key: str | None = None,
|
|
113
|
+
) -> Any:
|
|
114
|
+
return self._request(
|
|
115
|
+
"PATCH",
|
|
116
|
+
f"/api/v1/emails/{email_id}/read",
|
|
117
|
+
{"isRead": is_read},
|
|
118
|
+
idempotency_key,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
def delete_email(self, email_id: str, idempotency_key: str | None = None) -> Any:
|
|
122
|
+
return self._request("DELETE", f"/api/v1/emails/{email_id}", None, idempotency_key)
|
|
123
|
+
|
|
124
|
+
def list_domains(self) -> Any:
|
|
125
|
+
return self._request("GET", "/api/v1/domains")
|
|
126
|
+
|
|
127
|
+
def create_domain(self, name: str, idempotency_key: str | None = None) -> Any:
|
|
128
|
+
return self._request("POST", "/api/v1/domains", {"name": name}, idempotency_key)
|
|
129
|
+
|
|
130
|
+
def verify_domain(self, domain_id: str, idempotency_key: str | None = None) -> Any:
|
|
131
|
+
return self._request("POST", f"/api/v1/domains/{domain_id}/verify", None, idempotency_key)
|
|
132
|
+
|
|
133
|
+
def delete_domain(self, domain_id: str, idempotency_key: str | None = None) -> Any:
|
|
134
|
+
return self._request("DELETE", f"/api/v1/domains/{domain_id}", None, idempotency_key)
|
|
135
|
+
|
|
136
|
+
def list_api_keys(self) -> Any:
|
|
137
|
+
return self._request("GET", "/api/v1/api-keys")
|
|
138
|
+
|
|
139
|
+
def create_api_key(
|
|
140
|
+
self,
|
|
141
|
+
name: str,
|
|
142
|
+
scopes: list[str] | str | None = None,
|
|
143
|
+
idempotency_key: str | None = None,
|
|
144
|
+
) -> Any:
|
|
145
|
+
body: dict[str, Any] = {"name": name}
|
|
146
|
+
if scopes is not None:
|
|
147
|
+
body["scopes"] = scopes
|
|
148
|
+
return self._request("POST", "/api/v1/api-keys", body, idempotency_key)
|
|
149
|
+
|
|
150
|
+
def rotate_api_key(self, api_key_id: str, idempotency_key: str | None = None) -> Any:
|
|
151
|
+
return self._request("POST", f"/api/v1/api-keys/{api_key_id}/rotate", None, idempotency_key)
|
|
152
|
+
|
|
153
|
+
def revoke_api_key(self, api_key_id: str, idempotency_key: str | None = None) -> Any:
|
|
154
|
+
return self._request("POST", f"/api/v1/api-keys/{api_key_id}/revoke", None, idempotency_key)
|
|
155
|
+
|
|
156
|
+
def get_metrics(self) -> Any:
|
|
157
|
+
return self._request("GET", "/api/v1/metrics")
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
.openapi-generator-ignore
|
|
2
|
+
emailagent_sdk_generated/__init__.py
|
|
3
|
+
emailagent_sdk_generated/api/__init__.py
|
|
4
|
+
emailagent_sdk_generated/api/api_keys_api.py
|
|
5
|
+
emailagent_sdk_generated/api/domains_api.py
|
|
6
|
+
emailagent_sdk_generated/api/emails_api.py
|
|
7
|
+
emailagent_sdk_generated/api/inboxes_api.py
|
|
8
|
+
emailagent_sdk_generated/api/metrics_api.py
|
|
9
|
+
emailagent_sdk_generated/api_client.py
|
|
10
|
+
emailagent_sdk_generated/api_response.py
|
|
11
|
+
emailagent_sdk_generated/configuration.py
|
|
12
|
+
emailagent_sdk_generated/docs/APIKeysApi.md
|
|
13
|
+
emailagent_sdk_generated/docs/ApiKeyCreated.md
|
|
14
|
+
emailagent_sdk_generated/docs/ApiKeyCreatedResponse.md
|
|
15
|
+
emailagent_sdk_generated/docs/ApiKeyListItem.md
|
|
16
|
+
emailagent_sdk_generated/docs/ApiKeyListResponse.md
|
|
17
|
+
emailagent_sdk_generated/docs/CreateApiKeyRequest.md
|
|
18
|
+
emailagent_sdk_generated/docs/CreateApiKeyRequestScopes.md
|
|
19
|
+
emailagent_sdk_generated/docs/CreateDomainRequest.md
|
|
20
|
+
emailagent_sdk_generated/docs/CreateInboxRequest.md
|
|
21
|
+
emailagent_sdk_generated/docs/Domain.md
|
|
22
|
+
emailagent_sdk_generated/docs/DomainListResponse.md
|
|
23
|
+
emailagent_sdk_generated/docs/DomainResponse.md
|
|
24
|
+
emailagent_sdk_generated/docs/DomainsApi.md
|
|
25
|
+
emailagent_sdk_generated/docs/Email.md
|
|
26
|
+
emailagent_sdk_generated/docs/EmailListResponse.md
|
|
27
|
+
emailagent_sdk_generated/docs/EmailResponse.md
|
|
28
|
+
emailagent_sdk_generated/docs/EmailsApi.md
|
|
29
|
+
emailagent_sdk_generated/docs/ErrorResponse.md
|
|
30
|
+
emailagent_sdk_generated/docs/Inbox.md
|
|
31
|
+
emailagent_sdk_generated/docs/InboxListResponse.md
|
|
32
|
+
emailagent_sdk_generated/docs/InboxResponse.md
|
|
33
|
+
emailagent_sdk_generated/docs/InboxesApi.md
|
|
34
|
+
emailagent_sdk_generated/docs/MetricsApi.md
|
|
35
|
+
emailagent_sdk_generated/docs/MetricsData.md
|
|
36
|
+
emailagent_sdk_generated/docs/MetricsResponse.md
|
|
37
|
+
emailagent_sdk_generated/docs/OkResponse.md
|
|
38
|
+
emailagent_sdk_generated/docs/PlanLimits.md
|
|
39
|
+
emailagent_sdk_generated/docs/SendEmailRequest.md
|
|
40
|
+
emailagent_sdk_generated/docs/UpdateEmailReadRequest.md
|
|
41
|
+
emailagent_sdk_generated/docs/UpdateInboxRequest.md
|
|
42
|
+
emailagent_sdk_generated/exceptions.py
|
|
43
|
+
emailagent_sdk_generated/models/__init__.py
|
|
44
|
+
emailagent_sdk_generated/models/api_key_created.py
|
|
45
|
+
emailagent_sdk_generated/models/api_key_created_response.py
|
|
46
|
+
emailagent_sdk_generated/models/api_key_list_item.py
|
|
47
|
+
emailagent_sdk_generated/models/api_key_list_response.py
|
|
48
|
+
emailagent_sdk_generated/models/create_api_key_request.py
|
|
49
|
+
emailagent_sdk_generated/models/create_api_key_request_scopes.py
|
|
50
|
+
emailagent_sdk_generated/models/create_domain_request.py
|
|
51
|
+
emailagent_sdk_generated/models/create_inbox_request.py
|
|
52
|
+
emailagent_sdk_generated/models/domain.py
|
|
53
|
+
emailagent_sdk_generated/models/domain_list_response.py
|
|
54
|
+
emailagent_sdk_generated/models/domain_response.py
|
|
55
|
+
emailagent_sdk_generated/models/email.py
|
|
56
|
+
emailagent_sdk_generated/models/email_list_response.py
|
|
57
|
+
emailagent_sdk_generated/models/email_response.py
|
|
58
|
+
emailagent_sdk_generated/models/error_response.py
|
|
59
|
+
emailagent_sdk_generated/models/inbox.py
|
|
60
|
+
emailagent_sdk_generated/models/inbox_list_response.py
|
|
61
|
+
emailagent_sdk_generated/models/inbox_response.py
|
|
62
|
+
emailagent_sdk_generated/models/metrics_data.py
|
|
63
|
+
emailagent_sdk_generated/models/metrics_response.py
|
|
64
|
+
emailagent_sdk_generated/models/ok_response.py
|
|
65
|
+
emailagent_sdk_generated/models/plan_limits.py
|
|
66
|
+
emailagent_sdk_generated/models/send_email_request.py
|
|
67
|
+
emailagent_sdk_generated/models/update_email_read_request.py
|
|
68
|
+
emailagent_sdk_generated/models/update_inbox_request.py
|
|
69
|
+
emailagent_sdk_generated/rest.py
|
|
70
|
+
emailagent_sdk_generated/test/__init__.py
|
|
71
|
+
emailagent_sdk_generated/test/test_api_key_created.py
|
|
72
|
+
emailagent_sdk_generated/test/test_api_key_created_response.py
|
|
73
|
+
emailagent_sdk_generated/test/test_api_key_list_item.py
|
|
74
|
+
emailagent_sdk_generated/test/test_api_key_list_response.py
|
|
75
|
+
emailagent_sdk_generated/test/test_api_keys_api.py
|
|
76
|
+
emailagent_sdk_generated/test/test_create_api_key_request.py
|
|
77
|
+
emailagent_sdk_generated/test/test_create_api_key_request_scopes.py
|
|
78
|
+
emailagent_sdk_generated/test/test_create_domain_request.py
|
|
79
|
+
emailagent_sdk_generated/test/test_create_inbox_request.py
|
|
80
|
+
emailagent_sdk_generated/test/test_domain.py
|
|
81
|
+
emailagent_sdk_generated/test/test_domain_list_response.py
|
|
82
|
+
emailagent_sdk_generated/test/test_domain_response.py
|
|
83
|
+
emailagent_sdk_generated/test/test_domains_api.py
|
|
84
|
+
emailagent_sdk_generated/test/test_email.py
|
|
85
|
+
emailagent_sdk_generated/test/test_email_list_response.py
|
|
86
|
+
emailagent_sdk_generated/test/test_email_response.py
|
|
87
|
+
emailagent_sdk_generated/test/test_emails_api.py
|
|
88
|
+
emailagent_sdk_generated/test/test_error_response.py
|
|
89
|
+
emailagent_sdk_generated/test/test_inbox.py
|
|
90
|
+
emailagent_sdk_generated/test/test_inbox_list_response.py
|
|
91
|
+
emailagent_sdk_generated/test/test_inbox_response.py
|
|
92
|
+
emailagent_sdk_generated/test/test_inboxes_api.py
|
|
93
|
+
emailagent_sdk_generated/test/test_metrics_api.py
|
|
94
|
+
emailagent_sdk_generated/test/test_metrics_data.py
|
|
95
|
+
emailagent_sdk_generated/test/test_metrics_response.py
|
|
96
|
+
emailagent_sdk_generated/test/test_ok_response.py
|
|
97
|
+
emailagent_sdk_generated/test/test_plan_limits.py
|
|
98
|
+
emailagent_sdk_generated/test/test_send_email_request.py
|
|
99
|
+
emailagent_sdk_generated/test/test_update_email_read_request.py
|
|
100
|
+
emailagent_sdk_generated/test/test_update_inbox_request.py
|
|
101
|
+
emailagent_sdk_generated_README.md
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
7.14.0
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# OpenAPI Generator Ignore
|
|
2
|
+
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
|
3
|
+
|
|
4
|
+
# Use this file to prevent files from being overwritten by the generator.
|
|
5
|
+
# The patterns follow closely to .gitignore or .dockerignore.
|
|
6
|
+
|
|
7
|
+
# As an example, the C# client generator defines ApiClient.cs.
|
|
8
|
+
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
|
9
|
+
#ApiClient.cs
|
|
10
|
+
|
|
11
|
+
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
|
12
|
+
#foo/*/qux
|
|
13
|
+
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
|
14
|
+
|
|
15
|
+
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
|
16
|
+
#foo/**/qux
|
|
17
|
+
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
|
18
|
+
|
|
19
|
+
# You can also negate patterns with an exclamation (!).
|
|
20
|
+
# For example, you can ignore all files in a docs folder with the file extension .md:
|
|
21
|
+
#docs/*.md
|
|
22
|
+
# Then explicitly reverse the ignore rule for a single file:
|
|
23
|
+
#!docs/README.md
|