@omni-co/embed 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.
@@ -1,4 +1,4 @@
1
- import { EmbedSsoContentDiscoveryProps, EmbedSsoDashboardProps, EmbedSsoWorkbookProps, CreateSessionTokenProps, RedeemSessionTokenProps } from "./types.js";
1
+ import { EmbedSsoContentDiscoveryProps, EmbedSsoDashboardProps, EmbedSsoWorkbookProps, CreateSessionTokenProps, RedeemSessionTokenProps } from './types.js';
2
2
  export declare const embedSsoDashboard: (props: EmbedSsoDashboardProps) => Promise<string>;
3
3
  export declare const embedSsoWorkbook: (props: EmbedSsoWorkbookProps) => Promise<string>;
4
4
  /**
package/lib/cjs/embed.js CHANGED
@@ -4,59 +4,59 @@ exports.redeemSessionToken = exports.createSessionToken = exports.embedSsoConten
4
4
  const random_str_server_js_1 = require("./random-str.server.js");
5
5
  const signature_js_1 = require("./signature.js");
6
6
  const constants_js_1 = require("./constants.js");
7
- const defaultEmbedDomain = "embed-omniapp.co";
8
- const embedLoginPath = "/embed/login";
9
- const generateSsoEmbedSessionPath = "/api/unstable/embed/sso/generate-session";
10
- const redeemSsoEmbedSessionPath = "/embed/sso/redeem-session";
7
+ const defaultEmbedDomain = 'embed-omniapp.co';
8
+ const embedLoginPath = '/embed/login';
9
+ const generateSsoEmbedSessionPath = '/api/unstable/embed/sso/generate-session';
10
+ const redeemSsoEmbedSessionPath = '/embed/sso/redeem-session';
11
11
  const createEmbedRequestUrl = (props) => {
12
12
  let host, domain, organizationName;
13
- if ("host" in props)
13
+ if ('host' in props)
14
14
  host = props.host;
15
- if ("organizationName" in props) {
15
+ if ('organizationName' in props) {
16
16
  domain = props.domain;
17
17
  organizationName = props.organizationName;
18
18
  }
19
19
  // Generate the url for the embed login route
20
20
  if (!host)
21
21
  host = `${organizationName}.${domain ?? defaultEmbedDomain}`;
22
- const url = new URL(props.requestPath, `https://${host}${props.port ? `:${props.port}` : ""}`);
22
+ const url = new URL(props.requestPath, `https://${host}${props.port ? `:${props.port}` : ''}`);
23
23
  return url;
24
24
  };
25
25
  const validateProps = (props) => {
26
26
  const { externalId, name, nonce, secret, uiSettings, userAttributes, customTheme, customThemeId, } = props;
27
27
  let host, domain, organizationName;
28
- if ("host" in props)
28
+ if ('host' in props)
29
29
  host = props.host;
30
- if ("organizationName" in props)
30
+ if ('organizationName' in props)
31
31
  organizationName = props.organizationName;
32
- if ("domain" in props)
32
+ if ('domain' in props)
33
33
  domain = props.domain;
34
34
  if (!externalId)
35
- throw new Error("externalId is required");
35
+ throw new Error('externalId is required');
36
36
  if (!name)
37
- throw new Error("name is required");
37
+ throw new Error('name is required');
38
38
  if (!secret)
39
- throw new Error("secret is required");
39
+ throw new Error('secret is required');
40
40
  if (!host && !organizationName)
41
- throw new Error("Must specify either `host` or `organizationName`");
41
+ throw new Error('Must specify either `host` or `organizationName`');
42
42
  if (host && (organizationName || domain))
43
- throw new Error("`host` must be used exclusively and cannot be combined with `organizationName` or `domain` (domain is deprecated)");
43
+ throw new Error('`host` must be used exclusively and cannot be combined with `organizationName` or `domain` (domain is deprecated)');
44
44
  if (customThemeId && customTheme)
45
- console.warn("If you use a `customThemeId` any theme styles passed in via `customTheme` will be ignored.");
45
+ console.warn('If you use a `customThemeId` any theme styles passed in via `customTheme` will be ignored.');
46
46
  if (domain)
47
47
  console.warn("`domain` is deprecated and will be removed in a future v1.0.0 release. Use `host` to specify your vanity domain instead (eg `host: 'omni.my-company.com'`).");
48
48
  if (nonce && nonce.length !== 32)
49
- throw new Error("nonce must be 32 characters");
50
- if (typeof uiSettings !== "object" && uiSettings)
51
- throw new Error("uiSettings must be an object");
52
- if (typeof userAttributes !== "object" && userAttributes)
53
- throw new Error("userAttributes must be an object");
49
+ throw new Error('nonce must be 32 characters');
50
+ if (typeof uiSettings !== 'object' && uiSettings)
51
+ throw new Error('uiSettings must be an object');
52
+ if (typeof userAttributes !== 'object' && userAttributes)
53
+ throw new Error('userAttributes must be an object');
54
54
  };
55
55
  const embedSsoContent = async (props) => {
56
56
  validateProps(props);
57
- let { accessBoost, branch, connectionRoles: rawConnectionRoles, contentPath, customTheme: rawCustomTheme, customThemeId, domain, email, entity, entityFolderContentRole, entityFolderGroupContentRole, entityFolderLabel, entityGroupLabel, externalId, filterSearchParam, groups: rawGroups, host, linkAccess, mode, modelRoles: rawModelRoles, name, nonce, organizationName, preserveEntityFolderContentRole, prefersDark, port, secret, theme, uiSettings: rawUiSettings, userAttributes: rawUserAttributes, } = props;
57
+ const { accessBoost, branch, connectionRoles: rawConnectionRoles, contentPath, customTheme: rawCustomTheme, customThemeId, domain, email, entity, entityFolderContentRole, entityFolderGroupContentRole, entityFolderLabel, entityGroupLabel, externalId, filterSearchParam, groups: rawGroups, host, linkAccess, mode, modelRoles: rawModelRoles, name, organizationName, preserveEntityFolderContentRole, prefersDark, port, secret, theme, timezone, uiSettings: rawUiSettings, userAttributes: rawUserAttributes, } = props;
58
58
  // Handle defaults
59
- nonce = nonce ?? (await (0, random_str_server_js_1.random32ByteString)());
59
+ const nonce = props.nonce ?? (await (0, random_str_server_js_1.random32ByteString)());
60
60
  const uiSettings = rawUiSettings && JSON.stringify(rawUiSettings);
61
61
  const userAttributes = rawUserAttributes && JSON.stringify(rawUserAttributes);
62
62
  const customTheme = rawCustomTheme && JSON.stringify(rawCustomTheme);
@@ -99,44 +99,45 @@ const embedSsoContent = async (props) => {
99
99
  prefersDark,
100
100
  preserveEntityFolderContentRole,
101
101
  theme,
102
+ timezone,
102
103
  uiSettings,
103
104
  userAttributes,
104
105
  });
105
106
  // Build and return the signed url
106
- url.searchParams.append("contentPath", contentPath);
107
- url.searchParams.append("externalId", externalId);
108
- url.searchParams.append("name", name);
109
- url.searchParams.append("nonce", nonce);
110
- url.searchParams.append("signature", signature);
111
- userAttributes && url.searchParams.append("userAttributes", userAttributes);
107
+ url.searchParams.append('contentPath', contentPath);
108
+ url.searchParams.append('externalId', externalId);
109
+ url.searchParams.append('name', name);
110
+ url.searchParams.append('nonce', nonce);
111
+ url.searchParams.append('signature', signature);
112
+ userAttributes && url.searchParams.append('userAttributes', userAttributes);
112
113
  accessBoost !== undefined &&
113
- url.searchParams.append("accessBoost", accessBoost.toString());
114
- entity && url.searchParams.append("entity", entity);
115
- prefersDark && url.searchParams.append("prefersDark", prefersDark);
116
- theme && url.searchParams.append("theme", theme);
114
+ url.searchParams.append('accessBoost', accessBoost.toString());
115
+ entity && url.searchParams.append('entity', entity);
116
+ prefersDark && url.searchParams.append('prefersDark', prefersDark);
117
+ theme && url.searchParams.append('theme', theme);
118
+ timezone && url.searchParams.append('timezone', timezone);
117
119
  filterSearchParam &&
118
- url.searchParams.append("filterSearchParam", filterSearchParam);
119
- linkAccess && url.searchParams.append("linkAccess", linkAccess);
120
- customTheme && url.searchParams.append("customTheme", customTheme);
121
- customThemeId && url.searchParams.append("customThemeId", customThemeId);
122
- connectionRoles &&
123
- url.searchParams.append("connectionRoles", connectionRoles);
124
- mode && url.searchParams.append("mode", mode);
125
- modelRoles && url.searchParams.append("modelRoles", modelRoles);
120
+ url.searchParams.append('filterSearchParam', filterSearchParam);
121
+ linkAccess && url.searchParams.append('linkAccess', linkAccess);
122
+ customTheme && url.searchParams.append('customTheme', customTheme);
123
+ customThemeId && url.searchParams.append('customThemeId', customThemeId);
124
+ connectionRoles && url.searchParams.append('connectionRoles', connectionRoles);
125
+ mode && url.searchParams.append('mode', mode);
126
+ modelRoles && url.searchParams.append('modelRoles', modelRoles);
126
127
  entityFolderContentRole &&
127
- url.searchParams.append("entityFolderContentRole", entityFolderContentRole);
128
+ url.searchParams.append('entityFolderContentRole', entityFolderContentRole);
128
129
  entityFolderGroupContentRole &&
129
- url.searchParams.append("entityFolderGroupContentRole", entityFolderGroupContentRole);
130
- groups && url.searchParams.append("groups", groups);
131
- email && url.searchParams.append("email", email);
132
- uiSettings && url.searchParams.append("uiSettings", uiSettings);
130
+ url.searchParams.append('entityFolderGroupContentRole', entityFolderGroupContentRole);
131
+ groups && url.searchParams.append('groups', groups);
132
+ email && url.searchParams.append('email', email);
133
+ uiSettings && url.searchParams.append('uiSettings', uiSettings);
133
134
  entityGroupLabel &&
134
- url.searchParams.append("entityGroupLabel", entityGroupLabel);
135
+ url.searchParams.append('entityGroupLabel', entityGroupLabel);
135
136
  entityFolderLabel &&
136
- url.searchParams.append("entityFolderLabel", entityFolderLabel);
137
+ url.searchParams.append('entityFolderLabel', entityFolderLabel);
137
138
  preserveEntityFolderContentRole !== undefined &&
138
- url.searchParams.append("preserveEntityFolderContentRole", preserveEntityFolderContentRole.toString());
139
- branch && url.searchParams.append("branch", branch);
139
+ url.searchParams.append('preserveEntityFolderContentRole', preserveEntityFolderContentRole.toString());
140
+ branch && url.searchParams.append('branch', branch);
140
141
  return url.toString();
141
142
  };
142
143
  const buildContentPath = (contentType, contentId) => `/${contentType}/${contentId}`;
@@ -158,9 +159,7 @@ exports.embedSsoWorkbook = embedSsoWorkbook;
158
159
  const embedSsoContentDiscovery = async (props) => {
159
160
  // Entity paths for the Content Discovery embed no longer require stripping the leading `/`.
160
161
  // This check maintains backwards compatibility with the old behavior.
161
- const contentPath = props.path.startsWith("/")
162
- ? props.path
163
- : `/${props.path}`;
162
+ const contentPath = props.path.startsWith('/') ? props.path : `/${props.path}`;
164
163
  return embedSsoContent({
165
164
  ...props,
166
165
  contentPath,
@@ -185,13 +184,13 @@ const createSessionToken = async ({ apiKey, domain, host, organizationName, port
185
184
  });
186
185
  // Hit the endpoint with the endpoint params + signature
187
186
  const fetchResponse = await fetch(generateRequestUrl, {
188
- method: "POST",
187
+ method: 'POST',
189
188
  body: JSON.stringify({
190
189
  ...restProps,
191
190
  }),
192
191
  headers: {
193
192
  Authorization: `Bearer ${apiKey}`,
194
- "Content-type": "application/json",
193
+ 'Content-type': 'application/json',
195
194
  },
196
195
  });
197
196
  if (!fetchResponse.ok)
@@ -201,7 +200,7 @@ const createSessionToken = async ({ apiKey, domain, host, organizationName, port
201
200
  };
202
201
  const fetchData = (await fetchResponse.json());
203
202
  if (!fetchData.sessionId)
204
- return { error: "No session ID returned from endpoint.", success: false };
203
+ return { error: 'No session ID returned from endpoint.', success: false };
205
204
  return { sessionToken: fetchData.sessionId, success: true };
206
205
  };
207
206
  exports.createSessionToken = createSessionToken;
@@ -229,14 +228,13 @@ theme, }) => {
229
228
  theme,
230
229
  branch,
231
230
  });
232
- branch !== undefined &&
233
- redeemRequestUrl.searchParams.append("branch", branch);
231
+ branch !== undefined && redeemRequestUrl.searchParams.append('branch', branch);
234
232
  prefersDark !== undefined &&
235
- redeemRequestUrl.searchParams.append("prefersDark", prefersDark);
236
- theme !== undefined && redeemRequestUrl.searchParams.append("theme", theme);
237
- redeemRequestUrl.searchParams.append("nonce", nonce);
238
- redeemRequestUrl.searchParams.append("sessionId", sessionId);
239
- redeemRequestUrl.searchParams.append("signature", signature);
233
+ redeemRequestUrl.searchParams.append('prefersDark', prefersDark);
234
+ theme !== undefined && redeemRequestUrl.searchParams.append('theme', theme);
235
+ redeemRequestUrl.searchParams.append('nonce', nonce);
236
+ redeemRequestUrl.searchParams.append('sessionId', sessionId);
237
+ redeemRequestUrl.searchParams.append('signature', signature);
240
238
  return redeemRequestUrl.toString();
241
239
  };
242
240
  exports.redeemSessionToken = redeemSessionToken;
@@ -1,4 +1,4 @@
1
- export * from "./embed.js";
2
- export * from "./types.js";
3
- export * from "./signature.js";
4
- export * from "./constants.js";
1
+ export * from './embed.js';
2
+ export * from './types.js';
3
+ export * from './signature.js';
4
+ export * from './constants.js';
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * Client / browser entrypoint for the Omni Embed SDK.
3
3
  */
4
- export * from "./constants.js";
5
- export * from "./types.js";
4
+ export * from './constants.js';
5
+ export * from './types.js';
@@ -13,8 +13,8 @@ const crypto_1 = __importDefault(require("crypto"));
13
13
  * of at least one collision.
14
14
  */
15
15
  const random32ByteString = async () => {
16
- const humanReadableByteSpace = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
17
- let randomString = "";
16
+ const humanReadableByteSpace = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
17
+ let randomString = '';
18
18
  for (let i = 0; i < 32; i++) {
19
19
  // Generate a random number between 0 and humanReadableByteSpace.length - 1
20
20
  // and return the corresponding character from humanReadableByteSpace.
@@ -1,4 +1,4 @@
1
- import { RedeemSessionExclusiveProps } from "./types.js";
1
+ import { RedeemSessionExclusiveProps } from './types.js';
2
2
  export declare const hmacSign: (data: string, secret: string) => string;
3
3
  type SignatureProps = {
4
4
  /**
@@ -109,6 +109,12 @@ type SignatureProps = {
109
109
  * The theme of the embed.
110
110
  */
111
111
  theme?: string;
112
+ /**
113
+ * IANA timezone override applied to the embed session's query execution.
114
+ *
115
+ * Example: "America/New_York"
116
+ */
117
+ timezone?: string;
112
118
  /**
113
119
  * The UI settings for the embedded content.
114
120
  */
@@ -140,6 +146,6 @@ type SignSessionRedemptionProps = Pick<SignatureProps, RedeemSessionExclusivePro
140
146
  */
141
147
  export declare const signSessionRedemption: ({ requestUrl, nonce, sessionId, secret, branch, prefersDark, theme, }: SignSessionRedemptionProps) => string;
142
148
  export declare const TEST_ONLY: {
143
- generateStringForSignature: ({ loginUrl, contentPath, externalId, name, nonce, accessBoost, branch, connectionRoles, customTheme, customThemeId, email, entity, entityFolderContentRole, entityFolderGroupContentRole, entityFolderLabel, entityGroupLabel, filterSearchParam, groups, linkAccess, mode, modelRoles, prefersDark, preserveEntityFolderContentRole, theme, uiSettings, userAttributes, }: Omit<SignatureProps, "secret">) => string;
149
+ generateStringForSignature: ({ loginUrl, contentPath, externalId, name, nonce, accessBoost, branch, connectionRoles, customTheme, customThemeId, email, entity, entityFolderContentRole, entityFolderGroupContentRole, entityFolderLabel, entityGroupLabel, filterSearchParam, groups, linkAccess, mode, modelRoles, prefersDark, preserveEntityFolderContentRole, theme, timezone, uiSettings, userAttributes, }: Omit<SignatureProps, "secret">) => string;
144
150
  };
145
151
  export {};
@@ -6,20 +6,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.TEST_ONLY = exports.signSessionRedemption = exports.getSignature = exports.hmacSign = void 0;
7
7
  const crypto_1 = __importDefault(require("crypto"));
8
8
  const hmacSign = (data, secret) => {
9
- const hmac = crypto_1.default.createHmac("sha256", secret);
9
+ const hmac = crypto_1.default.createHmac('sha256', secret);
10
10
  hmac.update(data);
11
- return hmac.digest("base64url");
11
+ return hmac.digest('base64url');
12
12
  };
13
13
  exports.hmacSign = hmacSign;
14
14
  const generateStringForSignature = ({
15
15
  // Required parameters
16
16
  loginUrl, contentPath, externalId, name, nonce,
17
17
  // Optional parameters
18
- accessBoost, branch, connectionRoles, customTheme, customThemeId, email, entity, entityFolderContentRole, entityFolderGroupContentRole, entityFolderLabel, entityGroupLabel, filterSearchParam, groups, linkAccess, mode, modelRoles, prefersDark, preserveEntityFolderContentRole, theme, uiSettings, userAttributes, }) => {
18
+ accessBoost, branch, connectionRoles, customTheme, customThemeId, email, entity, entityFolderContentRole, entityFolderGroupContentRole, entityFolderLabel, entityGroupLabel, filterSearchParam, groups, linkAccess, mode, modelRoles, prefersDark, preserveEntityFolderContentRole, theme, timezone, uiSettings, userAttributes, }) => {
19
19
  // We create a map of optional params and convert it to an array
20
20
  // to ensure that the order of the optional params is alphabetical and consistent.
21
21
  const optionalParamsMap = {
22
- ...(accessBoost !== undefined && { accessBoost: accessBoost.toString() }),
22
+ ...(accessBoost !== undefined && { accessBoost: accessBoost.toString() }), // need to support accessBoost=false
23
23
  ...(branch && { branch }),
24
24
  ...(connectionRoles && { connectionRoles }),
25
25
  ...(customTheme && { customTheme }),
@@ -40,6 +40,7 @@ accessBoost, branch, connectionRoles, customTheme, customThemeId, email, entity,
40
40
  preserveEntityFolderContentRole: preserveEntityFolderContentRole.toString(),
41
41
  }),
42
42
  ...(theme && { theme }),
43
+ ...(timezone && { timezone }),
43
44
  ...(uiSettings && { uiSettings }),
44
45
  ...(userAttributes && { userAttributes }),
45
46
  };
@@ -54,10 +55,10 @@ accessBoost, branch, connectionRoles, customTheme, customThemeId, email, entity,
54
55
  ${externalId}
55
56
  ${name}
56
57
  ${nonce}
57
- ${optionalParams.join("\n")}
58
+ ${optionalParams.join('\n')}
58
59
  `
59
60
  .trim()
60
- .replace(/\n\s+/g, "\n");
61
+ .replace(/\n\s+/g, '\n');
61
62
  };
62
63
  /**
63
64
  * Creates a signature value for the /embed/login endpoint.
@@ -89,10 +90,10 @@ const signSessionRedemption = ({ requestUrl, nonce, sessionId, secret, branch, p
89
90
  ${requestUrl}
90
91
  ${nonce}
91
92
  ${sessionId}
92
- ${optionalParams.join("\n")}
93
+ ${optionalParams.join('\n')}
93
94
  `
94
95
  .trim()
95
- .replace(/\n\s+/g, "\n");
96
+ .replace(/\n\s+/g, '\n');
96
97
  return (0, exports.hmacSign)(signatureString, secret);
97
98
  };
98
99
  exports.signSessionRedemption = signSessionRedemption;
@@ -1,4 +1,4 @@
1
- import { CustomThemeProperty, EmbedEntityFolderContentRoles, EmbedSessionMode, EmbedUiSettings } from "./constants.js";
1
+ import type { CustomThemeProperty, EmbedEntityFolderContentRoles, EmbedSessionMode, EmbedUiSettings } from './constants.js';
2
2
  type UserAttributeValue = string | string[] | number | number[];
3
3
  type HostProps = ({
4
4
  host?: never;
@@ -39,6 +39,7 @@ type EmbedSsoBaseProps = {
39
39
  userAttributes?: Record<string, UserAttributeValue>;
40
40
  prefersDark?: string;
41
41
  theme?: string;
42
+ timezone?: string;
42
43
  customTheme?: CustomThemeProperties;
43
44
  customThemeId?: string;
44
45
  /**
@@ -188,7 +189,7 @@ export type EmbedSsoContentDiscoveryProps = EmbedSsoBaseProps & {
188
189
  */
189
190
  path: string;
190
191
  };
191
- export type RedeemSessionExclusiveProps = "branch" | "nonce" | "prefersDark" | "secret" | "theme";
192
+ export type RedeemSessionExclusiveProps = 'branch' | 'nonce' | 'prefersDark' | 'secret' | 'theme';
192
193
  export type CreateSessionTokenProps = Omit<EmbedSsoContentProps, RedeemSessionExclusiveProps> & {
193
194
  apiKey: string;
194
195
  } & HostProps;
package/lib/cjs/types.js CHANGED
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const constants_js_1 = require("./constants.js");
@@ -1,4 +1,4 @@
1
- import { EmbedSsoContentDiscoveryProps, EmbedSsoDashboardProps, EmbedSsoWorkbookProps, CreateSessionTokenProps, RedeemSessionTokenProps } from "./types.js";
1
+ import { EmbedSsoContentDiscoveryProps, EmbedSsoDashboardProps, EmbedSsoWorkbookProps, CreateSessionTokenProps, RedeemSessionTokenProps } from './types.js';
2
2
  export declare const embedSsoDashboard: (props: EmbedSsoDashboardProps) => Promise<string>;
3
3
  export declare const embedSsoWorkbook: (props: EmbedSsoWorkbookProps) => Promise<string>;
4
4
  /**
package/lib/esm/embed.js CHANGED
@@ -1,59 +1,59 @@
1
- import { random32ByteString } from "./random-str.server.js";
2
- import { getSignature, signSessionRedemption } from "./signature.js";
3
- import { EmbeddedContent } from "./constants.js";
4
- const defaultEmbedDomain = "embed-omniapp.co";
5
- const embedLoginPath = "/embed/login";
6
- const generateSsoEmbedSessionPath = "/api/unstable/embed/sso/generate-session";
7
- const redeemSsoEmbedSessionPath = "/embed/sso/redeem-session";
1
+ import { random32ByteString } from './random-str.server.js';
2
+ import { getSignature, signSessionRedemption } from './signature.js';
3
+ import { EmbeddedContent } from './constants.js';
4
+ const defaultEmbedDomain = 'embed-omniapp.co';
5
+ const embedLoginPath = '/embed/login';
6
+ const generateSsoEmbedSessionPath = '/api/unstable/embed/sso/generate-session';
7
+ const redeemSsoEmbedSessionPath = '/embed/sso/redeem-session';
8
8
  const createEmbedRequestUrl = (props) => {
9
9
  let host, domain, organizationName;
10
- if ("host" in props)
10
+ if ('host' in props)
11
11
  host = props.host;
12
- if ("organizationName" in props) {
12
+ if ('organizationName' in props) {
13
13
  domain = props.domain;
14
14
  organizationName = props.organizationName;
15
15
  }
16
16
  // Generate the url for the embed login route
17
17
  if (!host)
18
18
  host = `${organizationName}.${domain ?? defaultEmbedDomain}`;
19
- const url = new URL(props.requestPath, `https://${host}${props.port ? `:${props.port}` : ""}`);
19
+ const url = new URL(props.requestPath, `https://${host}${props.port ? `:${props.port}` : ''}`);
20
20
  return url;
21
21
  };
22
22
  const validateProps = (props) => {
23
23
  const { externalId, name, nonce, secret, uiSettings, userAttributes, customTheme, customThemeId, } = props;
24
24
  let host, domain, organizationName;
25
- if ("host" in props)
25
+ if ('host' in props)
26
26
  host = props.host;
27
- if ("organizationName" in props)
27
+ if ('organizationName' in props)
28
28
  organizationName = props.organizationName;
29
- if ("domain" in props)
29
+ if ('domain' in props)
30
30
  domain = props.domain;
31
31
  if (!externalId)
32
- throw new Error("externalId is required");
32
+ throw new Error('externalId is required');
33
33
  if (!name)
34
- throw new Error("name is required");
34
+ throw new Error('name is required');
35
35
  if (!secret)
36
- throw new Error("secret is required");
36
+ throw new Error('secret is required');
37
37
  if (!host && !organizationName)
38
- throw new Error("Must specify either `host` or `organizationName`");
38
+ throw new Error('Must specify either `host` or `organizationName`');
39
39
  if (host && (organizationName || domain))
40
- throw new Error("`host` must be used exclusively and cannot be combined with `organizationName` or `domain` (domain is deprecated)");
40
+ throw new Error('`host` must be used exclusively and cannot be combined with `organizationName` or `domain` (domain is deprecated)');
41
41
  if (customThemeId && customTheme)
42
- console.warn("If you use a `customThemeId` any theme styles passed in via `customTheme` will be ignored.");
42
+ console.warn('If you use a `customThemeId` any theme styles passed in via `customTheme` will be ignored.');
43
43
  if (domain)
44
44
  console.warn("`domain` is deprecated and will be removed in a future v1.0.0 release. Use `host` to specify your vanity domain instead (eg `host: 'omni.my-company.com'`).");
45
45
  if (nonce && nonce.length !== 32)
46
- throw new Error("nonce must be 32 characters");
47
- if (typeof uiSettings !== "object" && uiSettings)
48
- throw new Error("uiSettings must be an object");
49
- if (typeof userAttributes !== "object" && userAttributes)
50
- throw new Error("userAttributes must be an object");
46
+ throw new Error('nonce must be 32 characters');
47
+ if (typeof uiSettings !== 'object' && uiSettings)
48
+ throw new Error('uiSettings must be an object');
49
+ if (typeof userAttributes !== 'object' && userAttributes)
50
+ throw new Error('userAttributes must be an object');
51
51
  };
52
52
  const embedSsoContent = async (props) => {
53
53
  validateProps(props);
54
- let { accessBoost, branch, connectionRoles: rawConnectionRoles, contentPath, customTheme: rawCustomTheme, customThemeId, domain, email, entity, entityFolderContentRole, entityFolderGroupContentRole, entityFolderLabel, entityGroupLabel, externalId, filterSearchParam, groups: rawGroups, host, linkAccess, mode, modelRoles: rawModelRoles, name, nonce, organizationName, preserveEntityFolderContentRole, prefersDark, port, secret, theme, uiSettings: rawUiSettings, userAttributes: rawUserAttributes, } = props;
54
+ const { accessBoost, branch, connectionRoles: rawConnectionRoles, contentPath, customTheme: rawCustomTheme, customThemeId, domain, email, entity, entityFolderContentRole, entityFolderGroupContentRole, entityFolderLabel, entityGroupLabel, externalId, filterSearchParam, groups: rawGroups, host, linkAccess, mode, modelRoles: rawModelRoles, name, organizationName, preserveEntityFolderContentRole, prefersDark, port, secret, theme, timezone, uiSettings: rawUiSettings, userAttributes: rawUserAttributes, } = props;
55
55
  // Handle defaults
56
- nonce = nonce ?? (await random32ByteString());
56
+ const nonce = props.nonce ?? (await random32ByteString());
57
57
  const uiSettings = rawUiSettings && JSON.stringify(rawUiSettings);
58
58
  const userAttributes = rawUserAttributes && JSON.stringify(rawUserAttributes);
59
59
  const customTheme = rawCustomTheme && JSON.stringify(rawCustomTheme);
@@ -96,44 +96,45 @@ const embedSsoContent = async (props) => {
96
96
  prefersDark,
97
97
  preserveEntityFolderContentRole,
98
98
  theme,
99
+ timezone,
99
100
  uiSettings,
100
101
  userAttributes,
101
102
  });
102
103
  // Build and return the signed url
103
- url.searchParams.append("contentPath", contentPath);
104
- url.searchParams.append("externalId", externalId);
105
- url.searchParams.append("name", name);
106
- url.searchParams.append("nonce", nonce);
107
- url.searchParams.append("signature", signature);
108
- userAttributes && url.searchParams.append("userAttributes", userAttributes);
104
+ url.searchParams.append('contentPath', contentPath);
105
+ url.searchParams.append('externalId', externalId);
106
+ url.searchParams.append('name', name);
107
+ url.searchParams.append('nonce', nonce);
108
+ url.searchParams.append('signature', signature);
109
+ userAttributes && url.searchParams.append('userAttributes', userAttributes);
109
110
  accessBoost !== undefined &&
110
- url.searchParams.append("accessBoost", accessBoost.toString());
111
- entity && url.searchParams.append("entity", entity);
112
- prefersDark && url.searchParams.append("prefersDark", prefersDark);
113
- theme && url.searchParams.append("theme", theme);
111
+ url.searchParams.append('accessBoost', accessBoost.toString());
112
+ entity && url.searchParams.append('entity', entity);
113
+ prefersDark && url.searchParams.append('prefersDark', prefersDark);
114
+ theme && url.searchParams.append('theme', theme);
115
+ timezone && url.searchParams.append('timezone', timezone);
114
116
  filterSearchParam &&
115
- url.searchParams.append("filterSearchParam", filterSearchParam);
116
- linkAccess && url.searchParams.append("linkAccess", linkAccess);
117
- customTheme && url.searchParams.append("customTheme", customTheme);
118
- customThemeId && url.searchParams.append("customThemeId", customThemeId);
119
- connectionRoles &&
120
- url.searchParams.append("connectionRoles", connectionRoles);
121
- mode && url.searchParams.append("mode", mode);
122
- modelRoles && url.searchParams.append("modelRoles", modelRoles);
117
+ url.searchParams.append('filterSearchParam', filterSearchParam);
118
+ linkAccess && url.searchParams.append('linkAccess', linkAccess);
119
+ customTheme && url.searchParams.append('customTheme', customTheme);
120
+ customThemeId && url.searchParams.append('customThemeId', customThemeId);
121
+ connectionRoles && url.searchParams.append('connectionRoles', connectionRoles);
122
+ mode && url.searchParams.append('mode', mode);
123
+ modelRoles && url.searchParams.append('modelRoles', modelRoles);
123
124
  entityFolderContentRole &&
124
- url.searchParams.append("entityFolderContentRole", entityFolderContentRole);
125
+ url.searchParams.append('entityFolderContentRole', entityFolderContentRole);
125
126
  entityFolderGroupContentRole &&
126
- url.searchParams.append("entityFolderGroupContentRole", entityFolderGroupContentRole);
127
- groups && url.searchParams.append("groups", groups);
128
- email && url.searchParams.append("email", email);
129
- uiSettings && url.searchParams.append("uiSettings", uiSettings);
127
+ url.searchParams.append('entityFolderGroupContentRole', entityFolderGroupContentRole);
128
+ groups && url.searchParams.append('groups', groups);
129
+ email && url.searchParams.append('email', email);
130
+ uiSettings && url.searchParams.append('uiSettings', uiSettings);
130
131
  entityGroupLabel &&
131
- url.searchParams.append("entityGroupLabel", entityGroupLabel);
132
+ url.searchParams.append('entityGroupLabel', entityGroupLabel);
132
133
  entityFolderLabel &&
133
- url.searchParams.append("entityFolderLabel", entityFolderLabel);
134
+ url.searchParams.append('entityFolderLabel', entityFolderLabel);
134
135
  preserveEntityFolderContentRole !== undefined &&
135
- url.searchParams.append("preserveEntityFolderContentRole", preserveEntityFolderContentRole.toString());
136
- branch && url.searchParams.append("branch", branch);
136
+ url.searchParams.append('preserveEntityFolderContentRole', preserveEntityFolderContentRole.toString());
137
+ branch && url.searchParams.append('branch', branch);
137
138
  return url.toString();
138
139
  };
139
140
  const buildContentPath = (contentType, contentId) => `/${contentType}/${contentId}`;
@@ -153,9 +154,7 @@ export const embedSsoWorkbook = async (props) => {
153
154
  export const embedSsoContentDiscovery = async (props) => {
154
155
  // Entity paths for the Content Discovery embed no longer require stripping the leading `/`.
155
156
  // This check maintains backwards compatibility with the old behavior.
156
- const contentPath = props.path.startsWith("/")
157
- ? props.path
158
- : `/${props.path}`;
157
+ const contentPath = props.path.startsWith('/') ? props.path : `/${props.path}`;
159
158
  return embedSsoContent({
160
159
  ...props,
161
160
  contentPath,
@@ -179,13 +178,13 @@ export const createSessionToken = async ({ apiKey, domain, host, organizationNam
179
178
  });
180
179
  // Hit the endpoint with the endpoint params + signature
181
180
  const fetchResponse = await fetch(generateRequestUrl, {
182
- method: "POST",
181
+ method: 'POST',
183
182
  body: JSON.stringify({
184
183
  ...restProps,
185
184
  }),
186
185
  headers: {
187
186
  Authorization: `Bearer ${apiKey}`,
188
- "Content-type": "application/json",
187
+ 'Content-type': 'application/json',
189
188
  },
190
189
  });
191
190
  if (!fetchResponse.ok)
@@ -195,7 +194,7 @@ export const createSessionToken = async ({ apiKey, domain, host, organizationNam
195
194
  };
196
195
  const fetchData = (await fetchResponse.json());
197
196
  if (!fetchData.sessionId)
198
- return { error: "No session ID returned from endpoint.", success: false };
197
+ return { error: 'No session ID returned from endpoint.', success: false };
199
198
  return { sessionToken: fetchData.sessionId, success: true };
200
199
  };
201
200
  /**
@@ -222,13 +221,12 @@ theme, }) => {
222
221
  theme,
223
222
  branch,
224
223
  });
225
- branch !== undefined &&
226
- redeemRequestUrl.searchParams.append("branch", branch);
224
+ branch !== undefined && redeemRequestUrl.searchParams.append('branch', branch);
227
225
  prefersDark !== undefined &&
228
- redeemRequestUrl.searchParams.append("prefersDark", prefersDark);
229
- theme !== undefined && redeemRequestUrl.searchParams.append("theme", theme);
230
- redeemRequestUrl.searchParams.append("nonce", nonce);
231
- redeemRequestUrl.searchParams.append("sessionId", sessionId);
232
- redeemRequestUrl.searchParams.append("signature", signature);
226
+ redeemRequestUrl.searchParams.append('prefersDark', prefersDark);
227
+ theme !== undefined && redeemRequestUrl.searchParams.append('theme', theme);
228
+ redeemRequestUrl.searchParams.append('nonce', nonce);
229
+ redeemRequestUrl.searchParams.append('sessionId', sessionId);
230
+ redeemRequestUrl.searchParams.append('signature', signature);
233
231
  return redeemRequestUrl.toString();
234
232
  };
@@ -1,4 +1,4 @@
1
- export * from "./embed.js";
2
- export * from "./types.js";
3
- export * from "./signature.js";
4
- export * from "./constants.js";
1
+ export * from './embed.js';
2
+ export * from './types.js';
3
+ export * from './signature.js';
4
+ export * from './constants.js';
package/lib/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export * from "./embed.js";
2
- export * from "./types.js";
3
- export * from "./signature.js";
4
- export * from "./constants.js";
1
+ export * from './embed.js';
2
+ export * from './types.js';
3
+ export * from './signature.js';
4
+ export * from './constants.js';
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * Client / browser entrypoint for the Omni Embed SDK.
3
3
  */
4
- export * from "./constants.js";
5
- export * from "./types.js";
4
+ export * from './constants.js';
5
+ export * from './types.js';