@xyo-network/dapp-kit-cloudflare-r2 1.0.1 → 1.0.3
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/dist/node/cloudflareR2ResourcePlan.d.ts +9 -4
- package/dist/node/cloudflareR2ResourcePlan.d.ts.map +1 -1
- package/dist/node/index.mjs +4 -2
- package/dist/node/index.mjs.map +3 -3
- package/dist/node/qualifyCloudflareR2.d.ts +6 -3
- package/dist/node/qualifyCloudflareR2.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { type Schema } from '@xyo-network/sdk';
|
|
2
1
|
import { z } from 'zod';
|
|
3
2
|
export declare const CloudflareR2AdapterId: "network.xyo.dapp.adapter.cloudflare-r2-s3";
|
|
4
3
|
export declare const CloudflareR2AdapterVersion: "0.1.8";
|
|
5
|
-
export declare const CloudflareR2ResourcePlanSchema:
|
|
4
|
+
export declare const CloudflareR2ResourcePlanSchema: "network.xyo.dapp.cloudflare.r2.resource.plan" & {
|
|
5
|
+
readonly __schema: true;
|
|
6
|
+
};
|
|
6
7
|
export declare const CloudflareR2ResourcePlanHashAlgorithm: "jcs-sha256-v1";
|
|
7
8
|
export declare const CloudflareR2ResourcePlanDomainSeparator: "xyo-dapp-kit-cloudflare-r2:resource-plan:v1\n";
|
|
8
9
|
export declare const CloudflareR2ResourceClassZod: z.ZodEnum<{
|
|
@@ -32,7 +33,9 @@ export declare const CloudflareR2ResourceAccessZod: z.ZodDiscriminatedUnion<[z.Z
|
|
|
32
33
|
}, z.core.$strict>], "mode">;
|
|
33
34
|
export type CloudflareR2ResourceAccess = z.infer<typeof CloudflareR2ResourceAccessZod>;
|
|
34
35
|
export declare const CloudflareR2ResourcePlanPreimageZod: z.ZodObject<{
|
|
35
|
-
schema: z.ZodLiteral<
|
|
36
|
+
schema: z.ZodLiteral<"network.xyo.dapp.cloudflare.r2.resource.plan" & {
|
|
37
|
+
readonly __schema: true;
|
|
38
|
+
}>;
|
|
36
39
|
schemaVersion: z.ZodLiteral<1>;
|
|
37
40
|
hashAlgorithm: z.ZodLiteral<"jcs-sha256-v1">;
|
|
38
41
|
adapter: z.ZodObject<{
|
|
@@ -80,7 +83,9 @@ export declare const CloudflareR2ResourcePlanPreimageZod: z.ZodObject<{
|
|
|
80
83
|
}, z.core.$strict>;
|
|
81
84
|
export type CloudflareR2ResourcePlanPreimage = z.infer<typeof CloudflareR2ResourcePlanPreimageZod>;
|
|
82
85
|
export declare const CloudflareR2ResourcePlanZod: z.ZodObject<{
|
|
83
|
-
schema: z.ZodLiteral<
|
|
86
|
+
schema: z.ZodLiteral<"network.xyo.dapp.cloudflare.r2.resource.plan" & {
|
|
87
|
+
readonly __schema: true;
|
|
88
|
+
}>;
|
|
84
89
|
schemaVersion: z.ZodLiteral<1>;
|
|
85
90
|
hashAlgorithm: z.ZodLiteral<"jcs-sha256-v1">;
|
|
86
91
|
adapter: z.ZodObject<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudflareR2ResourcePlan.d.ts","sourceRoot":"","sources":["../../src/cloudflareR2ResourcePlan.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cloudflareR2ResourcePlan.d.ts","sourceRoot":"","sources":["../../src/cloudflareR2ResourcePlan.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,eAAO,MAAM,qBAAqB,EAAG,2CAAoD,CAAA;AACzF,eAAO,MAAM,0BAA0B,EAAG,OAAgB,CAAA;AAC1D,eAAO,MAAM,8BAA8B;;CAAiE,CAAA;AAC5G,eAAO,MAAM,qCAAqC,iBAA4B,CAAA;AAC9E,eAAO,MAAM,uCAAuC,EAAG,+CAAwD,CAAA;AAE/G,eAAO,MAAM,4BAA4B;;;;EAIvC,CAAA;AACF,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AAEpF,eAAO,MAAM,6BAA6B;;;EAAwC,CAAA;AAClF,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAA;AAqBtF,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;4BAWxC,CAAA;AACF,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAA;AAItF,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAkE9C,CAAA;AAEF,MAAM,MAAM,gCAAgC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAA;AAElG,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAA8E,CAAA;AACtH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAkBlF,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAKnE;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,CAMvF;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,CAQvF"}
|
package/dist/node/index.mjs
CHANGED
|
@@ -77,10 +77,11 @@ import {
|
|
|
77
77
|
IdentifierZod,
|
|
78
78
|
SemanticVersionZod
|
|
79
79
|
} from "@xyo-network/dapp-kit";
|
|
80
|
+
import { asSchema } from "@xyo-network/sdk";
|
|
80
81
|
import { z } from "zod";
|
|
81
82
|
var CloudflareR2AdapterId = "network.xyo.dapp.adapter.cloudflare-r2-s3";
|
|
82
83
|
var CloudflareR2AdapterVersion = "0.1.8";
|
|
83
|
-
var CloudflareR2ResourcePlanSchema = "network.xyo.dapp.cloudflare
|
|
84
|
+
var CloudflareR2ResourcePlanSchema = asSchema("network.xyo.dapp.cloudflare.r2.resource.plan", true);
|
|
84
85
|
var CloudflareR2ResourcePlanHashAlgorithm = DappDocumentHashAlgorithm;
|
|
85
86
|
var CloudflareR2ResourcePlanDomainSeparator = "xyo-dapp-kit-cloudflare-r2:resource-plan:v1\n";
|
|
86
87
|
var CloudflareR2ResourceClassZod = z.enum([
|
|
@@ -230,8 +231,9 @@ import {
|
|
|
230
231
|
ObjectStorePreconditionCode,
|
|
231
232
|
ObjectStorePreconditionError
|
|
232
233
|
} from "@xyo-network/dapp-kit";
|
|
234
|
+
import { asSchema as asSchema2 } from "@xyo-network/sdk";
|
|
233
235
|
import { z as z2 } from "zod";
|
|
234
|
-
var CloudflareR2QualificationEvidenceSchema = "network.xyo.dapp.cloudflare
|
|
236
|
+
var CloudflareR2QualificationEvidenceSchema = asSchema2("network.xyo.dapp.cloudflare.r2.qualification", true);
|
|
235
237
|
var IsoDateTimeZod = z2.iso.datetime({ offset: true });
|
|
236
238
|
var CloudflareR2QualificationEvidenceZod = z2.strictObject({
|
|
237
239
|
schema: z2.literal(CloudflareR2QualificationEvidenceSchema),
|
package/dist/node/index.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/cloudflareR2ObjectStore.ts", "../../src/cloudflareR2ResourcePlan.ts", "../../src/qualifyCloudflareR2.ts"],
|
|
4
|
-
"sourcesContent": ["import { S3Client } from '@aws-sdk/client-s3'\nimport { normalizeObjectStoreKey } from '@xyo-network/dapp-kit'\nimport type { S3CommandClient } from '@xyo-network/dapp-kit-s3'\nimport {\n createS3SdkObjectStoreTransport,\n S3ObjectStore,\n} from '@xyo-network/dapp-kit-s3'\n\nexport type CloudflareR2Jurisdiction = 'default' | 'eu'\n\nexport interface CloudflareR2Credentials {\n readonly accessKeyId: string\n readonly secretAccessKey: string\n readonly sessionToken?: string\n}\n\nexport interface CloudflareR2ObjectStoreOptions {\n readonly accountId: string\n readonly bucket: string\n readonly client?: S3Client | S3CommandClient\n readonly credentials?: CloudflareR2Credentials\n readonly jurisdiction?: CloudflareR2Jurisdiction\n readonly maximumObjectBytes: number\n readonly prefix: string\n}\n\nconst AccountIdPattern = /^[0-9a-f]{32}$/u\n\nfunction accountId(value: string): string {\n if (!AccountIdPattern.test(value)) throw new TypeError('Cloudflare account ID must be 32 lowercase hexadecimal characters')\n return value\n}\n\nfunction secret(value: string, name: string): string {\n if (value.trim() === '') throw new TypeError(`${name} must be non-empty`)\n return value\n}\n\nexport function cloudflareR2S3Endpoint(\n accountIdValue: string,\n jurisdiction: CloudflareR2Jurisdiction = 'default',\n): string {\n const prefix = accountId(accountIdValue)\n return jurisdiction === 'eu'\n ? `https://${prefix}.eu.r2.cloudflarestorage.com`\n : `https://${prefix}.r2.cloudflarestorage.com`\n}\n\nfunction publicBaseUrl(value: string): URL {\n const url = new URL(value)\n if (url.protocol !== 'https:' || url.origin !== value) {\n throw new TypeError('Cloudflare R2 public base URL must be an HTTPS origin without credentials, query, or fragment')\n }\n return url\n}\n\nexport function cloudflareR2PublicObjectUrl(baseUrl: string, prefix: string, key: string): string {\n const base = publicBaseUrl(baseUrl)\n const pathname = [\n normalizeObjectStoreKey(prefix, true),\n normalizeObjectStoreKey(key),\n ].filter(value => value !== '').flatMap(value => value.split('/')).map(segment => encodeURIComponent(segment)).join('/')\n return new URL(pathname, `${base.toString().replace(/\\/+$/u, '')}/`).toString()\n}\n\n/**\n * Cloudflare R2 specialization of the portable S3 store. Production\n * construction requires explicit credentials; ambient AWS credential lookup\n * is intentionally unavailable.\n */\nexport class CloudflareR2ObjectStore extends S3ObjectStore {\n readonly credentialSource: 'explicit-credentials' | 'injected-client'\n readonly endpoint: string\n\n private readonly ownedClient?: S3Client\n\n constructor(options: CloudflareR2ObjectStoreOptions) {\n if ((options.client === undefined) === (options.credentials === undefined)) {\n throw new TypeError('provide exactly one of Cloudflare R2 credentials or an injected S3 client')\n }\n const endpoint = cloudflareR2S3Endpoint(options.accountId, options.jurisdiction)\n const credentials = options.credentials\n const ownedClient = credentials === undefined\n ? undefined\n : new S3Client({\n credentials: {\n accessKeyId: secret(credentials.accessKeyId, 'Cloudflare R2 access key ID'),\n secretAccessKey: secret(credentials.secretAccessKey, 'Cloudflare R2 secret access key'),\n ...(credentials.sessionToken !== undefined && { sessionToken: secret(credentials.sessionToken, 'Cloudflare R2 session token') }),\n },\n endpoint,\n region: 'auto',\n })\n const client = options.client ?? ownedClient\n if (client === undefined) throw new TypeError('Cloudflare R2 client construction failed')\n super({\n maximumObjectBytes: options.maximumObjectBytes,\n prefix: options.prefix,\n transport: createS3SdkObjectStoreTransport({ bucket: options.bucket, client }),\n })\n this.endpoint = endpoint\n this.credentialSource = credentials === undefined ? 'injected-client' : 'explicit-credentials'\n this.ownedClient = ownedClient\n }\n\n close(): void {\n this.ownedClient?.destroy()\n }\n}\n", "import { createHash } from 'node:crypto'\n\nimport {\n canonicalizeIJson,\n DappDocumentHashAlgorithm,\n HashZod,\n IdentifierZod,\n SemanticVersionZod,\n} from '@xyo-network/dapp-kit'\nimport { type Schema } from '@xyo-network/sdk'\nimport { z } from 'zod'\nexport const CloudflareR2AdapterId = 'network.xyo.dapp.adapter.cloudflare-r2-s3' as const\nexport const CloudflareR2AdapterVersion = '0.1.8' as const\nexport const CloudflareR2ResourcePlanSchema = 'network.xyo.dapp.cloudflare-r2.resource.plan' as Schema<'network.xyo.dapp.cloudflare-r2.resource.plan'>\nexport const CloudflareR2ResourcePlanHashAlgorithm = DappDocumentHashAlgorithm\nexport const CloudflareR2ResourcePlanDomainSeparator = 'xyo-dapp-kit-cloudflare-r2:resource-plan:v1\\n' as const\n\nexport const CloudflareR2ResourceClassZod = z.enum([\n 'datalake',\n 'projection-store',\n 'checkpoint-store',\n])\nexport type CloudflareR2ResourceClass = z.infer<typeof CloudflareR2ResourceClassZod>\n\nexport const CloudflareR2CredentialModeZod = z.enum(['static-s3', 'temporary-s3'])\nexport type CloudflareR2CredentialMode = z.infer<typeof CloudflareR2CredentialModeZod>\n\nconst OriginZod = z.string().refine((value) => {\n if (value === '*') return true\n try {\n const url = new URL(value)\n return url.origin === value && ['http:', 'https:'].includes(url.protocol)\n } catch {\n return false\n }\n}, 'CORS origin must be * or an HTTP(S) origin')\n\nconst HttpsOriginZod = z.string().refine((value) => {\n try {\n const url = new URL(value)\n return url.protocol === 'https:' && url.origin === value\n } catch {\n return false\n }\n}, 'public base URL must be an HTTPS origin')\n\nexport const CloudflareR2ResourceAccessZod = z.discriminatedUnion('mode', [\n z.strictObject({ mode: z.literal('private') }),\n z.strictObject({\n mode: z.literal('public-custom-domain'),\n baseUrl: HttpsOriginZod,\n cors: z.strictObject({\n allowedOrigins: z.array(OriginZod).min(1),\n allowedMethods: z.array(z.enum(['GET', 'HEAD'])).min(1),\n exposeEtag: z.literal(true),\n }),\n }),\n])\nexport type CloudflareR2ResourceAccess = z.infer<typeof CloudflareR2ResourceAccessZod>\n\nconst IsoDatePattern = /^\\d{4}-\\d{2}-\\d{2}$/u\n\nexport const CloudflareR2ResourcePlanPreimageZod = z.strictObject({\n schema: z.literal(CloudflareR2ResourcePlanSchema),\n schemaVersion: z.literal(1),\n hashAlgorithm: z.literal(CloudflareR2ResourcePlanHashAlgorithm),\n adapter: z.strictObject({\n adapterId: z.literal(CloudflareR2AdapterId),\n adapterVersion: z.literal(CloudflareR2AdapterVersion),\n family: z.literal('s3-compatible'),\n provider: z.literal('cloudflare-r2'),\n }),\n policy: z.strictObject({\n policyId: IdentifierZod,\n policyVersion: SemanticVersionZod,\n reviewedOn: z.string().regex(IsoDatePattern),\n validUntil: z.string().regex(IsoDatePattern),\n }),\n resourceId: IdentifierZod,\n resourceClass: CloudflareR2ResourceClassZod,\n access: CloudflareR2ResourceAccessZod,\n credentialMode: CloudflareR2CredentialModeZod,\n maximumObjectBytes: z.number().int().positive(),\n guarantees: z.strictObject({\n conditionalPut: z.literal(true),\n globalReadAfterWrite: z.literal(true),\n maximumWritesPerSecondPerKey: z.literal(1),\n }),\n}).superRefine((plan, context) => {\n if (plan.policy.reviewedOn > plan.policy.validUntil) {\n context.addIssue({\n code: 'custom',\n message: 'R2 resource policy validity cannot end before its review date',\n path: ['policy', 'validUntil'],\n })\n }\n if (plan.resourceClass === 'checkpoint-store' && plan.access.mode !== 'private') {\n context.addIssue({\n code: 'custom',\n message: 'R2 checkpoint storage must remain private',\n path: ['access'],\n })\n }\n if (plan.access.mode === 'public-custom-domain') {\n if (new Set(plan.access.cors.allowedOrigins).size !== plan.access.cors.allowedOrigins.length) {\n context.addIssue({\n code: 'custom',\n message: 'public R2 CORS origins must be unique',\n path: ['access', 'cors', 'allowedOrigins'],\n })\n }\n if (new Set(plan.access.cors.allowedMethods).size !== plan.access.cors.allowedMethods.length) {\n context.addIssue({\n code: 'custom',\n message: 'public R2 CORS methods must be unique',\n path: ['access', 'cors', 'allowedMethods'],\n })\n }\n for (const method of ['GET', 'HEAD'] as const) {\n if (!plan.access.cors.allowedMethods.includes(method)) {\n context.addIssue({\n code: 'custom',\n message: `public R2 access requires CORS ${method}`,\n path: ['access', 'cors', 'allowedMethods'],\n })\n }\n }\n }\n})\n\nexport type CloudflareR2ResourcePlanPreimage = z.infer<typeof CloudflareR2ResourcePlanPreimageZod>\n\nexport const CloudflareR2ResourcePlanZod = CloudflareR2ResourcePlanPreimageZod.safeExtend({ resourcePlanId: HashZod })\nexport type CloudflareR2ResourcePlan = z.infer<typeof CloudflareR2ResourcePlanZod>\n\nfunction normalized(value: unknown): CloudflareR2ResourcePlanPreimage {\n const preimage = CloudflareR2ResourcePlanPreimageZod.parse(value)\n if (preimage.access.mode === 'private') return preimage\n return CloudflareR2ResourcePlanPreimageZod.parse({\n ...preimage,\n access: {\n ...preimage.access,\n cors: {\n ...preimage.access.cors,\n allowedMethods: [...preimage.access.cors.allowedMethods].sort(),\n allowedOrigins: [...preimage.access.cors.allowedOrigins].sort(),\n },\n },\n })\n}\n\nexport function hashCloudflareR2ResourcePlan(value: unknown): string {\n const preimage = normalized(value)\n return createHash('sha256')\n .update(`${CloudflareR2ResourcePlanDomainSeparator}${canonicalizeIJson(preimage)}`, 'utf8')\n .digest('hex')\n}\n\nexport function createCloudflareR2ResourcePlan(value: unknown): CloudflareR2ResourcePlan {\n const preimage = normalized(value)\n return CloudflareR2ResourcePlanZod.parse({\n ...preimage,\n resourcePlanId: hashCloudflareR2ResourcePlan(preimage),\n })\n}\n\nexport function verifyCloudflareR2ResourcePlan(value: unknown): CloudflareR2ResourcePlan {\n const plan = CloudflareR2ResourcePlanZod.parse(value)\n const { resourcePlanId, ...unresolvedPreimage } = plan\n const preimage = normalized(unresolvedPreimage)\n if (hashCloudflareR2ResourcePlan(preimage) !== resourcePlanId) {\n throw new TypeError('Cloudflare R2 resource plan ID does not match its canonical preimage')\n }\n return CloudflareR2ResourcePlanZod.parse({ ...preimage, resourcePlanId })\n}\n", "import type { ObjectStoreWriter } from '@xyo-network/dapp-kit'\nimport {\n IdentifierZod,\n normalizeObjectStoreKey,\n ObjectStorePreconditionCode,\n ObjectStorePreconditionError,\n} from '@xyo-network/dapp-kit'\nimport { type Schema } from '@xyo-network/sdk'\nimport { z } from 'zod'\n\nimport {\n CloudflareR2ObjectStore,\n cloudflareR2PublicObjectUrl,\n} from './cloudflareR2ObjectStore.ts'\nimport type { CloudflareR2ResourcePlan } from './cloudflareR2ResourcePlan.ts'\nimport {\n CloudflareR2AdapterId,\n CloudflareR2AdapterVersion,\n verifyCloudflareR2ResourcePlan,\n} from './cloudflareR2ResourcePlan.ts'\nexport const CloudflareR2QualificationEvidenceSchema = 'network.xyo.dapp.cloudflare-r2.qualification' as Schema<'network.xyo.dapp.cloudflare-r2.qualification'>\n\nconst IsoDateTimeZod = z.iso.datetime({ offset: true })\n\nexport const CloudflareR2QualificationEvidenceZod = z.strictObject({\n schema: z.literal(CloudflareR2QualificationEvidenceSchema),\n schemaVersion: z.literal(1),\n adapterId: z.literal(CloudflareR2AdapterId),\n adapterVersion: z.literal(CloudflareR2AdapterVersion),\n evidenceClass: z.literal('credentialed-cloudflare-r2'),\n observedAt: IsoDateTimeZod,\n probeId: IdentifierZod,\n resourcePlanId: z.string().regex(/^[0-9a-f]{64}$/u),\n capabilities: z.strictObject({\n conditionalCreate: z.literal(true),\n conditionalReplace: z.literal(true),\n deleteVisibility: z.literal(true),\n listVisibility: z.literal(true),\n readAfterWrite: z.literal(true),\n }),\n})\n\nexport type CloudflareR2QualificationEvidence = z.infer<typeof CloudflareR2QualificationEvidenceZod>\n\nexport interface QualifyCloudflareR2Options {\n readonly observedAt: string\n readonly plan: CloudflareR2ResourcePlan\n readonly probeId: string\n readonly store: CloudflareR2ObjectStore\n}\n\nexport interface ProbeCloudflareR2Options {\n readonly probeId: string\n readonly store: ObjectStoreWriter\n}\n\nexport interface CloudflareR2CapabilityProbeResult {\n readonly conditionalCreate: true\n readonly conditionalReplace: true\n readonly deleteVisibility: true\n readonly listVisibility: true\n readonly readAfterWrite: true\n}\n\nfunction equalBytes(left: Uint8Array | undefined, right: Uint8Array): boolean {\n return left?.byteLength === right.byteLength\n && left.every((value, index) => value === right[index])\n}\n\nfunction expectedPrecondition(error: unknown, code: string): boolean {\n return error instanceof ObjectStorePreconditionError && error.code === code\n}\n\n/** Exercises the destructive, prefix-confined capability matrix without assigning an evidence class. */\nexport async function probeCloudflareR2Capabilities(\n options: ProbeCloudflareR2Options,\n): Promise<CloudflareR2CapabilityProbeResult> {\n const probeId = IdentifierZod.parse(options.probeId)\n const key = normalizeObjectStoreKey(`qualification/${probeId}/cas.json`)\n const firstBody = new TextEncoder().encode('{\"revision\":1}')\n const secondBody = new TextEncoder().encode('{\"revision\":2}')\n try {\n const first = await options.store.put(key, firstBody, {\n contentType: 'application/json',\n ifNotExists: true,\n })\n if (first.etag === undefined) throw new Error('Cloudflare R2 qualification requires an ETag')\n if (!equalBytes(await options.store.get(key), firstBody)) throw new Error('Cloudflare R2 failed read-after-write')\n try {\n await options.store.put(key, firstBody, { ifNotExists: true })\n throw new Error('Cloudflare R2 admitted a duplicate conditional create')\n } catch (error) {\n if (!expectedPrecondition(error, ObjectStorePreconditionCode.ifNotExistsFailed)) throw error\n }\n const second = await options.store.put(key, secondBody, { ifMatch: first.etag })\n if (second.etag === undefined) throw new Error('Cloudflare R2 conditional replace returned no ETag')\n try {\n await options.store.put(key, firstBody, { ifMatch: first.etag })\n throw new Error('Cloudflare R2 admitted a stale conditional replace')\n } catch (error) {\n if (!expectedPrecondition(error, ObjectStorePreconditionCode.ifMatchFailed)) throw error\n }\n if (!(await options.store.list('qualification')).includes(key)) throw new Error('Cloudflare R2 listing omitted the probe')\n await options.store.delete(key)\n if (await options.store.get(key) !== undefined) throw new Error('Cloudflare R2 delete was not immediately visible')\n return {\n conditionalCreate: true,\n conditionalReplace: true,\n deleteVisibility: true,\n listVisibility: true,\n readAfterWrite: true,\n }\n } finally {\n await options.store.delete(key)\n }\n}\n\n/** Runs the destructive credentialed gate against an explicitly credentialed R2 instance. */\nexport async function qualifyCloudflareR2(options: QualifyCloudflareR2Options): Promise<CloudflareR2QualificationEvidence> {\n if (!(options.store instanceof CloudflareR2ObjectStore)\n || options.store.credentialSource !== 'explicit-credentials') {\n throw new TypeError('credentialed Cloudflare R2 qualification requires an explicitly credentialed R2 object store')\n }\n const plan = verifyCloudflareR2ResourcePlan(options.plan)\n const observedAt = IsoDateTimeZod.parse(options.observedAt)\n const observedOn = observedAt.slice(0, 10)\n if (observedOn < plan.policy.reviewedOn || observedOn > plan.policy.validUntil) {\n throw new TypeError('Cloudflare R2 resource policy is not valid at the qualification time')\n }\n const capabilities = await probeCloudflareR2Capabilities({\n probeId: options.probeId,\n store: options.store,\n })\n return CloudflareR2QualificationEvidenceZod.parse({\n schema: CloudflareR2QualificationEvidenceSchema,\n schemaVersion: 1,\n adapterId: CloudflareR2AdapterId,\n adapterVersion: CloudflareR2AdapterVersion,\n evidenceClass: 'credentialed-cloudflare-r2',\n observedAt,\n probeId: options.probeId,\n resourcePlanId: plan.resourcePlanId,\n capabilities,\n })\n}\n\nexport interface AuditCloudflareR2PublicReadOptions {\n readonly fetchImpl?: typeof fetch\n readonly key: string\n readonly origin: string\n readonly plan: CloudflareR2ResourcePlan\n}\n\nexport interface CloudflareR2PublicReadAudit {\n readonly issues: readonly string[]\n readonly success: boolean\n readonly url: string\n}\n\n/** Read-only hosted audit for the public custom-domain and browser CORS boundary. */\nexport async function auditCloudflareR2PublicRead(\n options: AuditCloudflareR2PublicReadOptions,\n): Promise<CloudflareR2PublicReadAudit> {\n const plan = verifyCloudflareR2ResourcePlan(options.plan)\n if (plan.access.mode !== 'public-custom-domain') throw new TypeError('R2 public-read audit requires a public resource plan')\n const url = cloudflareR2PublicObjectUrl(plan.access.baseUrl, '', options.key)\n const plannedOrigins = plan.access.cors.allowedOrigins\n const issues: string[] = []\n if (!plannedOrigins.includes('*') && !plannedOrigins.includes(options.origin)) {\n issues.push('requesting origin is not admitted by the R2 resource plan')\n }\n const response = await (options.fetchImpl ?? fetch)(url, {\n headers: { Origin: options.origin },\n method: 'HEAD',\n })\n if (!response.ok) issues.push(`public object returned HTTP ${response.status}`)\n const allowedOrigin = response.headers.get('access-control-allow-origin')\n if (allowedOrigin !== '*' && allowedOrigin !== options.origin) issues.push('public object did not admit the requesting origin')\n const exposed = (response.headers.get('access-control-expose-headers') ?? '')\n .split(',').map(value => value.trim().toLowerCase())\n if (!exposed.includes('etag')) issues.push('public object did not expose ETag through CORS')\n if (response.headers.get('etag') === null) issues.push('public object returned no ETag')\n return {\n issues, success: issues.length === 0, url,\n }\n}\n"],
|
|
5
|
-
"mappings": ";AAAA,SAAS,gBAAgB;AACzB,SAAS,+BAA+B;AAExC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAoBP,IAAM,mBAAmB;AAEzB,SAAS,UAAU,OAAuB;AACxC,MAAI,CAAC,iBAAiB,KAAK,KAAK,EAAG,OAAM,IAAI,UAAU,mEAAmE;AAC1H,SAAO;AACT;AAEA,SAAS,OAAO,OAAe,MAAsB;AACnD,MAAI,MAAM,KAAK,MAAM,GAAI,OAAM,IAAI,UAAU,GAAG,IAAI,oBAAoB;AACxE,SAAO;AACT;AAEO,SAAS,uBACd,gBACA,eAAyC,WACjC;AACR,QAAM,SAAS,UAAU,cAAc;AACvC,SAAO,iBAAiB,OACpB,WAAW,MAAM,iCACjB,WAAW,MAAM;AACvB;AAEA,SAAS,cAAc,OAAoB;AACzC,QAAM,MAAM,IAAI,IAAI,KAAK;AACzB,MAAI,IAAI,aAAa,YAAY,IAAI,WAAW,OAAO;AACrD,UAAM,IAAI,UAAU,+FAA+F;AAAA,EACrH;AACA,SAAO;AACT;AAEO,SAAS,4BAA4B,SAAiB,QAAgB,KAAqB;AAChG,QAAM,OAAO,cAAc,OAAO;AAClC,QAAM,WAAW;AAAA,IACf,wBAAwB,QAAQ,IAAI;AAAA,IACpC,wBAAwB,GAAG;AAAA,EAC7B,EAAE,OAAO,WAAS,UAAU,EAAE,EAAE,QAAQ,WAAS,MAAM,MAAM,GAAG,CAAC,EAAE,IAAI,aAAW,mBAAmB,OAAO,CAAC,EAAE,KAAK,GAAG;AACvH,SAAO,IAAI,IAAI,UAAU,GAAG,KAAK,SAAS,EAAE,QAAQ,SAAS,EAAE,CAAC,GAAG,EAAE,SAAS;AAChF;AAOO,IAAM,0BAAN,cAAsC,cAAc;AAAA,EAChD;AAAA,EACA;AAAA,EAEQ;AAAA,EAEjB,YAAY,SAAyC;AACnD,QAAK,QAAQ,WAAW,YAAgB,QAAQ,gBAAgB,SAAY;AAC1E,YAAM,IAAI,UAAU,2EAA2E;AAAA,IACjG;AACA,UAAM,WAAW,uBAAuB,QAAQ,WAAW,QAAQ,YAAY;AAC/E,UAAM,cAAc,QAAQ;AAC5B,UAAM,cAAc,gBAAgB,SAChC,SACA,IAAI,SAAS;AAAA,MACX,aAAa;AAAA,QACX,aAAa,OAAO,YAAY,aAAa,6BAA6B;AAAA,QAC1E,iBAAiB,OAAO,YAAY,iBAAiB,iCAAiC;AAAA,QACtF,GAAI,YAAY,iBAAiB,UAAa,EAAE,cAAc,OAAO,YAAY,cAAc,6BAA6B,EAAE;AAAA,MAChI;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AACL,UAAM,SAAS,QAAQ,UAAU;AACjC,QAAI,WAAW,OAAW,OAAM,IAAI,UAAU,0CAA0C;AACxF,UAAM;AAAA,MACJ,oBAAoB,QAAQ;AAAA,MAC5B,QAAQ,QAAQ;AAAA,MAChB,WAAW,gCAAgC,EAAE,QAAQ,QAAQ,QAAQ,OAAO,CAAC;AAAA,IAC/E,CAAC;AACD,SAAK,WAAW;AAChB,SAAK,mBAAmB,gBAAgB,SAAY,oBAAoB;AACxE,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,QAAc;AACZ,SAAK,aAAa,QAAQ;AAAA,EAC5B;AACF;;;AC5GA,SAAS,kBAAkB;AAE3B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;
|
|
6
|
-
"names": ["IdentifierZod", "normalizeObjectStoreKey", "z", "z", "IdentifierZod", "normalizeObjectStoreKey"]
|
|
4
|
+
"sourcesContent": ["import { S3Client } from '@aws-sdk/client-s3'\nimport { normalizeObjectStoreKey } from '@xyo-network/dapp-kit'\nimport type { S3CommandClient } from '@xyo-network/dapp-kit-s3'\nimport {\n createS3SdkObjectStoreTransport,\n S3ObjectStore,\n} from '@xyo-network/dapp-kit-s3'\n\nexport type CloudflareR2Jurisdiction = 'default' | 'eu'\n\nexport interface CloudflareR2Credentials {\n readonly accessKeyId: string\n readonly secretAccessKey: string\n readonly sessionToken?: string\n}\n\nexport interface CloudflareR2ObjectStoreOptions {\n readonly accountId: string\n readonly bucket: string\n readonly client?: S3Client | S3CommandClient\n readonly credentials?: CloudflareR2Credentials\n readonly jurisdiction?: CloudflareR2Jurisdiction\n readonly maximumObjectBytes: number\n readonly prefix: string\n}\n\nconst AccountIdPattern = /^[0-9a-f]{32}$/u\n\nfunction accountId(value: string): string {\n if (!AccountIdPattern.test(value)) throw new TypeError('Cloudflare account ID must be 32 lowercase hexadecimal characters')\n return value\n}\n\nfunction secret(value: string, name: string): string {\n if (value.trim() === '') throw new TypeError(`${name} must be non-empty`)\n return value\n}\n\nexport function cloudflareR2S3Endpoint(\n accountIdValue: string,\n jurisdiction: CloudflareR2Jurisdiction = 'default',\n): string {\n const prefix = accountId(accountIdValue)\n return jurisdiction === 'eu'\n ? `https://${prefix}.eu.r2.cloudflarestorage.com`\n : `https://${prefix}.r2.cloudflarestorage.com`\n}\n\nfunction publicBaseUrl(value: string): URL {\n const url = new URL(value)\n if (url.protocol !== 'https:' || url.origin !== value) {\n throw new TypeError('Cloudflare R2 public base URL must be an HTTPS origin without credentials, query, or fragment')\n }\n return url\n}\n\nexport function cloudflareR2PublicObjectUrl(baseUrl: string, prefix: string, key: string): string {\n const base = publicBaseUrl(baseUrl)\n const pathname = [\n normalizeObjectStoreKey(prefix, true),\n normalizeObjectStoreKey(key),\n ].filter(value => value !== '').flatMap(value => value.split('/')).map(segment => encodeURIComponent(segment)).join('/')\n return new URL(pathname, `${base.toString().replace(/\\/+$/u, '')}/`).toString()\n}\n\n/**\n * Cloudflare R2 specialization of the portable S3 store. Production\n * construction requires explicit credentials; ambient AWS credential lookup\n * is intentionally unavailable.\n */\nexport class CloudflareR2ObjectStore extends S3ObjectStore {\n readonly credentialSource: 'explicit-credentials' | 'injected-client'\n readonly endpoint: string\n\n private readonly ownedClient?: S3Client\n\n constructor(options: CloudflareR2ObjectStoreOptions) {\n if ((options.client === undefined) === (options.credentials === undefined)) {\n throw new TypeError('provide exactly one of Cloudflare R2 credentials or an injected S3 client')\n }\n const endpoint = cloudflareR2S3Endpoint(options.accountId, options.jurisdiction)\n const credentials = options.credentials\n const ownedClient = credentials === undefined\n ? undefined\n : new S3Client({\n credentials: {\n accessKeyId: secret(credentials.accessKeyId, 'Cloudflare R2 access key ID'),\n secretAccessKey: secret(credentials.secretAccessKey, 'Cloudflare R2 secret access key'),\n ...(credentials.sessionToken !== undefined && { sessionToken: secret(credentials.sessionToken, 'Cloudflare R2 session token') }),\n },\n endpoint,\n region: 'auto',\n })\n const client = options.client ?? ownedClient\n if (client === undefined) throw new TypeError('Cloudflare R2 client construction failed')\n super({\n maximumObjectBytes: options.maximumObjectBytes,\n prefix: options.prefix,\n transport: createS3SdkObjectStoreTransport({ bucket: options.bucket, client }),\n })\n this.endpoint = endpoint\n this.credentialSource = credentials === undefined ? 'injected-client' : 'explicit-credentials'\n this.ownedClient = ownedClient\n }\n\n close(): void {\n this.ownedClient?.destroy()\n }\n}\n", "import { createHash } from 'node:crypto'\n\nimport {\n canonicalizeIJson,\n DappDocumentHashAlgorithm,\n HashZod,\n IdentifierZod,\n SemanticVersionZod,\n} from '@xyo-network/dapp-kit'\nimport { asSchema } from '@xyo-network/sdk'\nimport { z } from 'zod'\nexport const CloudflareR2AdapterId = 'network.xyo.dapp.adapter.cloudflare-r2-s3' as const\nexport const CloudflareR2AdapterVersion = '0.1.8' as const\nexport const CloudflareR2ResourcePlanSchema = asSchema('network.xyo.dapp.cloudflare.r2.resource.plan', true)\nexport const CloudflareR2ResourcePlanHashAlgorithm = DappDocumentHashAlgorithm\nexport const CloudflareR2ResourcePlanDomainSeparator = 'xyo-dapp-kit-cloudflare-r2:resource-plan:v1\\n' as const\n\nexport const CloudflareR2ResourceClassZod = z.enum([\n 'datalake',\n 'projection-store',\n 'checkpoint-store',\n])\nexport type CloudflareR2ResourceClass = z.infer<typeof CloudflareR2ResourceClassZod>\n\nexport const CloudflareR2CredentialModeZod = z.enum(['static-s3', 'temporary-s3'])\nexport type CloudflareR2CredentialMode = z.infer<typeof CloudflareR2CredentialModeZod>\n\nconst OriginZod = z.string().refine((value) => {\n if (value === '*') return true\n try {\n const url = new URL(value)\n return url.origin === value && ['http:', 'https:'].includes(url.protocol)\n } catch {\n return false\n }\n}, 'CORS origin must be * or an HTTP(S) origin')\n\nconst HttpsOriginZod = z.string().refine((value) => {\n try {\n const url = new URL(value)\n return url.protocol === 'https:' && url.origin === value\n } catch {\n return false\n }\n}, 'public base URL must be an HTTPS origin')\n\nexport const CloudflareR2ResourceAccessZod = z.discriminatedUnion('mode', [\n z.strictObject({ mode: z.literal('private') }),\n z.strictObject({\n mode: z.literal('public-custom-domain'),\n baseUrl: HttpsOriginZod,\n cors: z.strictObject({\n allowedOrigins: z.array(OriginZod).min(1),\n allowedMethods: z.array(z.enum(['GET', 'HEAD'])).min(1),\n exposeEtag: z.literal(true),\n }),\n }),\n])\nexport type CloudflareR2ResourceAccess = z.infer<typeof CloudflareR2ResourceAccessZod>\n\nconst IsoDatePattern = /^\\d{4}-\\d{2}-\\d{2}$/u\n\nexport const CloudflareR2ResourcePlanPreimageZod = z.strictObject({\n schema: z.literal(CloudflareR2ResourcePlanSchema),\n schemaVersion: z.literal(1),\n hashAlgorithm: z.literal(CloudflareR2ResourcePlanHashAlgorithm),\n adapter: z.strictObject({\n adapterId: z.literal(CloudflareR2AdapterId),\n adapterVersion: z.literal(CloudflareR2AdapterVersion),\n family: z.literal('s3-compatible'),\n provider: z.literal('cloudflare-r2'),\n }),\n policy: z.strictObject({\n policyId: IdentifierZod,\n policyVersion: SemanticVersionZod,\n reviewedOn: z.string().regex(IsoDatePattern),\n validUntil: z.string().regex(IsoDatePattern),\n }),\n resourceId: IdentifierZod,\n resourceClass: CloudflareR2ResourceClassZod,\n access: CloudflareR2ResourceAccessZod,\n credentialMode: CloudflareR2CredentialModeZod,\n maximumObjectBytes: z.number().int().positive(),\n guarantees: z.strictObject({\n conditionalPut: z.literal(true),\n globalReadAfterWrite: z.literal(true),\n maximumWritesPerSecondPerKey: z.literal(1),\n }),\n}).superRefine((plan, context) => {\n if (plan.policy.reviewedOn > plan.policy.validUntil) {\n context.addIssue({\n code: 'custom',\n message: 'R2 resource policy validity cannot end before its review date',\n path: ['policy', 'validUntil'],\n })\n }\n if (plan.resourceClass === 'checkpoint-store' && plan.access.mode !== 'private') {\n context.addIssue({\n code: 'custom',\n message: 'R2 checkpoint storage must remain private',\n path: ['access'],\n })\n }\n if (plan.access.mode === 'public-custom-domain') {\n if (new Set(plan.access.cors.allowedOrigins).size !== plan.access.cors.allowedOrigins.length) {\n context.addIssue({\n code: 'custom',\n message: 'public R2 CORS origins must be unique',\n path: ['access', 'cors', 'allowedOrigins'],\n })\n }\n if (new Set(plan.access.cors.allowedMethods).size !== plan.access.cors.allowedMethods.length) {\n context.addIssue({\n code: 'custom',\n message: 'public R2 CORS methods must be unique',\n path: ['access', 'cors', 'allowedMethods'],\n })\n }\n for (const method of ['GET', 'HEAD'] as const) {\n if (!plan.access.cors.allowedMethods.includes(method)) {\n context.addIssue({\n code: 'custom',\n message: `public R2 access requires CORS ${method}`,\n path: ['access', 'cors', 'allowedMethods'],\n })\n }\n }\n }\n})\n\nexport type CloudflareR2ResourcePlanPreimage = z.infer<typeof CloudflareR2ResourcePlanPreimageZod>\n\nexport const CloudflareR2ResourcePlanZod = CloudflareR2ResourcePlanPreimageZod.safeExtend({ resourcePlanId: HashZod })\nexport type CloudflareR2ResourcePlan = z.infer<typeof CloudflareR2ResourcePlanZod>\n\nfunction normalized(value: unknown): CloudflareR2ResourcePlanPreimage {\n const preimage = CloudflareR2ResourcePlanPreimageZod.parse(value)\n if (preimage.access.mode === 'private') return preimage\n return CloudflareR2ResourcePlanPreimageZod.parse({\n ...preimage,\n access: {\n ...preimage.access,\n cors: {\n ...preimage.access.cors,\n allowedMethods: [...preimage.access.cors.allowedMethods].sort(),\n allowedOrigins: [...preimage.access.cors.allowedOrigins].sort(),\n },\n },\n })\n}\n\nexport function hashCloudflareR2ResourcePlan(value: unknown): string {\n const preimage = normalized(value)\n return createHash('sha256')\n .update(`${CloudflareR2ResourcePlanDomainSeparator}${canonicalizeIJson(preimage)}`, 'utf8')\n .digest('hex')\n}\n\nexport function createCloudflareR2ResourcePlan(value: unknown): CloudflareR2ResourcePlan {\n const preimage = normalized(value)\n return CloudflareR2ResourcePlanZod.parse({\n ...preimage,\n resourcePlanId: hashCloudflareR2ResourcePlan(preimage),\n })\n}\n\nexport function verifyCloudflareR2ResourcePlan(value: unknown): CloudflareR2ResourcePlan {\n const plan = CloudflareR2ResourcePlanZod.parse(value)\n const { resourcePlanId, ...unresolvedPreimage } = plan\n const preimage = normalized(unresolvedPreimage)\n if (hashCloudflareR2ResourcePlan(preimage) !== resourcePlanId) {\n throw new TypeError('Cloudflare R2 resource plan ID does not match its canonical preimage')\n }\n return CloudflareR2ResourcePlanZod.parse({ ...preimage, resourcePlanId })\n}\n", "import type { ObjectStoreWriter } from '@xyo-network/dapp-kit'\nimport {\n IdentifierZod,\n normalizeObjectStoreKey,\n ObjectStorePreconditionCode,\n ObjectStorePreconditionError,\n} from '@xyo-network/dapp-kit'\nimport { asSchema } from '@xyo-network/sdk'\nimport { z } from 'zod'\n\nimport {\n CloudflareR2ObjectStore,\n cloudflareR2PublicObjectUrl,\n} from './cloudflareR2ObjectStore.ts'\nimport type { CloudflareR2ResourcePlan } from './cloudflareR2ResourcePlan.ts'\nimport {\n CloudflareR2AdapterId,\n CloudflareR2AdapterVersion,\n verifyCloudflareR2ResourcePlan,\n} from './cloudflareR2ResourcePlan.ts'\nexport const CloudflareR2QualificationEvidenceSchema = asSchema('network.xyo.dapp.cloudflare.r2.qualification', true)\n\nconst IsoDateTimeZod = z.iso.datetime({ offset: true })\n\nexport const CloudflareR2QualificationEvidenceZod = z.strictObject({\n schema: z.literal(CloudflareR2QualificationEvidenceSchema),\n schemaVersion: z.literal(1),\n adapterId: z.literal(CloudflareR2AdapterId),\n adapterVersion: z.literal(CloudflareR2AdapterVersion),\n evidenceClass: z.literal('credentialed-cloudflare-r2'),\n observedAt: IsoDateTimeZod,\n probeId: IdentifierZod,\n resourcePlanId: z.string().regex(/^[0-9a-f]{64}$/u),\n capabilities: z.strictObject({\n conditionalCreate: z.literal(true),\n conditionalReplace: z.literal(true),\n deleteVisibility: z.literal(true),\n listVisibility: z.literal(true),\n readAfterWrite: z.literal(true),\n }),\n})\n\nexport type CloudflareR2QualificationEvidence = z.infer<typeof CloudflareR2QualificationEvidenceZod>\n\nexport interface QualifyCloudflareR2Options {\n readonly observedAt: string\n readonly plan: CloudflareR2ResourcePlan\n readonly probeId: string\n readonly store: CloudflareR2ObjectStore\n}\n\nexport interface ProbeCloudflareR2Options {\n readonly probeId: string\n readonly store: ObjectStoreWriter\n}\n\nexport interface CloudflareR2CapabilityProbeResult {\n readonly conditionalCreate: true\n readonly conditionalReplace: true\n readonly deleteVisibility: true\n readonly listVisibility: true\n readonly readAfterWrite: true\n}\n\nfunction equalBytes(left: Uint8Array | undefined, right: Uint8Array): boolean {\n return left?.byteLength === right.byteLength\n && left.every((value, index) => value === right[index])\n}\n\nfunction expectedPrecondition(error: unknown, code: string): boolean {\n return error instanceof ObjectStorePreconditionError && error.code === code\n}\n\n/** Exercises the destructive, prefix-confined capability matrix without assigning an evidence class. */\nexport async function probeCloudflareR2Capabilities(\n options: ProbeCloudflareR2Options,\n): Promise<CloudflareR2CapabilityProbeResult> {\n const probeId = IdentifierZod.parse(options.probeId)\n const key = normalizeObjectStoreKey(`qualification/${probeId}/cas.json`)\n const firstBody = new TextEncoder().encode('{\"revision\":1}')\n const secondBody = new TextEncoder().encode('{\"revision\":2}')\n try {\n const first = await options.store.put(key, firstBody, {\n contentType: 'application/json',\n ifNotExists: true,\n })\n if (first.etag === undefined) throw new Error('Cloudflare R2 qualification requires an ETag')\n if (!equalBytes(await options.store.get(key), firstBody)) throw new Error('Cloudflare R2 failed read-after-write')\n try {\n await options.store.put(key, firstBody, { ifNotExists: true })\n throw new Error('Cloudflare R2 admitted a duplicate conditional create')\n } catch (error) {\n if (!expectedPrecondition(error, ObjectStorePreconditionCode.ifNotExistsFailed)) throw error\n }\n const second = await options.store.put(key, secondBody, { ifMatch: first.etag })\n if (second.etag === undefined) throw new Error('Cloudflare R2 conditional replace returned no ETag')\n try {\n await options.store.put(key, firstBody, { ifMatch: first.etag })\n throw new Error('Cloudflare R2 admitted a stale conditional replace')\n } catch (error) {\n if (!expectedPrecondition(error, ObjectStorePreconditionCode.ifMatchFailed)) throw error\n }\n if (!(await options.store.list('qualification')).includes(key)) throw new Error('Cloudflare R2 listing omitted the probe')\n await options.store.delete(key)\n if (await options.store.get(key) !== undefined) throw new Error('Cloudflare R2 delete was not immediately visible')\n return {\n conditionalCreate: true,\n conditionalReplace: true,\n deleteVisibility: true,\n listVisibility: true,\n readAfterWrite: true,\n }\n } finally {\n await options.store.delete(key)\n }\n}\n\n/** Runs the destructive credentialed gate against an explicitly credentialed R2 instance. */\nexport async function qualifyCloudflareR2(options: QualifyCloudflareR2Options): Promise<CloudflareR2QualificationEvidence> {\n if (!(options.store instanceof CloudflareR2ObjectStore)\n || options.store.credentialSource !== 'explicit-credentials') {\n throw new TypeError('credentialed Cloudflare R2 qualification requires an explicitly credentialed R2 object store')\n }\n const plan = verifyCloudflareR2ResourcePlan(options.plan)\n const observedAt = IsoDateTimeZod.parse(options.observedAt)\n const observedOn = observedAt.slice(0, 10)\n if (observedOn < plan.policy.reviewedOn || observedOn > plan.policy.validUntil) {\n throw new TypeError('Cloudflare R2 resource policy is not valid at the qualification time')\n }\n const capabilities = await probeCloudflareR2Capabilities({\n probeId: options.probeId,\n store: options.store,\n })\n return CloudflareR2QualificationEvidenceZod.parse({\n schema: CloudflareR2QualificationEvidenceSchema,\n schemaVersion: 1,\n adapterId: CloudflareR2AdapterId,\n adapterVersion: CloudflareR2AdapterVersion,\n evidenceClass: 'credentialed-cloudflare-r2',\n observedAt,\n probeId: options.probeId,\n resourcePlanId: plan.resourcePlanId,\n capabilities,\n })\n}\n\nexport interface AuditCloudflareR2PublicReadOptions {\n readonly fetchImpl?: typeof fetch\n readonly key: string\n readonly origin: string\n readonly plan: CloudflareR2ResourcePlan\n}\n\nexport interface CloudflareR2PublicReadAudit {\n readonly issues: readonly string[]\n readonly success: boolean\n readonly url: string\n}\n\n/** Read-only hosted audit for the public custom-domain and browser CORS boundary. */\nexport async function auditCloudflareR2PublicRead(\n options: AuditCloudflareR2PublicReadOptions,\n): Promise<CloudflareR2PublicReadAudit> {\n const plan = verifyCloudflareR2ResourcePlan(options.plan)\n if (plan.access.mode !== 'public-custom-domain') throw new TypeError('R2 public-read audit requires a public resource plan')\n const url = cloudflareR2PublicObjectUrl(plan.access.baseUrl, '', options.key)\n const plannedOrigins = plan.access.cors.allowedOrigins\n const issues: string[] = []\n if (!plannedOrigins.includes('*') && !plannedOrigins.includes(options.origin)) {\n issues.push('requesting origin is not admitted by the R2 resource plan')\n }\n const response = await (options.fetchImpl ?? fetch)(url, {\n headers: { Origin: options.origin },\n method: 'HEAD',\n })\n if (!response.ok) issues.push(`public object returned HTTP ${response.status}`)\n const allowedOrigin = response.headers.get('access-control-allow-origin')\n if (allowedOrigin !== '*' && allowedOrigin !== options.origin) issues.push('public object did not admit the requesting origin')\n const exposed = (response.headers.get('access-control-expose-headers') ?? '')\n .split(',').map(value => value.trim().toLowerCase())\n if (!exposed.includes('etag')) issues.push('public object did not expose ETag through CORS')\n if (response.headers.get('etag') === null) issues.push('public object returned no ETag')\n return {\n issues, success: issues.length === 0, url,\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["IdentifierZod", "normalizeObjectStoreKey", "asSchema", "z", "asSchema", "z", "IdentifierZod", "normalizeObjectStoreKey"]
|
|
7
7
|
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { ObjectStoreWriter } from '@xyo-network/dapp-kit';
|
|
2
|
-
import { type Schema } from '@xyo-network/sdk';
|
|
3
2
|
import { z } from 'zod';
|
|
4
3
|
import { CloudflareR2ObjectStore } from './cloudflareR2ObjectStore.ts';
|
|
5
4
|
import type { CloudflareR2ResourcePlan } from './cloudflareR2ResourcePlan.ts';
|
|
6
|
-
export declare const CloudflareR2QualificationEvidenceSchema:
|
|
5
|
+
export declare const CloudflareR2QualificationEvidenceSchema: "network.xyo.dapp.cloudflare.r2.qualification" & {
|
|
6
|
+
readonly __schema: true;
|
|
7
|
+
};
|
|
7
8
|
export declare const CloudflareR2QualificationEvidenceZod: z.ZodObject<{
|
|
8
|
-
schema: z.ZodLiteral<
|
|
9
|
+
schema: z.ZodLiteral<"network.xyo.dapp.cloudflare.r2.qualification" & {
|
|
10
|
+
readonly __schema: true;
|
|
11
|
+
}>;
|
|
9
12
|
schemaVersion: z.ZodLiteral<1>;
|
|
10
13
|
adapterId: z.ZodLiteral<"network.xyo.dapp.adapter.cloudflare-r2-s3">;
|
|
11
14
|
adapterVersion: z.ZodLiteral<"0.1.8">;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qualifyCloudflareR2.d.ts","sourceRoot":"","sources":["../../src/qualifyCloudflareR2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"qualifyCloudflareR2.d.ts","sourceRoot":"","sources":["../../src/qualifyCloudflareR2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAQ9D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EACL,uBAAuB,EAExB,MAAM,8BAA8B,CAAA;AACrC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AAM7E,eAAO,MAAM,uCAAuC;;CAAiE,CAAA;AAIrH,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;;kBAgB/C,CAAA;AAEF,MAAM,MAAM,iCAAiC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oCAAoC,CAAC,CAAA;AAEpG,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAA;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,uBAAuB,CAAA;CACxC;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAA;CAClC;AAED,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,iBAAiB,EAAE,IAAI,CAAA;IAChC,QAAQ,CAAC,kBAAkB,EAAE,IAAI,CAAA;IACjC,QAAQ,CAAC,gBAAgB,EAAE,IAAI,CAAA;IAC/B,QAAQ,CAAC,cAAc,EAAE,IAAI,CAAA;IAC7B,QAAQ,CAAC,cAAc,EAAE,IAAI,CAAA;CAC9B;AAWD,wGAAwG;AACxG,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,iCAAiC,CAAC,CAuC5C;AAED,6FAA6F;AAC7F,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,iCAAiC,CAAC,CA0BzH;AAED,MAAM,WAAW,kCAAkC;IACjD,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAA;CACxC;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED,qFAAqF;AACrF,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,kCAAkC,GAC1C,OAAO,CAAC,2BAA2B,CAAC,CAuBtC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xyo-network/dapp-kit-cloudflare-r2",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Cloudflare R2 resource adapters and qualification for headless XL1 dApps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"xyo",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"README.md"
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@xyo-network/dapp-kit": "~1.0.
|
|
38
|
-
"@xyo-network/dapp-kit-s3": "~1.0.
|
|
37
|
+
"@xyo-network/dapp-kit": "~1.0.3",
|
|
38
|
+
"@xyo-network/dapp-kit-s3": "~1.0.3"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@ariestools/sdk": "~8.1.9",
|