@hasna/mementos 0.14.79 → 0.14.81
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/cli/commands/project.d.ts.map +1 -1
- package/dist/cli/index.js +19 -16
- package/dist/db/projects.d.ts +4 -4
- package/dist/db/projects.d.ts.map +1 -1
- package/dist/index.js +250 -19
- package/dist/project-registration/authority.d.ts +5 -1
- package/dist/project-registration/authority.d.ts.map +1 -1
- package/dist/project-registration/http.d.ts +4 -1
- package/dist/project-registration/http.d.ts.map +1 -1
- package/dist/project-registration/index.d.ts +1 -1
- package/dist/project-registration/index.d.ts.map +1 -1
- package/dist/project-registration/types.d.ts +73 -0
- package/dist/project-registration/types.d.ts.map +1 -1
- package/dist/project-registration.js +3261 -62
- package/dist/server/index.js +226 -19
- package/package.json +2 -2
package/dist/server/index.js
CHANGED
|
@@ -57624,8 +57624,8 @@ function normalizeProjectUpdateInput(input) {
|
|
|
57624
57624
|
}
|
|
57625
57625
|
return normalized;
|
|
57626
57626
|
}
|
|
57627
|
-
function assertProjectUpdateIdentity(identity) {
|
|
57628
|
-
if (identity.authority_id !==
|
|
57627
|
+
function assertProjectUpdateIdentity(identity, expectedIdentity = PROJECT_UPDATE_AUTHORITY) {
|
|
57628
|
+
if (identity.authority_id !== expectedIdentity.authority_id || identity.tenant_id !== expectedIdentity.tenant_id || identity.corpus_id !== expectedIdentity.corpus_id) {
|
|
57629
57629
|
throw new ProjectGuardedUpdateError("PROJECT_UPDATE_AUTHORITY_MISMATCH", "guarded project update does not match this authority, tenant, and corpus");
|
|
57630
57630
|
}
|
|
57631
57631
|
}
|
|
@@ -57634,8 +57634,8 @@ function assertBoundedIdentifier2(value, field) {
|
|
|
57634
57634
|
throw new ProjectGuardedUpdateError("PROJECT_UPDATE_INVALID_INPUT", `${field} must be an 8-128 character bounded identifier`);
|
|
57635
57635
|
}
|
|
57636
57636
|
}
|
|
57637
|
-
function assertProjectUpdateRequest(request) {
|
|
57638
|
-
assertProjectUpdateIdentity(request);
|
|
57637
|
+
function assertProjectUpdateRequest(request, expectedIdentity = PROJECT_UPDATE_AUTHORITY) {
|
|
57638
|
+
assertProjectUpdateIdentity(request, expectedIdentity);
|
|
57639
57639
|
assertBoundedIdentifier2(request.operation_id, "operation_id");
|
|
57640
57640
|
assertBoundedIdentifier2(request.step_id, "step_id");
|
|
57641
57641
|
assertBoundedIdentifier2(request.idempotency_key, "idempotency_key");
|
|
@@ -57748,7 +57748,7 @@ function makeProjectUpdateReceipt(input) {
|
|
|
57748
57748
|
target_id: input.target_id,
|
|
57749
57749
|
expected_revision: input.request.expected_revision,
|
|
57750
57750
|
result_revision: input.after_project.updated_at,
|
|
57751
|
-
result_digest: digestProjectUpdateValue(input.after_project),
|
|
57751
|
+
result_digest: input.result_digest ?? digestProjectUpdateValue(input.after_project),
|
|
57752
57752
|
accepted_receipt_id: input.accepted_receipt_id ?? null,
|
|
57753
57753
|
before_project: input.before_project,
|
|
57754
57754
|
after_project: input.after_project,
|
|
@@ -57812,8 +57812,8 @@ function listProjects(db) {
|
|
|
57812
57812
|
const rows = d.query("SELECT * FROM projects ORDER BY updated_at DESC").all();
|
|
57813
57813
|
return rows.map(parseProjectRow2);
|
|
57814
57814
|
}
|
|
57815
|
-
function previewProjectUpdate(id, request, db) {
|
|
57816
|
-
assertProjectUpdateRequest(request);
|
|
57815
|
+
function previewProjectUpdate(id, request, db, expectedIdentity = PROJECT_UPDATE_AUTHORITY) {
|
|
57816
|
+
assertProjectUpdateRequest(request, expectedIdentity);
|
|
57817
57817
|
const normalized = normalizeProjectUpdateInput(request.updates);
|
|
57818
57818
|
if (!db && isApiMode()) {
|
|
57819
57819
|
const { data } = apiJson("POST", `/projects/${encodeURIComponent(id)}/guarded-update`, { ...request, updates: normalized, dry_run: true });
|
|
@@ -57835,8 +57835,8 @@ function previewProjectUpdate(id, request, db) {
|
|
|
57835
57835
|
receipt: null
|
|
57836
57836
|
};
|
|
57837
57837
|
}
|
|
57838
|
-
function applyProjectUpdate(id, request, db) {
|
|
57839
|
-
assertProjectUpdateRequest(request);
|
|
57838
|
+
function applyProjectUpdate(id, request, db, expectedIdentity = PROJECT_UPDATE_AUTHORITY, resultDigestForProject) {
|
|
57839
|
+
assertProjectUpdateRequest(request, expectedIdentity);
|
|
57840
57840
|
const normalized = normalizeProjectUpdateInput(request.updates);
|
|
57841
57841
|
if (!db && isApiMode()) {
|
|
57842
57842
|
const { data } = apiJson("POST", `/projects/${encodeURIComponent(id)}/guarded-update`, { ...request, updates: normalized, dry_run: false });
|
|
@@ -57897,14 +57897,15 @@ function applyProjectUpdate(id, request, db) {
|
|
|
57897
57897
|
request_digest: requestDigest,
|
|
57898
57898
|
target_id: id,
|
|
57899
57899
|
before_project: before,
|
|
57900
|
-
after_project: readback
|
|
57900
|
+
after_project: readback,
|
|
57901
|
+
result_digest: resultDigestForProject?.(readback)
|
|
57901
57902
|
});
|
|
57902
57903
|
insertProjectUpdateReceipt(d, receipt);
|
|
57903
57904
|
return { dry_run: false, applied: true, project: readback, receipt };
|
|
57904
57905
|
});
|
|
57905
57906
|
}
|
|
57906
|
-
function rollbackProjectUpdate(id, request, db) {
|
|
57907
|
-
assertProjectUpdateRequest(request);
|
|
57907
|
+
function rollbackProjectUpdate(id, request, db, expectedIdentity = PROJECT_UPDATE_AUTHORITY, resultDigestForProject) {
|
|
57908
|
+
assertProjectUpdateRequest(request, expectedIdentity);
|
|
57908
57909
|
assertBoundedIdentifier2(request.accepted_receipt_id, "accepted_receipt_id");
|
|
57909
57910
|
if (!db && isApiMode()) {
|
|
57910
57911
|
const { data } = apiJson("POST", `/projects/${encodeURIComponent(id)}/guarded-rollback`, request);
|
|
@@ -57970,14 +57971,15 @@ function rollbackProjectUpdate(id, request, db) {
|
|
|
57970
57971
|
target_id: id,
|
|
57971
57972
|
before_project: current,
|
|
57972
57973
|
after_project: readback,
|
|
57974
|
+
result_digest: resultDigestForProject?.(readback),
|
|
57973
57975
|
accepted_receipt_id: accepted.receipt_id
|
|
57974
57976
|
});
|
|
57975
57977
|
insertProjectUpdateReceipt(d, receipt);
|
|
57976
57978
|
return { dry_run: false, applied: true, project: readback, receipt };
|
|
57977
57979
|
});
|
|
57978
57980
|
}
|
|
57979
|
-
function getProjectUpdateReceipt(id, receiptId, identity = PROJECT_UPDATE_AUTHORITY, db) {
|
|
57980
|
-
assertProjectUpdateIdentity(identity);
|
|
57981
|
+
function getProjectUpdateReceipt(id, receiptId, identity = PROJECT_UPDATE_AUTHORITY, db, expectedIdentity = PROJECT_UPDATE_AUTHORITY) {
|
|
57982
|
+
assertProjectUpdateIdentity(identity, expectedIdentity);
|
|
57981
57983
|
if (!db && isApiMode()) {
|
|
57982
57984
|
const { data } = apiJson("POST", `/projects/${encodeURIComponent(id)}/update-receipts/lookup`, { ...identity, receipt_id: receiptId });
|
|
57983
57985
|
return data;
|
|
@@ -58205,9 +58207,9 @@ function assertWithinBounds(value, bounds, startedAt) {
|
|
|
58205
58207
|
}
|
|
58206
58208
|
return { response_bytes: bytes, elapsed_ms: elapsed };
|
|
58207
58209
|
}
|
|
58208
|
-
function
|
|
58210
|
+
function withBoundedResponseControl(payload, bounds, startedAt) {
|
|
58209
58211
|
const result = {
|
|
58210
|
-
|
|
58212
|
+
...payload,
|
|
58211
58213
|
response_control: {
|
|
58212
58214
|
response_byte_limit: bounds.response_byte_limit,
|
|
58213
58215
|
time_budget_ms: bounds.time_budget_ms,
|
|
@@ -58230,6 +58232,9 @@ function withResponseControl(receipt, bounds, startedAt) {
|
|
|
58230
58232
|
result.response_control.elapsed_ms = measured.elapsed_ms;
|
|
58231
58233
|
return result;
|
|
58232
58234
|
}
|
|
58235
|
+
function withResponseControl(receipt, bounds, startedAt) {
|
|
58236
|
+
return withBoundedResponseControl({ receipt }, bounds, startedAt);
|
|
58237
|
+
}
|
|
58233
58238
|
function requireString(value, field, options = {}) {
|
|
58234
58239
|
const min = options.min ?? 1;
|
|
58235
58240
|
const max = options.max ?? 512;
|
|
@@ -58256,6 +58261,80 @@ function ownedPath(target) {
|
|
|
58256
58261
|
}
|
|
58257
58262
|
return path;
|
|
58258
58263
|
}
|
|
58264
|
+
function guardedAuthorityIdentity(capability) {
|
|
58265
|
+
return {
|
|
58266
|
+
authority_id: capability.authority_id,
|
|
58267
|
+
tenant_id: capability.tenant_id,
|
|
58268
|
+
corpus_id: capability.corpus_id
|
|
58269
|
+
};
|
|
58270
|
+
}
|
|
58271
|
+
function assertGuardedAuthorityRequest(targetId, request, capability) {
|
|
58272
|
+
assertBounds(request);
|
|
58273
|
+
requireString(targetId, "target_id", { min: 8, max: 128, pattern: OPERATION_PATTERN });
|
|
58274
|
+
if (request.authority !== "mementos" || request.authority_route !== MEMENTOS_PROJECT_GUARDED_UPDATE_ROUTE || request.package_version !== capability.package_version || request.authority_id !== capability.authority_id || request.tenant_id !== capability.tenant_id || request.corpus_id !== capability.corpus_id) {
|
|
58275
|
+
throw new MementosProjectRegistrationError("MEMENTOS_PROJECT_REGISTRATION_CAPABILITY_MISMATCH", "guarded project request does not match this authority capability identity");
|
|
58276
|
+
}
|
|
58277
|
+
return guardedAuthorityIdentity(capability);
|
|
58278
|
+
}
|
|
58279
|
+
function assertGuardedOperationFields(request) {
|
|
58280
|
+
requireString(request.operation_id, "operation_id", {
|
|
58281
|
+
min: 8,
|
|
58282
|
+
max: 128,
|
|
58283
|
+
pattern: OPERATION_PATTERN
|
|
58284
|
+
});
|
|
58285
|
+
requireString(request.step_id, "step_id", {
|
|
58286
|
+
min: 8,
|
|
58287
|
+
max: 128,
|
|
58288
|
+
pattern: OPERATION_PATTERN
|
|
58289
|
+
});
|
|
58290
|
+
requireString(request.idempotency_key, "idempotency_key", {
|
|
58291
|
+
min: 8,
|
|
58292
|
+
max: 128,
|
|
58293
|
+
pattern: OPERATION_PATTERN
|
|
58294
|
+
});
|
|
58295
|
+
requireString(request.expected_revision, "expected_revision", { max: 128 });
|
|
58296
|
+
}
|
|
58297
|
+
function assertGuardedUpdateRequest(targetId, request, capability) {
|
|
58298
|
+
const identity = assertGuardedAuthorityRequest(targetId, request, capability);
|
|
58299
|
+
assertGuardedOperationFields(request);
|
|
58300
|
+
if (!request.updates || typeof request.updates !== "object") {
|
|
58301
|
+
throw new MementosProjectRegistrationError("MEMENTOS_PROJECT_REGISTRATION_INVALID_INPUT", "guarded project updates must contain exactly one private path handle");
|
|
58302
|
+
}
|
|
58303
|
+
exactKeys(request.updates, ["path"], "updates");
|
|
58304
|
+
return { identity, path: ownedPath(request.updates.path) };
|
|
58305
|
+
}
|
|
58306
|
+
function publicGuardedUpdateReceipt(receipt, capability) {
|
|
58307
|
+
return {
|
|
58308
|
+
receipt_id: receipt.receipt_id,
|
|
58309
|
+
authority: "mementos",
|
|
58310
|
+
route: MEMENTOS_PROJECT_GUARDED_UPDATE_ROUTE,
|
|
58311
|
+
package_version: capability.package_version,
|
|
58312
|
+
authority_id: capability.authority_id,
|
|
58313
|
+
tenant_id: capability.tenant_id,
|
|
58314
|
+
corpus_id: capability.corpus_id,
|
|
58315
|
+
operation_id: receipt.operation_id,
|
|
58316
|
+
step_id: receipt.step_id,
|
|
58317
|
+
direction: receipt.direction,
|
|
58318
|
+
idempotency_key: receipt.idempotency_key,
|
|
58319
|
+
request_digest: receipt.request_digest,
|
|
58320
|
+
outcome: "accepted",
|
|
58321
|
+
target_id: receipt.target_id,
|
|
58322
|
+
expected_revision: receipt.expected_revision,
|
|
58323
|
+
result_revision: receipt.result_revision,
|
|
58324
|
+
result_digest: receipt.result_digest,
|
|
58325
|
+
accepted_receipt_id: receipt.accepted_receipt_id,
|
|
58326
|
+
created_at: receipt.created_at
|
|
58327
|
+
};
|
|
58328
|
+
}
|
|
58329
|
+
function guardedProjectError(cause) {
|
|
58330
|
+
if (cause instanceof MementosProjectRegistrationError)
|
|
58331
|
+
throw cause;
|
|
58332
|
+
if (cause instanceof ProjectGuardedUpdateError) {
|
|
58333
|
+
const code = cause.code === "PROJECT_UPDATE_INVALID_INPUT" ? "MEMENTOS_PROJECT_REGISTRATION_INVALID_INPUT" : cause.code === "PROJECT_UPDATE_AUTHORITY_MISMATCH" ? "MEMENTOS_PROJECT_REGISTRATION_CAPABILITY_MISMATCH" : cause.code === "PROJECT_UPDATE_NOT_FOUND" ? "MEMENTOS_PROJECT_REGISTRATION_RECORD_NOT_FOUND" : cause.code === "PROJECT_UPDATE_RECEIPT_NOT_FOUND" ? "MEMENTOS_PROJECT_REGISTRATION_RECEIPT_NOT_FOUND" : "MEMENTOS_PROJECT_REGISTRATION_CONFLICT";
|
|
58334
|
+
throw new MementosProjectRegistrationError(code, "guarded project operation was rejected without exposing private project data", { project_update_code: cause.code });
|
|
58335
|
+
}
|
|
58336
|
+
throw new MementosProjectRegistrationError("MEMENTOS_PROJECT_REGISTRATION_ATOMICITY_UNAVAILABLE", "guarded project operation failed before a bounded public result was available");
|
|
58337
|
+
}
|
|
58259
58338
|
function normalizedCallDigest(request) {
|
|
58260
58339
|
return digestMementosProjectRegistrationValue({
|
|
58261
58340
|
authority_route: request.authority_route,
|
|
@@ -58642,6 +58721,7 @@ class PackageOwnedMementosProjectRegistrationAuthority {
|
|
|
58642
58721
|
conditional_inverse: true,
|
|
58643
58722
|
ambiguous_outcome_reconciliation: true,
|
|
58644
58723
|
guarded_update: true,
|
|
58724
|
+
guarded_update_route: MEMENTOS_PROJECT_GUARDED_UPDATE_ROUTE,
|
|
58645
58725
|
no_write_dry_run: true,
|
|
58646
58726
|
expected_revision_compare_and_swap: true,
|
|
58647
58727
|
caller_idempotency: true,
|
|
@@ -58703,6 +58783,90 @@ class PackageOwnedMementosProjectRegistrationAuthority {
|
|
|
58703
58783
|
supported_resources: ["project"]
|
|
58704
58784
|
};
|
|
58705
58785
|
}
|
|
58786
|
+
boundedGuardedUpdateResult(targetId2, project, receipt, bounds, startedAt) {
|
|
58787
|
+
if (!receipt || project.id !== targetId2 || receipt.target_id !== targetId2) {
|
|
58788
|
+
throw new MementosProjectRegistrationError("MEMENTOS_PROJECT_REGISTRATION_ATOMICITY_UNAVAILABLE", "guarded project operation did not return its exact immutable receipt");
|
|
58789
|
+
}
|
|
58790
|
+
if (project.updated_at !== receipt.result_revision) {
|
|
58791
|
+
throw new MementosProjectRegistrationError("MEMENTOS_PROJECT_REGISTRATION_ATOMICITY_UNAVAILABLE", "guarded project result revision did not match its immutable receipt");
|
|
58792
|
+
}
|
|
58793
|
+
const record = {
|
|
58794
|
+
target_id: targetId2,
|
|
58795
|
+
revision: receipt.result_revision,
|
|
58796
|
+
digest: receipt.result_digest
|
|
58797
|
+
};
|
|
58798
|
+
return withBoundedResponseControl({
|
|
58799
|
+
dry_run: false,
|
|
58800
|
+
applied: true,
|
|
58801
|
+
record,
|
|
58802
|
+
receipt: publicGuardedUpdateReceipt(receipt, this.capabilityValue)
|
|
58803
|
+
}, bounds, startedAt);
|
|
58804
|
+
}
|
|
58805
|
+
async guardedUpdateProject(targetId2, request) {
|
|
58806
|
+
const startedAt = Date.now();
|
|
58807
|
+
const { identity, path } = assertGuardedUpdateRequest(targetId2, request, this.capabilityValue);
|
|
58808
|
+
try {
|
|
58809
|
+
const result = applyProjectUpdate(targetId2, {
|
|
58810
|
+
...identity,
|
|
58811
|
+
operation_id: request.operation_id,
|
|
58812
|
+
step_id: request.step_id,
|
|
58813
|
+
idempotency_key: request.idempotency_key,
|
|
58814
|
+
expected_revision: request.expected_revision,
|
|
58815
|
+
updates: { path }
|
|
58816
|
+
}, this.db, identity, (project) => projectRecord(this.db, project).digest);
|
|
58817
|
+
return this.boundedGuardedUpdateResult(targetId2, result.project, result.receipt, request, startedAt);
|
|
58818
|
+
} catch (cause) {
|
|
58819
|
+
return guardedProjectError(cause);
|
|
58820
|
+
}
|
|
58821
|
+
}
|
|
58822
|
+
async getGuardedProjectUpdateReceipt(targetId2, receiptId2, request) {
|
|
58823
|
+
const startedAt = Date.now();
|
|
58824
|
+
const identity = assertGuardedAuthorityRequest(targetId2, request, this.capabilityValue);
|
|
58825
|
+
requireString(receiptId2, "receipt_id", {
|
|
58826
|
+
min: 8,
|
|
58827
|
+
max: 128,
|
|
58828
|
+
pattern: OPERATION_PATTERN
|
|
58829
|
+
});
|
|
58830
|
+
try {
|
|
58831
|
+
const receipt = getProjectUpdateReceipt(targetId2, receiptId2, identity, this.db, identity);
|
|
58832
|
+
return withBoundedResponseControl({
|
|
58833
|
+
receipt: publicGuardedUpdateReceipt(receipt, this.capabilityValue)
|
|
58834
|
+
}, request, startedAt);
|
|
58835
|
+
} catch (cause) {
|
|
58836
|
+
return guardedProjectError(cause);
|
|
58837
|
+
}
|
|
58838
|
+
}
|
|
58839
|
+
async rollbackGuardedProjectUpdate(targetId2, request) {
|
|
58840
|
+
const startedAt = Date.now();
|
|
58841
|
+
const identity = assertGuardedAuthorityRequest(targetId2, request, this.capabilityValue);
|
|
58842
|
+
assertGuardedOperationFields(request);
|
|
58843
|
+
if (!request.accepted_receipt || typeof request.accepted_receipt !== "object") {
|
|
58844
|
+
throw new MementosProjectRegistrationError("MEMENTOS_PROJECT_REGISTRATION_INVALID_INPUT", "conditional rollback requires the exact sanitized accepted receipt");
|
|
58845
|
+
}
|
|
58846
|
+
requireString(request.accepted_receipt.receipt_id, "accepted_receipt.receipt_id", {
|
|
58847
|
+
min: 8,
|
|
58848
|
+
max: 128,
|
|
58849
|
+
pattern: OPERATION_PATTERN
|
|
58850
|
+
});
|
|
58851
|
+
try {
|
|
58852
|
+
const internalAccepted = getProjectUpdateReceipt(targetId2, request.accepted_receipt.receipt_id, identity, this.db, identity);
|
|
58853
|
+
const accepted = publicGuardedUpdateReceipt(internalAccepted, this.capabilityValue);
|
|
58854
|
+
if (accepted.direction !== "forward" || accepted.target_id !== targetId2 || request.expected_revision !== accepted.result_revision || canonicalMementosProjectRegistrationJson(request.accepted_receipt) !== canonicalMementosProjectRegistrationJson(accepted)) {
|
|
58855
|
+
throw new MementosProjectRegistrationError("MEMENTOS_PROJECT_REGISTRATION_INVALID_INPUT", "conditional rollback receipt does not exactly match the accepted forward update");
|
|
58856
|
+
}
|
|
58857
|
+
const result = rollbackProjectUpdate(targetId2, {
|
|
58858
|
+
...identity,
|
|
58859
|
+
operation_id: request.operation_id,
|
|
58860
|
+
step_id: request.step_id,
|
|
58861
|
+
idempotency_key: request.idempotency_key,
|
|
58862
|
+
expected_revision: request.expected_revision,
|
|
58863
|
+
accepted_receipt_id: accepted.receipt_id
|
|
58864
|
+
}, this.db, identity, (project) => projectRecord(this.db, project).digest);
|
|
58865
|
+
return this.boundedGuardedUpdateResult(targetId2, result.project, result.receipt, request, startedAt);
|
|
58866
|
+
} catch (cause) {
|
|
58867
|
+
return guardedProjectError(cause);
|
|
58868
|
+
}
|
|
58869
|
+
}
|
|
58706
58870
|
async create(request) {
|
|
58707
58871
|
const startedAt = Date.now();
|
|
58708
58872
|
const path = assertForwardRequest2(request, this.capabilityValue);
|
|
@@ -58799,9 +58963,9 @@ class PackageOwnedMementosProjectRegistrationAuthority {
|
|
|
58799
58963
|
throw new MementosProjectRegistrationError("MEMENTOS_PROJECT_REGISTRATION_INVALID_INPUT", "resource_kind must be project");
|
|
58800
58964
|
}
|
|
58801
58965
|
requireString(request.target_id, "target_id", {
|
|
58802
|
-
min:
|
|
58803
|
-
max:
|
|
58804
|
-
pattern:
|
|
58966
|
+
min: 8,
|
|
58967
|
+
max: 128,
|
|
58968
|
+
pattern: OPERATION_PATTERN
|
|
58805
58969
|
});
|
|
58806
58970
|
const path = ownedPath(request.target);
|
|
58807
58971
|
const project = getProjectByExactId3(this.db, request.target_id);
|
|
@@ -59059,6 +59223,31 @@ function fromWireReadRequest(body) {
|
|
|
59059
59223
|
target: new WirePathHandle(canonicalPath)
|
|
59060
59224
|
};
|
|
59061
59225
|
}
|
|
59226
|
+
function fromWireGuardedUpdateRequest(body) {
|
|
59227
|
+
const { target_id: targetId2, updates, ...request } = body;
|
|
59228
|
+
if (typeof targetId2 !== "string") {
|
|
59229
|
+
throw new MementosProjectRegistrationError("MEMENTOS_PROJECT_REGISTRATION_INVALID_INPUT", "target_id is required on the private guarded-update transport");
|
|
59230
|
+
}
|
|
59231
|
+
if (!updates || typeof updates !== "object" || Array.isArray(updates) || typeof updates["path"] !== "string") {
|
|
59232
|
+
throw new MementosProjectRegistrationError("MEMENTOS_PROJECT_REGISTRATION_INVALID_INPUT", "updates.path is required on the private guarded-update transport");
|
|
59233
|
+
}
|
|
59234
|
+
return {
|
|
59235
|
+
targetId: targetId2,
|
|
59236
|
+
request: {
|
|
59237
|
+
...request,
|
|
59238
|
+
updates: {
|
|
59239
|
+
path: new WirePathHandle(String(updates["path"]))
|
|
59240
|
+
}
|
|
59241
|
+
}
|
|
59242
|
+
};
|
|
59243
|
+
}
|
|
59244
|
+
function exactWireIdentifier(body, field) {
|
|
59245
|
+
const value = body[field];
|
|
59246
|
+
if (typeof value !== "string") {
|
|
59247
|
+
throw new MementosProjectRegistrationError("MEMENTOS_PROJECT_REGISTRATION_INVALID_INPUT", `${field} is required on the guarded-update transport`);
|
|
59248
|
+
}
|
|
59249
|
+
return value;
|
|
59250
|
+
}
|
|
59062
59251
|
async function handleMementosProjectRegistrationHttpRequest(request, url, authority, basePath = "/v1/project-registration") {
|
|
59063
59252
|
const path = url.pathname;
|
|
59064
59253
|
if (path !== basePath && !path.startsWith(`${basePath}/`))
|
|
@@ -59093,6 +59282,21 @@ async function handleMementosProjectRegistrationHttpRequest(request, url, author
|
|
|
59093
59282
|
if (action === "verify-inverse") {
|
|
59094
59283
|
return json2({ verification: await authority.verifyInverse(fromWireRequest(body)) });
|
|
59095
59284
|
}
|
|
59285
|
+
if (action === "projects/guarded-update") {
|
|
59286
|
+
const guarded = fromWireGuardedUpdateRequest(body);
|
|
59287
|
+
return json2(await authority.guardedUpdateProject(guarded.targetId, guarded.request));
|
|
59288
|
+
}
|
|
59289
|
+
if (action === "projects/update-receipts/lookup") {
|
|
59290
|
+
const targetId2 = exactWireIdentifier(body, "target_id");
|
|
59291
|
+
const receiptId2 = exactWireIdentifier(body, "receipt_id");
|
|
59292
|
+
const { target_id: _targetId, receipt_id: _receiptId, ...lookup } = body;
|
|
59293
|
+
return json2(await authority.getGuardedProjectUpdateReceipt(targetId2, receiptId2, lookup));
|
|
59294
|
+
}
|
|
59295
|
+
if (action === "projects/guarded-rollback") {
|
|
59296
|
+
const targetId2 = exactWireIdentifier(body, "target_id");
|
|
59297
|
+
const { target_id: _targetId, ...rollback } = body;
|
|
59298
|
+
return json2(await authority.rollbackGuardedProjectUpdate(targetId2, rollback));
|
|
59299
|
+
}
|
|
59096
59300
|
return json2({
|
|
59097
59301
|
error: "unknown Mementos project-registration route",
|
|
59098
59302
|
code: "MEMENTOS_PROJECT_REGISTRATION_RECEIPT_NOT_FOUND"
|
|
@@ -59129,6 +59333,9 @@ addRoute("POST", "/api/project-registration/receipts/lookup", handle);
|
|
|
59129
59333
|
addRoute("POST", "/api/project-registration/read-exact", handle);
|
|
59130
59334
|
addRoute("POST", "/api/project-registration/compensate", handle);
|
|
59131
59335
|
addRoute("POST", "/api/project-registration/verify-inverse", handle);
|
|
59336
|
+
addRoute("POST", "/api/project-registration/projects/guarded-update", handle);
|
|
59337
|
+
addRoute("POST", "/api/project-registration/projects/update-receipts/lookup", handle);
|
|
59338
|
+
addRoute("POST", "/api/project-registration/projects/guarded-rollback", handle);
|
|
59132
59339
|
|
|
59133
59340
|
// src/server/routes/entities.ts
|
|
59134
59341
|
init_entities();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/mementos",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.81",
|
|
4
4
|
"description": "Universal memory system for AI agents - CLI + MCP server + library API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -108,5 +108,5 @@
|
|
|
108
108
|
"sigstore": "5.0.0",
|
|
109
109
|
"typescript": "^5.7.3"
|
|
110
110
|
},
|
|
111
|
-
"gitHead": "
|
|
111
|
+
"gitHead": "cb2c4c46e64f71e28018307fe00b7083e2e0a8aa"
|
|
112
112
|
}
|