@adcp/sdk 16.0.0-beta.2 → 16.0.0-beta.4
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/README.md +54 -0
- package/dist/lib/auth/oauth/diagnose.js +3 -11
- package/dist/lib/auth/oauth/diagnose.mjs +4 -12
- package/dist/lib/auth/oauth/diagnostics.d.mts +2 -1
- package/dist/lib/auth/oauth/diagnostics.d.ts +2 -1
- package/dist/lib/auth/oauth/diagnostics.js +8 -10
- package/dist/lib/auth/oauth/diagnostics.mjs +7 -10
- package/dist/lib/core/ConversationTypes.d.mts +8 -3
- package/dist/lib/core/ConversationTypes.d.ts +8 -3
- package/dist/lib/core/SingleAgentClient.d.mts +5 -3
- package/dist/lib/core/SingleAgentClient.d.ts +5 -3
- package/dist/lib/core/TaskExecutor.js +5 -1
- package/dist/lib/core/TaskExecutor.mjs +5 -1
- package/dist/lib/errors/index.d.mts +9 -4
- package/dist/lib/errors/index.d.ts +9 -4
- package/dist/lib/index.d.mts +3 -3
- package/dist/lib/index.d.ts +3 -3
- package/dist/lib/index.js +8 -0
- package/dist/lib/index.mjs +14 -2
- package/dist/lib/negotiation/types.d.mts +20 -39
- package/dist/lib/negotiation/types.d.ts +20 -39
- package/dist/lib/protocols/index.d.mts +60 -24
- package/dist/lib/protocols/index.d.ts +60 -24
- package/dist/lib/protocols/index.js +9 -4
- package/dist/lib/protocols/index.mjs +3 -0
- package/dist/lib/protocols/mcp-modern.js +1 -0
- package/dist/lib/protocols/mcp-modern.mjs +2 -1
- package/dist/lib/protocols/mcp.js +1 -0
- package/dist/lib/protocols/mcp.mjs +2 -1
- package/dist/lib/protocols/responseSizeLimit.d.mts +91 -5
- package/dist/lib/protocols/responseSizeLimit.d.ts +91 -5
- package/dist/lib/protocols/responseSizeLimit.js +195 -31
- package/dist/lib/protocols/responseSizeLimit.mjs +192 -31
- package/dist/lib/reporting/consumer-runtime.js +2 -1
- package/dist/lib/reporting/consumer-runtime.mjs +2 -1
- package/dist/lib/reporting/ledger/handler.js +50 -11
- package/dist/lib/reporting/ledger/handler.mjs +50 -12
- package/dist/lib/reporting/ledger/index.d.mts +17 -14
- package/dist/lib/reporting/ledger/index.d.ts +17 -14
- package/dist/lib/reporting/ledger/index.js +32 -20
- package/dist/lib/reporting/ledger/index.mjs +21 -10
- package/dist/lib/reporting/ledger/offering-validation.d.mts +9 -0
- package/dist/lib/reporting/ledger/offering-validation.d.ts +9 -0
- package/dist/lib/reporting/{gcs/bucket-policy.js → ledger/offering-validation.js} +9 -8
- package/dist/lib/reporting/ledger/offering-validation.mjs +8 -0
- package/dist/lib/reporting/ledger/receipts.d.mts +48 -0
- package/dist/lib/reporting/ledger/receipts.d.ts +48 -0
- package/dist/lib/reporting/ledger/receipts.js +186 -0
- package/dist/lib/reporting/ledger/receipts.mjs +161 -0
- package/dist/lib/reporting/ledger/status-ingest.js +3 -3
- package/dist/lib/reporting/ledger/status-ingest.mjs +4 -5
- package/dist/lib/reporting/ledger/types.d.mts +43 -0
- package/dist/lib/reporting/ledger/types.d.ts +43 -0
- package/dist/lib/reporting/ledger/types.js +31 -2
- package/dist/lib/reporting/ledger/types.mjs +26 -1
- package/dist/lib/reporting/pagination.d.mts +6 -0
- package/dist/lib/reporting/pagination.d.ts +6 -0
- package/dist/lib/reporting/{gcs/errors.js → pagination.js} +12 -17
- package/dist/lib/reporting/pagination.mjs +12 -0
- package/dist/lib/reporting/reconciliation.d.mts +1 -0
- package/dist/lib/reporting/reconciliation.d.ts +1 -0
- package/dist/lib/reporting/reconciliation.js +3 -2
- package/dist/lib/reporting/reconciliation.mjs +3 -2
- package/dist/lib/reporting/service/index.d.mts +79 -153
- package/dist/lib/reporting/service/index.d.ts +79 -153
- package/dist/lib/reporting/service/index.js +34 -491
- package/dist/lib/reporting/service/index.mjs +36 -510
- package/dist/lib/reporting/service/scheduler-support.d.mts +43 -0
- package/dist/lib/reporting/service/scheduler-support.d.ts +43 -0
- package/dist/lib/reporting/service/scheduler-support.js +125 -0
- package/dist/lib/reporting/service/scheduler-support.mjs +96 -0
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/signing/canonicalize.d.mts +4 -0
- package/dist/lib/signing/canonicalize.d.ts +4 -0
- package/dist/lib/signing/canonicalize.js +14 -8
- package/dist/lib/signing/canonicalize.mjs +14 -8
- package/dist/lib/signing/content-digest.d.mts +8 -0
- package/dist/lib/signing/content-digest.d.ts +8 -0
- package/dist/lib/signing/content-digest.js +11 -5
- package/dist/lib/signing/content-digest.mjs +10 -5
- package/dist/lib/signing/crypto.d.mts +15 -0
- package/dist/lib/signing/crypto.d.ts +15 -0
- package/dist/lib/signing/crypto.js +75 -3
- package/dist/lib/signing/crypto.mjs +78 -3
- package/dist/lib/signing/server.d.mts +1 -1
- package/dist/lib/signing/server.d.ts +1 -1
- package/dist/lib/signing/server.js +2 -0
- package/dist/lib/signing/server.mjs +2 -1
- package/dist/lib/signing/signer.js +11 -14
- package/dist/lib/signing/signer.mjs +13 -16
- package/dist/lib/signing/testing.js +2 -6
- package/dist/lib/signing/testing.mjs +3 -7
- package/dist/lib/signing/verifier.js +2 -2
- package/dist/lib/signing/verifier.mjs +3 -3
- package/dist/lib/signing/web-bot-auth.js +122 -43
- package/dist/lib/signing/web-bot-auth.mjs +128 -44
- package/dist/lib/signing/webhook-verifier.js +2 -2
- package/dist/lib/signing/webhook-verifier.mjs +3 -3
- package/dist/lib/substitution/compile.js +2 -1
- package/dist/lib/substitution/compile.mjs +2 -1
- package/dist/lib/substitution/consent-macros.d.mts +4 -0
- package/dist/lib/substitution/consent-macros.d.ts +4 -0
- package/dist/lib/substitution/consent-macros.js +45 -0
- package/dist/lib/substitution/consent-macros.mjs +20 -0
- package/dist/lib/substitution/index.d.mts +1 -1
- package/dist/lib/substitution/index.d.ts +1 -1
- package/dist/lib/substitution/index.js +2 -0
- package/dist/lib/substitution/index.mjs +2 -1
- package/dist/lib/substitution/translate.d.mts +15 -2
- package/dist/lib/substitution/translate.d.ts +15 -2
- package/dist/lib/substitution/translate.js +148 -26
- package/dist/lib/substitution/translate.mjs +147 -26
- package/dist/lib/testing/client.js +2 -1
- package/dist/lib/testing/client.mjs +2 -1
- package/dist/lib/testing/scenarios/capabilities.js +1 -1
- package/dist/lib/testing/scenarios/capabilities.mjs +1 -1
- package/dist/lib/testing/storyboard/junit.js +16 -3
- package/dist/lib/testing/storyboard/junit.mjs +16 -3
- package/dist/lib/testing/storyboard/request-signing/builder.js +12 -14
- package/dist/lib/testing/storyboard/request-signing/builder.mjs +13 -15
- package/dist/lib/testing/storyboard/runner.js +94 -25
- package/dist/lib/testing/storyboard/runner.mjs +94 -25
- package/dist/lib/testing/storyboard/signer-grader/grader.js +2 -7
- package/dist/lib/testing/storyboard/signer-grader/grader.mjs +2 -7
- package/dist/lib/testing/storyboard/types.d.mts +6 -0
- package/dist/lib/testing/storyboard/types.d.ts +6 -0
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/types/enums.generated.d.mts +3 -0
- package/dist/lib/types/enums.generated.d.ts +3 -0
- package/dist/lib/types/enums.generated.js +9 -0
- package/dist/lib/types/enums.generated.mjs +6 -0
- package/dist/lib/validation/schema-loader.js +25 -0
- package/dist/lib/validation/schema-loader.mjs +24 -0
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.mjs +3 -3
- package/docs/TYPE-SUMMARY.md +28 -5
- package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +3 -2
- package/docs/guides/REPORTING-GCS-FENCE.md +3 -3
- package/docs/guides/REPORTING-GCS-MANAGED.md +4 -4
- package/docs/guides/REPORTING-LEDGER-CUTOVER.md +7 -7
- package/docs/guides/REPORTING-LEDGER.md +107 -51
- package/docs/guides/REPORTING-OPERATIONS.md +66 -5
- package/docs/guides/REPORTING-STABILITY.md +36 -32
- package/docs/guides/UNIVERSAL-MACRO-COMPILATION.md +38 -0
- package/docs/guides/VALIDATE-YOUR-AGENT.md +12 -0
- package/docs/llms.txt +4 -3
- package/docs/migration-14.x-rc-worksheet.md +4 -7
- package/docs/migration-reporting-storage-package.md +186 -0
- package/examples/README.md +1 -1
- package/package.json +14 -78
- package/dist/lib/reporting/azure/index.d.mts +0 -31
- package/dist/lib/reporting/azure/index.d.ts +0 -31
- package/dist/lib/reporting/azure/index.js +0 -266
- package/dist/lib/reporting/azure/index.mjs +0 -249
- package/dist/lib/reporting/bigquery/index.d.mts +0 -246
- package/dist/lib/reporting/bigquery/index.d.ts +0 -246
- package/dist/lib/reporting/bigquery/index.js +0 -633
- package/dist/lib/reporting/bigquery/index.mjs +0 -594
- package/dist/lib/reporting/gcs/adapter.d.mts +0 -38
- package/dist/lib/reporting/gcs/adapter.d.ts +0 -38
- package/dist/lib/reporting/gcs/adapter.js +0 -342
- package/dist/lib/reporting/gcs/adapter.mjs +0 -325
- package/dist/lib/reporting/gcs/bucket-policy.d.mts +0 -3
- package/dist/lib/reporting/gcs/bucket-policy.d.ts +0 -3
- package/dist/lib/reporting/gcs/bucket-policy.mjs +0 -7
- package/dist/lib/reporting/gcs/errors.d.mts +0 -11
- package/dist/lib/reporting/gcs/errors.d.ts +0 -11
- package/dist/lib/reporting/gcs/errors.mjs +0 -16
- package/dist/lib/reporting/gcs/fence.d.mts +0 -41
- package/dist/lib/reporting/gcs/fence.d.ts +0 -41
- package/dist/lib/reporting/gcs/fence.js +0 -250
- package/dist/lib/reporting/gcs/fence.mjs +0 -230
- package/dist/lib/reporting/gcs/index.d.mts +0 -18
- package/dist/lib/reporting/gcs/index.d.ts +0 -18
- package/dist/lib/reporting/gcs/index.js +0 -44
- package/dist/lib/reporting/gcs/index.mjs +0 -14
- package/dist/lib/reporting/gcs/io.d.mts +0 -7
- package/dist/lib/reporting/gcs/io.d.ts +0 -7
- package/dist/lib/reporting/gcs/io.js +0 -95
- package/dist/lib/reporting/gcs/io.mjs +0 -69
- package/dist/lib/reporting/gcs/reader.d.mts +0 -67
- package/dist/lib/reporting/gcs/reader.d.ts +0 -67
- package/dist/lib/reporting/gcs/reader.js +0 -193
- package/dist/lib/reporting/gcs/reader.mjs +0 -169
- package/dist/lib/reporting/gcs/row-provider.d.mts +0 -39
- package/dist/lib/reporting/gcs/row-provider.d.ts +0 -39
- package/dist/lib/reporting/gcs/row-provider.js +0 -225
- package/dist/lib/reporting/gcs/row-provider.mjs +0 -208
- package/dist/lib/reporting/gcs/validation.d.mts +0 -5
- package/dist/lib/reporting/gcs/validation.d.ts +0 -5
- package/dist/lib/reporting/gcs/validation.js +0 -49
- package/dist/lib/reporting/gcs/validation.mjs +0 -25
- package/dist/lib/reporting/ledger/change-feed.d.mts +0 -69
- package/dist/lib/reporting/ledger/change-feed.d.ts +0 -69
- package/dist/lib/reporting/ledger/change-feed.js +0 -107
- package/dist/lib/reporting/ledger/change-feed.mjs +0 -80
- package/dist/lib/reporting/ledger/managed-postgres.d.mts +0 -293
- package/dist/lib/reporting/ledger/managed-postgres.d.ts +0 -293
- package/dist/lib/reporting/ledger/managed-postgres.js +0 -2346
- package/dist/lib/reporting/ledger/managed-postgres.mjs +0 -2332
- package/dist/lib/reporting/ledger/managed-router.d.mts +0 -148
- package/dist/lib/reporting/ledger/managed-router.d.ts +0 -148
- package/dist/lib/reporting/ledger/managed-router.js +0 -280
- package/dist/lib/reporting/ledger/managed-router.mjs +0 -258
- package/dist/lib/reporting/ledger/managed.d.mts +0 -535
- package/dist/lib/reporting/ledger/managed.d.ts +0 -535
- package/dist/lib/reporting/ledger/managed.js +0 -761
- package/dist/lib/reporting/ledger/managed.mjs +0 -729
- package/dist/lib/reporting/ledger/notification-activity.d.mts +0 -332
- package/dist/lib/reporting/ledger/notification-activity.d.ts +0 -332
- package/dist/lib/reporting/ledger/notification-activity.js +0 -1366
- package/dist/lib/reporting/ledger/notification-activity.mjs +0 -1337
- package/dist/lib/reporting/ledger/object-writes.d.mts +0 -128
- package/dist/lib/reporting/ledger/object-writes.d.ts +0 -128
- package/dist/lib/reporting/ledger/object-writes.js +0 -147
- package/dist/lib/reporting/ledger/object-writes.mjs +0 -114
- package/dist/lib/reporting/ledger/postgres.d.mts +0 -689
- package/dist/lib/reporting/ledger/postgres.d.ts +0 -689
- package/dist/lib/reporting/ledger/postgres.js +0 -4462
- package/dist/lib/reporting/ledger/postgres.mjs +0 -4462
- package/dist/lib/reporting/ledger/row-storage-migration.d.mts +0 -59
- package/dist/lib/reporting/ledger/row-storage-migration.d.ts +0 -59
- package/dist/lib/reporting/ledger/row-storage-migration.js +0 -365
- package/dist/lib/reporting/ledger/row-storage-migration.mjs +0 -339
- package/dist/lib/reporting/ledger/row-storage-object.d.mts +0 -203
- package/dist/lib/reporting/ledger/row-storage-object.d.ts +0 -203
- package/dist/lib/reporting/ledger/row-storage-object.js +0 -379
- package/dist/lib/reporting/ledger/row-storage-object.mjs +0 -335
- package/dist/lib/reporting/ledger/row-storage-provider-io.d.mts +0 -44
- package/dist/lib/reporting/ledger/row-storage-provider-io.d.ts +0 -44
- package/dist/lib/reporting/ledger/row-storage-provider-io.js +0 -142
- package/dist/lib/reporting/ledger/row-storage-provider-io.mjs +0 -111
- package/dist/lib/reporting/ledger/row-storage.d.mts +0 -316
- package/dist/lib/reporting/ledger/row-storage.d.ts +0 -316
- package/dist/lib/reporting/ledger/row-storage.js +0 -812
- package/dist/lib/reporting/ledger/row-storage.mjs +0 -802
- package/dist/lib/reporting/s3/index.d.mts +0 -34
- package/dist/lib/reporting/s3/index.d.ts +0 -34
- package/dist/lib/reporting/s3/index.js +0 -347
- package/dist/lib/reporting/s3/index.mjs +0 -340
- package/dist/lib/reporting/service/maintenance.d.mts +0 -148
- package/dist/lib/reporting/service/maintenance.d.ts +0 -148
- package/dist/lib/reporting/service/maintenance.js +0 -185
- package/dist/lib/reporting/service/maintenance.mjs +0 -159
- package/examples/reliable-reporting-service/README.md +0 -169
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
function assertGcsReportingBucketPolicy(metadata) {
|
|
2
|
-
if (!metadata || metadata.versioning?.enabled || metadata.softDeletePolicy?.retentionDurationSeconds === void 0 || Number(metadata.softDeletePolicy.retentionDurationSeconds) !== 0 || Number(metadata.retentionPolicy?.retentionPeriod ?? 0) !== 0 || metadata.defaultEventBasedHold === true || metadata.objectRetention?.mode === "Enabled" || (metadata.lifecycle?.rule?.length ?? 0) > 0 || metadata.iamConfiguration?.uniformBucketLevelAccess?.enabled !== true || metadata.iamConfiguration?.publicAccessPrevention !== "enforced")
|
|
3
|
-
throw new Error("Unsafe reporting GCS bucket policy");
|
|
4
|
-
}
|
|
5
|
-
export {
|
|
6
|
-
assertGcsReportingBucketPolicy
|
|
7
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
3
|
-
*/
|
|
4
|
-
export declare class ReportingGcsFenceError extends Error {
|
|
5
|
-
readonly code: 'INVALID_INPUT' | 'UNSAFE_BUCKET' | 'REVOKED' | 'NOT_REVOKED' | 'CONTENT_CONFLICT' | 'ABORTED' | 'PROVIDER_UNAVAILABLE' | 'DEADLINE_EXCEEDED' | 'HOST_CALLBACK_FAILED' | 'STATE_UNAVAILABLE';
|
|
6
|
-
constructor(code: 'INVALID_INPUT' | 'UNSAFE_BUCKET' | 'REVOKED' | 'NOT_REVOKED' | 'CONTENT_CONFLICT' | 'ABORTED' | 'PROVIDER_UNAVAILABLE' | 'DEADLINE_EXCEEDED' | 'HOST_CALLBACK_FAILED' | 'STATE_UNAVAILABLE');
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
10
|
-
*/
|
|
11
|
-
export declare function isReportingGcsFenceError(error: unknown): error is ReportingGcsFenceError;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
3
|
-
*/
|
|
4
|
-
export declare class ReportingGcsFenceError extends Error {
|
|
5
|
-
readonly code: 'INVALID_INPUT' | 'UNSAFE_BUCKET' | 'REVOKED' | 'NOT_REVOKED' | 'CONTENT_CONFLICT' | 'ABORTED' | 'PROVIDER_UNAVAILABLE' | 'DEADLINE_EXCEEDED' | 'HOST_CALLBACK_FAILED' | 'STATE_UNAVAILABLE';
|
|
6
|
-
constructor(code: 'INVALID_INPUT' | 'UNSAFE_BUCKET' | 'REVOKED' | 'NOT_REVOKED' | 'CONTENT_CONFLICT' | 'ABORTED' | 'PROVIDER_UNAVAILABLE' | 'DEADLINE_EXCEEDED' | 'HOST_CALLBACK_FAILED' | 'STATE_UNAVAILABLE');
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
10
|
-
*/
|
|
11
|
-
export declare function isReportingGcsFenceError(error: unknown): error is ReportingGcsFenceError;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
class ReportingGcsFenceError extends Error {
|
|
2
|
-
constructor(code) {
|
|
3
|
-
super(`Reporting GCS fence: ${code}`);
|
|
4
|
-
this.code = code;
|
|
5
|
-
this.name = "ReportingGcsFenceError";
|
|
6
|
-
Object.defineProperty(this, /* @__PURE__ */ Symbol.for("adcp.reportingGcsFenceError"), { value: true });
|
|
7
|
-
}
|
|
8
|
-
code;
|
|
9
|
-
}
|
|
10
|
-
function isReportingGcsFenceError(error) {
|
|
11
|
-
return !!error && typeof error === "object" && error[/* @__PURE__ */ Symbol.for("adcp.reportingGcsFenceError")] === true;
|
|
12
|
-
}
|
|
13
|
-
export {
|
|
14
|
-
ReportingGcsFenceError,
|
|
15
|
-
isReportingGcsFenceError
|
|
16
|
-
};
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import type { Storage } from '@google-cloud/storage';
|
|
2
|
-
import { type ReportingObjectWriteScopeV1, type ReportingObjectWritePlanV1, type ReportingObjectWriteStoreV1 } from '../ledger/object-writes.mjs';
|
|
3
|
-
export { ReportingGcsFenceError } from './errors.mjs';
|
|
4
|
-
/**
|
|
5
|
-
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
6
|
-
*/
|
|
7
|
-
export interface GcsReportingObjectFenceV1 {
|
|
8
|
-
probe(context?: {
|
|
9
|
-
signal?: AbortSignal;
|
|
10
|
-
}): Promise<void>;
|
|
11
|
-
register(scope: ReportingObjectWriteScopeV1, deliveryId: string, bodies: readonly Uint8Array[], context?: {
|
|
12
|
-
signal?: AbortSignal;
|
|
13
|
-
}): Promise<ReportingObjectWritePlanV1>;
|
|
14
|
-
write(plan: ReportingObjectWritePlanV1, index: number, bytes: Uint8Array, context: {
|
|
15
|
-
signal: AbortSignal;
|
|
16
|
-
}): Promise<void>;
|
|
17
|
-
revoke(scope: ReportingObjectWriteScopeV1, context: {
|
|
18
|
-
signal: AbortSignal;
|
|
19
|
-
maxObjects?: number;
|
|
20
|
-
}): Promise<{
|
|
21
|
-
fenced: number;
|
|
22
|
-
complete: boolean;
|
|
23
|
-
}>;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Provider-side write fence, not a complete Managed Delivery adapter.
|
|
27
|
-
* Derive scope from authenticated host state; these methods do not authorize callers.
|
|
28
|
-
* Bucket configuration must remain managed exclusively by the trusted host.
|
|
29
|
-
* Tombstones and inventory MUST NOT be deleted while stale requests can execute.
|
|
30
|
-
* Inject the official Storage client with host-owned, keyless credentials.
|
|
31
|
-
*
|
|
32
|
-
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
33
|
-
*/
|
|
34
|
-
export declare function createGcsReportingObjectFenceV1(options: {
|
|
35
|
-
storage: Storage;
|
|
36
|
-
store: ReportingObjectWriteStoreV1;
|
|
37
|
-
bucket: string;
|
|
38
|
-
/** Opaque deployment identity, separate from account and destination generations. */
|
|
39
|
-
namespace: string;
|
|
40
|
-
operationDeadlineMilliseconds?: number;
|
|
41
|
-
}): GcsReportingObjectFenceV1;
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import type { Storage } from '@google-cloud/storage';
|
|
2
|
-
import { type ReportingObjectWriteScopeV1, type ReportingObjectWritePlanV1, type ReportingObjectWriteStoreV1 } from '../ledger/object-writes';
|
|
3
|
-
export { ReportingGcsFenceError } from './errors';
|
|
4
|
-
/**
|
|
5
|
-
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
6
|
-
*/
|
|
7
|
-
export interface GcsReportingObjectFenceV1 {
|
|
8
|
-
probe(context?: {
|
|
9
|
-
signal?: AbortSignal;
|
|
10
|
-
}): Promise<void>;
|
|
11
|
-
register(scope: ReportingObjectWriteScopeV1, deliveryId: string, bodies: readonly Uint8Array[], context?: {
|
|
12
|
-
signal?: AbortSignal;
|
|
13
|
-
}): Promise<ReportingObjectWritePlanV1>;
|
|
14
|
-
write(plan: ReportingObjectWritePlanV1, index: number, bytes: Uint8Array, context: {
|
|
15
|
-
signal: AbortSignal;
|
|
16
|
-
}): Promise<void>;
|
|
17
|
-
revoke(scope: ReportingObjectWriteScopeV1, context: {
|
|
18
|
-
signal: AbortSignal;
|
|
19
|
-
maxObjects?: number;
|
|
20
|
-
}): Promise<{
|
|
21
|
-
fenced: number;
|
|
22
|
-
complete: boolean;
|
|
23
|
-
}>;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Provider-side write fence, not a complete Managed Delivery adapter.
|
|
27
|
-
* Derive scope from authenticated host state; these methods do not authorize callers.
|
|
28
|
-
* Bucket configuration must remain managed exclusively by the trusted host.
|
|
29
|
-
* Tombstones and inventory MUST NOT be deleted while stale requests can execute.
|
|
30
|
-
* Inject the official Storage client with host-owned, keyless credentials.
|
|
31
|
-
*
|
|
32
|
-
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
33
|
-
*/
|
|
34
|
-
export declare function createGcsReportingObjectFenceV1(options: {
|
|
35
|
-
storage: Storage;
|
|
36
|
-
store: ReportingObjectWriteStoreV1;
|
|
37
|
-
bucket: string;
|
|
38
|
-
/** Opaque deployment identity, separate from account and destination generations. */
|
|
39
|
-
namespace: string;
|
|
40
|
-
operationDeadlineMilliseconds?: number;
|
|
41
|
-
}): GcsReportingObjectFenceV1;
|
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
var fence_exports = {};
|
|
20
|
-
__export(fence_exports, {
|
|
21
|
-
ReportingGcsFenceError: () => import_errors2.ReportingGcsFenceError,
|
|
22
|
-
createGcsReportingObjectFenceV1: () => createGcsReportingObjectFenceV1
|
|
23
|
-
});
|
|
24
|
-
module.exports = __toCommonJS(fence_exports);
|
|
25
|
-
var import_node_crypto = require("node:crypto");
|
|
26
|
-
var import_object_writes = require('../ledger/object-writes.js');
|
|
27
|
-
var import_errors = require('./errors.js');
|
|
28
|
-
var import_io = require('./io.js');
|
|
29
|
-
var import_bucket_policy = require('./bucket-policy.js');
|
|
30
|
-
var import_errors2 = require('./errors.js');
|
|
31
|
-
const hash = (bytes) => (0, import_node_crypto.createHash)("sha256").update(bytes).digest("hex");
|
|
32
|
-
const TOMBSTONE = "adcp_reporting_tombstone";
|
|
33
|
-
function createGcsReportingObjectFenceV1(options) {
|
|
34
|
-
if (!options || typeof options.bucket !== "string" || !/^[a-z0-9][a-z0-9.-]{1,220}[a-z0-9]$/.test(options.bucket) || typeof options.namespace !== "string" || options.namespace.length < 1 || options.namespace.length > 255 || !options.storage || typeof options.storage.bucket !== "function" || !options.store)
|
|
35
|
-
throw new import_errors.ReportingGcsFenceError("INVALID_INPUT");
|
|
36
|
-
const { storage, store, bucket: bucketName, namespace } = options;
|
|
37
|
-
const deadline = options.operationDeadlineMilliseconds ?? 6e4;
|
|
38
|
-
if (!Number.isSafeInteger(deadline) || deadline < 1 || deadline > 6e4)
|
|
39
|
-
throw new import_errors.ReportingGcsFenceError("INVALID_INPUT");
|
|
40
|
-
const provider = { bucket: bucketName, namespace_key: hash(namespace) };
|
|
41
|
-
const status = (error, code) => !!error && typeof error === "object" && "code" in error && Number(error.code) === code;
|
|
42
|
-
const bounded = (work, signal) => (0, import_io.withGcsDeadline)(work, { signal, milliseconds: deadline });
|
|
43
|
-
async function probe(bucket, signal) {
|
|
44
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
45
|
-
try {
|
|
46
|
-
const [metadata] = await bucket.getMetadata();
|
|
47
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
48
|
-
try {
|
|
49
|
-
(0, import_bucket_policy.assertGcsReportingBucketPolicy)(metadata);
|
|
50
|
-
} catch {
|
|
51
|
-
throw new import_errors.ReportingGcsFenceError("UNSAFE_BUCKET");
|
|
52
|
-
}
|
|
53
|
-
} catch (error) {
|
|
54
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
55
|
-
if ((0, import_errors.isReportingGcsFenceError)(error)) throw error;
|
|
56
|
-
throw new import_errors.ReportingGcsFenceError("PROVIDER_UNAVAILABLE");
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
function assertScope(scope) {
|
|
60
|
-
try {
|
|
61
|
-
(0, import_object_writes.assertReportingObjectWriteScope)(scope);
|
|
62
|
-
} catch {
|
|
63
|
-
throw new import_errors.ReportingGcsFenceError("INVALID_INPUT");
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
function assertPlan(plan) {
|
|
67
|
-
try {
|
|
68
|
-
(0, import_object_writes.reportingObjectWritePlanFingerprint)(plan);
|
|
69
|
-
} catch {
|
|
70
|
-
throw new import_errors.ReportingGcsFenceError("INVALID_INPUT");
|
|
71
|
-
}
|
|
72
|
-
if (plan.provider.bucket !== bucketName || plan.provider.namespace_key !== provider.namespace_key)
|
|
73
|
-
throw new import_errors.ReportingGcsFenceError("INVALID_INPUT");
|
|
74
|
-
}
|
|
75
|
-
async function register(scope, deliveryId, bodies, signal) {
|
|
76
|
-
assertScope(scope);
|
|
77
|
-
if (typeof deliveryId !== "string" || deliveryId.length < 1 || deliveryId.length > 255 || !Array.isArray(bodies) || bodies.length < 1 || bodies.length > 128 || bodies.some((b) => !(b instanceof Uint8Array) || b.byteLength > 64 * 1024 * 1024) || bodies.reduce((total, b) => total + b.byteLength, 0) > 64 * 1024 * 1024)
|
|
78
|
-
throw new import_errors.ReportingGcsFenceError("INVALID_INPUT");
|
|
79
|
-
const scopeCopy = {
|
|
80
|
-
account_id: scope.account_id,
|
|
81
|
-
destination_ref: scope.destination_ref,
|
|
82
|
-
generation: scope.generation
|
|
83
|
-
};
|
|
84
|
-
const planId = hash(deliveryId);
|
|
85
|
-
const plan = {
|
|
86
|
-
...scopeCopy,
|
|
87
|
-
provider: { ...provider },
|
|
88
|
-
plan_id: planId,
|
|
89
|
-
objects: bodies.map((b, i) => ({
|
|
90
|
-
bucket: bucketName,
|
|
91
|
-
object_name: (0, import_object_writes.reportingObjectWriteName)(scopeCopy, provider, planId, i),
|
|
92
|
-
sha256: hash(b),
|
|
93
|
-
size_bytes: b.byteLength
|
|
94
|
-
}))
|
|
95
|
-
};
|
|
96
|
-
await probe(storage.bucket(bucketName), signal);
|
|
97
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
98
|
-
const registered = await store.registerObjectWritePlan(plan, { signal });
|
|
99
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
100
|
-
if (registered === "revoked") throw new import_errors.ReportingGcsFenceError("REVOKED");
|
|
101
|
-
return plan;
|
|
102
|
-
}
|
|
103
|
-
async function write(input, index, inputBytes, signal) {
|
|
104
|
-
const plan = structuredClone(input);
|
|
105
|
-
assertPlan(plan);
|
|
106
|
-
const expected = plan.objects[index];
|
|
107
|
-
if (!Number.isInteger(index) || !expected || !(inputBytes instanceof Uint8Array))
|
|
108
|
-
throw new import_errors.ReportingGcsFenceError("INVALID_INPUT");
|
|
109
|
-
if (inputBytes.byteLength !== expected.size_bytes) throw new import_errors.ReportingGcsFenceError("CONTENT_CONFLICT");
|
|
110
|
-
const bytes = Buffer.from(inputBytes);
|
|
111
|
-
if (hash(bytes) !== expected.sha256) throw new import_errors.ReportingGcsFenceError("CONTENT_CONFLICT");
|
|
112
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
113
|
-
const bucket = storage.bucket(bucketName);
|
|
114
|
-
await probe(bucket, signal);
|
|
115
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
116
|
-
const registered = await store.registerObjectWritePlan(plan, { signal });
|
|
117
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
118
|
-
if (registered === "revoked") throw new import_errors.ReportingGcsFenceError("REVOKED");
|
|
119
|
-
const file = bucket.file(expected.object_name);
|
|
120
|
-
try {
|
|
121
|
-
await file.save(bytes, {
|
|
122
|
-
resumable: false,
|
|
123
|
-
preconditionOpts: { ifGenerationMatch: 0 },
|
|
124
|
-
metadata: { cacheControl: "no-store" }
|
|
125
|
-
});
|
|
126
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
127
|
-
} catch (error) {
|
|
128
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
129
|
-
if (!status(error, 412)) throw new import_errors.ReportingGcsFenceError("PROVIDER_UNAVAILABLE");
|
|
130
|
-
try {
|
|
131
|
-
const [metadata] = await file.getMetadata();
|
|
132
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
133
|
-
if (metadata.metadata?.[TOMBSTONE] !== void 0) throw new import_errors.ReportingGcsFenceError("REVOKED");
|
|
134
|
-
const existing = await (0, import_io.readGcsBytes)(
|
|
135
|
-
bucket.file(expected.object_name, { generation: metadata.generation }),
|
|
136
|
-
bytes.length,
|
|
137
|
-
signal
|
|
138
|
-
);
|
|
139
|
-
if (existing.length !== bytes.length || hash(existing) !== expected.sha256)
|
|
140
|
-
throw new import_errors.ReportingGcsFenceError("CONTENT_CONFLICT");
|
|
141
|
-
} catch (error2) {
|
|
142
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
143
|
-
if (status(error2, 404)) {
|
|
144
|
-
const current = await store.registerObjectWritePlan(plan, { signal });
|
|
145
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
146
|
-
if (current === "revoked") throw new import_errors.ReportingGcsFenceError("REVOKED");
|
|
147
|
-
}
|
|
148
|
-
if ((0, import_errors.isReportingGcsFenceError)(error2)) throw error2;
|
|
149
|
-
throw new import_errors.ReportingGcsFenceError("PROVIDER_UNAVAILABLE");
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
153
|
-
if (await store.registerObjectWritePlan(plan, { signal }) === "revoked")
|
|
154
|
-
throw new import_errors.ReportingGcsFenceError("REVOKED");
|
|
155
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
156
|
-
}
|
|
157
|
-
async function revoke(scopeInput, maxObjects, signal) {
|
|
158
|
-
assertScope(scopeInput);
|
|
159
|
-
const scope = {
|
|
160
|
-
account_id: scopeInput.account_id,
|
|
161
|
-
destination_ref: scopeInput.destination_ref,
|
|
162
|
-
generation: scopeInput.generation
|
|
163
|
-
};
|
|
164
|
-
const limit = maxObjects ?? 10;
|
|
165
|
-
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 1e3) throw new import_errors.ReportingGcsFenceError("INVALID_INPUT");
|
|
166
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
167
|
-
const binding = await store.getObjectWriteBinding(scope, { signal });
|
|
168
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
169
|
-
const objects = await store.listRevokedObjectWrites(scope, { limit }, { signal });
|
|
170
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
171
|
-
if (!binding) {
|
|
172
|
-
if (objects.length) throw new import_errors.ReportingGcsFenceError("STATE_UNAVAILABLE");
|
|
173
|
-
return { fenced: 0, complete: true };
|
|
174
|
-
}
|
|
175
|
-
const bucket = storage.bucket(binding.bucket);
|
|
176
|
-
await probe(bucket, signal);
|
|
177
|
-
const scopeKey = (0, import_object_writes.reportingObjectWriteScopeKey)(scope);
|
|
178
|
-
for (const object of objects) {
|
|
179
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
180
|
-
if (object.bucket !== binding.bucket || object.object_name !== (0, import_object_writes.reportingObjectWriteName)(scope, binding, object.plan_id, object.object_index))
|
|
181
|
-
throw new import_errors.ReportingGcsFenceError("STATE_UNAVAILABLE");
|
|
182
|
-
const file = bucket.file(object.object_name);
|
|
183
|
-
let fencedGeneration;
|
|
184
|
-
for (let attempt = 0; attempt < 4 && !fencedGeneration; attempt++) {
|
|
185
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
186
|
-
let generation = 0;
|
|
187
|
-
try {
|
|
188
|
-
const [metadata] = await file.getMetadata();
|
|
189
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
190
|
-
generation = String(metadata.generation);
|
|
191
|
-
if (metadata.metadata?.[TOMBSTONE] === scopeKey && String(metadata.size) === "0") {
|
|
192
|
-
fencedGeneration = String(metadata.generation);
|
|
193
|
-
break;
|
|
194
|
-
}
|
|
195
|
-
} catch (error) {
|
|
196
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
197
|
-
if (!status(error, 404)) throw new import_errors.ReportingGcsFenceError("PROVIDER_UNAVAILABLE");
|
|
198
|
-
}
|
|
199
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
200
|
-
try {
|
|
201
|
-
await file.save(Buffer.alloc(0), {
|
|
202
|
-
resumable: false,
|
|
203
|
-
preconditionOpts: { ifGenerationMatch: generation },
|
|
204
|
-
metadata: { cacheControl: "no-store", metadata: { [TOMBSTONE]: scopeKey } }
|
|
205
|
-
});
|
|
206
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
207
|
-
const [verified] = await file.getMetadata();
|
|
208
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
209
|
-
if (verified.metadata?.[TOMBSTONE] !== scopeKey || String(verified.size) !== "0")
|
|
210
|
-
throw new import_errors.ReportingGcsFenceError("PROVIDER_UNAVAILABLE");
|
|
211
|
-
fencedGeneration = String(verified.generation);
|
|
212
|
-
} catch (error) {
|
|
213
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
214
|
-
if ((0, import_errors.isReportingGcsFenceError)(error)) throw error;
|
|
215
|
-
if (!status(error, 412)) throw new import_errors.ReportingGcsFenceError("PROVIDER_UNAVAILABLE");
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
if (!fencedGeneration) throw new import_errors.ReportingGcsFenceError("PROVIDER_UNAVAILABLE");
|
|
219
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
220
|
-
await store.markObjectWriteFenced(
|
|
221
|
-
{
|
|
222
|
-
...scope,
|
|
223
|
-
plan_id: object.plan_id,
|
|
224
|
-
object_index: object.object_index,
|
|
225
|
-
tombstone_generation: fencedGeneration
|
|
226
|
-
},
|
|
227
|
-
{ signal }
|
|
228
|
-
);
|
|
229
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
230
|
-
}
|
|
231
|
-
const remaining = await store.listRevokedObjectWrites(scope, { limit: 1 }, { signal });
|
|
232
|
-
(0, import_io.activeGcsSignal)(signal);
|
|
233
|
-
return { fenced: objects.length, complete: remaining.length === 0 };
|
|
234
|
-
}
|
|
235
|
-
function requireSignal(context) {
|
|
236
|
-
if (!(context?.signal instanceof AbortSignal)) throw new import_errors.ReportingGcsFenceError("INVALID_INPUT");
|
|
237
|
-
return context.signal;
|
|
238
|
-
}
|
|
239
|
-
return {
|
|
240
|
-
probe: async (context) => bounded((signal) => probe(storage.bucket(bucketName), signal), context?.signal),
|
|
241
|
-
register: async (scope, deliveryId, bodies, context) => bounded((signal) => register(scope, deliveryId, bodies, signal), context?.signal),
|
|
242
|
-
write: async (plan, index, bytes, context) => bounded((signal) => write(plan, index, bytes, signal), requireSignal(context)),
|
|
243
|
-
revoke: async (scope, context) => bounded((signal) => revoke(scope, context.maxObjects, signal), requireSignal(context))
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
247
|
-
0 && (module.exports = {
|
|
248
|
-
ReportingGcsFenceError,
|
|
249
|
-
createGcsReportingObjectFenceV1
|
|
250
|
-
});
|
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import {
|
|
3
|
-
assertReportingObjectWriteScope,
|
|
4
|
-
reportingObjectWritePlanFingerprint,
|
|
5
|
-
reportingObjectWriteName,
|
|
6
|
-
reportingObjectWriteScopeKey
|
|
7
|
-
} from "../ledger/object-writes.mjs";
|
|
8
|
-
import { ReportingGcsFenceError, isReportingGcsFenceError } from "./errors.mjs";
|
|
9
|
-
import { activeGcsSignal as active, withGcsDeadline, readGcsBytes } from "./io.mjs";
|
|
10
|
-
import { assertGcsReportingBucketPolicy } from "./bucket-policy.mjs";
|
|
11
|
-
const hash = (bytes) => createHash("sha256").update(bytes).digest("hex");
|
|
12
|
-
const TOMBSTONE = "adcp_reporting_tombstone";
|
|
13
|
-
import { ReportingGcsFenceError as ReportingGcsFenceError2 } from "./errors.mjs";
|
|
14
|
-
function createGcsReportingObjectFenceV1(options) {
|
|
15
|
-
if (!options || typeof options.bucket !== "string" || !/^[a-z0-9][a-z0-9.-]{1,220}[a-z0-9]$/.test(options.bucket) || typeof options.namespace !== "string" || options.namespace.length < 1 || options.namespace.length > 255 || !options.storage || typeof options.storage.bucket !== "function" || !options.store)
|
|
16
|
-
throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
17
|
-
const { storage, store, bucket: bucketName, namespace } = options;
|
|
18
|
-
const deadline = options.operationDeadlineMilliseconds ?? 6e4;
|
|
19
|
-
if (!Number.isSafeInteger(deadline) || deadline < 1 || deadline > 6e4)
|
|
20
|
-
throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
21
|
-
const provider = { bucket: bucketName, namespace_key: hash(namespace) };
|
|
22
|
-
const status = (error, code) => !!error && typeof error === "object" && "code" in error && Number(error.code) === code;
|
|
23
|
-
const bounded = (work, signal) => withGcsDeadline(work, { signal, milliseconds: deadline });
|
|
24
|
-
async function probe(bucket, signal) {
|
|
25
|
-
active(signal);
|
|
26
|
-
try {
|
|
27
|
-
const [metadata] = await bucket.getMetadata();
|
|
28
|
-
active(signal);
|
|
29
|
-
try {
|
|
30
|
-
assertGcsReportingBucketPolicy(metadata);
|
|
31
|
-
} catch {
|
|
32
|
-
throw new ReportingGcsFenceError("UNSAFE_BUCKET");
|
|
33
|
-
}
|
|
34
|
-
} catch (error) {
|
|
35
|
-
active(signal);
|
|
36
|
-
if (isReportingGcsFenceError(error)) throw error;
|
|
37
|
-
throw new ReportingGcsFenceError("PROVIDER_UNAVAILABLE");
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
function assertScope(scope) {
|
|
41
|
-
try {
|
|
42
|
-
assertReportingObjectWriteScope(scope);
|
|
43
|
-
} catch {
|
|
44
|
-
throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
function assertPlan(plan) {
|
|
48
|
-
try {
|
|
49
|
-
reportingObjectWritePlanFingerprint(plan);
|
|
50
|
-
} catch {
|
|
51
|
-
throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
52
|
-
}
|
|
53
|
-
if (plan.provider.bucket !== bucketName || plan.provider.namespace_key !== provider.namespace_key)
|
|
54
|
-
throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
55
|
-
}
|
|
56
|
-
async function register(scope, deliveryId, bodies, signal) {
|
|
57
|
-
assertScope(scope);
|
|
58
|
-
if (typeof deliveryId !== "string" || deliveryId.length < 1 || deliveryId.length > 255 || !Array.isArray(bodies) || bodies.length < 1 || bodies.length > 128 || bodies.some((b) => !(b instanceof Uint8Array) || b.byteLength > 64 * 1024 * 1024) || bodies.reduce((total, b) => total + b.byteLength, 0) > 64 * 1024 * 1024)
|
|
59
|
-
throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
60
|
-
const scopeCopy = {
|
|
61
|
-
account_id: scope.account_id,
|
|
62
|
-
destination_ref: scope.destination_ref,
|
|
63
|
-
generation: scope.generation
|
|
64
|
-
};
|
|
65
|
-
const planId = hash(deliveryId);
|
|
66
|
-
const plan = {
|
|
67
|
-
...scopeCopy,
|
|
68
|
-
provider: { ...provider },
|
|
69
|
-
plan_id: planId,
|
|
70
|
-
objects: bodies.map((b, i) => ({
|
|
71
|
-
bucket: bucketName,
|
|
72
|
-
object_name: reportingObjectWriteName(scopeCopy, provider, planId, i),
|
|
73
|
-
sha256: hash(b),
|
|
74
|
-
size_bytes: b.byteLength
|
|
75
|
-
}))
|
|
76
|
-
};
|
|
77
|
-
await probe(storage.bucket(bucketName), signal);
|
|
78
|
-
active(signal);
|
|
79
|
-
const registered = await store.registerObjectWritePlan(plan, { signal });
|
|
80
|
-
active(signal);
|
|
81
|
-
if (registered === "revoked") throw new ReportingGcsFenceError("REVOKED");
|
|
82
|
-
return plan;
|
|
83
|
-
}
|
|
84
|
-
async function write(input, index, inputBytes, signal) {
|
|
85
|
-
const plan = structuredClone(input);
|
|
86
|
-
assertPlan(plan);
|
|
87
|
-
const expected = plan.objects[index];
|
|
88
|
-
if (!Number.isInteger(index) || !expected || !(inputBytes instanceof Uint8Array))
|
|
89
|
-
throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
90
|
-
if (inputBytes.byteLength !== expected.size_bytes) throw new ReportingGcsFenceError("CONTENT_CONFLICT");
|
|
91
|
-
const bytes = Buffer.from(inputBytes);
|
|
92
|
-
if (hash(bytes) !== expected.sha256) throw new ReportingGcsFenceError("CONTENT_CONFLICT");
|
|
93
|
-
active(signal);
|
|
94
|
-
const bucket = storage.bucket(bucketName);
|
|
95
|
-
await probe(bucket, signal);
|
|
96
|
-
active(signal);
|
|
97
|
-
const registered = await store.registerObjectWritePlan(plan, { signal });
|
|
98
|
-
active(signal);
|
|
99
|
-
if (registered === "revoked") throw new ReportingGcsFenceError("REVOKED");
|
|
100
|
-
const file = bucket.file(expected.object_name);
|
|
101
|
-
try {
|
|
102
|
-
await file.save(bytes, {
|
|
103
|
-
resumable: false,
|
|
104
|
-
preconditionOpts: { ifGenerationMatch: 0 },
|
|
105
|
-
metadata: { cacheControl: "no-store" }
|
|
106
|
-
});
|
|
107
|
-
active(signal);
|
|
108
|
-
} catch (error) {
|
|
109
|
-
active(signal);
|
|
110
|
-
if (!status(error, 412)) throw new ReportingGcsFenceError("PROVIDER_UNAVAILABLE");
|
|
111
|
-
try {
|
|
112
|
-
const [metadata] = await file.getMetadata();
|
|
113
|
-
active(signal);
|
|
114
|
-
if (metadata.metadata?.[TOMBSTONE] !== void 0) throw new ReportingGcsFenceError("REVOKED");
|
|
115
|
-
const existing = await readGcsBytes(
|
|
116
|
-
bucket.file(expected.object_name, { generation: metadata.generation }),
|
|
117
|
-
bytes.length,
|
|
118
|
-
signal
|
|
119
|
-
);
|
|
120
|
-
if (existing.length !== bytes.length || hash(existing) !== expected.sha256)
|
|
121
|
-
throw new ReportingGcsFenceError("CONTENT_CONFLICT");
|
|
122
|
-
} catch (error2) {
|
|
123
|
-
active(signal);
|
|
124
|
-
if (status(error2, 404)) {
|
|
125
|
-
const current = await store.registerObjectWritePlan(plan, { signal });
|
|
126
|
-
active(signal);
|
|
127
|
-
if (current === "revoked") throw new ReportingGcsFenceError("REVOKED");
|
|
128
|
-
}
|
|
129
|
-
if (isReportingGcsFenceError(error2)) throw error2;
|
|
130
|
-
throw new ReportingGcsFenceError("PROVIDER_UNAVAILABLE");
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
active(signal);
|
|
134
|
-
if (await store.registerObjectWritePlan(plan, { signal }) === "revoked")
|
|
135
|
-
throw new ReportingGcsFenceError("REVOKED");
|
|
136
|
-
active(signal);
|
|
137
|
-
}
|
|
138
|
-
async function revoke(scopeInput, maxObjects, signal) {
|
|
139
|
-
assertScope(scopeInput);
|
|
140
|
-
const scope = {
|
|
141
|
-
account_id: scopeInput.account_id,
|
|
142
|
-
destination_ref: scopeInput.destination_ref,
|
|
143
|
-
generation: scopeInput.generation
|
|
144
|
-
};
|
|
145
|
-
const limit = maxObjects ?? 10;
|
|
146
|
-
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 1e3) throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
147
|
-
active(signal);
|
|
148
|
-
const binding = await store.getObjectWriteBinding(scope, { signal });
|
|
149
|
-
active(signal);
|
|
150
|
-
const objects = await store.listRevokedObjectWrites(scope, { limit }, { signal });
|
|
151
|
-
active(signal);
|
|
152
|
-
if (!binding) {
|
|
153
|
-
if (objects.length) throw new ReportingGcsFenceError("STATE_UNAVAILABLE");
|
|
154
|
-
return { fenced: 0, complete: true };
|
|
155
|
-
}
|
|
156
|
-
const bucket = storage.bucket(binding.bucket);
|
|
157
|
-
await probe(bucket, signal);
|
|
158
|
-
const scopeKey = reportingObjectWriteScopeKey(scope);
|
|
159
|
-
for (const object of objects) {
|
|
160
|
-
active(signal);
|
|
161
|
-
if (object.bucket !== binding.bucket || object.object_name !== reportingObjectWriteName(scope, binding, object.plan_id, object.object_index))
|
|
162
|
-
throw new ReportingGcsFenceError("STATE_UNAVAILABLE");
|
|
163
|
-
const file = bucket.file(object.object_name);
|
|
164
|
-
let fencedGeneration;
|
|
165
|
-
for (let attempt = 0; attempt < 4 && !fencedGeneration; attempt++) {
|
|
166
|
-
active(signal);
|
|
167
|
-
let generation = 0;
|
|
168
|
-
try {
|
|
169
|
-
const [metadata] = await file.getMetadata();
|
|
170
|
-
active(signal);
|
|
171
|
-
generation = String(metadata.generation);
|
|
172
|
-
if (metadata.metadata?.[TOMBSTONE] === scopeKey && String(metadata.size) === "0") {
|
|
173
|
-
fencedGeneration = String(metadata.generation);
|
|
174
|
-
break;
|
|
175
|
-
}
|
|
176
|
-
} catch (error) {
|
|
177
|
-
active(signal);
|
|
178
|
-
if (!status(error, 404)) throw new ReportingGcsFenceError("PROVIDER_UNAVAILABLE");
|
|
179
|
-
}
|
|
180
|
-
active(signal);
|
|
181
|
-
try {
|
|
182
|
-
await file.save(Buffer.alloc(0), {
|
|
183
|
-
resumable: false,
|
|
184
|
-
preconditionOpts: { ifGenerationMatch: generation },
|
|
185
|
-
metadata: { cacheControl: "no-store", metadata: { [TOMBSTONE]: scopeKey } }
|
|
186
|
-
});
|
|
187
|
-
active(signal);
|
|
188
|
-
const [verified] = await file.getMetadata();
|
|
189
|
-
active(signal);
|
|
190
|
-
if (verified.metadata?.[TOMBSTONE] !== scopeKey || String(verified.size) !== "0")
|
|
191
|
-
throw new ReportingGcsFenceError("PROVIDER_UNAVAILABLE");
|
|
192
|
-
fencedGeneration = String(verified.generation);
|
|
193
|
-
} catch (error) {
|
|
194
|
-
active(signal);
|
|
195
|
-
if (isReportingGcsFenceError(error)) throw error;
|
|
196
|
-
if (!status(error, 412)) throw new ReportingGcsFenceError("PROVIDER_UNAVAILABLE");
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
if (!fencedGeneration) throw new ReportingGcsFenceError("PROVIDER_UNAVAILABLE");
|
|
200
|
-
active(signal);
|
|
201
|
-
await store.markObjectWriteFenced(
|
|
202
|
-
{
|
|
203
|
-
...scope,
|
|
204
|
-
plan_id: object.plan_id,
|
|
205
|
-
object_index: object.object_index,
|
|
206
|
-
tombstone_generation: fencedGeneration
|
|
207
|
-
},
|
|
208
|
-
{ signal }
|
|
209
|
-
);
|
|
210
|
-
active(signal);
|
|
211
|
-
}
|
|
212
|
-
const remaining = await store.listRevokedObjectWrites(scope, { limit: 1 }, { signal });
|
|
213
|
-
active(signal);
|
|
214
|
-
return { fenced: objects.length, complete: remaining.length === 0 };
|
|
215
|
-
}
|
|
216
|
-
function requireSignal(context) {
|
|
217
|
-
if (!(context?.signal instanceof AbortSignal)) throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
218
|
-
return context.signal;
|
|
219
|
-
}
|
|
220
|
-
return {
|
|
221
|
-
probe: async (context) => bounded((signal) => probe(storage.bucket(bucketName), signal), context?.signal),
|
|
222
|
-
register: async (scope, deliveryId, bodies, context) => bounded((signal) => register(scope, deliveryId, bodies, signal), context?.signal),
|
|
223
|
-
write: async (plan, index, bytes, context) => bounded((signal) => write(plan, index, bytes, signal), requireSignal(context)),
|
|
224
|
-
revoke: async (scope, context) => bounded((signal) => revoke(scope, context.maxObjects, signal), requireSignal(context))
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
export {
|
|
228
|
-
ReportingGcsFenceError2 as ReportingGcsFenceError,
|
|
229
|
-
createGcsReportingObjectFenceV1
|
|
230
|
-
};
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Google Cloud Storage fence, reader, managed-delivery adapter and row-object provider for Reliable Reporting.
|
|
3
|
-
*
|
|
4
|
-
* Every export of this subpath is `@experimental` and may change in minor releases.
|
|
5
|
-
*
|
|
6
|
-
* Stability policy: https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
7
|
-
*
|
|
8
|
-
* @packageDocumentation
|
|
9
|
-
*/
|
|
10
|
-
export { createGcsReportingObjectFenceV1 } from './fence.mjs';
|
|
11
|
-
export type { GcsReportingObjectFenceV1 } from './fence.mjs';
|
|
12
|
-
export { ReportingGcsFenceError, isReportingGcsFenceError } from './errors.mjs';
|
|
13
|
-
export { createGcsReportingResourceReaderV1, createGcsReportingReferenceResolverV1 } from './reader.mjs';
|
|
14
|
-
export type { GcsReportingReadScopeV1, GcsReportingReadAuthorizationV1, GcsReportingReaderOptionsV1 } from './reader.mjs';
|
|
15
|
-
export { createGcsReportingManagedDeliveryAdapterV1 } from './adapter.mjs';
|
|
16
|
-
export type { CreateGcsReportingManagedDeliveryAdapterOptionsV1 } from './adapter.mjs';
|
|
17
|
-
export { createGcsReportingRowObjectProviderV1 } from './row-provider.mjs';
|
|
18
|
-
export type { CreateGcsReportingRowObjectProviderOptionsV1 } from './row-provider.mjs';
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Google Cloud Storage fence, reader, managed-delivery adapter and row-object provider for Reliable Reporting.
|
|
3
|
-
*
|
|
4
|
-
* Every export of this subpath is `@experimental` and may change in minor releases.
|
|
5
|
-
*
|
|
6
|
-
* Stability policy: https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
7
|
-
*
|
|
8
|
-
* @packageDocumentation
|
|
9
|
-
*/
|
|
10
|
-
export { createGcsReportingObjectFenceV1 } from './fence';
|
|
11
|
-
export type { GcsReportingObjectFenceV1 } from './fence';
|
|
12
|
-
export { ReportingGcsFenceError, isReportingGcsFenceError } from './errors';
|
|
13
|
-
export { createGcsReportingResourceReaderV1, createGcsReportingReferenceResolverV1 } from './reader';
|
|
14
|
-
export type { GcsReportingReadScopeV1, GcsReportingReadAuthorizationV1, GcsReportingReaderOptionsV1 } from './reader';
|
|
15
|
-
export { createGcsReportingManagedDeliveryAdapterV1 } from './adapter';
|
|
16
|
-
export type { CreateGcsReportingManagedDeliveryAdapterOptionsV1 } from './adapter';
|
|
17
|
-
export { createGcsReportingRowObjectProviderV1 } from './row-provider';
|
|
18
|
-
export type { CreateGcsReportingRowObjectProviderOptionsV1 } from './row-provider';
|