@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,208 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import { ReportingRowStoreError } from "../ledger/row-storage-errors.mjs";
|
|
3
|
-
import {
|
|
4
|
-
assertReportingRowLocationKeys,
|
|
5
|
-
assertReportingRowReadBounds,
|
|
6
|
-
readReportingRowStream,
|
|
7
|
-
reportingRowClientMap,
|
|
8
|
-
reportingRowPrefixFilterOverlaps,
|
|
9
|
-
runReportingRowProviderOperation,
|
|
10
|
-
selectReportingRowClient
|
|
11
|
-
} from "../ledger/row-storage-provider-io.mjs";
|
|
12
|
-
const BUCKET = /^[a-z0-9][a-z0-9._-]{1,220}[a-z0-9]$/;
|
|
13
|
-
const GENERATION = /^[1-9][0-9]{0,15}$/;
|
|
14
|
-
const NONCURRENT_ONLY_CONDITIONS = ["numNewerVersions", "daysSinceNoncurrentTime", "noncurrentTimeBefore"];
|
|
15
|
-
function status(error) {
|
|
16
|
-
if (!error || typeof error !== "object" || !("code" in error)) return void 0;
|
|
17
|
-
const code = Number(error.code);
|
|
18
|
-
return Number.isInteger(code) ? code : void 0;
|
|
19
|
-
}
|
|
20
|
-
function generationOf(metadata) {
|
|
21
|
-
const generation = metadata?.generation === void 0 ? "" : String(metadata.generation);
|
|
22
|
-
if (!GENERATION.test(generation) || !Number.isSafeInteger(Number(generation))) {
|
|
23
|
-
throw new ReportingRowStoreError("PROVIDER_UNAVAILABLE", "object generation is missing");
|
|
24
|
-
}
|
|
25
|
-
return generation;
|
|
26
|
-
}
|
|
27
|
-
function pinnedGeneration(nativeVersionRef) {
|
|
28
|
-
return typeof nativeVersionRef === "string" && GENERATION.test(nativeVersionRef) && Number.isSafeInteger(Number(nativeVersionRef)) ? nativeVersionRef : null;
|
|
29
|
-
}
|
|
30
|
-
function assertGcsReportingRowBucketPolicyV1(metadata, prefix) {
|
|
31
|
-
if (!metadata || typeof metadata !== "object") {
|
|
32
|
-
throw new ReportingRowStoreError("UNSAFE_BINDING", "bucket policy is unavailable");
|
|
33
|
-
}
|
|
34
|
-
if (metadata.iamConfiguration?.uniformBucketLevelAccess?.enabled !== true) {
|
|
35
|
-
throw new ReportingRowStoreError("UNSAFE_BINDING", "bucket must enable uniform bucket-level access");
|
|
36
|
-
}
|
|
37
|
-
if (metadata.iamConfiguration?.publicAccessPrevention !== "enforced") {
|
|
38
|
-
throw new ReportingRowStoreError("UNSAFE_BINDING", "bucket must enforce public access prevention");
|
|
39
|
-
}
|
|
40
|
-
for (const rule of metadata.lifecycle?.rule ?? []) {
|
|
41
|
-
if (rule?.action?.type !== "Delete") continue;
|
|
42
|
-
const condition = rule.condition ?? {};
|
|
43
|
-
if (condition.isLive === false) continue;
|
|
44
|
-
if (NONCURRENT_ONLY_CONDITIONS.some((name) => condition[name] !== void 0 && condition[name] !== null)) continue;
|
|
45
|
-
const prefixes = condition.matchesPrefix ?? [];
|
|
46
|
-
if (prefixes.length === 0 || prefixes.some((filter) => reportingRowPrefixFilterOverlaps(filter, prefix))) {
|
|
47
|
-
throw new ReportingRowStoreError("UNSAFE_BINDING", "a bucket lifecycle rule can delete live row objects");
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
function createGcsReportingRowObjectProviderV1(options) {
|
|
52
|
-
if (!options || typeof options !== "object") {
|
|
53
|
-
throw new ReportingRowStoreError("INVALID_INPUT", "GCS row provider options are required");
|
|
54
|
-
}
|
|
55
|
-
const clients = reportingRowClientMap(options.clients);
|
|
56
|
-
const isStorage = (value) => !!value && typeof value === "object" && typeof value.bucket === "function";
|
|
57
|
-
if (options.storage !== void 0 && !isStorage(options.storage) || [...clients.values()].some((client) => !isStorage(client)) || options.storage === void 0 && clients.size === 0) {
|
|
58
|
-
throw new ReportingRowStoreError("INVALID_INPUT", "inject an official Storage client as storage or clients");
|
|
59
|
-
}
|
|
60
|
-
const validateLocation = (location) => {
|
|
61
|
-
assertReportingRowLocationKeys(location, ["bucket"]);
|
|
62
|
-
if (!BUCKET.test(location.bucket) || location.bucket.includes("..")) {
|
|
63
|
-
throw new ReportingRowStoreError("INVALID_INPUT", "GCS bucket name is invalid");
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
const bucketFor = (input) => {
|
|
67
|
-
validateLocation(input.location);
|
|
68
|
-
return selectReportingRowClient(options.storage, clients, input.credentialRef).bucket(input.location.bucket);
|
|
69
|
-
};
|
|
70
|
-
const assertKey = (key) => {
|
|
71
|
-
if (typeof key !== "string" || key.length === 0 || Buffer.byteLength(key) > 1024) {
|
|
72
|
-
throw new ReportingRowStoreError("INVALID_INPUT", "object key is invalid");
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
return {
|
|
76
|
-
name: "gcs",
|
|
77
|
-
rangedReads: true,
|
|
78
|
-
validateLocation,
|
|
79
|
-
probe(input, context) {
|
|
80
|
-
return runReportingRowProviderOperation(context.signal, async () => {
|
|
81
|
-
const bucket = bucketFor(input);
|
|
82
|
-
let metadata;
|
|
83
|
-
try {
|
|
84
|
-
[metadata] = await bucket.getMetadata();
|
|
85
|
-
} catch (error) {
|
|
86
|
-
const code = status(error);
|
|
87
|
-
if (code === 404) throw new ReportingRowStoreError("UNSAFE_BINDING", "bucket does not exist");
|
|
88
|
-
if (code === 401 || code === 403) {
|
|
89
|
-
throw new ReportingRowStoreError("UNSAFE_BINDING", "bucket policy cannot be read with this client");
|
|
90
|
-
}
|
|
91
|
-
throw error;
|
|
92
|
-
}
|
|
93
|
-
assertGcsReportingRowBucketPolicyV1(metadata, input.prefix);
|
|
94
|
-
});
|
|
95
|
-
},
|
|
96
|
-
putIfAbsent(input, context) {
|
|
97
|
-
return runReportingRowProviderOperation(context.signal, async () => {
|
|
98
|
-
const bucket = bucketFor(input);
|
|
99
|
-
assertKey(input.objectRef);
|
|
100
|
-
const file = bucket.file(input.objectRef);
|
|
101
|
-
try {
|
|
102
|
-
const bytes = Buffer.from(input.bytes);
|
|
103
|
-
await file.save(bytes, {
|
|
104
|
-
resumable: false,
|
|
105
|
-
gzip: false,
|
|
106
|
-
// GCS verifies the declared MD5 before creating the object, so a corrupted upload
|
|
107
|
-
// is refused server-side. Client-side validation is off because on mismatch the
|
|
108
|
-
// client deletes the key without a generation precondition.
|
|
109
|
-
validation: false,
|
|
110
|
-
contentType: input.contentType,
|
|
111
|
-
metadata: {
|
|
112
|
-
contentType: input.contentType,
|
|
113
|
-
md5Hash: createHash("md5").update(bytes).digest("base64"),
|
|
114
|
-
cacheControl: "no-store",
|
|
115
|
-
metadata: { ...input.metadata }
|
|
116
|
-
},
|
|
117
|
-
preconditionOpts: { ifGenerationMatch: 0 }
|
|
118
|
-
});
|
|
119
|
-
} catch (error) {
|
|
120
|
-
if (status(error) !== 412) throw error;
|
|
121
|
-
context.signal.throwIfAborted();
|
|
122
|
-
const [existing] = await bucket.file(input.objectRef).getMetadata();
|
|
123
|
-
return { created: false, nativeVersionRef: generationOf(existing) };
|
|
124
|
-
}
|
|
125
|
-
if (file.metadata?.generation !== void 0) {
|
|
126
|
-
return { created: true, nativeVersionRef: generationOf(file.metadata) };
|
|
127
|
-
}
|
|
128
|
-
const [created] = await file.getMetadata();
|
|
129
|
-
return { created: true, nativeVersionRef: generationOf(created) };
|
|
130
|
-
});
|
|
131
|
-
},
|
|
132
|
-
get(input, context) {
|
|
133
|
-
return runReportingRowProviderOperation(context.signal, async () => {
|
|
134
|
-
const bucket = bucketFor(input);
|
|
135
|
-
assertKey(input.objectRef);
|
|
136
|
-
assertReportingRowReadBounds(input);
|
|
137
|
-
const generation = pinnedGeneration(input.nativeVersionRef);
|
|
138
|
-
if (generation === null) return null;
|
|
139
|
-
const file = bucket.file(input.objectRef, { generation });
|
|
140
|
-
try {
|
|
141
|
-
if (input.range?.length === 0) {
|
|
142
|
-
const [metadata] = await file.getMetadata();
|
|
143
|
-
if (input.range.offset > Number(metadata.size)) {
|
|
144
|
-
throw new ReportingRowStoreError("ROWS_INTEGRITY_FAILED", "requested range exceeds the stored object");
|
|
145
|
-
}
|
|
146
|
-
return Buffer.alloc(0);
|
|
147
|
-
}
|
|
148
|
-
const stream = file.createReadStream({
|
|
149
|
-
// The client always sends `Accept-Encoding: gzip`; with `decompress: false`
|
|
150
|
-
// neither GCS nor the client transcodes, so these are the stored bytes.
|
|
151
|
-
decompress: false,
|
|
152
|
-
// Digests recorded in PostgreSQL verify every byte returned.
|
|
153
|
-
validation: false,
|
|
154
|
-
...input.range ? { start: input.range.offset, end: input.range.offset + input.range.length - 1 } : {}
|
|
155
|
-
});
|
|
156
|
-
return await readReportingRowStream(stream, input.maxBytes, context.signal);
|
|
157
|
-
} catch (error) {
|
|
158
|
-
const code = status(error);
|
|
159
|
-
if (code === 404) return null;
|
|
160
|
-
if (code === 416) {
|
|
161
|
-
throw new ReportingRowStoreError("ROWS_INTEGRITY_FAILED", "requested range exceeds the stored object");
|
|
162
|
-
}
|
|
163
|
-
throw error;
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
},
|
|
167
|
-
stat(input, context) {
|
|
168
|
-
return runReportingRowProviderOperation(context.signal, async () => {
|
|
169
|
-
const bucket = bucketFor(input);
|
|
170
|
-
assertKey(input.objectRef);
|
|
171
|
-
const generation = pinnedGeneration(input.nativeVersionRef);
|
|
172
|
-
if (generation === null) return null;
|
|
173
|
-
try {
|
|
174
|
-
const [metadata] = await bucket.file(input.objectRef, { generation }).getMetadata();
|
|
175
|
-
const size = Number(metadata.size);
|
|
176
|
-
if (String(metadata.generation) !== generation) return null;
|
|
177
|
-
if (!Number.isSafeInteger(size) || size < 0) {
|
|
178
|
-
throw new ReportingRowStoreError("PROVIDER_UNAVAILABLE", "object metadata is malformed");
|
|
179
|
-
}
|
|
180
|
-
return { nativeVersionRef: generation, sizeBytes: size };
|
|
181
|
-
} catch (error) {
|
|
182
|
-
if (status(error) === 404) return null;
|
|
183
|
-
throw error;
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
},
|
|
187
|
-
delete(input, context) {
|
|
188
|
-
return runReportingRowProviderOperation(context.signal, async () => {
|
|
189
|
-
const bucket = bucketFor(input);
|
|
190
|
-
assertKey(input.objectRef);
|
|
191
|
-
const generation = pinnedGeneration(input.nativeVersionRef);
|
|
192
|
-
if (generation === null) return "absent";
|
|
193
|
-
try {
|
|
194
|
-
await bucket.file(input.objectRef, { generation }).delete();
|
|
195
|
-
return "deleted";
|
|
196
|
-
} catch (error) {
|
|
197
|
-
const code = status(error);
|
|
198
|
-
if (code === 404 || code === 412) return "absent";
|
|
199
|
-
throw error;
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
export {
|
|
206
|
-
assertGcsReportingRowBucketPolicyV1,
|
|
207
|
-
createGcsReportingRowObjectProviderV1
|
|
208
|
-
};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { ReportingManagedDeliveryAdapterV1 } from '../ledger/managed.mjs';
|
|
2
|
-
import type { ExpectedReportingPeriod } from '../reconciliation.mjs';
|
|
3
|
-
type DeliveryInput = Parameters<ReportingManagedDeliveryAdapterV1['deliver']>[0];
|
|
4
|
-
export declare function assertExpectedBinding(input: DeliveryInput, expected: ExpectedReportingPeriod): void;
|
|
5
|
-
export {};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { ReportingManagedDeliveryAdapterV1 } from '../ledger/managed';
|
|
2
|
-
import type { ExpectedReportingPeriod } from '../reconciliation';
|
|
3
|
-
type DeliveryInput = Parameters<ReportingManagedDeliveryAdapterV1['deliver']>[0];
|
|
4
|
-
export declare function assertExpectedBinding(input: DeliveryInput, expected: ExpectedReportingPeriod): void;
|
|
5
|
-
export {};
|
|
@@ -1,49 +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 validation_exports = {};
|
|
20
|
-
__export(validation_exports, {
|
|
21
|
-
assertExpectedBinding: () => assertExpectedBinding
|
|
22
|
-
});
|
|
23
|
-
module.exports = __toCommonJS(validation_exports);
|
|
24
|
-
var import_jcs = require('../../utils/jcs.js');
|
|
25
|
-
var import_errors = require('./errors.js');
|
|
26
|
-
function assertExpectedBinding(input, expected) {
|
|
27
|
-
const {
|
|
28
|
-
binding,
|
|
29
|
-
revision: { wireRevision: r },
|
|
30
|
-
obligation
|
|
31
|
-
} = input;
|
|
32
|
-
const shaMatches = (a, b) => typeof a === "string" && /^[a-fA-F0-9]{64}$/.test(a) && /^[a-fA-F0-9]{64}$/.test(b) && a.toLowerCase() === b.toLowerCase();
|
|
33
|
-
if (expected.verificationProfile !== binding.verification_profile || expected.destinationRef !== binding.destination_ref || expected.deliveryMethod !== binding.method || expected.deliveryConfigId !== binding.delivery_config_id || expected.deliveryConfigVersion !== binding.delivery_config_version || expected.reportDefinitionId !== r.report_definition_id || expected.feedPurpose !== binding.feed_purpose || expected.reportingProfile !== r.reporting_profile || expected.reconciliationMode !== binding.reconciliation_mode || expected.requiredFinality !== obligation.requiredFinality || expected.periodStart !== r.period.start || expected.periodEnd !== r.period.end || (0, import_jcs.canonicalize)([...expected.mediaBuyIds].sort()) !== (0, import_jcs.canonicalize)([...r.media_buy_ids].sort()) || expected.reportDefinitionUri !== r.report_definition_uri || !shaMatches(r.report_definition_sha256, expected.reportDefinitionSha256) || expected.schemaUri !== r.schema_uri || !shaMatches(r.schema_sha256, expected.schemaSha256) || expected.schemaVersion !== r.schema_version || expected.schemaDialect !== r.schema_dialect || expected.schemaRefPolicy !== r.schema_ref_policy || r.finality === "official" && (!expected.officialFinality || expected.officialFinality.policyId !== r.finality_policy_id || expected.officialFinality.basis !== r.finality_basis))
|
|
34
|
-
throw new import_errors.ReportingGcsFenceError("CONTENT_CONFLICT");
|
|
35
|
-
const coverage = (value) => Object.fromEntries(
|
|
36
|
-
Object.entries(value).filter(([key]) => !["evaluated_at", "limitations"].includes(key)).map(([key, item]) => [key, Array.isArray(item) ? [...item].sort() : item])
|
|
37
|
-
);
|
|
38
|
-
if ((0, import_jcs.canonicalize)(coverage(expected.coverage)) !== (0, import_jcs.canonicalize)(coverage(r.coverage)))
|
|
39
|
-
throw new import_errors.ReportingGcsFenceError("CONTENT_CONFLICT");
|
|
40
|
-
if (expected.verificationProfile === "canonical_digest") {
|
|
41
|
-
const pin = expected.canonicalization, digest = r.canonical_content_digest;
|
|
42
|
-
if (!digest || digest.canonicalization_id !== pin.id || digest.canonicalization_uri !== pin.uri || !shaMatches(digest.canonicalization_sha256, pin.sha256))
|
|
43
|
-
throw new import_errors.ReportingGcsFenceError("CONTENT_CONFLICT");
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
47
|
-
0 && (module.exports = {
|
|
48
|
-
assertExpectedBinding
|
|
49
|
-
});
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { canonicalize } from "../../utils/jcs.mjs";
|
|
2
|
-
import { ReportingGcsFenceError } from "./errors.mjs";
|
|
3
|
-
function assertExpectedBinding(input, expected) {
|
|
4
|
-
const {
|
|
5
|
-
binding,
|
|
6
|
-
revision: { wireRevision: r },
|
|
7
|
-
obligation
|
|
8
|
-
} = input;
|
|
9
|
-
const shaMatches = (a, b) => typeof a === "string" && /^[a-fA-F0-9]{64}$/.test(a) && /^[a-fA-F0-9]{64}$/.test(b) && a.toLowerCase() === b.toLowerCase();
|
|
10
|
-
if (expected.verificationProfile !== binding.verification_profile || expected.destinationRef !== binding.destination_ref || expected.deliveryMethod !== binding.method || expected.deliveryConfigId !== binding.delivery_config_id || expected.deliveryConfigVersion !== binding.delivery_config_version || expected.reportDefinitionId !== r.report_definition_id || expected.feedPurpose !== binding.feed_purpose || expected.reportingProfile !== r.reporting_profile || expected.reconciliationMode !== binding.reconciliation_mode || expected.requiredFinality !== obligation.requiredFinality || expected.periodStart !== r.period.start || expected.periodEnd !== r.period.end || canonicalize([...expected.mediaBuyIds].sort()) !== canonicalize([...r.media_buy_ids].sort()) || expected.reportDefinitionUri !== r.report_definition_uri || !shaMatches(r.report_definition_sha256, expected.reportDefinitionSha256) || expected.schemaUri !== r.schema_uri || !shaMatches(r.schema_sha256, expected.schemaSha256) || expected.schemaVersion !== r.schema_version || expected.schemaDialect !== r.schema_dialect || expected.schemaRefPolicy !== r.schema_ref_policy || r.finality === "official" && (!expected.officialFinality || expected.officialFinality.policyId !== r.finality_policy_id || expected.officialFinality.basis !== r.finality_basis))
|
|
11
|
-
throw new ReportingGcsFenceError("CONTENT_CONFLICT");
|
|
12
|
-
const coverage = (value) => Object.fromEntries(
|
|
13
|
-
Object.entries(value).filter(([key]) => !["evaluated_at", "limitations"].includes(key)).map(([key, item]) => [key, Array.isArray(item) ? [...item].sort() : item])
|
|
14
|
-
);
|
|
15
|
-
if (canonicalize(coverage(expected.coverage)) !== canonicalize(coverage(r.coverage)))
|
|
16
|
-
throw new ReportingGcsFenceError("CONTENT_CONFLICT");
|
|
17
|
-
if (expected.verificationProfile === "canonical_digest") {
|
|
18
|
-
const pin = expected.canonicalization, digest = r.canonical_content_digest;
|
|
19
|
-
if (!digest || digest.canonicalization_id !== pin.id || digest.canonicalization_uri !== pin.uri || !shaMatches(digest.canonicalization_sha256, pin.sha256))
|
|
20
|
-
throw new ReportingGcsFenceError("CONTENT_CONFLICT");
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
export {
|
|
24
|
-
assertExpectedBinding
|
|
25
|
-
};
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Host-facing reporting change feed (shared SDK persistence spec,
|
|
3
|
-
* adcontextprotocol/adcp#7996 §2.1 and §3.7).
|
|
4
|
-
*
|
|
5
|
-
* Apply after {@link REPORTING_LEDGER_MIGRATION}; PostgreSQL 13 or later
|
|
6
|
-
* (`xid8`). The store appends one row per committed obligation, revision,
|
|
7
|
-
* adjustment and retirement in the same transaction as the record, taking the
|
|
8
|
-
* sequence value only after the account lock, so per-account sequence order is
|
|
9
|
-
* commit order. Deployment-wide readers order by `(xid, seq)` and stop below
|
|
10
|
-
* the reading snapshot's `xmin`, so a slow commit is never skipped. Account
|
|
11
|
-
* readers order by `seq` and end the page before the first change at or above
|
|
12
|
-
* that `xmin`. Use exactly one writer SDK per ledger database.
|
|
13
|
-
*
|
|
14
|
-
* @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
|
|
15
|
-
*/
|
|
16
|
-
export declare const REPORTING_LEDGER_CHANGES_MIGRATION: string;
|
|
17
|
-
/**
|
|
18
|
-
* @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
|
|
19
|
-
*/
|
|
20
|
-
export type ReportingChangeKindV1 = 'obligation' | 'revision' | 'adjustment' | 'retirement';
|
|
21
|
-
/**
|
|
22
|
-
* @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
|
|
23
|
-
*/
|
|
24
|
-
export interface ReportingChangeRecordV1 {
|
|
25
|
-
kind: ReportingChangeKindV1;
|
|
26
|
-
record_id: string;
|
|
27
|
-
reporting_obligation_id: string;
|
|
28
|
-
account_id: string;
|
|
29
|
-
recorded_at: string;
|
|
30
|
-
}
|
|
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 interface ReportingChangesPageV1 {
|
|
35
|
-
records: ReportingChangeRecordV1[];
|
|
36
|
-
/** Pass back to resume. Always present; equal to the input when nothing new committed. */
|
|
37
|
-
cursor: string;
|
|
38
|
-
}
|
|
39
|
-
interface ChangeCursorV1 {
|
|
40
|
-
v: 1;
|
|
41
|
-
/** Account scope, or `null` for the deployment-wide feed. */
|
|
42
|
-
account: string | null;
|
|
43
|
-
seq: string;
|
|
44
|
-
/** Deployment-wide feeds only: the writing transaction of the last record returned. */
|
|
45
|
-
xid?: string;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* @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
|
|
49
|
-
*/
|
|
50
|
-
export declare function encodeReportingChangeCursorV1(cursor: ChangeCursorV1): string;
|
|
51
|
-
/**
|
|
52
|
-
* @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
|
|
53
|
-
*/
|
|
54
|
-
export declare function decodeReportingChangeCursorV1(value: string, account: string | null): ChangeCursorV1;
|
|
55
|
-
/**
|
|
56
|
-
* Thrown when a change cursor is older than the retained change history.
|
|
57
|
-
*
|
|
58
|
-
* @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
|
|
59
|
-
*/
|
|
60
|
-
export declare class ReportingChangeCursorExpiredError extends Error {
|
|
61
|
-
readonly cursor?: string | undefined;
|
|
62
|
-
readonly code: "CURSOR_EXPIRED";
|
|
63
|
-
/**
|
|
64
|
-
* Original feed position, when available, so a cold-start consumer can retain its recovery
|
|
65
|
-
* boundary. It encodes the feed's account scope: do not serialize it to other tenants.
|
|
66
|
-
*/
|
|
67
|
-
constructor(cursor?: string | undefined);
|
|
68
|
-
}
|
|
69
|
-
export {};
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Host-facing reporting change feed (shared SDK persistence spec,
|
|
3
|
-
* adcontextprotocol/adcp#7996 §2.1 and §3.7).
|
|
4
|
-
*
|
|
5
|
-
* Apply after {@link REPORTING_LEDGER_MIGRATION}; PostgreSQL 13 or later
|
|
6
|
-
* (`xid8`). The store appends one row per committed obligation, revision,
|
|
7
|
-
* adjustment and retirement in the same transaction as the record, taking the
|
|
8
|
-
* sequence value only after the account lock, so per-account sequence order is
|
|
9
|
-
* commit order. Deployment-wide readers order by `(xid, seq)` and stop below
|
|
10
|
-
* the reading snapshot's `xmin`, so a slow commit is never skipped. Account
|
|
11
|
-
* readers order by `seq` and end the page before the first change at or above
|
|
12
|
-
* that `xmin`. Use exactly one writer SDK per ledger database.
|
|
13
|
-
*
|
|
14
|
-
* @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
|
|
15
|
-
*/
|
|
16
|
-
export declare const REPORTING_LEDGER_CHANGES_MIGRATION: string;
|
|
17
|
-
/**
|
|
18
|
-
* @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
|
|
19
|
-
*/
|
|
20
|
-
export type ReportingChangeKindV1 = 'obligation' | 'revision' | 'adjustment' | 'retirement';
|
|
21
|
-
/**
|
|
22
|
-
* @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
|
|
23
|
-
*/
|
|
24
|
-
export interface ReportingChangeRecordV1 {
|
|
25
|
-
kind: ReportingChangeKindV1;
|
|
26
|
-
record_id: string;
|
|
27
|
-
reporting_obligation_id: string;
|
|
28
|
-
account_id: string;
|
|
29
|
-
recorded_at: string;
|
|
30
|
-
}
|
|
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 interface ReportingChangesPageV1 {
|
|
35
|
-
records: ReportingChangeRecordV1[];
|
|
36
|
-
/** Pass back to resume. Always present; equal to the input when nothing new committed. */
|
|
37
|
-
cursor: string;
|
|
38
|
-
}
|
|
39
|
-
interface ChangeCursorV1 {
|
|
40
|
-
v: 1;
|
|
41
|
-
/** Account scope, or `null` for the deployment-wide feed. */
|
|
42
|
-
account: string | null;
|
|
43
|
-
seq: string;
|
|
44
|
-
/** Deployment-wide feeds only: the writing transaction of the last record returned. */
|
|
45
|
-
xid?: string;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* @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
|
|
49
|
-
*/
|
|
50
|
-
export declare function encodeReportingChangeCursorV1(cursor: ChangeCursorV1): string;
|
|
51
|
-
/**
|
|
52
|
-
* @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
|
|
53
|
-
*/
|
|
54
|
-
export declare function decodeReportingChangeCursorV1(value: string, account: string | null): ChangeCursorV1;
|
|
55
|
-
/**
|
|
56
|
-
* Thrown when a change cursor is older than the retained change history.
|
|
57
|
-
*
|
|
58
|
-
* @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
|
|
59
|
-
*/
|
|
60
|
-
export declare class ReportingChangeCursorExpiredError extends Error {
|
|
61
|
-
readonly cursor?: string | undefined;
|
|
62
|
-
readonly code: "CURSOR_EXPIRED";
|
|
63
|
-
/**
|
|
64
|
-
* Original feed position, when available, so a cold-start consumer can retain its recovery
|
|
65
|
-
* boundary. It encodes the feed's account scope: do not serialize it to other tenants.
|
|
66
|
-
*/
|
|
67
|
-
constructor(cursor?: string | undefined);
|
|
68
|
-
}
|
|
69
|
-
export {};
|
|
@@ -1,107 +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 change_feed_exports = {};
|
|
20
|
-
__export(change_feed_exports, {
|
|
21
|
-
REPORTING_LEDGER_CHANGES_MIGRATION: () => REPORTING_LEDGER_CHANGES_MIGRATION,
|
|
22
|
-
ReportingChangeCursorExpiredError: () => ReportingChangeCursorExpiredError,
|
|
23
|
-
decodeReportingChangeCursorV1: () => decodeReportingChangeCursorV1,
|
|
24
|
-
encodeReportingChangeCursorV1: () => encodeReportingChangeCursorV1
|
|
25
|
-
});
|
|
26
|
-
module.exports = __toCommonJS(change_feed_exports);
|
|
27
|
-
var import_row_storage_errors = require('./row-storage-errors.js');
|
|
28
|
-
const REPORTING_LEDGER_CHANGES_MIGRATION = `
|
|
29
|
-
CREATE TABLE IF NOT EXISTS adcp_reporting_changes (
|
|
30
|
-
seq BIGSERIAL PRIMARY KEY,
|
|
31
|
-
xid xid8 NOT NULL DEFAULT pg_current_xact_id(),
|
|
32
|
-
account_id TEXT NOT NULL,
|
|
33
|
-
record_kind TEXT NOT NULL
|
|
34
|
-
CHECK (record_kind IN ('obligation', 'revision', 'adjustment', 'retirement')),
|
|
35
|
-
record_id TEXT NOT NULL,
|
|
36
|
-
obligation_id TEXT NOT NULL,
|
|
37
|
-
recorded_at TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp()
|
|
38
|
-
);
|
|
39
|
-
CREATE INDEX IF NOT EXISTS adcp_reporting_changes_account
|
|
40
|
-
ON adcp_reporting_changes (account_id, seq);
|
|
41
|
-
CREATE INDEX IF NOT EXISTS adcp_reporting_changes_deployment
|
|
42
|
-
ON adcp_reporting_changes (xid, seq);
|
|
43
|
-
CREATE INDEX IF NOT EXISTS adcp_reporting_changes_recorded
|
|
44
|
-
ON adcp_reporting_changes (recorded_at, seq);
|
|
45
|
-
|
|
46
|
-
-- Highest (xid, seq) ever pruned: a deployment-wide cursor below it may have
|
|
47
|
-
-- missed a deleted change and fails closed.
|
|
48
|
-
CREATE TABLE IF NOT EXISTS adcp_reporting_change_horizon (
|
|
49
|
-
singleton BOOLEAN PRIMARY KEY DEFAULT TRUE CHECK (singleton),
|
|
50
|
-
pruned_through_xid xid8 NOT NULL DEFAULT '0',
|
|
51
|
-
pruned_through_seq BIGINT NOT NULL DEFAULT 0
|
|
52
|
-
);
|
|
53
|
-
INSERT INTO adcp_reporting_change_horizon (singleton) VALUES (TRUE) ON CONFLICT DO NOTHING;
|
|
54
|
-
|
|
55
|
-
-- Highest seq ever pruned per account: an account cursor below it fails closed.
|
|
56
|
-
CREATE TABLE IF NOT EXISTS adcp_reporting_change_account_horizon (
|
|
57
|
-
account_id TEXT PRIMARY KEY,
|
|
58
|
-
pruned_through_seq BIGINT NOT NULL
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
-- Registered consumers hold back pruning in their own feed order: account
|
|
62
|
-
-- consumers by seq within their account, deployment consumers by (xid, seq).
|
|
63
|
-
CREATE TABLE IF NOT EXISTS adcp_reporting_feed_consumers (
|
|
64
|
-
consumer_name TEXT PRIMARY KEY CHECK (consumer_name ~ '^[A-Za-z0-9_.:-]{1,128}$'),
|
|
65
|
-
account_id TEXT,
|
|
66
|
-
cursor_xid xid8,
|
|
67
|
-
cursor_seq BIGINT NOT NULL,
|
|
68
|
-
updated_at TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp(),
|
|
69
|
-
CHECK ((account_id IS NULL) = (cursor_xid IS NOT NULL))
|
|
70
|
-
);
|
|
71
|
-
`.trim();
|
|
72
|
-
function encodeReportingChangeCursorV1(cursor) {
|
|
73
|
-
return Buffer.from(JSON.stringify(cursor), "utf8").toString("base64url");
|
|
74
|
-
}
|
|
75
|
-
function decodeReportingChangeCursorV1(value, account) {
|
|
76
|
-
let parsed;
|
|
77
|
-
try {
|
|
78
|
-
parsed = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
|
|
79
|
-
} catch {
|
|
80
|
-
throw new import_row_storage_errors.ReportingRowStoreError("INVALID_INPUT", "change cursor is malformed");
|
|
81
|
-
}
|
|
82
|
-
const cursor = parsed;
|
|
83
|
-
if (cursor.v !== 1 || (cursor.account ?? null) !== account || typeof cursor.seq !== "string" || !/^\d{1,19}$/.test(cursor.seq) || (account === null ? typeof cursor.xid !== "string" || !/^\d{1,20}$/.test(cursor.xid) : cursor.xid !== void 0)) {
|
|
84
|
-
throw new import_row_storage_errors.ReportingRowStoreError("INVALID_INPUT", "change cursor does not belong to this feed");
|
|
85
|
-
}
|
|
86
|
-
return cursor;
|
|
87
|
-
}
|
|
88
|
-
class ReportingChangeCursorExpiredError extends Error {
|
|
89
|
-
/**
|
|
90
|
-
* Original feed position, when available, so a cold-start consumer can retain its recovery
|
|
91
|
-
* boundary. It encodes the feed's account scope: do not serialize it to other tenants.
|
|
92
|
-
*/
|
|
93
|
-
constructor(cursor) {
|
|
94
|
-
super("Reporting change cursor is older than the retained change history; resynchronize from current revisions");
|
|
95
|
-
this.cursor = cursor;
|
|
96
|
-
this.name = "ReportingChangeCursorExpiredError";
|
|
97
|
-
}
|
|
98
|
-
cursor;
|
|
99
|
-
code = "CURSOR_EXPIRED";
|
|
100
|
-
}
|
|
101
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
102
|
-
0 && (module.exports = {
|
|
103
|
-
REPORTING_LEDGER_CHANGES_MIGRATION,
|
|
104
|
-
ReportingChangeCursorExpiredError,
|
|
105
|
-
decodeReportingChangeCursorV1,
|
|
106
|
-
encodeReportingChangeCursorV1
|
|
107
|
-
});
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { ReportingRowStoreError } from "./row-storage-errors.mjs";
|
|
2
|
-
const REPORTING_LEDGER_CHANGES_MIGRATION = `
|
|
3
|
-
CREATE TABLE IF NOT EXISTS adcp_reporting_changes (
|
|
4
|
-
seq BIGSERIAL PRIMARY KEY,
|
|
5
|
-
xid xid8 NOT NULL DEFAULT pg_current_xact_id(),
|
|
6
|
-
account_id TEXT NOT NULL,
|
|
7
|
-
record_kind TEXT NOT NULL
|
|
8
|
-
CHECK (record_kind IN ('obligation', 'revision', 'adjustment', 'retirement')),
|
|
9
|
-
record_id TEXT NOT NULL,
|
|
10
|
-
obligation_id TEXT NOT NULL,
|
|
11
|
-
recorded_at TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp()
|
|
12
|
-
);
|
|
13
|
-
CREATE INDEX IF NOT EXISTS adcp_reporting_changes_account
|
|
14
|
-
ON adcp_reporting_changes (account_id, seq);
|
|
15
|
-
CREATE INDEX IF NOT EXISTS adcp_reporting_changes_deployment
|
|
16
|
-
ON adcp_reporting_changes (xid, seq);
|
|
17
|
-
CREATE INDEX IF NOT EXISTS adcp_reporting_changes_recorded
|
|
18
|
-
ON adcp_reporting_changes (recorded_at, seq);
|
|
19
|
-
|
|
20
|
-
-- Highest (xid, seq) ever pruned: a deployment-wide cursor below it may have
|
|
21
|
-
-- missed a deleted change and fails closed.
|
|
22
|
-
CREATE TABLE IF NOT EXISTS adcp_reporting_change_horizon (
|
|
23
|
-
singleton BOOLEAN PRIMARY KEY DEFAULT TRUE CHECK (singleton),
|
|
24
|
-
pruned_through_xid xid8 NOT NULL DEFAULT '0',
|
|
25
|
-
pruned_through_seq BIGINT NOT NULL DEFAULT 0
|
|
26
|
-
);
|
|
27
|
-
INSERT INTO adcp_reporting_change_horizon (singleton) VALUES (TRUE) ON CONFLICT DO NOTHING;
|
|
28
|
-
|
|
29
|
-
-- Highest seq ever pruned per account: an account cursor below it fails closed.
|
|
30
|
-
CREATE TABLE IF NOT EXISTS adcp_reporting_change_account_horizon (
|
|
31
|
-
account_id TEXT PRIMARY KEY,
|
|
32
|
-
pruned_through_seq BIGINT NOT NULL
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
-- Registered consumers hold back pruning in their own feed order: account
|
|
36
|
-
-- consumers by seq within their account, deployment consumers by (xid, seq).
|
|
37
|
-
CREATE TABLE IF NOT EXISTS adcp_reporting_feed_consumers (
|
|
38
|
-
consumer_name TEXT PRIMARY KEY CHECK (consumer_name ~ '^[A-Za-z0-9_.:-]{1,128}$'),
|
|
39
|
-
account_id TEXT,
|
|
40
|
-
cursor_xid xid8,
|
|
41
|
-
cursor_seq BIGINT NOT NULL,
|
|
42
|
-
updated_at TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp(),
|
|
43
|
-
CHECK ((account_id IS NULL) = (cursor_xid IS NOT NULL))
|
|
44
|
-
);
|
|
45
|
-
`.trim();
|
|
46
|
-
function encodeReportingChangeCursorV1(cursor) {
|
|
47
|
-
return Buffer.from(JSON.stringify(cursor), "utf8").toString("base64url");
|
|
48
|
-
}
|
|
49
|
-
function decodeReportingChangeCursorV1(value, account) {
|
|
50
|
-
let parsed;
|
|
51
|
-
try {
|
|
52
|
-
parsed = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
|
|
53
|
-
} catch {
|
|
54
|
-
throw new ReportingRowStoreError("INVALID_INPUT", "change cursor is malformed");
|
|
55
|
-
}
|
|
56
|
-
const cursor = parsed;
|
|
57
|
-
if (cursor.v !== 1 || (cursor.account ?? null) !== account || typeof cursor.seq !== "string" || !/^\d{1,19}$/.test(cursor.seq) || (account === null ? typeof cursor.xid !== "string" || !/^\d{1,20}$/.test(cursor.xid) : cursor.xid !== void 0)) {
|
|
58
|
-
throw new ReportingRowStoreError("INVALID_INPUT", "change cursor does not belong to this feed");
|
|
59
|
-
}
|
|
60
|
-
return cursor;
|
|
61
|
-
}
|
|
62
|
-
class ReportingChangeCursorExpiredError extends Error {
|
|
63
|
-
/**
|
|
64
|
-
* Original feed position, when available, so a cold-start consumer can retain its recovery
|
|
65
|
-
* boundary. It encodes the feed's account scope: do not serialize it to other tenants.
|
|
66
|
-
*/
|
|
67
|
-
constructor(cursor) {
|
|
68
|
-
super("Reporting change cursor is older than the retained change history; resynchronize from current revisions");
|
|
69
|
-
this.cursor = cursor;
|
|
70
|
-
this.name = "ReportingChangeCursorExpiredError";
|
|
71
|
-
}
|
|
72
|
-
cursor;
|
|
73
|
-
code = "CURSOR_EXPIRED";
|
|
74
|
-
}
|
|
75
|
-
export {
|
|
76
|
-
REPORTING_LEDGER_CHANGES_MIGRATION,
|
|
77
|
-
ReportingChangeCursorExpiredError,
|
|
78
|
-
decodeReportingChangeCursorV1,
|
|
79
|
-
encodeReportingChangeCursorV1
|
|
80
|
-
};
|