@adcp/sdk 16.0.0-beta.3 → 16.0.0-beta.5
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/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/index.d.mts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.js +2 -0
- package/dist/lib/index.mjs +7 -1
- 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/signer.js +9 -6
- package/dist/lib/signing/signer.mjs +10 -7
- package/dist/lib/signing/web-bot-auth.js +103 -37
- package/dist/lib/signing/web-bot-auth.mjs +108 -37
- 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 +10 -9
- package/dist/lib/testing/storyboard/request-signing/builder.mjs +10 -9
- package/dist/lib/testing/storyboard/runner.js +94 -25
- package/dist/lib/testing/storyboard/runner.mjs +94 -25
- 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/schemas.generated.d.ts +907 -60
- package/dist/lib/types/schemas.generated.js +7 -7
- package/dist/lib/types/schemas.generated.mjs +7 -7
- 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 +23 -5
- 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/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 +13 -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,169 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CanonicalDocumentReadError,
|
|
3
|
-
createCanonicalReferenceResolver
|
|
4
|
-
} from "../../canonical-references/index.mjs";
|
|
5
|
-
import { assertReportingObjectWriteScope } from "../ledger/object-writes.mjs";
|
|
6
|
-
import { ReportingGcsFenceError, isReportingGcsFenceError } from "./errors.mjs";
|
|
7
|
-
import { activeGcsSignal, readGcsBytes, withGcsDeadline } from "./io.mjs";
|
|
8
|
-
function gcsReportingObjectFromUriV1(uri, bucket, prefix) {
|
|
9
|
-
if (typeof uri !== "string" || uri.length > 2048) throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
10
|
-
const expectedBase = `https://storage.googleapis.com/${bucket}/`;
|
|
11
|
-
let parsed;
|
|
12
|
-
try {
|
|
13
|
-
parsed = new URL(uri);
|
|
14
|
-
} catch {
|
|
15
|
-
throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
16
|
-
}
|
|
17
|
-
const name = uri.startsWith(expectedBase) ? uri.slice(expectedBase.length) : "";
|
|
18
|
-
if (parsed.href !== uri || parsed.username || parsed.password || parsed.search || parsed.hash || !name.startsWith(prefix) || name.length <= prefix.length || name.length > 1024 || !/^[A-Za-z0-9/_.-]+$/.test(name) || name.split("/").some((part) => !part || part === "." || part === ".."))
|
|
19
|
-
throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
20
|
-
return name;
|
|
21
|
-
}
|
|
22
|
-
function createGcsScopedObjectReadV1(options) {
|
|
23
|
-
let scope;
|
|
24
|
-
try {
|
|
25
|
-
scope = structuredClone(options.scope);
|
|
26
|
-
assertReportingObjectWriteScope(scope);
|
|
27
|
-
} catch {
|
|
28
|
-
throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
29
|
-
}
|
|
30
|
-
if (typeof scope.principal_id !== "string" || scope.principal_id.length < 1 || scope.principal_id.length > 255 || typeof options.bucket !== "string" || !/^[a-z0-9][a-z0-9.-]{1,220}[a-z0-9]$/.test(options.bucket) || typeof options.objectPrefix !== "string" || !/^[A-Za-z0-9/_.-]+\/$/.test(options.objectPrefix) || options.objectPrefix.length > 1e3 || options.objectPrefix.split("/").slice(0, -1).some((p) => !p || p === "." || p === "..") || typeof options.authorize !== "function" || typeof options.getStorage !== "function")
|
|
31
|
-
throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
32
|
-
Object.freeze(scope);
|
|
33
|
-
const { bucket, objectPrefix, authorize, getStorage, signal: parentSignal } = options;
|
|
34
|
-
if (parentSignal !== void 0 && !(parentSignal instanceof AbortSignal))
|
|
35
|
-
throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
36
|
-
const maximum = options.maxBytes ?? 64 * 1024 * 1024;
|
|
37
|
-
const milliseconds = options.operationDeadlineMilliseconds ?? 6e4;
|
|
38
|
-
if (!Number.isSafeInteger(maximum) || maximum < 1 || maximum > 64 * 1024 * 1024 || !Number.isSafeInteger(milliseconds) || milliseconds < 1 || milliseconds > 6e4)
|
|
39
|
-
throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
40
|
-
async function authorized(signal, objectName) {
|
|
41
|
-
activeGcsSignal(signal);
|
|
42
|
-
const allowed = await authorize({ scope, bucket, objectPrefix, objectName }, { signal });
|
|
43
|
-
activeGcsSignal(signal);
|
|
44
|
-
if (allowed !== true) throw new ReportingGcsFenceError("REVOKED");
|
|
45
|
-
}
|
|
46
|
-
return async (uri, maxBytes, signal, nativeVersion) => withGcsDeadline(
|
|
47
|
-
async (active) => {
|
|
48
|
-
const name = gcsReportingObjectFromUriV1(uri, bucket, objectPrefix);
|
|
49
|
-
if (!Number.isSafeInteger(maxBytes) || maxBytes < 1 || nativeVersion !== void 0 && !/^[1-9][0-9]{0,39}$/.test(nativeVersion))
|
|
50
|
-
throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
51
|
-
await authorized(active, name);
|
|
52
|
-
const storage = await getStorage(scope, { signal: active });
|
|
53
|
-
activeGcsSignal(active);
|
|
54
|
-
try {
|
|
55
|
-
const file = storage.bucket(bucket).file(name, nativeVersion ? { generation: nativeVersion } : void 0);
|
|
56
|
-
const [metadata] = await file.getMetadata();
|
|
57
|
-
activeGcsSignal(active);
|
|
58
|
-
if (metadata.metadata?.adcp_reporting_tombstone !== void 0) throw new ReportingGcsFenceError("REVOKED");
|
|
59
|
-
const generation = String(metadata.generation);
|
|
60
|
-
if (nativeVersion !== void 0 && generation !== nativeVersion)
|
|
61
|
-
throw new ReportingGcsFenceError("CONTENT_CONFLICT");
|
|
62
|
-
if (!/^[1-9][0-9]{0,39}$/.test(generation) || !/^(?:0|[1-9][0-9]{0,19})$/.test(String(metadata.size)) || BigInt(String(metadata.size)) > BigInt(Math.min(maxBytes, maximum)))
|
|
63
|
-
throw new ReportingGcsFenceError("CONTENT_CONFLICT");
|
|
64
|
-
const body = await readGcsBytes(
|
|
65
|
-
storage.bucket(bucket).file(name, { generation }),
|
|
66
|
-
Math.min(maxBytes, maximum),
|
|
67
|
-
active
|
|
68
|
-
);
|
|
69
|
-
activeGcsSignal(active);
|
|
70
|
-
await authorized(active, name);
|
|
71
|
-
return { body, contentType: metadata.contentType, generation };
|
|
72
|
-
} catch (error) {
|
|
73
|
-
activeGcsSignal(active);
|
|
74
|
-
if (isReportingGcsFenceError(error)) throw error;
|
|
75
|
-
await authorized(active, name);
|
|
76
|
-
throw new ReportingGcsFenceError("PROVIDER_UNAVAILABLE");
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
signal: parentSignal && signal ? AbortSignal.any([parentSignal, signal]) : parentSignal ?? signal,
|
|
81
|
-
milliseconds
|
|
82
|
-
}
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
function createGcsReportingResourceReaderV1(options) {
|
|
86
|
-
const read = createGcsScopedObjectReadV1(options);
|
|
87
|
-
const scope = structuredClone(options.scope);
|
|
88
|
-
const { bucket, objectPrefix } = options;
|
|
89
|
-
return {
|
|
90
|
-
async read(request) {
|
|
91
|
-
if (!request?.context?.materialization?.resource || !["manifest", "object"].includes(request.role) || request.context.obligation?.account_id !== scope.account_id || request.location !== request.context.materialization.resource.location || request.context.materialization.destination_ref !== scope.destination_ref)
|
|
92
|
-
throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
93
|
-
let uri = request.location;
|
|
94
|
-
if (request.role === "object") {
|
|
95
|
-
if (typeof request.objectRef !== "string" || !/^[A-Za-z0-9_.-]+$/.test(request.objectRef) || request.objectRef === "." || request.objectRef === "..")
|
|
96
|
-
throw new ReportingGcsFenceError("INVALID_INPUT");
|
|
97
|
-
const name = gcsReportingObjectFromUriV1(request.location, bucket, objectPrefix);
|
|
98
|
-
uri = `https://storage.googleapis.com/${bucket}/${name.slice(0, name.lastIndexOf("/") + 1)}${request.objectRef}`;
|
|
99
|
-
}
|
|
100
|
-
return read(
|
|
101
|
-
uri,
|
|
102
|
-
request.maxBytes,
|
|
103
|
-
request.signal,
|
|
104
|
-
request.role === "manifest" ? request.context.materialization.resource?.native_version_ref : void 0
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
function createGcsReportingReferenceResolverV1(options) {
|
|
110
|
-
const read = createGcsScopedObjectReadV1(options);
|
|
111
|
-
const documentReader = {
|
|
112
|
-
async read(request) {
|
|
113
|
-
try {
|
|
114
|
-
return await read(request.uri, request.maxBytes, request.signal);
|
|
115
|
-
} catch (error) {
|
|
116
|
-
if (isReportingGcsFenceError(error)) {
|
|
117
|
-
if (error.code === "ABORTED") throw new CanonicalDocumentReadError("aborted");
|
|
118
|
-
if (error.code === "INVALID_INPUT") throw new CanonicalDocumentReadError("unsafe_url");
|
|
119
|
-
if (error.code === "REVOKED") throw new CanonicalDocumentReadError("access_denied");
|
|
120
|
-
if (error.code === "CONTENT_CONFLICT") throw new CanonicalDocumentReadError("body_too_large");
|
|
121
|
-
}
|
|
122
|
-
throw new CanonicalDocumentReadError("network_error");
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
const parentSignal = options.signal;
|
|
127
|
-
const resolver = createCanonicalReferenceResolver({ documentReader, signal: parentSignal });
|
|
128
|
-
const routing = { bucket: options.bucket, objectPrefix: options.objectPrefix };
|
|
129
|
-
const forced = (input) => ({
|
|
130
|
-
...input,
|
|
131
|
-
documentReader,
|
|
132
|
-
signal: parentSignal && input?.signal ? AbortSignal.any([parentSignal, input.signal]) : parentSignal ?? input?.signal
|
|
133
|
-
});
|
|
134
|
-
function blocked(ref, kind) {
|
|
135
|
-
try {
|
|
136
|
-
gcsReportingObjectFromUriV1(ref.uri, routing.bucket, routing.objectPrefix);
|
|
137
|
-
return void 0;
|
|
138
|
-
} catch {
|
|
139
|
-
return {
|
|
140
|
-
ok: false,
|
|
141
|
-
status: "blocked_unsafe_url",
|
|
142
|
-
kind,
|
|
143
|
-
ref: {
|
|
144
|
-
uri: "https://storage.googleapis.com/redacted-invalid-reference",
|
|
145
|
-
digest: /^sha256:[a-f0-9]{64}$/.test(ref?.digest) ? ref.digest : "invalid"
|
|
146
|
-
},
|
|
147
|
-
cacheKey: "private-reference-refused",
|
|
148
|
-
fromCache: false,
|
|
149
|
-
error: {
|
|
150
|
-
code: "unsafe_url",
|
|
151
|
-
message: "Private reference is outside the saved destination scope",
|
|
152
|
-
retryable: false
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
return {
|
|
158
|
-
cache: resolver.cache,
|
|
159
|
-
resolve: async (ref, context) => blocked(ref, "generic") ?? resolver.resolve(ref, forced(context)),
|
|
160
|
-
resolveFormatSchema: async (ref, context) => blocked(ref, "format_schema") ?? resolver.resolveFormatSchema(ref, forced(context)),
|
|
161
|
-
resolvePlatformExtensions: async (ref, context) => blocked(ref, "platform_extensions") ?? resolver.resolvePlatformExtensions(ref, forced(context))
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
export {
|
|
165
|
-
createGcsReportingReferenceResolverV1,
|
|
166
|
-
createGcsReportingResourceReaderV1,
|
|
167
|
-
createGcsScopedObjectReadV1,
|
|
168
|
-
gcsReportingObjectFromUriV1
|
|
169
|
-
};
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { BucketMetadata, Storage } from '@google-cloud/storage';
|
|
2
|
-
import type { ReportingRowObjectProviderV1 } from '../ledger/row-storage-object.mjs';
|
|
3
|
-
/**
|
|
4
|
-
* @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
|
|
5
|
-
*/
|
|
6
|
-
export interface CreateGcsReportingRowObjectProviderOptionsV1 {
|
|
7
|
-
/** Official client used by bindings without a `credentialRef`. */
|
|
8
|
-
storage?: Storage;
|
|
9
|
-
/**
|
|
10
|
-
* Official clients keyed by `credentialRef`. This map is the closed set of
|
|
11
|
-
* references a binding may name; an unknown reference fails `UNSAFE_BINDING`.
|
|
12
|
-
*/
|
|
13
|
-
clients?: Readonly<Record<string, Storage>>;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Row-binding bucket policy (shared persistence spec §3.4). Unlike the Managed
|
|
17
|
-
* Delivery probe, versioning, soft delete and retention are allowed as
|
|
18
|
-
* backstops. Refused: buckets without uniform bucket-level access or enforced
|
|
19
|
-
* public access prevention, and any lifecycle `Delete` rule that can match a
|
|
20
|
-
* live object under the binding prefix (no prefix filter, or a prefix that
|
|
21
|
-
* overlaps it). Rules limited to noncurrent versions are allowed.
|
|
22
|
-
*
|
|
23
|
-
* @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
|
|
24
|
-
*/
|
|
25
|
-
export declare function assertGcsReportingRowBucketPolicyV1(metadata: BucketMetadata, prefix: string): void;
|
|
26
|
-
/**
|
|
27
|
-
* Google Cloud Storage row-object provider (`@adcp/sdk/reporting/gcs`).
|
|
28
|
-
*
|
|
29
|
-
* Inject official `Storage` clients with host-owned, keyless credentials.
|
|
30
|
-
* Bindings use `location: { bucket }`; `credentialRef` selects an injected
|
|
31
|
-
* client. Writes are single-request uploads with `ifGenerationMatch: 0`, so an
|
|
32
|
-
* existing object is never replaced; the recorded native version is the
|
|
33
|
-
* object generation, and reads and deletes pin it. Objects are stored without
|
|
34
|
-
* `Content-Encoding`, and reads request raw stored bytes, so GCS never
|
|
35
|
-
* transcodes them.
|
|
36
|
-
*
|
|
37
|
-
* @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
|
|
38
|
-
*/
|
|
39
|
-
export declare function createGcsReportingRowObjectProviderV1(options: CreateGcsReportingRowObjectProviderOptionsV1): ReportingRowObjectProviderV1;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { BucketMetadata, Storage } from '@google-cloud/storage';
|
|
2
|
-
import type { ReportingRowObjectProviderV1 } from '../ledger/row-storage-object';
|
|
3
|
-
/**
|
|
4
|
-
* @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
|
|
5
|
-
*/
|
|
6
|
-
export interface CreateGcsReportingRowObjectProviderOptionsV1 {
|
|
7
|
-
/** Official client used by bindings without a `credentialRef`. */
|
|
8
|
-
storage?: Storage;
|
|
9
|
-
/**
|
|
10
|
-
* Official clients keyed by `credentialRef`. This map is the closed set of
|
|
11
|
-
* references a binding may name; an unknown reference fails `UNSAFE_BINDING`.
|
|
12
|
-
*/
|
|
13
|
-
clients?: Readonly<Record<string, Storage>>;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Row-binding bucket policy (shared persistence spec §3.4). Unlike the Managed
|
|
17
|
-
* Delivery probe, versioning, soft delete and retention are allowed as
|
|
18
|
-
* backstops. Refused: buckets without uniform bucket-level access or enforced
|
|
19
|
-
* public access prevention, and any lifecycle `Delete` rule that can match a
|
|
20
|
-
* live object under the binding prefix (no prefix filter, or a prefix that
|
|
21
|
-
* overlaps it). Rules limited to noncurrent versions are allowed.
|
|
22
|
-
*
|
|
23
|
-
* @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
|
|
24
|
-
*/
|
|
25
|
-
export declare function assertGcsReportingRowBucketPolicyV1(metadata: BucketMetadata, prefix: string): void;
|
|
26
|
-
/**
|
|
27
|
-
* Google Cloud Storage row-object provider (`@adcp/sdk/reporting/gcs`).
|
|
28
|
-
*
|
|
29
|
-
* Inject official `Storage` clients with host-owned, keyless credentials.
|
|
30
|
-
* Bindings use `location: { bucket }`; `credentialRef` selects an injected
|
|
31
|
-
* client. Writes are single-request uploads with `ifGenerationMatch: 0`, so an
|
|
32
|
-
* existing object is never replaced; the recorded native version is the
|
|
33
|
-
* object generation, and reads and deletes pin it. Objects are stored without
|
|
34
|
-
* `Content-Encoding`, and reads request raw stored bytes, so GCS never
|
|
35
|
-
* transcodes them.
|
|
36
|
-
*
|
|
37
|
-
* @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
|
|
38
|
-
*/
|
|
39
|
-
export declare function createGcsReportingRowObjectProviderV1(options: CreateGcsReportingRowObjectProviderOptionsV1): ReportingRowObjectProviderV1;
|
|
@@ -1,225 +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 row_provider_exports = {};
|
|
20
|
-
__export(row_provider_exports, {
|
|
21
|
-
assertGcsReportingRowBucketPolicyV1: () => assertGcsReportingRowBucketPolicyV1,
|
|
22
|
-
createGcsReportingRowObjectProviderV1: () => createGcsReportingRowObjectProviderV1
|
|
23
|
-
});
|
|
24
|
-
module.exports = __toCommonJS(row_provider_exports);
|
|
25
|
-
var import_node_crypto = require("node:crypto");
|
|
26
|
-
var import_row_storage_errors = require('../ledger/row-storage-errors.js');
|
|
27
|
-
var import_row_storage_provider_io = require('../ledger/row-storage-provider-io.js');
|
|
28
|
-
const BUCKET = /^[a-z0-9][a-z0-9._-]{1,220}[a-z0-9]$/;
|
|
29
|
-
const GENERATION = /^[1-9][0-9]{0,15}$/;
|
|
30
|
-
const NONCURRENT_ONLY_CONDITIONS = ["numNewerVersions", "daysSinceNoncurrentTime", "noncurrentTimeBefore"];
|
|
31
|
-
function status(error) {
|
|
32
|
-
if (!error || typeof error !== "object" || !("code" in error)) return void 0;
|
|
33
|
-
const code = Number(error.code);
|
|
34
|
-
return Number.isInteger(code) ? code : void 0;
|
|
35
|
-
}
|
|
36
|
-
function generationOf(metadata) {
|
|
37
|
-
const generation = metadata?.generation === void 0 ? "" : String(metadata.generation);
|
|
38
|
-
if (!GENERATION.test(generation) || !Number.isSafeInteger(Number(generation))) {
|
|
39
|
-
throw new import_row_storage_errors.ReportingRowStoreError("PROVIDER_UNAVAILABLE", "object generation is missing");
|
|
40
|
-
}
|
|
41
|
-
return generation;
|
|
42
|
-
}
|
|
43
|
-
function pinnedGeneration(nativeVersionRef) {
|
|
44
|
-
return typeof nativeVersionRef === "string" && GENERATION.test(nativeVersionRef) && Number.isSafeInteger(Number(nativeVersionRef)) ? nativeVersionRef : null;
|
|
45
|
-
}
|
|
46
|
-
function assertGcsReportingRowBucketPolicyV1(metadata, prefix) {
|
|
47
|
-
if (!metadata || typeof metadata !== "object") {
|
|
48
|
-
throw new import_row_storage_errors.ReportingRowStoreError("UNSAFE_BINDING", "bucket policy is unavailable");
|
|
49
|
-
}
|
|
50
|
-
if (metadata.iamConfiguration?.uniformBucketLevelAccess?.enabled !== true) {
|
|
51
|
-
throw new import_row_storage_errors.ReportingRowStoreError("UNSAFE_BINDING", "bucket must enable uniform bucket-level access");
|
|
52
|
-
}
|
|
53
|
-
if (metadata.iamConfiguration?.publicAccessPrevention !== "enforced") {
|
|
54
|
-
throw new import_row_storage_errors.ReportingRowStoreError("UNSAFE_BINDING", "bucket must enforce public access prevention");
|
|
55
|
-
}
|
|
56
|
-
for (const rule of metadata.lifecycle?.rule ?? []) {
|
|
57
|
-
if (rule?.action?.type !== "Delete") continue;
|
|
58
|
-
const condition = rule.condition ?? {};
|
|
59
|
-
if (condition.isLive === false) continue;
|
|
60
|
-
if (NONCURRENT_ONLY_CONDITIONS.some((name) => condition[name] !== void 0 && condition[name] !== null)) continue;
|
|
61
|
-
const prefixes = condition.matchesPrefix ?? [];
|
|
62
|
-
if (prefixes.length === 0 || prefixes.some((filter) => (0, import_row_storage_provider_io.reportingRowPrefixFilterOverlaps)(filter, prefix))) {
|
|
63
|
-
throw new import_row_storage_errors.ReportingRowStoreError("UNSAFE_BINDING", "a bucket lifecycle rule can delete live row objects");
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
function createGcsReportingRowObjectProviderV1(options) {
|
|
68
|
-
if (!options || typeof options !== "object") {
|
|
69
|
-
throw new import_row_storage_errors.ReportingRowStoreError("INVALID_INPUT", "GCS row provider options are required");
|
|
70
|
-
}
|
|
71
|
-
const clients = (0, import_row_storage_provider_io.reportingRowClientMap)(options.clients);
|
|
72
|
-
const isStorage = (value) => !!value && typeof value === "object" && typeof value.bucket === "function";
|
|
73
|
-
if (options.storage !== void 0 && !isStorage(options.storage) || [...clients.values()].some((client) => !isStorage(client)) || options.storage === void 0 && clients.size === 0) {
|
|
74
|
-
throw new import_row_storage_errors.ReportingRowStoreError("INVALID_INPUT", "inject an official Storage client as storage or clients");
|
|
75
|
-
}
|
|
76
|
-
const validateLocation = (location) => {
|
|
77
|
-
(0, import_row_storage_provider_io.assertReportingRowLocationKeys)(location, ["bucket"]);
|
|
78
|
-
if (!BUCKET.test(location.bucket) || location.bucket.includes("..")) {
|
|
79
|
-
throw new import_row_storage_errors.ReportingRowStoreError("INVALID_INPUT", "GCS bucket name is invalid");
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
const bucketFor = (input) => {
|
|
83
|
-
validateLocation(input.location);
|
|
84
|
-
return (0, import_row_storage_provider_io.selectReportingRowClient)(options.storage, clients, input.credentialRef).bucket(input.location.bucket);
|
|
85
|
-
};
|
|
86
|
-
const assertKey = (key) => {
|
|
87
|
-
if (typeof key !== "string" || key.length === 0 || Buffer.byteLength(key) > 1024) {
|
|
88
|
-
throw new import_row_storage_errors.ReportingRowStoreError("INVALID_INPUT", "object key is invalid");
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
return {
|
|
92
|
-
name: "gcs",
|
|
93
|
-
rangedReads: true,
|
|
94
|
-
validateLocation,
|
|
95
|
-
probe(input, context) {
|
|
96
|
-
return (0, import_row_storage_provider_io.runReportingRowProviderOperation)(context.signal, async () => {
|
|
97
|
-
const bucket = bucketFor(input);
|
|
98
|
-
let metadata;
|
|
99
|
-
try {
|
|
100
|
-
[metadata] = await bucket.getMetadata();
|
|
101
|
-
} catch (error) {
|
|
102
|
-
const code = status(error);
|
|
103
|
-
if (code === 404) throw new import_row_storage_errors.ReportingRowStoreError("UNSAFE_BINDING", "bucket does not exist");
|
|
104
|
-
if (code === 401 || code === 403) {
|
|
105
|
-
throw new import_row_storage_errors.ReportingRowStoreError("UNSAFE_BINDING", "bucket policy cannot be read with this client");
|
|
106
|
-
}
|
|
107
|
-
throw error;
|
|
108
|
-
}
|
|
109
|
-
assertGcsReportingRowBucketPolicyV1(metadata, input.prefix);
|
|
110
|
-
});
|
|
111
|
-
},
|
|
112
|
-
putIfAbsent(input, context) {
|
|
113
|
-
return (0, import_row_storage_provider_io.runReportingRowProviderOperation)(context.signal, async () => {
|
|
114
|
-
const bucket = bucketFor(input);
|
|
115
|
-
assertKey(input.objectRef);
|
|
116
|
-
const file = bucket.file(input.objectRef);
|
|
117
|
-
try {
|
|
118
|
-
const bytes = Buffer.from(input.bytes);
|
|
119
|
-
await file.save(bytes, {
|
|
120
|
-
resumable: false,
|
|
121
|
-
gzip: false,
|
|
122
|
-
// GCS verifies the declared MD5 before creating the object, so a corrupted upload
|
|
123
|
-
// is refused server-side. Client-side validation is off because on mismatch the
|
|
124
|
-
// client deletes the key without a generation precondition.
|
|
125
|
-
validation: false,
|
|
126
|
-
contentType: input.contentType,
|
|
127
|
-
metadata: {
|
|
128
|
-
contentType: input.contentType,
|
|
129
|
-
md5Hash: (0, import_node_crypto.createHash)("md5").update(bytes).digest("base64"),
|
|
130
|
-
cacheControl: "no-store",
|
|
131
|
-
metadata: { ...input.metadata }
|
|
132
|
-
},
|
|
133
|
-
preconditionOpts: { ifGenerationMatch: 0 }
|
|
134
|
-
});
|
|
135
|
-
} catch (error) {
|
|
136
|
-
if (status(error) !== 412) throw error;
|
|
137
|
-
context.signal.throwIfAborted();
|
|
138
|
-
const [existing] = await bucket.file(input.objectRef).getMetadata();
|
|
139
|
-
return { created: false, nativeVersionRef: generationOf(existing) };
|
|
140
|
-
}
|
|
141
|
-
if (file.metadata?.generation !== void 0) {
|
|
142
|
-
return { created: true, nativeVersionRef: generationOf(file.metadata) };
|
|
143
|
-
}
|
|
144
|
-
const [created] = await file.getMetadata();
|
|
145
|
-
return { created: true, nativeVersionRef: generationOf(created) };
|
|
146
|
-
});
|
|
147
|
-
},
|
|
148
|
-
get(input, context) {
|
|
149
|
-
return (0, import_row_storage_provider_io.runReportingRowProviderOperation)(context.signal, async () => {
|
|
150
|
-
const bucket = bucketFor(input);
|
|
151
|
-
assertKey(input.objectRef);
|
|
152
|
-
(0, import_row_storage_provider_io.assertReportingRowReadBounds)(input);
|
|
153
|
-
const generation = pinnedGeneration(input.nativeVersionRef);
|
|
154
|
-
if (generation === null) return null;
|
|
155
|
-
const file = bucket.file(input.objectRef, { generation });
|
|
156
|
-
try {
|
|
157
|
-
if (input.range?.length === 0) {
|
|
158
|
-
const [metadata] = await file.getMetadata();
|
|
159
|
-
if (input.range.offset > Number(metadata.size)) {
|
|
160
|
-
throw new import_row_storage_errors.ReportingRowStoreError("ROWS_INTEGRITY_FAILED", "requested range exceeds the stored object");
|
|
161
|
-
}
|
|
162
|
-
return Buffer.alloc(0);
|
|
163
|
-
}
|
|
164
|
-
const stream = file.createReadStream({
|
|
165
|
-
// The client always sends `Accept-Encoding: gzip`; with `decompress: false`
|
|
166
|
-
// neither GCS nor the client transcodes, so these are the stored bytes.
|
|
167
|
-
decompress: false,
|
|
168
|
-
// Digests recorded in PostgreSQL verify every byte returned.
|
|
169
|
-
validation: false,
|
|
170
|
-
...input.range ? { start: input.range.offset, end: input.range.offset + input.range.length - 1 } : {}
|
|
171
|
-
});
|
|
172
|
-
return await (0, import_row_storage_provider_io.readReportingRowStream)(stream, input.maxBytes, context.signal);
|
|
173
|
-
} catch (error) {
|
|
174
|
-
const code = status(error);
|
|
175
|
-
if (code === 404) return null;
|
|
176
|
-
if (code === 416) {
|
|
177
|
-
throw new import_row_storage_errors.ReportingRowStoreError("ROWS_INTEGRITY_FAILED", "requested range exceeds the stored object");
|
|
178
|
-
}
|
|
179
|
-
throw error;
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
},
|
|
183
|
-
stat(input, context) {
|
|
184
|
-
return (0, import_row_storage_provider_io.runReportingRowProviderOperation)(context.signal, async () => {
|
|
185
|
-
const bucket = bucketFor(input);
|
|
186
|
-
assertKey(input.objectRef);
|
|
187
|
-
const generation = pinnedGeneration(input.nativeVersionRef);
|
|
188
|
-
if (generation === null) return null;
|
|
189
|
-
try {
|
|
190
|
-
const [metadata] = await bucket.file(input.objectRef, { generation }).getMetadata();
|
|
191
|
-
const size = Number(metadata.size);
|
|
192
|
-
if (String(metadata.generation) !== generation) return null;
|
|
193
|
-
if (!Number.isSafeInteger(size) || size < 0) {
|
|
194
|
-
throw new import_row_storage_errors.ReportingRowStoreError("PROVIDER_UNAVAILABLE", "object metadata is malformed");
|
|
195
|
-
}
|
|
196
|
-
return { nativeVersionRef: generation, sizeBytes: size };
|
|
197
|
-
} catch (error) {
|
|
198
|
-
if (status(error) === 404) return null;
|
|
199
|
-
throw error;
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
},
|
|
203
|
-
delete(input, context) {
|
|
204
|
-
return (0, import_row_storage_provider_io.runReportingRowProviderOperation)(context.signal, async () => {
|
|
205
|
-
const bucket = bucketFor(input);
|
|
206
|
-
assertKey(input.objectRef);
|
|
207
|
-
const generation = pinnedGeneration(input.nativeVersionRef);
|
|
208
|
-
if (generation === null) return "absent";
|
|
209
|
-
try {
|
|
210
|
-
await bucket.file(input.objectRef, { generation }).delete();
|
|
211
|
-
return "deleted";
|
|
212
|
-
} catch (error) {
|
|
213
|
-
const code = status(error);
|
|
214
|
-
if (code === 404 || code === 412) return "absent";
|
|
215
|
-
throw error;
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
222
|
-
0 && (module.exports = {
|
|
223
|
-
assertGcsReportingRowBucketPolicyV1,
|
|
224
|
-
createGcsReportingRowObjectProviderV1
|
|
225
|
-
});
|