@stardeck-customer-apps/testing 0.6.0 → 0.6.1
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 +5 -2
- package/dist/index.js +16 -6
- package/dist/index.mjs +16 -6
- package/dist/setup.js +14 -13
- package/dist/setup.mjs +14 -13
- package/package.json +1 -1
package/SKILL.md
CHANGED
|
@@ -215,10 +215,13 @@ describe the code, and the owner can't tell from them what is or isn't covered.
|
|
|
215
215
|
- `client.identities` from integrations-sdk (create/get/update/list accounts &
|
|
216
216
|
persons, attach channel links, guest/staff `resolveOrCreate`, paginated
|
|
217
217
|
`search`, and batch `getAliases`) — served offline by the simulated directory.
|
|
218
|
-
`resolveOrCreate`
|
|
218
|
+
`resolveOrCreate` applies the production email contract (trim + ASCII-only
|
|
219
|
+
A–Z→a–z; Turkish İ is left unchanged), requires E.164 phone values, and
|
|
219
220
|
always writes an unverified link. A guest lookup of a verified link returns
|
|
220
221
|
`{ identityId: null, reason: "verified_conflict" }`; staff provenance may
|
|
221
|
-
resolve either verified or unverified links. `attachLink
|
|
222
|
+
resolve either verified or unverified links. `attachLink` accepts only
|
|
223
|
+
channel kinds (line/facebook/instagram/email/phone); login keys must be
|
|
224
|
+
seeded via `app.identities.seedVerifiedLink`. `attachLink(..., { verified:
|
|
222
225
|
true })` remains source-compatible but the simulator (like the control plane)
|
|
223
226
|
ignores that flag and returns `verified: false`. `update` replaces the
|
|
224
227
|
`profile` object (not a merge), like the control plane. Inspect via
|
package/dist/index.js
CHANGED
|
@@ -679,7 +679,8 @@ function createInbox() {
|
|
|
679
679
|
|
|
680
680
|
// src/simulator/identities.ts
|
|
681
681
|
var import_node_crypto3 = __toESM(require("crypto"));
|
|
682
|
-
var
|
|
682
|
+
var ATTACH_LINK_KINDS = /* @__PURE__ */ new Set(["line", "facebook", "instagram", "email", "phone"]);
|
|
683
|
+
var TRUSTED_LINK_KINDS = /* @__PURE__ */ new Set([
|
|
683
684
|
"line",
|
|
684
685
|
"facebook",
|
|
685
686
|
"instagram",
|
|
@@ -692,6 +693,15 @@ var RESOLVE_KINDS = /* @__PURE__ */ new Set(["phone", "email", "line"]);
|
|
|
692
693
|
var E164_PHONE = /^\+[1-9]\d{1,14}$/;
|
|
693
694
|
var SEARCH_DEFAULT_LIMIT = 50;
|
|
694
695
|
var SEARCH_MAX_LIMIT = 100;
|
|
696
|
+
function asciiLowercaseTrim(value) {
|
|
697
|
+
const trimmed = value.trim();
|
|
698
|
+
let out = "";
|
|
699
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
700
|
+
const code = trimmed.charCodeAt(i);
|
|
701
|
+
out += code >= 65 && code <= 90 ? String.fromCharCode(code + 32) : trimmed[i];
|
|
702
|
+
}
|
|
703
|
+
return out;
|
|
704
|
+
}
|
|
695
705
|
var IdentityGraphError = class extends Error {
|
|
696
706
|
};
|
|
697
707
|
function now() {
|
|
@@ -701,12 +711,12 @@ function linksFor(identityId) {
|
|
|
701
711
|
return state.identityLinks.filter((l) => l.identityId === identityId);
|
|
702
712
|
}
|
|
703
713
|
function comparableExternalId(kind, externalId) {
|
|
704
|
-
if (kind === "email") return externalId
|
|
714
|
+
if (kind === "email") return asciiLowercaseTrim(externalId);
|
|
705
715
|
return externalId;
|
|
706
716
|
}
|
|
707
717
|
function normalizeExternalId(kind, externalId) {
|
|
708
718
|
if (kind === "email") {
|
|
709
|
-
const normalized = externalId
|
|
719
|
+
const normalized = asciiLowercaseTrim(externalId);
|
|
710
720
|
return normalized.length > 0 ? { externalId: normalized } : { error: "externalId is required" };
|
|
711
721
|
}
|
|
712
722
|
if (kind === "phone" && !E164_PHONE.test(externalId)) {
|
|
@@ -870,8 +880,8 @@ async function handleAttachLink(identityId, request) {
|
|
|
870
880
|
const normalized = normalizeLinkInput(
|
|
871
881
|
body.kind,
|
|
872
882
|
body.externalId,
|
|
873
|
-
|
|
874
|
-
`kind must be one of: ${[...
|
|
883
|
+
ATTACH_LINK_KINDS,
|
|
884
|
+
`kind must be one of: ${[...ATTACH_LINK_KINDS].join(", ")}`
|
|
875
885
|
);
|
|
876
886
|
if ("error" in normalized) return failure(normalized.error);
|
|
877
887
|
const { kind, externalId } = normalized;
|
|
@@ -1046,7 +1056,7 @@ function seedVerifiedLink(identityId, params) {
|
|
|
1046
1056
|
const normalized = normalizeLinkInput(
|
|
1047
1057
|
params.kind,
|
|
1048
1058
|
params.externalId,
|
|
1049
|
-
|
|
1059
|
+
TRUSTED_LINK_KINDS,
|
|
1050
1060
|
"unknown identity link kind"
|
|
1051
1061
|
);
|
|
1052
1062
|
if ("error" in normalized) throw new Error(normalized.error);
|
package/dist/index.mjs
CHANGED
|
@@ -633,7 +633,8 @@ function createInbox() {
|
|
|
633
633
|
|
|
634
634
|
// src/simulator/identities.ts
|
|
635
635
|
import crypto3 from "crypto";
|
|
636
|
-
var
|
|
636
|
+
var ATTACH_LINK_KINDS = /* @__PURE__ */ new Set(["line", "facebook", "instagram", "email", "phone"]);
|
|
637
|
+
var TRUSTED_LINK_KINDS = /* @__PURE__ */ new Set([
|
|
637
638
|
"line",
|
|
638
639
|
"facebook",
|
|
639
640
|
"instagram",
|
|
@@ -646,6 +647,15 @@ var RESOLVE_KINDS = /* @__PURE__ */ new Set(["phone", "email", "line"]);
|
|
|
646
647
|
var E164_PHONE = /^\+[1-9]\d{1,14}$/;
|
|
647
648
|
var SEARCH_DEFAULT_LIMIT = 50;
|
|
648
649
|
var SEARCH_MAX_LIMIT = 100;
|
|
650
|
+
function asciiLowercaseTrim(value) {
|
|
651
|
+
const trimmed = value.trim();
|
|
652
|
+
let out = "";
|
|
653
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
654
|
+
const code = trimmed.charCodeAt(i);
|
|
655
|
+
out += code >= 65 && code <= 90 ? String.fromCharCode(code + 32) : trimmed[i];
|
|
656
|
+
}
|
|
657
|
+
return out;
|
|
658
|
+
}
|
|
649
659
|
var IdentityGraphError = class extends Error {
|
|
650
660
|
};
|
|
651
661
|
function now() {
|
|
@@ -655,12 +665,12 @@ function linksFor(identityId) {
|
|
|
655
665
|
return state.identityLinks.filter((l) => l.identityId === identityId);
|
|
656
666
|
}
|
|
657
667
|
function comparableExternalId(kind, externalId) {
|
|
658
|
-
if (kind === "email") return externalId
|
|
668
|
+
if (kind === "email") return asciiLowercaseTrim(externalId);
|
|
659
669
|
return externalId;
|
|
660
670
|
}
|
|
661
671
|
function normalizeExternalId(kind, externalId) {
|
|
662
672
|
if (kind === "email") {
|
|
663
|
-
const normalized = externalId
|
|
673
|
+
const normalized = asciiLowercaseTrim(externalId);
|
|
664
674
|
return normalized.length > 0 ? { externalId: normalized } : { error: "externalId is required" };
|
|
665
675
|
}
|
|
666
676
|
if (kind === "phone" && !E164_PHONE.test(externalId)) {
|
|
@@ -824,8 +834,8 @@ async function handleAttachLink(identityId, request) {
|
|
|
824
834
|
const normalized = normalizeLinkInput(
|
|
825
835
|
body.kind,
|
|
826
836
|
body.externalId,
|
|
827
|
-
|
|
828
|
-
`kind must be one of: ${[...
|
|
837
|
+
ATTACH_LINK_KINDS,
|
|
838
|
+
`kind must be one of: ${[...ATTACH_LINK_KINDS].join(", ")}`
|
|
829
839
|
);
|
|
830
840
|
if ("error" in normalized) return failure(normalized.error);
|
|
831
841
|
const { kind, externalId } = normalized;
|
|
@@ -1000,7 +1010,7 @@ function seedVerifiedLink(identityId, params) {
|
|
|
1000
1010
|
const normalized = normalizeLinkInput(
|
|
1001
1011
|
params.kind,
|
|
1002
1012
|
params.externalId,
|
|
1003
|
-
|
|
1013
|
+
TRUSTED_LINK_KINDS,
|
|
1004
1014
|
"unknown identity link kind"
|
|
1005
1015
|
);
|
|
1006
1016
|
if ("error" in normalized) throw new Error(normalized.error);
|
package/dist/setup.js
CHANGED
|
@@ -609,19 +609,20 @@ async function handleEmailSend(request) {
|
|
|
609
609
|
|
|
610
610
|
// src/simulator/identities.ts
|
|
611
611
|
var import_node_crypto3 = __toESM(require("crypto"));
|
|
612
|
-
var
|
|
613
|
-
"line",
|
|
614
|
-
"facebook",
|
|
615
|
-
"instagram",
|
|
616
|
-
"email",
|
|
617
|
-
"phone",
|
|
618
|
-
"project_auth_user",
|
|
619
|
-
"dashboard_user"
|
|
620
|
-
]);
|
|
612
|
+
var ATTACH_LINK_KINDS = /* @__PURE__ */ new Set(["line", "facebook", "instagram", "email", "phone"]);
|
|
621
613
|
var RESOLVE_KINDS = /* @__PURE__ */ new Set(["phone", "email", "line"]);
|
|
622
614
|
var E164_PHONE = /^\+[1-9]\d{1,14}$/;
|
|
623
615
|
var SEARCH_DEFAULT_LIMIT = 50;
|
|
624
616
|
var SEARCH_MAX_LIMIT = 100;
|
|
617
|
+
function asciiLowercaseTrim(value) {
|
|
618
|
+
const trimmed = value.trim();
|
|
619
|
+
let out = "";
|
|
620
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
621
|
+
const code = trimmed.charCodeAt(i);
|
|
622
|
+
out += code >= 65 && code <= 90 ? String.fromCharCode(code + 32) : trimmed[i];
|
|
623
|
+
}
|
|
624
|
+
return out;
|
|
625
|
+
}
|
|
625
626
|
var IdentityGraphError = class extends Error {
|
|
626
627
|
};
|
|
627
628
|
function now() {
|
|
@@ -631,12 +632,12 @@ function linksFor(identityId) {
|
|
|
631
632
|
return state.identityLinks.filter((l) => l.identityId === identityId);
|
|
632
633
|
}
|
|
633
634
|
function comparableExternalId(kind, externalId) {
|
|
634
|
-
if (kind === "email") return externalId
|
|
635
|
+
if (kind === "email") return asciiLowercaseTrim(externalId);
|
|
635
636
|
return externalId;
|
|
636
637
|
}
|
|
637
638
|
function normalizeExternalId(kind, externalId) {
|
|
638
639
|
if (kind === "email") {
|
|
639
|
-
const normalized = externalId
|
|
640
|
+
const normalized = asciiLowercaseTrim(externalId);
|
|
640
641
|
return normalized.length > 0 ? { externalId: normalized } : { error: "externalId is required" };
|
|
641
642
|
}
|
|
642
643
|
if (kind === "phone" && !E164_PHONE.test(externalId)) {
|
|
@@ -797,8 +798,8 @@ async function handleAttachLink(identityId, request) {
|
|
|
797
798
|
const normalized = normalizeLinkInput(
|
|
798
799
|
body.kind,
|
|
799
800
|
body.externalId,
|
|
800
|
-
|
|
801
|
-
`kind must be one of: ${[...
|
|
801
|
+
ATTACH_LINK_KINDS,
|
|
802
|
+
`kind must be one of: ${[...ATTACH_LINK_KINDS].join(", ")}`
|
|
802
803
|
);
|
|
803
804
|
if ("error" in normalized) return failure(normalized.error);
|
|
804
805
|
const { kind, externalId } = normalized;
|
package/dist/setup.mjs
CHANGED
|
@@ -585,19 +585,20 @@ async function handleEmailSend(request) {
|
|
|
585
585
|
|
|
586
586
|
// src/simulator/identities.ts
|
|
587
587
|
import crypto3 from "crypto";
|
|
588
|
-
var
|
|
589
|
-
"line",
|
|
590
|
-
"facebook",
|
|
591
|
-
"instagram",
|
|
592
|
-
"email",
|
|
593
|
-
"phone",
|
|
594
|
-
"project_auth_user",
|
|
595
|
-
"dashboard_user"
|
|
596
|
-
]);
|
|
588
|
+
var ATTACH_LINK_KINDS = /* @__PURE__ */ new Set(["line", "facebook", "instagram", "email", "phone"]);
|
|
597
589
|
var RESOLVE_KINDS = /* @__PURE__ */ new Set(["phone", "email", "line"]);
|
|
598
590
|
var E164_PHONE = /^\+[1-9]\d{1,14}$/;
|
|
599
591
|
var SEARCH_DEFAULT_LIMIT = 50;
|
|
600
592
|
var SEARCH_MAX_LIMIT = 100;
|
|
593
|
+
function asciiLowercaseTrim(value) {
|
|
594
|
+
const trimmed = value.trim();
|
|
595
|
+
let out = "";
|
|
596
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
597
|
+
const code = trimmed.charCodeAt(i);
|
|
598
|
+
out += code >= 65 && code <= 90 ? String.fromCharCode(code + 32) : trimmed[i];
|
|
599
|
+
}
|
|
600
|
+
return out;
|
|
601
|
+
}
|
|
601
602
|
var IdentityGraphError = class extends Error {
|
|
602
603
|
};
|
|
603
604
|
function now() {
|
|
@@ -607,12 +608,12 @@ function linksFor(identityId) {
|
|
|
607
608
|
return state.identityLinks.filter((l) => l.identityId === identityId);
|
|
608
609
|
}
|
|
609
610
|
function comparableExternalId(kind, externalId) {
|
|
610
|
-
if (kind === "email") return externalId
|
|
611
|
+
if (kind === "email") return asciiLowercaseTrim(externalId);
|
|
611
612
|
return externalId;
|
|
612
613
|
}
|
|
613
614
|
function normalizeExternalId(kind, externalId) {
|
|
614
615
|
if (kind === "email") {
|
|
615
|
-
const normalized = externalId
|
|
616
|
+
const normalized = asciiLowercaseTrim(externalId);
|
|
616
617
|
return normalized.length > 0 ? { externalId: normalized } : { error: "externalId is required" };
|
|
617
618
|
}
|
|
618
619
|
if (kind === "phone" && !E164_PHONE.test(externalId)) {
|
|
@@ -773,8 +774,8 @@ async function handleAttachLink(identityId, request) {
|
|
|
773
774
|
const normalized = normalizeLinkInput(
|
|
774
775
|
body.kind,
|
|
775
776
|
body.externalId,
|
|
776
|
-
|
|
777
|
-
`kind must be one of: ${[...
|
|
777
|
+
ATTACH_LINK_KINDS,
|
|
778
|
+
`kind must be one of: ${[...ATTACH_LINK_KINDS].join(", ")}`
|
|
778
779
|
);
|
|
779
780
|
if ("error" in normalized) return failure(normalized.error);
|
|
780
781
|
const { kind, externalId } = normalized;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stardeck-customer-apps/testing",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
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",
|