diff --git a/README.md b/README.md index 53e93c3..ff7de98 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ Console Home is available for all three clouds. Runtime gaps — an adapter exists but the local runtime does not implement it: -- Azure Serverless: the Floci-AZ runtime returns 501 NotImplemented for the Azure Functions endpoint. +- Azure Serverless: TheCloud's Azure runtime returns 501 NotImplemented for the Azure Functions endpoint. Services marked `No` render as a disabled sidebar row whose tooltip carries the server-supplied reason. Adding one is a catalog row in diff --git a/packages/api/src/adapter-aws/AwsLogsAdapter.ts b/packages/api/src/adapter-aws/AwsLogsAdapter.ts index a396bdd..d1da7b4 100644 --- a/packages/api/src/adapter-aws/AwsLogsAdapter.ts +++ b/packages/api/src/adapter-aws/AwsLogsAdapter.ts @@ -135,7 +135,7 @@ export class AwsLogsAdapter implements CloudServiceAdapter { limit: input.limit, }), ) - if (!queryId) throw new NotFoundError(`Floci did not return a query id for ${logGroupName}.`) + if (!queryId) throw new NotFoundError(`The runtime did not return a query id for ${logGroupName}.`) const deadline = Date.now() + (this.queryPoll.timeoutMs ?? QUERY_POLL_TIMEOUT_MS) const pollInterval = this.queryPoll.intervalMs ?? QUERY_POLL_INTERVAL_MS diff --git a/packages/api/src/adapter-aws/AwsSesAdapter.ts b/packages/api/src/adapter-aws/AwsSesAdapter.ts index 14878b0..fea9083 100644 --- a/packages/api/src/adapter-aws/AwsSesAdapter.ts +++ b/packages/api/src/adapter-aws/AwsSesAdapter.ts @@ -62,7 +62,7 @@ export class AwsSesAdapter implements CloudServiceAdapter { } async delete(_id: string): Promise { - throw new NotSupportedError('Deleting individual captured emails is not supported by Floci SES') + throw new NotSupportedError('Deleting individual captured emails is not supported by TheCloud SES') } async clearEmailInbox(): Promise { @@ -76,10 +76,10 @@ export class AwsSesAdapter implements CloudServiceAdapter { try { body = await response.json() as FlociSesInbox } catch (error) { - throw new RuntimeError('Floci SES inspection returned invalid JSON', {cause: error}) + throw new RuntimeError('TheCloud SES inspection returned invalid JSON', {cause: error}) } if (!Array.isArray(body.messages)) { - throw new RuntimeError('Floci SES inspection response did not contain messages') + throw new RuntimeError('TheCloud SES inspection response did not contain messages') } return body.messages } @@ -89,14 +89,14 @@ export class AwsSesAdapter implements CloudServiceAdapter { try { response = await this.fetcher(`${this.endpoint.replace(/\/$/, '')}${path}`, init) } catch (error) { - throw new RuntimeUnavailableError(`Cannot reach Floci SES at ${this.endpoint}`, {cause: error}) + throw new RuntimeUnavailableError(`Cannot reach TheCloud SES at ${this.endpoint}`, {cause: error}) } if (response.ok) return response const detail = await response.text().catch(() => '') throw httpStatusToCloudError( response.status, - detail || `Floci SES inspection returned HTTP ${response.status}`, + detail || `TheCloud SES inspection returned HTTP ${response.status}`, ) } } diff --git a/packages/api/src/adapter-azure/AzureAksAdapter.ts b/packages/api/src/adapter-azure/AzureAksAdapter.ts index e3b71f8..3c1ca0a 100644 --- a/packages/api/src/adapter-azure/AzureAksAdapter.ts +++ b/packages/api/src/adapter-azure/AzureAksAdapter.ts @@ -106,7 +106,7 @@ export class AzureAksAdapter implements CloudServiceAdapter { const body = await this.json>('/subscriptions') const id = body?.value?.[0]?.subscriptionId - if (!id) throw new RuntimeError('Floci-AZ returned no subscription to scope cluster requests to') + if (!id) throw new RuntimeError('The Azure runtime returned no subscription to scope cluster requests to') this.subscriptionId = id return id diff --git a/packages/api/src/adapter-azure/AzureComputeAdapter.ts b/packages/api/src/adapter-azure/AzureComputeAdapter.ts index ad745af..dc52c35 100644 --- a/packages/api/src/adapter-azure/AzureComputeAdapter.ts +++ b/packages/api/src/adapter-azure/AzureComputeAdapter.ts @@ -182,7 +182,7 @@ export class AzureComputeAdapter implements CloudServiceAdapter { const body = await this.json>('/subscriptions') const id = body?.value?.[0]?.subscriptionId - if (!id) throw new RuntimeError('Floci-AZ returned no subscription to scope compute requests to') + if (!id) throw new RuntimeError('The Azure runtime returned no subscription to scope compute requests to') this.subscriptionId = id return id diff --git a/packages/api/src/adapter-azure/AzureServerlessAdapter.ts b/packages/api/src/adapter-azure/AzureServerlessAdapter.ts index d95a41e..83716e1 100644 --- a/packages/api/src/adapter-azure/AzureServerlessAdapter.ts +++ b/packages/api/src/adapter-azure/AzureServerlessAdapter.ts @@ -49,7 +49,7 @@ export class AzureServerlessAdapter implements CloudServiceAdapter { descriptorOverride(): CloudServiceDescriptorOverride { return { availability: 'coming_soon', - reason: 'The Floci-AZ runtime returns 501 NotImplemented for the Azure Functions endpoint.', + reason: 'TheCloud\'s Azure runtime returns 501 NotImplemented for the Azure Functions endpoint.', } } diff --git a/packages/api/src/adapter-azure/CosmosNoSqlUnavailableError.ts b/packages/api/src/adapter-azure/CosmosNoSqlUnavailableError.ts index 6469094..d968127 100644 --- a/packages/api/src/adapter-azure/CosmosNoSqlUnavailableError.ts +++ b/packages/api/src/adapter-azure/CosmosNoSqlUnavailableError.ts @@ -8,5 +8,5 @@ import {CloudError, type CloudErrorStatus} from '../cloud-spi/errors' export class CosmosNoSqlUnavailableError extends CloudError { readonly status: CloudErrorStatus = 502 readonly code = 'cosmos_nosql_unavailable' as const - protected readonly label = 'Cosmos NoSQL endpoint is not available on the selected Floci-AZ runtime' + protected readonly label = 'Cosmos NoSQL endpoint is not available on the selected Azure runtime' } diff --git a/packages/api/src/adapter-azure/MssqlDataClient.ts b/packages/api/src/adapter-azure/MssqlDataClient.ts index e3f88fc..22f2258 100644 --- a/packages/api/src/adapter-azure/MssqlDataClient.ts +++ b/packages/api/src/adapter-azure/MssqlDataClient.ts @@ -57,7 +57,7 @@ function connectionConfig(connection: SqlDataConnection): MssqlConfig { options: { encrypt: connection.tlsMode !== 'disable', trustServerCertificate: connection.tlsMode !== 'verify', - appName: 'Floci UI', + appName: 'TheCloud', }, } } diff --git a/packages/api/src/adapter-azure/PostgresDataClient.ts b/packages/api/src/adapter-azure/PostgresDataClient.ts index fce7459..2da7bf0 100644 --- a/packages/api/src/adapter-azure/PostgresDataClient.ts +++ b/packages/api/src/adapter-azure/PostgresDataClient.ts @@ -26,7 +26,7 @@ export class PostgresDataClient implements SqlDataClient { connectionTimeoutMillis: 10_000, query_timeout: 30_000, statement_timeout: 30_000, - application_name: 'Floci UI', + application_name: 'TheCloud', }) const startedAt = performance.now() let phase: SqlDataPhase = 'connect' diff --git a/packages/api/src/auth.ts b/packages/api/src/auth.ts index c53204e..849cc09 100644 --- a/packages/api/src/auth.ts +++ b/packages/api/src/auth.ts @@ -270,7 +270,7 @@ function loginPage(c: Context, config: AuthConfig): Response { ? `
` : `
` const error = loginErrorMessage(c.req.query('error')) - return c.html(`Welcome back | TheCloud
Floci DevToolsLocal AWS, on your own infrastructure.
Secure console

Welcome back

Sign in with your account to access the console.

${error ? `` : ''}${content}
`) + return c.html(`Welcome back | TheCloud
TheCloudLocal AWS, on your own infrastructure.
Secure console

Welcome back

Sign in with your account to access the console.

${error ? `` : ''}${content}
`) } function loginFailure(c: Context, status: 401 | 403 | 429): Response { diff --git a/packages/api/src/azure.test.ts b/packages/api/src/azure.test.ts index 35db2cb..29877dc 100644 --- a/packages/api/src/azure.test.ts +++ b/packages/api/src/azure.test.ts @@ -32,7 +32,7 @@ describe('AzureRestRuntimeClient', () => { const client = new AzureRestRuntimeClient('http://localhost:4577', 'devstoreaccount1') await expect(client.fetch('/container?restype=container', {method: 'PUT'})).rejects.toThrow( - 'Cannot reach Floci-AZ at http://localhost:4577: connection refused', + "Cannot reach TheCloud's Azure runtime at http://localhost:4577: connection refused", ) }) }) diff --git a/packages/api/src/azure.ts b/packages/api/src/azure.ts index a141f57..aae9ea4 100644 --- a/packages/api/src/azure.ts +++ b/packages/api/src/azure.ts @@ -29,7 +29,7 @@ export class AzureRestRuntimeClient implements AzureRuntimeClient { }) } catch (error) { throw new RuntimeUnavailableError( - `Cannot reach Floci-AZ at ${this.endpoint}: ${errorMessage(error)}`, + `Cannot reach TheCloud's Azure runtime at ${this.endpoint}: ${errorMessage(error)}`, {cause: error}, ) } diff --git a/packages/api/src/cloud-spi/codebuildSchema.ts b/packages/api/src/cloud-spi/codebuildSchema.ts index 4e4c88e..2b07d67 100644 --- a/packages/api/src/cloud-spi/codebuildSchema.ts +++ b/packages/api/src/cloud-spi/codebuildSchema.ts @@ -36,7 +36,7 @@ export function awsCodeBuildSchema(): ServiceSchema { { name: 'buildspec', label: 'Buildspec', type: 'textarea', required: false, group: 'Source', span: true, defaultValueWhen: {field: 'sourceType', values: {NO_SOURCE: DEFAULT_DOCKER_TO_ECR_BUILDSPEC, S3: ''}}, - description: 'For no source, this is a Floci Node 20 Docker-to-ECR buildspec. For S3, leave blank to use buildspec.yml from the source, or provide an override. Include taskdef.json and appspec.yaml in the source for CodeDeployToECS.', + description: 'For no source, this is TheCloud\'s Node 20 Docker-to-ECR buildspec. For S3, leave blank to use buildspec.yml from the source, or provide an override. Include taskdef.json and appspec.yaml in the source for CodeDeployToECS.', }, { name: 'artifactsType', label: 'Artifact type', type: 'select', required: true, group: 'Artifacts', defaultValue: 'NO_ARTIFACTS', diff --git a/packages/api/src/cloud-spi/databaseSchema.ts b/packages/api/src/cloud-spi/databaseSchema.ts index 12f029d..59952f1 100644 --- a/packages/api/src/cloud-spi/databaseSchema.ts +++ b/packages/api/src/cloud-spi/databaseSchema.ts @@ -131,7 +131,7 @@ export function awsDatabaseSchema(): ServiceSchema { label: 'Create DB snapshot', enabled: true, status: 'partial', - reason: 'The Cloud Proxy operation is available, but the current Floci runtime does not implement CreateDBSnapshot.', + reason: 'The Cloud Proxy operation is available, but the current runtime does not implement CreateDBSnapshot.', runtimeRequired: true, }, ], diff --git a/packages/api/src/cloudProxy.test.ts b/packages/api/src/cloudProxy.test.ts index 33ec257..4cf6084 100644 --- a/packages/api/src/cloudProxy.test.ts +++ b/packages/api/src/cloudProxy.test.ts @@ -233,7 +233,7 @@ describe('adapter capability advertisements match the runtime reality', () => { label: 'Create DB snapshot', enabled: true, status: 'partial', - reason: 'The Cloud Proxy operation is available, but the current Floci runtime does not implement CreateDBSnapshot.', + reason: 'The Cloud Proxy operation is available, but the current runtime does not implement CreateDBSnapshot.', runtimeRequired: true, }, ]) diff --git a/packages/api/src/gcp.test.ts b/packages/api/src/gcp.test.ts index e3c6d09..1a52145 100644 --- a/packages/api/src/gcp.test.ts +++ b/packages/api/src/gcp.test.ts @@ -122,6 +122,6 @@ describe('GcpRestRuntimeClient.health', () => { stubFetch(() => { throw Object.assign(new Error('connect ECONNREFUSED'), {code: 'ECONNREFUSED'}) }) - await expect(client().health()).rejects.toThrow(`Cannot reach Floci-GCP at ${ENDPOINT}`) + await expect(client().health()).rejects.toThrow(`Cannot reach TheCloud's GCP runtime at ${ENDPOINT}`) }) }) diff --git a/packages/api/src/gcp.ts b/packages/api/src/gcp.ts index fb42ab6..f545948 100644 --- a/packages/api/src/gcp.ts +++ b/packages/api/src/gcp.ts @@ -40,7 +40,7 @@ export class GcpRestRuntimeClient implements GcpRuntimeClient { res = await globalThis.fetch(`${this.endpoint}${path}`, init) } catch (error) { throw new RuntimeUnavailableError( - `Cannot reach Floci-GCP at ${this.endpoint}: ${errorMessage(error)}`, + `Cannot reach TheCloud's GCP runtime at ${this.endpoint}: ${errorMessage(error)}`, {cause: error}, ) } @@ -76,12 +76,12 @@ export class GcpRestRuntimeClient implements GcpRuntimeClient { res = await globalThis.fetch(url, {method: 'GET'}) } catch (error) { throw new RuntimeUnavailableError( - `Cannot reach Floci-GCP at ${this.endpoint}: ${errorMessage(error)}`, + `Cannot reach TheCloud's GCP runtime at ${this.endpoint}: ${errorMessage(error)}`, {cause: error}, ) } if (res.status >= 500) { - throw new RuntimeUnavailableError(`Floci-GCP at ${this.endpoint} returned HTTP ${res.status}`) + throw new RuntimeUnavailableError(`TheCloud's GCP runtime at ${this.endpoint} returned HTTP ${res.status}`) } } } diff --git a/packages/api/src/service/runtimeProbe.ts b/packages/api/src/service/runtimeProbe.ts index 85a772d..824a793 100644 --- a/packages/api/src/service/runtimeProbe.ts +++ b/packages/api/src/service/runtimeProbe.ts @@ -16,7 +16,7 @@ export type RuntimeProbe = () => Promise export const runtimeProbes: Record = { // Every runtime exposes a health endpoint, but under its own path: core and // Floci-AZ use /_floci/health, Floci-GCP uses /_floci-gcp/health. - aws: () => probeHttp(`${awsEndpoint()}/_floci/health`, 'Floci core'), + aws: () => probeHttp(`${awsEndpoint()}/_floci/health`, 'TheCloud AWS runtime'), azure: async () => { await azure.fetch('/_floci/health', {method: 'GET'}) }, diff --git a/packages/api/src/services/lightsailDeployment.ts b/packages/api/src/services/lightsailDeployment.ts index c14c846..b829f8b 100644 --- a/packages/api/src/services/lightsailDeployment.ts +++ b/packages/api/src/services/lightsailDeployment.ts @@ -5,7 +5,7 @@ export type LightsailNodeDeployment = {status: 'deployed'; files: number; port: export async function deployLightsailStaticFiles(instanceName: string, form: FormData): Promise { const endpoint = process.env.FLOCI_ENDPOINT - if (!endpoint) throw new RuntimeUnavailableError('Floci diagnostics are unavailable') + if (!endpoint) throw new RuntimeUnavailableError('TheCloud diagnostics are unavailable') let response: Response try { @@ -13,19 +13,19 @@ export async function deployLightsailStaticFiles(instanceName: string, form: For method: 'POST', body: form, redirect: 'error', signal: AbortSignal.timeout(30_000), }) } catch (error) { - throw new RuntimeUnavailableError('Floci diagnostics are unavailable', {cause: error}) + throw new RuntimeUnavailableError('TheCloud diagnostics are unavailable', {cause: error}) } const body = await response.json().catch(() => ({})) as {message?: unknown; files?: unknown; status?: unknown} if (!response.ok) throw httpStatusToCloudError(response.status, typeof body.message === 'string' ? body.message : 'Static file deployment failed') if (body.status !== 'deployed' || typeof body.files !== 'number') { - throw new RuntimeUnavailableError('Floci diagnostics returned an invalid deployment response') + throw new RuntimeUnavailableError('TheCloud diagnostics returned an invalid deployment response') } return {status: 'deployed', files: body.files} } export async function deployLightsailNodeApplication(instanceName: string, form: FormData): Promise { const endpoint = process.env.FLOCI_ENDPOINT - if (!endpoint) throw new RuntimeUnavailableError('Floci diagnostics are unavailable') + if (!endpoint) throw new RuntimeUnavailableError('TheCloud diagnostics are unavailable') let response: Response try { @@ -33,12 +33,12 @@ export async function deployLightsailNodeApplication(instanceName: string, form: method: 'POST', body: form, redirect: 'error', signal: AbortSignal.timeout(360_000), }) } catch (error) { - throw new RuntimeUnavailableError('Floci diagnostics are unavailable', {cause: error}) + throw new RuntimeUnavailableError('TheCloud diagnostics are unavailable', {cause: error}) } const body = await response.json().catch(() => ({})) as {message?: unknown; files?: unknown; status?: unknown; port?: unknown; releaseId?: unknown} if (!response.ok) throw httpStatusToCloudError(response.status, typeof body.message === 'string' ? body.message : 'Node.js deployment failed') if (body.status !== 'deployed' || typeof body.files !== 'number' || typeof body.port !== 'number' || typeof body.releaseId !== 'string') { - throw new RuntimeUnavailableError('Floci diagnostics returned an invalid Node.js deployment response') + throw new RuntimeUnavailableError('TheCloud diagnostics returned an invalid Node.js deployment response') } return {status: 'deployed', files: body.files, port: body.port, releaseId: body.releaseId} } diff --git a/packages/api/src/services/sshCheck.ts b/packages/api/src/services/sshCheck.ts index ff18b18..626b19c 100644 --- a/packages/api/src/services/sshCheck.ts +++ b/packages/api/src/services/sshCheck.ts @@ -59,23 +59,23 @@ type SshCheckDependencies = { async function fetchDiagnostics(): Promise { const endpoint = process.env.FLOCI_ENDPOINT if (!endpoint) { - throw new SshCheckError('DIAGNOSTICS_UNAVAILABLE', 'Floci diagnostics are unavailable', 503) + throw new SshCheckError('DIAGNOSTICS_UNAVAILABLE', 'TheCloud diagnostics are unavailable', 503) } let response: Response try { response = await fetch(`${endpoint}/_floci/diagnose`, {signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS)}) } catch { - throw new SshCheckError('DIAGNOSTICS_UNAVAILABLE', 'Floci diagnostics are unavailable', 503) + throw new SshCheckError('DIAGNOSTICS_UNAVAILABLE', 'TheCloud diagnostics are unavailable', 503) } if (!response.ok) { - throw new SshCheckError('DIAGNOSTICS_UNAVAILABLE', 'Floci diagnostics are unavailable', 503) + throw new SshCheckError('DIAGNOSTICS_UNAVAILABLE', 'TheCloud diagnostics are unavailable', 503) } try { return await response.json() as DiagnosticResponse } catch { - throw new SshCheckError('DIAGNOSTICS_UNAVAILABLE', 'Floci diagnostics returned an invalid response', 502) + throw new SshCheckError('DIAGNOSTICS_UNAVAILABLE', 'TheCloud diagnostics returned an invalid response', 502) } } @@ -149,12 +149,12 @@ export function createSshCheckService(dependencies: SshCheckDependencies = {}) { diagnostics = await diagnosticFetcher() } catch (error) { if (error instanceof SshCheckError) throw error - throw new SshCheckError('DIAGNOSTICS_UNAVAILABLE', 'Floci diagnostics are unavailable', 503) + throw new SshCheckError('DIAGNOSTICS_UNAVAILABLE', 'TheCloud diagnostics are unavailable', 503) } if (!diagnostics || typeof diagnostics !== 'object' || !Array.isArray(diagnostics.ec2?.instances)) { - throw new SshCheckError('DIAGNOSTICS_UNAVAILABLE', 'Floci diagnostics returned an invalid response', 502) + throw new SshCheckError('DIAGNOSTICS_UNAVAILABLE', 'TheCloud diagnostics returned an invalid response', 502) } const instance = diagnostics.ec2.instances.find((candidate) => candidate.instanceId === instanceId) if (!instance) { diff --git a/packages/frontend/src/components/AzureSqlPanel.tsx b/packages/frontend/src/components/AzureSqlPanel.tsx index f2048f3..5d12d7f 100644 --- a/packages/frontend/src/components/AzureSqlPanel.tsx +++ b/packages/frontend/src/components/AzureSqlPanel.tsx @@ -234,7 +234,7 @@ export function AzureSqlPanel({ )} {isAwsRds - ? "Queries use Floci's local RDS Data API credentials. Database passwords are not sent by the console." + ? "Queries use TheCloud's local RDS Data API credentials. Database passwords are not sent by the console." : "Credentials remain in this page only and are sent to the local API per request."} {connectionError &&
{connectionError}
} @@ -243,7 +243,7 @@ export function AzureSqlPanel({ {!connected ? (

Connect to browse SQL data

-

{isAwsRds ? "Connect through Floci's local RDS Data API to browse databases and run SQL." : "Use the administrator login configured for this local engine."}

+

{isAwsRds ? "Connect through TheCloud's local RDS Data API to browse databases and run SQL." : "Use the administrator login configured for this local engine."}

) : (
diff --git a/packages/frontend/src/components/DatabaseSnapshotsPanel.tsx b/packages/frontend/src/components/DatabaseSnapshotsPanel.tsx index 6d71816..93f874b 100644 --- a/packages/frontend/src/components/DatabaseSnapshotsPanel.tsx +++ b/packages/frontend/src/components/DatabaseSnapshotsPanel.tsx @@ -77,7 +77,7 @@ export function DatabaseSnapshotsPanel({ "code" in error.body && (error.body as { code?: unknown }).code === "operation_not_implemented" ) { - return "Snapshot creation is available in Floci UI, but the selected Floci runtime does not implement CreateDBSnapshot."; + return "Snapshot creation is available in TheCloud, but the selected runtime does not implement CreateDBSnapshot."; } if (error instanceof Error) { return error.message; diff --git a/packages/frontend/src/components/Layout.tsx b/packages/frontend/src/components/Layout.tsx index daa57e8..871b1a8 100644 --- a/packages/frontend/src/components/Layout.tsx +++ b/packages/frontend/src/components/Layout.tsx @@ -190,7 +190,7 @@ export function Layout() {
- Floci DevTools · Local + TheCloud · Local
diff --git a/packages/frontend/src/components/LogsQueryPanel.tsx b/packages/frontend/src/components/LogsQueryPanel.tsx index 1863919..8c3b1cc 100644 --- a/packages/frontend/src/components/LogsQueryPanel.tsx +++ b/packages/frontend/src/components/LogsQueryPanel.tsx @@ -190,7 +190,7 @@ function LogsQueryResults({result, expanded}: {result?: LogsInsightsQueryResult; {stillRunning && (
- Floci hadn't finished this query when the console stopped waiting — these rows are a partial, + The runtime hadn't finished this query when the console stopped waiting — these rows are a partial, in-progress result, not the full answer. Run the query again to see if it has finished (query id: {result.queryId}).
diff --git a/packages/frontend/src/components/SesConsolePanel.tsx b/packages/frontend/src/components/SesConsolePanel.tsx index 808d52e..8d5f39c 100644 --- a/packages/frontend/src/components/SesConsolePanel.tsx +++ b/packages/frontend/src/components/SesConsolePanel.tsx @@ -13,12 +13,12 @@ export function SesConsolePanel({runtimeReachable}: {runtimeReachable: boolean}) const [from, setFrom] = useState('') const [to, setTo] = useState(SIMULATORS[0]) const [subject, setSubject] = useState('Local SES test') - const [text, setText] = useState('Sent from the Floci SES console.') + const [text, setText] = useState('Sent from TheCloud\'s SES console.') const [html, setHtml] = useState('') const [raw, setRaw] = useState('From: sender@example.test\r\nTo: success@simulator.amazonses.com\r\nSubject: Raw SES test\r\nMIME-Version: 1.0\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\nHello from a raw MIME message.') const [configurationSet, setConfigurationSet] = useState('') const [templateName, setTemplateName] = useState('') - const [templateData, setTemplateData] = useState('{"name":"Floci"}') + const [templateData, setTemplateData] = useState('{"name":"TheCloud"}') const [editingTemplate, setEditingTemplate] = useState('') const [templateSubject, setTemplateSubject] = useState('Hello {{name}}') const [templateText, setTemplateText] = useState('Hello {{name}}') @@ -61,7 +61,7 @@ export function SesConsolePanel({runtimeReachable}: {runtimeReachable: boolean}) const pending = send.isPending || createIdentity.isPending || saveTemplate.isPending || addSuppression.isPending || createConfigurationSet.isPending || addDestination.isPending return
-

SES identities

Verify senders

Floci verifies identities immediately for AWS-compatible workflows. Local sending is not sandbox-gated.

{event.preventDefault(); if (identity.trim()) createIdentity.mutate()}}> setIdentity(event.target.value)} placeholder="sender@example.test or example.test" required/>
{identities.data?.map((item) =>
{item.IdentityName}{item.IdentityType} · {item.VerifiedForSendingStatus ? 'verified for sending' : 'not verified'}
)}
+

SES identities

Verify senders

TheCloud verifies identities immediately for AWS-compatible workflows. Local sending is not sandbox-gated.

{event.preventDefault(); if (identity.trim()) createIdentity.mutate()}}> setIdentity(event.target.value)} placeholder="sender@example.test or example.test" required/>
{identities.data?.map((item) =>
{item.IdentityName}{item.IdentityType} · {item.VerifiedForSendingStatus ? 'verified for sending' : 'not verified'}
)}

Compose

Send through SES

Simulator recipients produce documented delivery, bounce, and complaint events locally.

{SIMULATORS.map((address) => )}
{event.preventDefault(); send.mutate()}}>{mode === 'simple' && <>