@usemogul/connect-common 0.1.0 → 0.3.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/README.md CHANGED
@@ -5,7 +5,7 @@ the `postMessage` contract between the Mogul application and the partner-side
5
5
  loader (`@usemogul/connect-js`). Both sides depend on this package so the message
6
6
  shapes can't drift.
7
7
 
8
- Zero runtime dependencies. Ships ESM + TypeScript types.
8
+ Zero runtime dependencies. Ships ESM + CJS + TypeScript types.
9
9
 
10
10
  ## Exports
11
11
 
@@ -13,8 +13,17 @@ Zero runtime dependencies. Ships ESM + TypeScript types.
13
13
  the session `token` and the partner's public `clientId`)
14
14
  - `ConnectedIdentity` — identity payload carried on `mogul:success`
15
15
  - `FRAME_EVENT` / `PARENT_EVENT` — event-name constants
16
- - `parseFrameMessage(data)` — validates untrusted `postMessage` data into a known
17
- `FrameMessage`, or `null`.
16
+ - `CONNECT_ERROR_CODE` / `ConnectErrorCode` — the `mogul:error` codes
17
+ (`token_error`, `invalid_target`, `client_mismatch`, `identity_unavailable`,
18
+ `origin_not_allowed`, `verification_failed`).
19
+ `mogul:error.code` stays typed as `string` on the wire, so handle unknown codes.
20
+ - `parseFrameMessage(data)` — for the loader: validates untrusted `postMessage`
21
+ data into a known `FrameMessage`, or `null`.
22
+ - `parseParentMessage(data)` — for the frame: validates untrusted `postMessage`
23
+ data into a known `ParentMessage`, or `null`.
24
+
25
+ Both parsers rebuild the message from the checked fields, so unknown keys are
26
+ dropped. Check the message origin before calling them.
18
27
 
19
28
  ```ts
20
29
  import { parseFrameMessage, type ParentMessage } from '@usemogul/connect-common'
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i={ready:"mogul:ready",requestToken:"mogul:request-token",success:"mogul:success",exit:"mogul:exit",error:"mogul:error"},s={init:"mogul:init",logout:"mogul:logout"},u={tokenError:"token_error",invalidTarget:"invalid_target",clientMismatch:"client_mismatch",identityUnavailable:"identity_unavailable",originNotAllowed:"origin_not_allowed",verificationFailed:"verification_failed"},l=t=>{if(typeof t!="object"||t===null)return;const e=t;if(typeof e.id!="string"||typeof e.name!="string"||!Array.isArray(e.accounts))return;const n=[];for(const o of e.accounts){if(typeof o!="object"||o===null)return;const r=o;if(typeof r.id!="string"||typeof r.name!="string")return;n.push({id:r.id,name:r.name})}return{id:e.id,name:e.name,accounts:n}},c=t=>{if(typeof t!="object"||t===null)return null;const e=t;switch(e.type){case"mogul:ready":case"mogul:request-token":case"mogul:exit":return{type:e.type};case"mogul:success":{const n=l(e.connectedIdentity);return typeof e.integrationId=="number"&&typeof e.accountId=="string"&&n?{type:"mogul:success",integrationId:e.integrationId,accountId:e.accountId,connectedIdentity:n}:null}case"mogul:error":return typeof e.code=="string"?{type:"mogul:error",code:e.code}:null;default:return null}},a=t=>{if(typeof t!="object"||t===null)return null;const e=t;switch(e.type){case"mogul:init":{const{token:n,clientId:o,locale:r}=e;return typeof n!="string"||n.length===0||typeof o!="string"||o.length===0?null:typeof r=="string"?{type:"mogul:init",token:n,clientId:o,locale:r}:{type:"mogul:init",token:n,clientId:o}}case"mogul:logout":return{type:"mogul:logout"};default:return null}};exports.CONNECT_ERROR_CODE=u;exports.FRAME_EVENT=i;exports.PARENT_EVENT=s;exports.parseFrameMessage=c;exports.parseParentMessage=a;
@@ -0,0 +1,135 @@
1
+ /** `mogul:error` codes, so neither side hard-codes the raw strings. */
2
+ export declare const CONNECT_ERROR_CODE: {
3
+ /** Loader: the partner's `getToken()` threw. */
4
+ readonly tokenError: "token_error";
5
+ /** Frame: the preselected `/embed/connect/<target>` isn't a known source. */
6
+ readonly invalidTarget: "invalid_target";
7
+ /**
8
+ * Frame: `mogul:init.clientId` doesn't match the session token's `client_id`
9
+ * claim, so the token is refused.
10
+ */
11
+ readonly clientMismatch: "client_mismatch";
12
+ /**
13
+ * Frame: the connection succeeded, but the integration ID or a complete
14
+ * identity couldn't be resolved, so no `mogul:success` is sent.
15
+ */
16
+ readonly identityUnavailable: "identity_unavailable";
17
+ /**
18
+ * Frame: the embedding page's origin isn't registered for the partner the
19
+ * session token belongs to (or the token's partner doesn't match `clientId`),
20
+ * so the token is refused and the flow never loads.
21
+ */
22
+ readonly originNotAllowed: "origin_not_allowed";
23
+ /**
24
+ * Frame: the frame couldn't reach Mogul to verify the embedding origin, so
25
+ * the token is refused. Transient: remount (or the next `mogul:init`) retries.
26
+ */
27
+ readonly verificationFailed: "verification_failed";
28
+ };
29
+
30
+ /** Identity the connected source resolved to, parsed from the integration. */
31
+ export declare type ConnectedIdentity = {
32
+ /** Source-side account/entity id. */
33
+ id: string;
34
+ /** Display name (artist / label / handle) as the source reports it. */
35
+ name: string;
36
+ /**
37
+ * One entry per synced account: for a multi-account login, the accounts the
38
+ * user chose in the picker; a single-account source has exactly one.
39
+ */
40
+ accounts: Array<{
41
+ id: string;
42
+ name: string;
43
+ }>;
44
+ };
45
+
46
+ export declare type ConnectErrorCode = (typeof CONNECT_ERROR_CODE)[keyof typeof CONNECT_ERROR_CODE];
47
+
48
+ /** Event-name constants, so neither side hard-codes the raw strings. */
49
+ export declare const FRAME_EVENT: {
50
+ readonly ready: "mogul:ready";
51
+ readonly requestToken: "mogul:request-token";
52
+ readonly success: "mogul:success";
53
+ readonly exit: "mogul:exit";
54
+ readonly error: "mogul:error";
55
+ };
56
+
57
+ /** Messages the frame sends to the parent — the loader listens for these. */
58
+ export declare type FrameMessage = {
59
+ type: 'mogul:ready';
60
+ } | {
61
+ type: 'mogul:request-token';
62
+ } | {
63
+ /**
64
+ * Sent when the user dismisses the success screen (Done), and only when
65
+ * every field below — including a name for every account — is present.
66
+ * Otherwise the frame sends `mogul:error` `identity_unavailable` instead.
67
+ */
68
+ type: 'mogul:success';
69
+ /** The created integration — the handle for later royalty-report API calls. */
70
+ integrationId: number;
71
+ /** Mogul account the integration belongs to (from the session token). */
72
+ accountId: string;
73
+ /** Identity parsed from the connected integration. */
74
+ connectedIdentity: ConnectedIdentity;
75
+ }
76
+ /**
77
+ * Flow closed. Always follows the `mogul:success` or `mogul:error` for the
78
+ * same completion, so the parent can safely tear the frame down here.
79
+ */
80
+ | {
81
+ type: 'mogul:exit';
82
+ } | {
83
+ type: 'mogul:error';
84
+ /**
85
+ * A {@link ConnectErrorCode}, typed as `string` so older loaders keep
86
+ * working when the frame adds a code.
87
+ */
88
+ code: string;
89
+ };
90
+
91
+ export declare type FrameMessageType = FrameMessage['type'];
92
+
93
+ export declare const PARENT_EVENT: {
94
+ readonly init: "mogul:init";
95
+ readonly logout: "mogul:logout";
96
+ };
97
+
98
+ /** Messages the parent sends to the frame — the loader posts these. */
99
+ export declare type ParentMessage = {
100
+ type: 'mogul:init';
101
+ token: string;
102
+ /**
103
+ * Mogul-issued partner client ID (`mcci_…`). Identifies the partner; not a
104
+ * secret. Must equal the token's `client_id` claim: on a mismatch (or a
105
+ * token with no claim) the frame refuses the token and answers with
106
+ * `mogul:error` `client_mismatch`.
107
+ */
108
+ clientId: string;
109
+ locale?: string;
110
+ }
111
+ /** Reserved: the frame accepts and ignores it. */
112
+ | {
113
+ type: 'mogul:logout';
114
+ };
115
+
116
+ export declare type ParentMessageType = ParentMessage['type'];
117
+
118
+ /**
119
+ * Narrow untrusted `postMessage` data to a known {@link FrameMessage}. Check the
120
+ * discriminant first, then the payload shape. Anything that doesn't match
121
+ * returns `null` and must be ignored by the caller — the origin/source checks
122
+ * happen separately, before this runs.
123
+ */
124
+ export declare const parseFrameMessage: (data: unknown) => FrameMessage | null;
125
+
126
+ /**
127
+ * Narrow untrusted `postMessage` data to a known {@link ParentMessage} — the
128
+ * frame's counterpart to {@link parseFrameMessage}. The returned object is
129
+ * rebuilt from the checked fields, so extra keys never reach the frame. Anything
130
+ * that doesn't match returns `null`; the origin check happens separately, before
131
+ * this runs.
132
+ */
133
+ export declare const parseParentMessage: (data: unknown) => ParentMessage | null;
134
+
135
+ export { }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,135 @@
1
- export * from './messages';
2
- export { parseFrameMessage } from './parse';
1
+ /** `mogul:error` codes, so neither side hard-codes the raw strings. */
2
+ export declare const CONNECT_ERROR_CODE: {
3
+ /** Loader: the partner's `getToken()` threw. */
4
+ readonly tokenError: "token_error";
5
+ /** Frame: the preselected `/embed/connect/<target>` isn't a known source. */
6
+ readonly invalidTarget: "invalid_target";
7
+ /**
8
+ * Frame: `mogul:init.clientId` doesn't match the session token's `client_id`
9
+ * claim, so the token is refused.
10
+ */
11
+ readonly clientMismatch: "client_mismatch";
12
+ /**
13
+ * Frame: the connection succeeded, but the integration ID or a complete
14
+ * identity couldn't be resolved, so no `mogul:success` is sent.
15
+ */
16
+ readonly identityUnavailable: "identity_unavailable";
17
+ /**
18
+ * Frame: the embedding page's origin isn't registered for the partner the
19
+ * session token belongs to (or the token's partner doesn't match `clientId`),
20
+ * so the token is refused and the flow never loads.
21
+ */
22
+ readonly originNotAllowed: "origin_not_allowed";
23
+ /**
24
+ * Frame: the frame couldn't reach Mogul to verify the embedding origin, so
25
+ * the token is refused. Transient: remount (or the next `mogul:init`) retries.
26
+ */
27
+ readonly verificationFailed: "verification_failed";
28
+ };
29
+
30
+ /** Identity the connected source resolved to, parsed from the integration. */
31
+ export declare type ConnectedIdentity = {
32
+ /** Source-side account/entity id. */
33
+ id: string;
34
+ /** Display name (artist / label / handle) as the source reports it. */
35
+ name: string;
36
+ /**
37
+ * One entry per synced account: for a multi-account login, the accounts the
38
+ * user chose in the picker; a single-account source has exactly one.
39
+ */
40
+ accounts: Array<{
41
+ id: string;
42
+ name: string;
43
+ }>;
44
+ };
45
+
46
+ export declare type ConnectErrorCode = (typeof CONNECT_ERROR_CODE)[keyof typeof CONNECT_ERROR_CODE];
47
+
48
+ /** Event-name constants, so neither side hard-codes the raw strings. */
49
+ export declare const FRAME_EVENT: {
50
+ readonly ready: "mogul:ready";
51
+ readonly requestToken: "mogul:request-token";
52
+ readonly success: "mogul:success";
53
+ readonly exit: "mogul:exit";
54
+ readonly error: "mogul:error";
55
+ };
56
+
57
+ /** Messages the frame sends to the parent — the loader listens for these. */
58
+ export declare type FrameMessage = {
59
+ type: 'mogul:ready';
60
+ } | {
61
+ type: 'mogul:request-token';
62
+ } | {
63
+ /**
64
+ * Sent when the user dismisses the success screen (Done), and only when
65
+ * every field below — including a name for every account — is present.
66
+ * Otherwise the frame sends `mogul:error` `identity_unavailable` instead.
67
+ */
68
+ type: 'mogul:success';
69
+ /** The created integration — the handle for later royalty-report API calls. */
70
+ integrationId: number;
71
+ /** Mogul account the integration belongs to (from the session token). */
72
+ accountId: string;
73
+ /** Identity parsed from the connected integration. */
74
+ connectedIdentity: ConnectedIdentity;
75
+ }
76
+ /**
77
+ * Flow closed. Always follows the `mogul:success` or `mogul:error` for the
78
+ * same completion, so the parent can safely tear the frame down here.
79
+ */
80
+ | {
81
+ type: 'mogul:exit';
82
+ } | {
83
+ type: 'mogul:error';
84
+ /**
85
+ * A {@link ConnectErrorCode}, typed as `string` so older loaders keep
86
+ * working when the frame adds a code.
87
+ */
88
+ code: string;
89
+ };
90
+
91
+ export declare type FrameMessageType = FrameMessage['type'];
92
+
93
+ export declare const PARENT_EVENT: {
94
+ readonly init: "mogul:init";
95
+ readonly logout: "mogul:logout";
96
+ };
97
+
98
+ /** Messages the parent sends to the frame — the loader posts these. */
99
+ export declare type ParentMessage = {
100
+ type: 'mogul:init';
101
+ token: string;
102
+ /**
103
+ * Mogul-issued partner client ID (`mcci_…`). Identifies the partner; not a
104
+ * secret. Must equal the token's `client_id` claim: on a mismatch (or a
105
+ * token with no claim) the frame refuses the token and answers with
106
+ * `mogul:error` `client_mismatch`.
107
+ */
108
+ clientId: string;
109
+ locale?: string;
110
+ }
111
+ /** Reserved: the frame accepts and ignores it. */
112
+ | {
113
+ type: 'mogul:logout';
114
+ };
115
+
116
+ export declare type ParentMessageType = ParentMessage['type'];
117
+
118
+ /**
119
+ * Narrow untrusted `postMessage` data to a known {@link FrameMessage}. Check the
120
+ * discriminant first, then the payload shape. Anything that doesn't match
121
+ * returns `null` and must be ignored by the caller — the origin/source checks
122
+ * happen separately, before this runs.
123
+ */
124
+ export declare const parseFrameMessage: (data: unknown) => FrameMessage | null;
125
+
126
+ /**
127
+ * Narrow untrusted `postMessage` data to a known {@link ParentMessage} — the
128
+ * frame's counterpart to {@link parseFrameMessage}. The returned object is
129
+ * rebuilt from the checked fields, so extra keys never reach the frame. Anything
130
+ * that doesn't match returns `null`; the origin check happens separately, before
131
+ * this runs.
132
+ */
133
+ export declare const parseParentMessage: (data: unknown) => ParentMessage | null;
134
+
135
+ export { }
package/dist/index.js CHANGED
@@ -1,2 +1,93 @@
1
- export * from './messages';
2
- export { parseFrameMessage } from './parse';
1
+ const u = {
2
+ ready: "mogul:ready",
3
+ requestToken: "mogul:request-token",
4
+ success: "mogul:success",
5
+ exit: "mogul:exit",
6
+ error: "mogul:error"
7
+ }, l = {
8
+ init: "mogul:init",
9
+ logout: "mogul:logout"
10
+ }, c = {
11
+ /** Loader: the partner's `getToken()` threw. */
12
+ tokenError: "token_error",
13
+ /** Frame: the preselected `/embed/connect/<target>` isn't a known source. */
14
+ invalidTarget: "invalid_target",
15
+ /**
16
+ * Frame: `mogul:init.clientId` doesn't match the session token's `client_id`
17
+ * claim, so the token is refused.
18
+ */
19
+ clientMismatch: "client_mismatch",
20
+ /**
21
+ * Frame: the connection succeeded, but the integration ID or a complete
22
+ * identity couldn't be resolved, so no `mogul:success` is sent.
23
+ */
24
+ identityUnavailable: "identity_unavailable",
25
+ /**
26
+ * Frame: the embedding page's origin isn't registered for the partner the
27
+ * session token belongs to (or the token's partner doesn't match `clientId`),
28
+ * so the token is refused and the flow never loads.
29
+ */
30
+ originNotAllowed: "origin_not_allowed",
31
+ /**
32
+ * Frame: the frame couldn't reach Mogul to verify the embedding origin, so
33
+ * the token is refused. Transient: remount (or the next `mogul:init`) retries.
34
+ */
35
+ verificationFailed: "verification_failed"
36
+ }, i = (t) => {
37
+ if (typeof t != "object" || t === null) return;
38
+ const e = t;
39
+ if (typeof e.id != "string" || typeof e.name != "string" || !Array.isArray(e.accounts)) return;
40
+ const n = [];
41
+ for (const o of e.accounts) {
42
+ if (typeof o != "object" || o === null) return;
43
+ const r = o;
44
+ if (typeof r.id != "string" || typeof r.name != "string")
45
+ return;
46
+ n.push({ id: r.id, name: r.name });
47
+ }
48
+ return { id: e.id, name: e.name, accounts: n };
49
+ }, s = (t) => {
50
+ if (typeof t != "object" || t === null) return null;
51
+ const e = t;
52
+ switch (e.type) {
53
+ case "mogul:ready":
54
+ case "mogul:request-token":
55
+ case "mogul:exit":
56
+ return { type: e.type };
57
+ case "mogul:success": {
58
+ const n = i(
59
+ e.connectedIdentity
60
+ );
61
+ return typeof e.integrationId == "number" && typeof e.accountId == "string" && n ? {
62
+ type: "mogul:success",
63
+ integrationId: e.integrationId,
64
+ accountId: e.accountId,
65
+ connectedIdentity: n
66
+ } : null;
67
+ }
68
+ case "mogul:error":
69
+ return typeof e.code == "string" ? { type: "mogul:error", code: e.code } : null;
70
+ default:
71
+ return null;
72
+ }
73
+ }, a = (t) => {
74
+ if (typeof t != "object" || t === null) return null;
75
+ const e = t;
76
+ switch (e.type) {
77
+ case "mogul:init": {
78
+ const { token: n, clientId: o, locale: r } = e;
79
+ return typeof n != "string" || n.length === 0 || typeof o != "string" || o.length === 0 ? null : typeof r == "string" ? { type: "mogul:init", token: n, clientId: o, locale: r } : { type: "mogul:init", token: n, clientId: o };
80
+ }
81
+ case "mogul:logout":
82
+ return { type: "mogul:logout" };
83
+ default:
84
+ return null;
85
+ }
86
+ };
87
+ export {
88
+ c as CONNECT_ERROR_CODE,
89
+ u as FRAME_EVENT,
90
+ l as PARENT_EVENT,
91
+ s as parseFrameMessage,
92
+ a as parseParentMessage
93
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usemogul/connect-common",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Shared schemas for the Mogul Connect embedded component: message types, event-name constants, and validators shared by the connect-js loader and the Mogul application.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "shawn@usemogul.com",
@@ -15,24 +15,30 @@
15
15
  },
16
16
  "type": "module",
17
17
  "sideEffects": false,
18
- "main": "./dist/index.js",
18
+ "main": "./dist/index.cjs",
19
19
  "module": "./dist/index.js",
20
20
  "types": "./dist/index.d.ts",
21
21
  "exports": {
22
22
  ".": {
23
- "types": "./dist/index.d.ts",
24
- "import": "./dist/index.js"
23
+ "import": {
24
+ "types": "./dist/index.d.ts",
25
+ "default": "./dist/index.js"
26
+ },
27
+ "require": {
28
+ "types": "./dist/index.d.cts",
29
+ "default": "./dist/index.cjs"
30
+ }
25
31
  }
26
32
  },
27
33
  "files": [
28
34
  "dist"
29
35
  ],
30
36
  "scripts": {
31
- "build": "tsc -p tsconfig.build.json",
37
+ "build": "vite build",
32
38
  "test": "vitest run",
33
39
  "typecheck": "tsc --noEmit",
34
40
  "prepack": "npm run build",
35
- "prepublishOnly": "npm run typecheck && npm run test"
41
+ "prepublishOnly": "npm run typecheck && npm run test && npm run build && publint && attw --pack ."
36
42
  },
37
43
  "publishConfig": {
38
44
  "access": "public"
@@ -1,67 +0,0 @@
1
- /**
2
- * Mogul Connect — wire message schemas.
3
- *
4
- * The single source of truth for the `postMessage` contract between the Mogul
5
- * application (running in the iframe) and the partner-side loader
6
- * (`@usemogul/connect-js`). Both sides depend on this package so the shapes
7
- * can't drift.
8
- */
9
- /** Event-name constants, so neither side hard-codes the raw strings. */
10
- export declare const FRAME_EVENT: {
11
- readonly ready: "mogul:ready";
12
- readonly requestToken: "mogul:request-token";
13
- readonly resize: "mogul:resize";
14
- readonly success: "mogul:success";
15
- readonly exit: "mogul:exit";
16
- readonly error: "mogul:error";
17
- };
18
- export declare const PARENT_EVENT: {
19
- readonly init: "mogul:init";
20
- readonly logout: "mogul:logout";
21
- };
22
- /** Identity the connected source resolved to, parsed from the integration. */
23
- export type ConnectedIdentity = {
24
- /** Source-side account/entity id. */
25
- id: string;
26
- /** Display name (artist / label / handle) as the source reports it. */
27
- name: string;
28
- /** One entry per connected account (a single-account target has one). */
29
- accounts: Array<{
30
- id: string;
31
- name: string;
32
- }>;
33
- };
34
- /** Messages the frame sends to the parent — the loader listens for these. */
35
- export type FrameMessage = {
36
- type: 'mogul:ready';
37
- } | {
38
- type: 'mogul:request-token';
39
- } | {
40
- type: 'mogul:resize';
41
- height: number;
42
- } | {
43
- type: 'mogul:success';
44
- /** The created integration — the handle for later royalty-report API calls. */
45
- integrationId: number;
46
- /** Mogul account the integration belongs to (from the session token). */
47
- accountId: string;
48
- /** Identity parsed from the connected integration. */
49
- connectedIdentity: ConnectedIdentity;
50
- } | {
51
- type: 'mogul:exit';
52
- } | {
53
- type: 'mogul:error';
54
- code: string;
55
- };
56
- /** Messages the parent sends to the frame — the loader posts these. */
57
- export type ParentMessage = {
58
- type: 'mogul:init';
59
- token: string;
60
- /** Mogul-issued partner client ID (`mcci_…`). Identifies the partner; not a secret. */
61
- clientId: string;
62
- locale?: string;
63
- } | {
64
- type: 'mogul:logout';
65
- };
66
- export type FrameMessageType = FrameMessage['type'];
67
- export type ParentMessageType = ParentMessage['type'];
package/dist/messages.js DELETED
@@ -1,21 +0,0 @@
1
- /**
2
- * Mogul Connect — wire message schemas.
3
- *
4
- * The single source of truth for the `postMessage` contract between the Mogul
5
- * application (running in the iframe) and the partner-side loader
6
- * (`@usemogul/connect-js`). Both sides depend on this package so the shapes
7
- * can't drift.
8
- */
9
- /** Event-name constants, so neither side hard-codes the raw strings. */
10
- export const FRAME_EVENT = {
11
- ready: 'mogul:ready',
12
- requestToken: 'mogul:request-token',
13
- resize: 'mogul:resize',
14
- success: 'mogul:success',
15
- exit: 'mogul:exit',
16
- error: 'mogul:error',
17
- };
18
- export const PARENT_EVENT = {
19
- init: 'mogul:init',
20
- logout: 'mogul:logout',
21
- };
package/dist/parse.d.ts DELETED
@@ -1,8 +0,0 @@
1
- import type { FrameMessage } from './messages';
2
- /**
3
- * Narrow untrusted `postMessage` data to a known {@link FrameMessage}. Check the
4
- * discriminant first, then the payload shape. Anything that doesn't match
5
- * returns `null` and must be ignored by the caller — the origin/source checks
6
- * happen separately, before this runs.
7
- */
8
- export declare const parseFrameMessage: (data: unknown) => FrameMessage | null;
package/dist/parse.js DELETED
@@ -1,67 +0,0 @@
1
- /**
2
- * Parse the optional `connectedIdentity` payload. All fields are required, so a
3
- * partially-formed identity is rejected entirely (returns `undefined`); the
4
- * payload itself may still be absent.
5
- */
6
- const parseConnectedIdentity = (value) => {
7
- if (typeof value !== 'object' || value === null)
8
- return undefined;
9
- const raw = value;
10
- if (typeof raw.id !== 'string')
11
- return undefined;
12
- if (typeof raw.name !== 'string')
13
- return undefined;
14
- if (!Array.isArray(raw.accounts))
15
- return undefined;
16
- const accounts = [];
17
- for (const entry of raw.accounts) {
18
- if (typeof entry !== 'object' || entry === null)
19
- return undefined;
20
- const acc = entry;
21
- if (typeof acc.id !== 'string' || typeof acc.name !== 'string') {
22
- return undefined;
23
- }
24
- accounts.push({ id: acc.id, name: acc.name });
25
- }
26
- return { id: raw.id, name: raw.name, accounts };
27
- };
28
- /**
29
- * Narrow untrusted `postMessage` data to a known {@link FrameMessage}. Check the
30
- * discriminant first, then the payload shape. Anything that doesn't match
31
- * returns `null` and must be ignored by the caller — the origin/source checks
32
- * happen separately, before this runs.
33
- */
34
- export const parseFrameMessage = (data) => {
35
- if (typeof data !== 'object' || data === null)
36
- return null;
37
- const message = data;
38
- switch (message.type) {
39
- case 'mogul:ready':
40
- case 'mogul:request-token':
41
- case 'mogul:exit':
42
- return { type: message.type };
43
- case 'mogul:resize':
44
- return typeof message.height === 'number'
45
- ? { type: 'mogul:resize', height: message.height }
46
- : null;
47
- case 'mogul:success': {
48
- const connectedIdentity = parseConnectedIdentity(message.connectedIdentity);
49
- return typeof message.integrationId === 'number' &&
50
- typeof message.accountId === 'string' &&
51
- connectedIdentity
52
- ? {
53
- type: 'mogul:success',
54
- integrationId: message.integrationId,
55
- accountId: message.accountId,
56
- connectedIdentity,
57
- }
58
- : null;
59
- }
60
- case 'mogul:error':
61
- return typeof message.code === 'string'
62
- ? { type: 'mogul:error', code: message.code }
63
- : null;
64
- default:
65
- return null;
66
- }
67
- };