@limrun/ui 0.9.0-rc.8 → 0.13.3-rc.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.
Files changed (67) hide show
  1. package/README.md +25 -8
  2. package/dist/app-store-relay/index.cjs +9 -0
  3. package/dist/app-store-relay/index.d.ts +102 -0
  4. package/dist/app-store-relay/index.js +430 -0
  5. package/dist/app-store-relay/react.cjs +1 -0
  6. package/dist/app-store-relay/react.d.ts +15 -0
  7. package/dist/app-store-relay/react.js +65 -0
  8. package/dist/browser-storage-BJ__DGJ6.mjs +202 -0
  9. package/dist/browser-storage-C1jQLXat.js +1 -0
  10. package/dist/client-Bk1N3XIF.mjs +228 -0
  11. package/dist/client-CnbCWvCs.js +1 -0
  12. package/dist/components/device-install/index.d.ts +1 -2
  13. package/dist/core/device-install/apple/provisioning.d.ts +55 -4
  14. package/dist/core/device-install/operations/limbuild-client.d.ts +15 -1
  15. package/dist/core/device-install/storage/browser-storage.d.ts +9 -5
  16. package/dist/core/device-install/types.d.ts +4 -1
  17. package/dist/device-build/index.cjs +1 -0
  18. package/dist/device-build/index.d.ts +4 -0
  19. package/dist/device-build/index.js +84 -0
  20. package/dist/device-build/react.cjs +1 -0
  21. package/dist/device-build/react.d.ts +20 -0
  22. package/dist/device-build/react.js +66 -0
  23. package/dist/device-build/signing.d.ts +20 -0
  24. package/dist/device-install/index.cjs +1 -1
  25. package/dist/device-install/index.d.ts +18 -3
  26. package/dist/device-install/index.js +570 -76
  27. package/dist/device-install/react.cjs +1 -1
  28. package/dist/device-install/react.d.ts +23 -1
  29. package/dist/device-install/react.js +93 -2
  30. package/dist/hooks/index.d.ts +1 -1
  31. package/dist/index-BXg7HdIs.mjs +11547 -0
  32. package/dist/index-CMeQfhYy.js +22 -0
  33. package/dist/index.cjs +1 -1
  34. package/dist/index.d.ts +0 -2
  35. package/dist/index.js +502 -495
  36. package/dist/limbuild-client-CFJhYsRx.mjs +79 -0
  37. package/dist/limbuild-client-C_CMNLYV.js +1 -0
  38. package/dist/provisioning-CdseoMJQ.mjs +239 -0
  39. package/dist/provisioning-D2ZZQeyX.js +1 -0
  40. package/package.json +21 -1
  41. package/src/app-store-relay/index.test.ts +74 -0
  42. package/src/app-store-relay/index.ts +447 -0
  43. package/src/app-store-relay/react.ts +125 -0
  44. package/src/components/device-install/index.ts +1 -2
  45. package/src/core/device-install/apple/provisioning.test.ts +84 -0
  46. package/src/core/device-install/apple/provisioning.ts +91 -7
  47. package/src/core/device-install/operations/limbuild-client.ts +32 -2
  48. package/src/core/device-install/storage/browser-storage.ts +29 -14
  49. package/src/core/device-install/types.ts +5 -1
  50. package/src/device-build/index.ts +42 -0
  51. package/src/device-build/react.ts +128 -0
  52. package/src/device-build/signing.ts +94 -0
  53. package/src/device-install/index.ts +49 -3
  54. package/src/device-install/react.ts +180 -1
  55. package/src/hooks/index.ts +1 -1
  56. package/src/index.ts +1 -4
  57. package/vite.config.ts +4 -0
  58. package/dist/components/device-install/device-install-dialog.d.ts +0 -5
  59. package/dist/device-install-dialog-DGn2ZdBB.js +0 -2
  60. package/dist/device-install-dialog-DgWsZF6o.mjs +0 -443
  61. package/dist/device-install-dialog.css +0 -1
  62. package/dist/hooks/use-device-install.d.ts +0 -73
  63. package/dist/use-device-install-ByUSmeYz.js +0 -31
  64. package/dist/use-device-install-Y42p84we.mjs +0 -13624
  65. package/src/components/device-install/device-install-dialog.css +0 -325
  66. package/src/components/device-install/device-install-dialog.tsx +0 -495
  67. package/src/hooks/use-device-install.ts +0 -1219
@@ -0,0 +1,79 @@
1
+ async function u(o, t) {
2
+ const a = new URL(`${o}/info`);
3
+ t && a.searchParams.set("token", t);
4
+ const e = await fetch(a.toString(), {
5
+ headers: t ? { Authorization: `Bearer ${t}` } : void 0
6
+ });
7
+ if (!e.ok) {
8
+ const n = await e.text();
9
+ throw new Error(`Info request failed: HTTP ${e.status} ${n}`);
10
+ }
11
+ return await e.json();
12
+ }
13
+ async function l({
14
+ limbuildApiUrl: o,
15
+ token: t,
16
+ certificateP12Base64: a,
17
+ certificatePassword: e,
18
+ provisioningProfileBase64: n
19
+ }) {
20
+ const d = new URL(`${o}/exec`);
21
+ t && d.searchParams.set("token", t);
22
+ const r = await fetch(d.toString(), {
23
+ method: "POST",
24
+ headers: {
25
+ "Content-Type": "application/json",
26
+ ...t ? { Authorization: `Bearer ${t}` } : {}
27
+ },
28
+ body: JSON.stringify({
29
+ command: "xcodebuild",
30
+ xcodebuild: { sdk: "iphoneos" },
31
+ signing: {
32
+ certificateP12Base64: a,
33
+ ...e ? { certificatePassword: e } : {},
34
+ provisioningProfileBase64: n
35
+ }
36
+ })
37
+ });
38
+ if (!r.ok) {
39
+ const s = await r.text();
40
+ throw new Error(`Build request failed: HTTP ${r.status} ${s}`);
41
+ }
42
+ return await r.json();
43
+ }
44
+ async function f({ limbuildApiUrl: o, execId: t, token: a }) {
45
+ const e = new URL(`${o}/exec/${encodeURIComponent(t)}/ios/ota`);
46
+ a && e.searchParams.set("token", a);
47
+ const n = await fetch(e.toString(), {
48
+ headers: a ? { Authorization: `Bearer ${a}` } : void 0
49
+ });
50
+ if (!n.ok) {
51
+ const d = await n.text();
52
+ throw new Error(`OTA install metadata failed: HTTP ${n.status} ${d}`);
53
+ }
54
+ return await n.json();
55
+ }
56
+ function w({
57
+ limbuildApiUrl: o,
58
+ execId: t,
59
+ token: a,
60
+ onLine: e,
61
+ onStatus: n,
62
+ onError: d
63
+ }) {
64
+ const r = new URL(`${o}/exec/${t}/events`);
65
+ a && r.searchParams.set("token", a);
66
+ const s = new EventSource(r.toString());
67
+ return n("running"), s.addEventListener("command", (i) => e({ type: "command", data: i.data })), s.addEventListener("stdout", (i) => e({ type: "stdout", data: i.data })), s.addEventListener("stderr", (i) => e({ type: "stderr", data: i.data })), s.addEventListener("exitCode", (i) => {
68
+ const c = parseInt(i.data, 10);
69
+ n(c === 0 ? "succeeded" : c < 0 ? "cancelled" : "failed"), s.close();
70
+ }), s.onerror = () => {
71
+ s.close(), d?.(new Error("Build log stream closed before completion."));
72
+ }, () => s.close();
73
+ }
74
+ export {
75
+ u as f,
76
+ f as g,
77
+ l as s,
78
+ w
79
+ };
@@ -0,0 +1 @@
1
+ "use strict";async function u(o,e){const a=new URL(`${o}/info`);e&&a.searchParams.set("token",e);const t=await fetch(a.toString(),{headers:e?{Authorization:`Bearer ${e}`}:void 0});if(!t.ok){const n=await t.text();throw new Error(`Info request failed: HTTP ${t.status} ${n}`)}return await t.json()}async function l({limbuildApiUrl:o,token:e,certificateP12Base64:a,certificatePassword:t,provisioningProfileBase64:n}){const d=new URL(`${o}/exec`);e&&d.searchParams.set("token",e);const r=await fetch(d.toString(),{method:"POST",headers:{"Content-Type":"application/json",...e?{Authorization:`Bearer ${e}`}:{}},body:JSON.stringify({command:"xcodebuild",xcodebuild:{sdk:"iphoneos"},signing:{certificateP12Base64:a,...t?{certificatePassword:t}:{},provisioningProfileBase64:n}})});if(!r.ok){const s=await r.text();throw new Error(`Build request failed: HTTP ${r.status} ${s}`)}return await r.json()}async function f({limbuildApiUrl:o,execId:e,token:a}){const t=new URL(`${o}/exec/${encodeURIComponent(e)}/ios/ota`);a&&t.searchParams.set("token",a);const n=await fetch(t.toString(),{headers:a?{Authorization:`Bearer ${a}`}:void 0});if(!n.ok){const d=await n.text();throw new Error(`OTA install metadata failed: HTTP ${n.status} ${d}`)}return await n.json()}function h({limbuildApiUrl:o,execId:e,token:a,onLine:t,onStatus:n,onError:d}){const r=new URL(`${o}/exec/${e}/events`);a&&r.searchParams.set("token",a);const s=new EventSource(r.toString());return n("running"),s.addEventListener("command",i=>t({type:"command",data:i.data})),s.addEventListener("stdout",i=>t({type:"stdout",data:i.data})),s.addEventListener("stderr",i=>t({type:"stderr",data:i.data})),s.addEventListener("exitCode",i=>{const c=parseInt(i.data,10);n(c===0?"succeeded":c<0?"cancelled":"failed"),s.close()}),s.onerror=()=>{s.close(),d?.(new Error("Build log stream closed before completion."))},()=>s.close()}exports.fetchLimbuildInfo=u;exports.getIOSOTAInstall=f;exports.startSignedDeviceBuild=l;exports.watchBuildLogEvents=h;
@@ -0,0 +1,239 @@
1
+ import { e as c, a as u, n as d, b as f, c as l, i as r } from "./browser-storage-BJ__DGJ6.mjs";
2
+ function g() {
3
+ return {
4
+ method: "POST",
5
+ path: "/account/listTeams.action",
6
+ payload: {}
7
+ };
8
+ }
9
+ function v({ bundleID: e, teamID: i = "" }) {
10
+ return n("/account/ios/identifiers/listAppIds.action", i, { sort: "name=asc" });
11
+ }
12
+ function P({ deviceUDID: e, teamID: i = "" }) {
13
+ return n("/account/ios/device/listDevices.action", i, {
14
+ sort: "name=asc",
15
+ includeRemovedDevices: !1
16
+ });
17
+ }
18
+ function h(e = "") {
19
+ return n("/account/ios/certificate/listCertRequests.action", e, {
20
+ sort: "name=asc",
21
+ types: "83Q87W3TGH,5QPB9NHCEI"
22
+ });
23
+ }
24
+ function I(e = "") {
25
+ return n("/account/ios/certificate/listCertRequests.action", e, {
26
+ sort: "name=asc",
27
+ types: "WXV89964HE,R58UK2EWSO"
28
+ });
29
+ }
30
+ function R({
31
+ bundleID: e,
32
+ teamID: i = ""
33
+ }) {
34
+ return n("/account/ios/profile/listProvisioningProfiles.action", i, {
35
+ search: e,
36
+ sort: "name=asc"
37
+ });
38
+ }
39
+ function y({
40
+ bundleID: e,
41
+ teamID: i = ""
42
+ }) {
43
+ return n("/account/ios/profile/listProvisioningProfiles.action", i, {
44
+ search: e,
45
+ sort: "name=asc",
46
+ distributionType: "adhoc"
47
+ });
48
+ }
49
+ function D({
50
+ deviceUDID: e,
51
+ teamID: i = "",
52
+ name: t = "Limrun iPhone"
53
+ }) {
54
+ return {
55
+ method: "POST",
56
+ path: "/account/ios/device/addDevices.action",
57
+ payload: {
58
+ teamId: i,
59
+ deviceNames: t,
60
+ deviceNumbers: d(e),
61
+ deviceClasses: "iphone",
62
+ register: "single"
63
+ }
64
+ };
65
+ }
66
+ function q({
67
+ bundleID: e,
68
+ teamID: i = "",
69
+ name: t
70
+ }) {
71
+ return {
72
+ method: "POST",
73
+ path: "/account/ios/identifiers/addAppId.action",
74
+ payload: {
75
+ teamId: i,
76
+ name: t ?? e,
77
+ identifier: e,
78
+ type: "explicit"
79
+ }
80
+ };
81
+ }
82
+ function b({
83
+ csrPEM: e,
84
+ teamID: i = ""
85
+ }) {
86
+ return {
87
+ method: "POST",
88
+ path: "/account/ios/certificate/submitCertificateRequest.action",
89
+ payload: {
90
+ teamId: i,
91
+ type: "83Q87W3TGH",
92
+ csrContent: e
93
+ }
94
+ };
95
+ }
96
+ function C({
97
+ csrPEM: e,
98
+ teamID: i = ""
99
+ }) {
100
+ return {
101
+ method: "POST",
102
+ path: "/account/ios/certificate/submitCertificateRequest.action",
103
+ payload: {
104
+ teamId: i,
105
+ type: "WXV89964HE",
106
+ csrContent: e
107
+ }
108
+ };
109
+ }
110
+ function T(e, i = "") {
111
+ return {
112
+ method: "GET",
113
+ path: "/account/ios/certificate/downloadCertificateContent.action",
114
+ payload: {
115
+ teamId: i,
116
+ certificateId: e,
117
+ type: "83Q87W3TGH"
118
+ }
119
+ };
120
+ }
121
+ function S(e, i = "") {
122
+ return {
123
+ method: "GET",
124
+ path: "/account/ios/certificate/downloadCertificateContent.action",
125
+ payload: {
126
+ teamId: i,
127
+ certificateId: e,
128
+ type: "WXV89964HE"
129
+ }
130
+ };
131
+ }
132
+ function A({
133
+ bundleID: e,
134
+ teamID: i = "",
135
+ appIDID: t,
136
+ certificateID: o,
137
+ deviceIDs: a,
138
+ name: s
139
+ }) {
140
+ return {
141
+ method: "POST",
142
+ path: "/account/ios/profile/createProvisioningProfile.action",
143
+ payload: {
144
+ teamId: i,
145
+ provisioningProfileName: s ?? `Limrun ${e}`,
146
+ certificateIds: [o],
147
+ appIdId: t,
148
+ deviceIds: a,
149
+ distributionType: "limited",
150
+ subPlatform: "ios"
151
+ }
152
+ };
153
+ }
154
+ function w({
155
+ bundleID: e,
156
+ teamID: i = "",
157
+ appIDID: t,
158
+ certificateID: o,
159
+ deviceIDs: a,
160
+ name: s
161
+ }) {
162
+ return {
163
+ method: "POST",
164
+ path: "/account/ios/profile/createProvisioningProfile.action",
165
+ payload: {
166
+ teamId: i,
167
+ provisioningProfileName: s ?? `Limrun Ad Hoc ${e}`,
168
+ certificateIds: [o],
169
+ appIdId: t,
170
+ deviceIds: a,
171
+ distributionType: "adhoc",
172
+ subPlatform: "ios"
173
+ }
174
+ };
175
+ }
176
+ function H(e, i = "") {
177
+ return {
178
+ method: "GET",
179
+ path: "/account/ios/profile/downloadProfileContent",
180
+ payload: {
181
+ teamId: i,
182
+ provisioningProfileId: e
183
+ }
184
+ };
185
+ }
186
+ async function O({
187
+ bundleID: e,
188
+ deviceUDID: i,
189
+ teamID: t,
190
+ signingMode: o
191
+ }) {
192
+ const a = await c({ bundleID: e, deviceUDID: i, signingMode: o });
193
+ if (!(!a || !p(a, { bundleID: e, deviceUDID: i, teamID: t, signingMode: o })))
194
+ return a;
195
+ }
196
+ async function E(e) {
197
+ return u({
198
+ ...e,
199
+ certificateFileName: e.certificateID ? `${e.certificateID}.p12` : `apple-${e.signingMode ?? "development"}.p12`,
200
+ certificatePassword: e.certificatePassword || void 0,
201
+ signingMode: e.signingMode,
202
+ profileFileName: e.profile.uuid ? `${e.profile.uuid}.mobileprovision` : `${e.signingMode ?? "development"}.mobileprovision`
203
+ });
204
+ }
205
+ function p(e, { bundleID: i, deviceUDID: t, teamID: o, signingMode: a = "development" }) {
206
+ return (e.signingMode ?? "development") !== a || !f(e.profile, i) || o && e.teamID && e.teamID !== o || t && !l(e.profile, t) || e.profile.expirationDate && new Date(e.profile.expirationDate).getTime() <= Date.now() ? !1 : r(e.bundleID) === r(i);
207
+ }
208
+ function n(e, i, t = {}) {
209
+ const o = {
210
+ pageNumber: 1,
211
+ pageSize: 200,
212
+ ...t
213
+ };
214
+ return i && (o.teamId = i), {
215
+ method: "POST",
216
+ path: e,
217
+ payload: o
218
+ };
219
+ }
220
+ export {
221
+ h as a,
222
+ b,
223
+ T as c,
224
+ S as d,
225
+ v as e,
226
+ I as f,
227
+ q as g,
228
+ P as h,
229
+ y as i,
230
+ R as j,
231
+ w as k,
232
+ g as l,
233
+ A as m,
234
+ H as n,
235
+ O as o,
236
+ E as p,
237
+ D as r,
238
+ C as s
239
+ };
@@ -0,0 +1 @@
1
+ "use strict";const a=require("./browser-storage-C1jQLXat.js");function c(){return{method:"POST",path:"/account/listTeams.action",payload:{}}}function u({bundleID:e,teamID:t=""}){return s("/account/ios/identifiers/listAppIds.action",t,{sort:"name=asc"})}function d({deviceUDID:e,teamID:t=""}){return s("/account/ios/device/listDevices.action",t,{sort:"name=asc",includeRemovedDevices:!1})}function f(e=""){return s("/account/ios/certificate/listCertRequests.action",e,{sort:"name=asc",types:"83Q87W3TGH,5QPB9NHCEI"})}function l(e=""){return s("/account/ios/certificate/listCertRequests.action",e,{sort:"name=asc",types:"WXV89964HE,R58UK2EWSO"})}function p({bundleID:e,teamID:t=""}){return s("/account/ios/profile/listProvisioningProfiles.action",t,{search:e,sort:"name=asc"})}function m({bundleID:e,teamID:t=""}){return s("/account/ios/profile/listProvisioningProfiles.action",t,{search:e,sort:"name=asc",distributionType:"adhoc"})}function R({deviceUDID:e,teamID:t="",name:i="Limrun iPhone"}){return{method:"POST",path:"/account/ios/device/addDevices.action",payload:{teamId:t,deviceNames:i,deviceNumbers:a.normalizeUDID(e),deviceClasses:"iphone",register:"single"}}}function g({bundleID:e,teamID:t="",name:i}){return{method:"POST",path:"/account/ios/identifiers/addAppId.action",payload:{teamId:t,name:i??e,identifier:e,type:"explicit"}}}function q({csrPEM:e,teamID:t=""}){return{method:"POST",path:"/account/ios/certificate/submitCertificateRequest.action",payload:{teamId:t,type:"83Q87W3TGH",csrContent:e}}}function v({csrPEM:e,teamID:t=""}){return{method:"POST",path:"/account/ios/certificate/submitCertificateRequest.action",payload:{teamId:t,type:"WXV89964HE",csrContent:e}}}function P(e,t=""){return{method:"GET",path:"/account/ios/certificate/downloadCertificateContent.action",payload:{teamId:t,certificateId:e,type:"83Q87W3TGH"}}}function D(e,t=""){return{method:"GET",path:"/account/ios/certificate/downloadCertificateContent.action",payload:{teamId:t,certificateId:e,type:"WXV89964HE"}}}function I({bundleID:e,teamID:t="",appIDID:i,certificateID:o,deviceIDs:n,name:r}){return{method:"POST",path:"/account/ios/profile/createProvisioningProfile.action",payload:{teamId:t,provisioningProfileName:r??`Limrun ${e}`,certificateIds:[o],appIdId:i,deviceIds:n,distributionType:"limited",subPlatform:"ios"}}}function h({bundleID:e,teamID:t="",appIDID:i,certificateID:o,deviceIDs:n,name:r}){return{method:"POST",path:"/account/ios/profile/createProvisioningProfile.action",payload:{teamId:t,provisioningProfileName:r??`Limrun Ad Hoc ${e}`,certificateIds:[o],appIdId:i,deviceIds:n,distributionType:"adhoc",subPlatform:"ios"}}}function C(e,t=""){return{method:"GET",path:"/account/ios/profile/downloadProfileContent",payload:{teamId:t,provisioningProfileId:e}}}async function b({bundleID:e,deviceUDID:t,teamID:i,signingMode:o}){const n=await a.getSigningAssets({bundleID:e,deviceUDID:t,signingMode:o});if(!(!n||!S(n,{bundleID:e,deviceUDID:t,teamID:i,signingMode:o})))return n}async function y(e){return a.putSigningAssets({...e,certificateFileName:e.certificateID?`${e.certificateID}.p12`:`apple-${e.signingMode??"development"}.p12`,certificatePassword:e.certificatePassword||void 0,signingMode:e.signingMode,profileFileName:e.profile.uuid?`${e.profile.uuid}.mobileprovision`:`${e.signingMode??"development"}.mobileprovision`})}function S(e,{bundleID:t,deviceUDID:i,teamID:o,signingMode:n="development"}){return(e.signingMode??"development")!==n||!a.profileMatchesBundleID(e.profile,t)||o&&e.teamID&&e.teamID!==o||i&&!a.profileContainsDevice(e.profile,i)||e.profile.expirationDate&&new Date(e.profile.expirationDate).getTime()<=Date.now()?!1:a.normalizeBundleID(e.bundleID)===a.normalizeBundleID(t)}function s(e,t,i={}){const o={pageNumber:1,pageSize:200,...i};return t&&(o.teamId=t),{method:"POST",path:e,payload:o}}exports.createAdHocProfileRequest=h;exports.createBundleIDRequest=g;exports.createDevelopmentProfileRequest=I;exports.downloadCertificateRequest=P;exports.downloadDistributionCertificateRequest=D;exports.downloadProfileRequest=C;exports.findAdHocProfilesRequest=m;exports.findBundleIDRequest=u;exports.findDevelopmentCertificatesRequest=f;exports.findDevelopmentProfilesRequest=p;exports.findDeviceRequest=d;exports.findDistributionCertificatesRequest=l;exports.getReusableAppleSigningAssets=b;exports.listTeamsRequest=c;exports.putAppleGeneratedSigningAssets=y;exports.registerDeviceRequest=R;exports.submitDevelopmentCSRRequest=q;exports.submitDistributionCSRRequest=v;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@limrun/ui",
3
- "version": "0.9.0-rc.8",
3
+ "version": "0.13.3-rc.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -13,6 +13,26 @@
13
13
  "import": "./dist/index.js",
14
14
  "require": "./dist/index.cjs"
15
15
  },
16
+ "./app-store-relay": {
17
+ "types": "./dist/app-store-relay/index.d.ts",
18
+ "import": "./dist/app-store-relay/index.js",
19
+ "require": "./dist/app-store-relay/index.cjs"
20
+ },
21
+ "./app-store-relay/react": {
22
+ "types": "./dist/app-store-relay/react.d.ts",
23
+ "import": "./dist/app-store-relay/react.js",
24
+ "require": "./dist/app-store-relay/react.cjs"
25
+ },
26
+ "./device-build": {
27
+ "types": "./dist/device-build/index.d.ts",
28
+ "import": "./dist/device-build/index.js",
29
+ "require": "./dist/device-build/index.cjs"
30
+ },
31
+ "./device-build/react": {
32
+ "types": "./dist/device-build/react.d.ts",
33
+ "import": "./dist/device-build/react.js",
34
+ "require": "./dist/device-build/react.cjs"
35
+ },
16
36
  "./device-install": {
17
37
  "types": "./dist/device-install/index.d.ts",
18
38
  "import": "./dist/device-install/index.js",
@@ -0,0 +1,74 @@
1
+ // @vitest-environment node
2
+
3
+ import { afterEach, describe, expect, test, vi } from 'vitest';
4
+ import {
5
+ assertAppleDeveloperPortalResponseOK,
6
+ deleteAppleProfile,
7
+ listAppleTeams,
8
+ } from './index';
9
+
10
+ describe('App Store relay primitives', () => {
11
+ afterEach(() => {
12
+ vi.restoreAllMocks();
13
+ });
14
+
15
+ test('sends explicit CRUD requests through the provisioning proxy', async () => {
16
+ const fetchMock = vi.spyOn(globalThis, 'fetch').mockResolvedValue(
17
+ new Response(JSON.stringify({ status: 200, body: { resultCode: 0 } }), {
18
+ status: 200,
19
+ }),
20
+ );
21
+
22
+ await deleteAppleProfile({
23
+ apiUrl: 'https://limbuild.example',
24
+ token: 'token',
25
+ appleSessionId: 'apple-session',
26
+ teamId: 'TEAM',
27
+ profileId: 'PROFILE',
28
+ });
29
+
30
+ expect(fetchMock).toHaveBeenCalledOnce();
31
+ const [url, init] = fetchMock.mock.calls[0];
32
+ expect(String(url)).toBe('https://limbuild.example/apple/provisioning?token=token');
33
+ expect(JSON.parse(String(init?.body))).toMatchObject({
34
+ appleSessionId: 'apple-session',
35
+ method: 'POST',
36
+ path: '/account/ios/profile/deleteProvisioningProfile.action',
37
+ payload: {
38
+ teamId: 'TEAM',
39
+ provisioningProfileId: 'PROFILE',
40
+ },
41
+ });
42
+ });
43
+
44
+ test('maps team list responses to teams', async () => {
45
+ vi.spyOn(globalThis, 'fetch').mockResolvedValue(
46
+ new Response(
47
+ JSON.stringify({
48
+ status: 200,
49
+ body: {
50
+ resultCode: 0,
51
+ teams: [{ name: 'Team One', teamId: 'TEAM1' }],
52
+ },
53
+ }),
54
+ { status: 200 },
55
+ ),
56
+ );
57
+
58
+ await expect(
59
+ listAppleTeams({
60
+ apiUrl: 'https://limbuild.example',
61
+ appleSessionId: 'apple-session',
62
+ }),
63
+ ).resolves.toEqual([{ name: 'Team One', teamId: 'TEAM1' }]);
64
+ });
65
+
66
+ test('surfaces Apple portal errors', () => {
67
+ expect(() =>
68
+ assertAppleDeveloperPortalResponseOK(
69
+ { resultCode: 35, userString: 'No permission' },
70
+ 'Apple device list',
71
+ ),
72
+ ).toThrow('Apple device list failed: No permission');
73
+ });
74
+ });