@stardeck-customer-apps/testing 0.18.0 → 0.19.0

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/SKILL.md CHANGED
@@ -371,7 +371,11 @@ externalId })` helper models a trusted platform/channel link, and
371
371
  back `refused` / `owned_elsewhere`. That refusal is the one a leaked bearer
372
372
  link runs into, so test it. A profile that holds an email or phone is refused
373
373
  at `create` with a 409 (send an `invite`); one that gains a contact before
374
- the link is used completes as `refused` / `protected`, and a link still
374
+ the link is used completes as `refused` / `protected`. The same holds for a
375
+ profile another one was merged into (`app.identities.merge(other, target)`):
376
+ `create` is a 409 and an outstanding link completes as `refused` /
377
+ `protected`, because a bearer link hands over one visit's profile, never
378
+ history staff folded into it. A link still
375
379
  outstanding when `.enableBearerLinks(false)` runs completes as `refused` /
376
380
  `expired`. People seeded with only a `dashboard_user` link (team members) are
377
381
  left out of `identities.list()` and `search()`, as on the platform.
package/dist/index.js CHANGED
@@ -867,6 +867,9 @@ function isCurrentTeamMember(identityId) {
867
867
  function hasRecordedContact(identityId) {
868
868
  return linksFor(identityId).some((link) => link.kind === "email" || link.kind === "phone");
869
869
  }
870
+ function hasAbsorbedIdentity(identityId) {
871
+ return [...state.identities.values()].some((identity) => identity.mergedIntoId === identityId);
872
+ }
870
873
  function handleList(request) {
871
874
  const typeParam = new URL(request.url).searchParams.get("type");
872
875
  const type = typeParam === "person" || typeParam === "account" ? typeParam : void 0;
@@ -1217,6 +1220,9 @@ function createBearerClaim(body, returnTo) {
1217
1220
  if (hasRecordedContact(identity.id)) {
1218
1221
  return failure("identity has an email or phone on record; send an invite claim instead", 409);
1219
1222
  }
1223
+ if (hasAbsorbedIdentity(identity.id)) {
1224
+ return failure("another profile was merged into this identity; reception must connect it", 409);
1225
+ }
1220
1226
  return mintClaim({
1221
1227
  flow: "bearer",
1222
1228
  identityId: identity.id,
@@ -1463,7 +1469,7 @@ function completeBearerClaim(claim, clerkUserId) {
1463
1469
  claim.state = "invalidated";
1464
1470
  return claim;
1465
1471
  }
1466
- const refusal = !state.identityBearerLinksEnabled ? "expired" : hasRecordedContact(claim.identityId) ? "protected" : ownedByAnotherLogin(claim.identityId, clerkUserId) ? "owned_elsewhere" : null;
1472
+ const refusal = !state.identityBearerLinksEnabled ? "expired" : hasRecordedContact(claim.identityId) || hasAbsorbedIdentity(claim.identityId) ? "protected" : ownedByAnotherLogin(claim.identityId, clerkUserId) ? "owned_elsewhere" : null;
1467
1473
  if (refusal) {
1468
1474
  claim.state = "refused";
1469
1475
  claim.refusalReason = refusal;
package/dist/index.mjs CHANGED
@@ -818,6 +818,9 @@ function isCurrentTeamMember(identityId) {
818
818
  function hasRecordedContact(identityId) {
819
819
  return linksFor(identityId).some((link) => link.kind === "email" || link.kind === "phone");
820
820
  }
821
+ function hasAbsorbedIdentity(identityId) {
822
+ return [...state.identities.values()].some((identity) => identity.mergedIntoId === identityId);
823
+ }
821
824
  function handleList(request) {
822
825
  const typeParam = new URL(request.url).searchParams.get("type");
823
826
  const type = typeParam === "person" || typeParam === "account" ? typeParam : void 0;
@@ -1168,6 +1171,9 @@ function createBearerClaim(body, returnTo) {
1168
1171
  if (hasRecordedContact(identity.id)) {
1169
1172
  return failure("identity has an email or phone on record; send an invite claim instead", 409);
1170
1173
  }
1174
+ if (hasAbsorbedIdentity(identity.id)) {
1175
+ return failure("another profile was merged into this identity; reception must connect it", 409);
1176
+ }
1171
1177
  return mintClaim({
1172
1178
  flow: "bearer",
1173
1179
  identityId: identity.id,
@@ -1414,7 +1420,7 @@ function completeBearerClaim(claim, clerkUserId) {
1414
1420
  claim.state = "invalidated";
1415
1421
  return claim;
1416
1422
  }
1417
- const refusal = !state.identityBearerLinksEnabled ? "expired" : hasRecordedContact(claim.identityId) ? "protected" : ownedByAnotherLogin(claim.identityId, clerkUserId) ? "owned_elsewhere" : null;
1423
+ const refusal = !state.identityBearerLinksEnabled ? "expired" : hasRecordedContact(claim.identityId) || hasAbsorbedIdentity(claim.identityId) ? "protected" : ownedByAnotherLogin(claim.identityId, clerkUserId) ? "owned_elsewhere" : null;
1418
1424
  if (refusal) {
1419
1425
  claim.state = "refused";
1420
1426
  claim.refusalReason = refusal;
package/dist/setup.js CHANGED
@@ -769,6 +769,9 @@ function isCurrentTeamMember(identityId) {
769
769
  function hasRecordedContact(identityId) {
770
770
  return linksFor(identityId).some((link) => link.kind === "email" || link.kind === "phone");
771
771
  }
772
+ function hasAbsorbedIdentity(identityId) {
773
+ return [...state.identities.values()].some((identity) => identity.mergedIntoId === identityId);
774
+ }
772
775
  function handleList(request) {
773
776
  const typeParam = new URL(request.url).searchParams.get("type");
774
777
  const type = typeParam === "person" || typeParam === "account" ? typeParam : void 0;
@@ -1119,6 +1122,9 @@ function createBearerClaim(body, returnTo) {
1119
1122
  if (hasRecordedContact(identity.id)) {
1120
1123
  return failure("identity has an email or phone on record; send an invite claim instead", 409);
1121
1124
  }
1125
+ if (hasAbsorbedIdentity(identity.id)) {
1126
+ return failure("another profile was merged into this identity; reception must connect it", 409);
1127
+ }
1122
1128
  return mintClaim({
1123
1129
  flow: "bearer",
1124
1130
  identityId: identity.id,
package/dist/setup.mjs CHANGED
@@ -745,6 +745,9 @@ function isCurrentTeamMember(identityId) {
745
745
  function hasRecordedContact(identityId) {
746
746
  return linksFor(identityId).some((link) => link.kind === "email" || link.kind === "phone");
747
747
  }
748
+ function hasAbsorbedIdentity(identityId) {
749
+ return [...state.identities.values()].some((identity) => identity.mergedIntoId === identityId);
750
+ }
748
751
  function handleList(request) {
749
752
  const typeParam = new URL(request.url).searchParams.get("type");
750
753
  const type = typeParam === "person" || typeParam === "account" ? typeParam : void 0;
@@ -1095,6 +1098,9 @@ function createBearerClaim(body, returnTo) {
1095
1098
  if (hasRecordedContact(identity.id)) {
1096
1099
  return failure("identity has an email or phone on record; send an invite claim instead", 409);
1097
1100
  }
1101
+ if (hasAbsorbedIdentity(identity.id)) {
1102
+ return failure("another profile was merged into this identity; reception must connect it", 409);
1103
+ }
1098
1104
  return mintClaim({
1099
1105
  flow: "bearer",
1100
1106
  identityId: identity.id,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stardeck-customer-apps/testing",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "description": "Vitest test harness for Stardeck customer apps — in-process Postgres (PGlite) plus a control-plane simulator so the real Stardeck SDKs run unmodified in tests",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",