Repository navigation
S3 Schemas
The @tundraconnect/s3/schemas subpath exports Guardian validators and
inferred types. Client methods validate every header-derived result or
parsed body before returning it.
import {
type ObjectMetadataSchema,
ObjectMetadataSchemaObject,
} from '@tundraconnect/s3/schemas';
const raw: unknown = {
contentType: 'text/plain',
contentLength: '1234',
etag: '"9a0364b9e99bb480dd25e1f0284c8555"',
};
const [error, meta] = ObjectMetadataSchemaObject.safeParse(raw);
if (error || !meta) throw error;
const typedMeta: ObjectMetadataSchema = meta;
console.log(typedMeta.contentLength); // 1234 (coerced from the header string)| Schema | Endpoint |
|---|---|
PutObjectResponseSchemaObject |
PUT /{bucket}/{key} |
DeleteObjectResponseSchemaObject |
DELETE /{bucket}/{key} |
ListObjectsResponseSchemaObject |
GET /{bucket}?list-type=2 |
S3ErrorEnvelopeSchemaObject |
Vendor <Error> XML envelopes |
InitiateMultipartUploadResultSchemaObject |
POST /{key}?uploads (putObjectStream) |
CompleteMultipartUploadResultSchemaObject |
POST /{key}?uploadId=… (putObjectStream) |
GetObjectStreamResult (from getObjectStream) is likewise a plain type:
ObjectMetadataSchema intersected with { body: ReadableStream<Uint8Array> }.
GetObjectResponseSchema and HeadObjectResponseSchema are plain
TypeScript types (not Guardian schema objects) — getObject's body is a
raw Blob, which Guardian has no binary validator for, so only the
header-derived metadata half is schema-validated at runtime; the body is
intersected onto that type.
| Schema | Purpose |
|---|---|
ObjectMetadataSchemaObject |
Header-derived metadata shared by getObject/headObject (contentType, contentLength, etag, lastModified, versionId, metadata) |
S3ObjectSchemaObject |
One <Contents> entry within a ListObjectsV2 result |
bucketGuard, keyGuard, etagGuard, and metadataGuard are reusable
component validators for bucket names, object keys, ETags, and
x-amz-meta-*-derived metadata maps.
RESTler's bundled XML parser (verified empirically, not assumed from the
XML spec) produces two shapes that need normalizing before validation,
handled via Guardian.preprocess:
- A single
<Contents>element parses to a bare object, not a one-element array — only two or more produce an array. Normalized to always be an array (possibly empty). - An empty element (e.g.
<Prefix></Prefix>) parses tonull, not''. Normalized toundefined.
- Algolia
- AzureBlob
- CloudflareDNS
- CloudflareEmail
- CloudflareSaaS
- CloudflareTurnstile
- CoinGecko
- Discord
- DodoPayments
- GCS
- GoogleAnalytics
- GoogleCertificateManager
- GoogleWebRisk
- Kalshi
- ntfy
- OpenExchange
- OpenWeatherMap
- PayPal
- Polymarket
- Razorpay
- Resend
- S3
- SendGrid
- Sentry
- Slack
- Stripe
- Telegram
- Twilio
- UpstashRedis
- URLhaus