@wspc/cli 0.0.16 → 0.0.17

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.js CHANGED
@@ -1177,10 +1177,21 @@ var V1_CRED_KEYS = [
1177
1177
  "actor",
1178
1178
  "agent_label"
1179
1179
  ];
1180
+ var CONSISTENCY_BOOKMARK_SERVICES = ["auth", "todo", "calendar", "email", "push"];
1181
+ function normalizeConsistencyBookmarks(raw) {
1182
+ if (typeof raw !== "object" || raw === null) return void 0;
1183
+ const out = {};
1184
+ const obj = raw;
1185
+ for (const service of CONSISTENCY_BOOKMARK_SERVICES) {
1186
+ if (typeof obj[service] === "string") out[service] = obj[service];
1187
+ }
1188
+ return Object.keys(out).length ? out : void 0;
1189
+ }
1180
1190
  function migrateEnv(raw) {
1181
1191
  const api_base = typeof raw.api_base === "string" ? raw.api_base : "";
1182
1192
  const env = { api_base, accounts: {} };
1183
- if (typeof raw.consistency_bookmark === "string") env.consistency_bookmark = raw.consistency_bookmark;
1193
+ const consistency_bookmarks = normalizeConsistencyBookmarks(raw.consistency_bookmarks);
1194
+ if (consistency_bookmarks) env.consistency_bookmarks = consistency_bookmarks;
1184
1195
  if (typeof raw.client_id === "string") env.client_id = raw.client_id;
1185
1196
  if (raw.accounts && typeof raw.accounts === "object") {
1186
1197
  env.accounts = raw.accounts;
@@ -1302,8 +1313,22 @@ var ConfigStore = class {
1302
1313
  };
1303
1314
 
1304
1315
  // src/handwritten/auth/consistency-fetch.ts
1305
- var HEADER = "x-consistency-bookmark";
1306
1316
  var INVALID_BOOKMARK = "INVALID_CONSISTENCY_BOOKMARK";
1317
+ var SERVICE_HEADERS = {
1318
+ auth: "x-cb-auth",
1319
+ todo: "x-cb-todo",
1320
+ calendar: "x-cb-cal",
1321
+ email: "x-cb-email",
1322
+ push: "x-cb-push"
1323
+ };
1324
+ var SERVICE_PREFIXES = [
1325
+ { service: "auth", prefix: "/auth" },
1326
+ { service: "todo", prefix: "/todo" },
1327
+ { service: "calendar", prefix: "/calendar" },
1328
+ { service: "email", prefix: "/email" },
1329
+ { service: "push", prefix: "/push" }
1330
+ ];
1331
+ var KNOWN_HEADERS = Object.values(SERVICE_HEADERS);
1307
1332
  function normalizeBasePath(pathname) {
1308
1333
  const trimmed = pathname.replace(/\/+$/, "");
1309
1334
  return trimmed === "" ? "/" : trimmed;
@@ -1313,6 +1338,26 @@ function isUnderApiBase(url, apiBase) {
1313
1338
  const basePath = normalizeBasePath(base.pathname);
1314
1339
  return url.origin === base.origin && (basePath === "/" || url.pathname === basePath || url.pathname.startsWith(`${basePath}/`));
1315
1340
  }
1341
+ function pathWithinApiBase(url, apiBase) {
1342
+ const basePath = normalizeBasePath(new URL(apiBase).pathname);
1343
+ if (basePath === "/") return url.pathname;
1344
+ if (url.pathname === basePath) return "/";
1345
+ return url.pathname.slice(basePath.length) || "/";
1346
+ }
1347
+ function pathMatchesPrefix(pathname, prefix) {
1348
+ return pathname === prefix || pathname.startsWith(`${prefix}/`);
1349
+ }
1350
+ function serviceForPath(pathname) {
1351
+ return SERVICE_PREFIXES.find(({ prefix }) => pathMatchesPrefix(pathname, prefix))?.service;
1352
+ }
1353
+ function stripKnownBookmarkHeaders(request, keep) {
1354
+ if (!KNOWN_HEADERS.some((header) => header !== keep && request.headers.has(header))) return request;
1355
+ const headers = new Headers(request.headers);
1356
+ for (const header of KNOWN_HEADERS) {
1357
+ if (header !== keep) headers.delete(header);
1358
+ }
1359
+ return new Request(request, { headers });
1360
+ }
1316
1361
  function isJsonContentType(contentType) {
1317
1362
  const mediaType = contentType.toLowerCase().split(";")[0]?.trim() ?? "";
1318
1363
  return mediaType === "application/json" || mediaType.endsWith("+json");
@@ -1334,36 +1379,44 @@ function createConsistencyFetch(opts) {
1334
1379
  const url = new URL(request.url);
1335
1380
  const applies = isUnderApiBase(url, opts.apiBase);
1336
1381
  let outgoing = request;
1337
- let injectedStoredBookmark = false;
1338
- if (applies && !outgoing.headers.has(HEADER)) {
1339
- const config = await opts.store.read();
1340
- const bookmark = config.envs[opts.envName]?.consistency_bookmark;
1341
- if (bookmark) {
1342
- const headers = new Headers(outgoing.headers);
1343
- headers.set(HEADER, bookmark);
1344
- outgoing = new Request(outgoing, { headers });
1345
- injectedStoredBookmark = true;
1382
+ let injectedService;
1383
+ const service = applies ? serviceForPath(pathWithinApiBase(url, opts.apiBase)) : void 0;
1384
+ const serviceHeader = service ? SERVICE_HEADERS[service] : void 0;
1385
+ outgoing = stripKnownBookmarkHeaders(outgoing, applies ? serviceHeader : void 0);
1386
+ if (applies && service) {
1387
+ const header = SERVICE_HEADERS[service];
1388
+ if (!outgoing.headers.has(header)) {
1389
+ const config = await opts.store.read();
1390
+ const bookmark = config.envs[opts.envName]?.consistency_bookmarks?.[service];
1391
+ if (bookmark) {
1392
+ const headers = new Headers(outgoing.headers);
1393
+ headers.set(header, bookmark);
1394
+ outgoing = new Request(outgoing, { headers });
1395
+ injectedService = service;
1396
+ }
1346
1397
  }
1347
1398
  }
1348
- if (!applies && outgoing.headers.has(HEADER)) {
1349
- const headers = new Headers(outgoing.headers);
1350
- headers.delete(HEADER);
1351
- outgoing = new Request(outgoing, { headers });
1352
- }
1353
1399
  const response = await fetchImpl(outgoing);
1354
1400
  if (!applies) return response;
1355
- const nextBookmark = response.headers.get(HEADER);
1356
- const shouldCheckInvalidBookmark = injectedStoredBookmark && !nextBookmark;
1401
+ const nextBookmarks = Object.entries(SERVICE_HEADERS).flatMap(([serviceName, header]) => {
1402
+ const value = response.headers.get(header);
1403
+ return value ? [[serviceName, value]] : [];
1404
+ });
1405
+ const shouldCheckInvalidBookmark = injectedService !== void 0;
1357
1406
  const invalidBookmark = shouldCheckInvalidBookmark ? await responseHasInvalidBookmark(response) : false;
1358
- const shouldClearBookmark = invalidBookmark;
1359
- if (!nextBookmark && !shouldClearBookmark) return response;
1407
+ if (nextBookmarks.length === 0 && !invalidBookmark) return response;
1360
1408
  await opts.store.update((config) => {
1361
1409
  const env = config.envs[opts.envName];
1362
1410
  if (!env) return;
1363
- if (nextBookmark) {
1364
- env.consistency_bookmark = nextBookmark;
1365
- } else if (shouldClearBookmark) {
1366
- delete env.consistency_bookmark;
1411
+ env.consistency_bookmarks ??= {};
1412
+ for (const [serviceName, value] of nextBookmarks) {
1413
+ env.consistency_bookmarks[serviceName] = value;
1414
+ }
1415
+ if (invalidBookmark && injectedService) {
1416
+ delete env.consistency_bookmarks[injectedService];
1417
+ }
1418
+ if (Object.keys(env.consistency_bookmarks).length === 0) {
1419
+ delete env.consistency_bookmarks;
1367
1420
  }
1368
1421
  });
1369
1422
  return response;
@@ -1371,9 +1424,9 @@ function createConsistencyFetch(opts) {
1371
1424
  }
1372
1425
 
1373
1426
  // src/version.ts
1374
- var VERSION = "0.0.16";
1375
- var SPEC_SHA = "b505a817";
1376
- var SPEC_FETCHED_AT = "2026-06-16T07:42:43.911Z";
1427
+ var VERSION = "0.0.17";
1428
+ var SPEC_SHA = "d0ccc741";
1429
+ var SPEC_FETCHED_AT = "2026-06-16T14:51:59.656Z";
1377
1430
  var API_BASE = "https://api.wspc.ai";
1378
1431
 
1379
1432
  // src/index.ts