@kittl/sdk 0.0.8 → 1.0.0-alpha.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/dist/dashboardStandalonePage/sdk.d.ts +8261 -0
- package/dist/dashboardStandalonePage/sdk.esm.js +1176 -0
- package/dist/dashboardStandalonePage/sdk.js +1176 -0
- package/dist/editorContentPanel/sdk.d.ts +8613 -0
- package/dist/editorContentPanel/sdk.esm.js +1462 -0
- package/dist/editorContentPanel/sdk.js +1462 -0
- package/dist/editorScriptRunner/sdk.d.ts +7977 -0
- package/dist/{kittl-sdk.esm.js → editorScriptRunner/sdk.esm.js} +400 -180
- package/dist/{kittl-sdk.js → editorScriptRunner/sdk.js} +400 -180
- package/dist/sharedFileBrowser/sdk.d.ts +328 -0
- package/dist/sharedFileBrowser/sdk.esm.js +1177 -0
- package/dist/sharedFileBrowser/sdk.js +1177 -0
- package/package.json +25 -6
- package/dist/sdk.d.ts +0 -2424
|
@@ -0,0 +1,1176 @@
|
|
|
1
|
+
// @ts-self-types="./sdk.d.ts"
|
|
2
|
+
/*! Kittl SDK - https://kittl.com - see license for terms */
|
|
3
|
+
|
|
4
|
+
"use strict";
|
|
5
|
+
(() => {
|
|
6
|
+
|
|
7
|
+
var FROM_EXTENSION_COMMANDS = {
|
|
8
|
+
/** Capability-owned AI callback registration. */
|
|
9
|
+
AI_GENERATOR_SUBSCRIBE: "ai-generator-subscribe",
|
|
10
|
+
/** Capability-owned AI callback teardown. */
|
|
11
|
+
AI_GENERATOR_UNSUBSCRIBE: "ai-generator-unsubscribe",
|
|
12
|
+
/** SDK API call */
|
|
13
|
+
SDK_CALL: "sdk-call",
|
|
14
|
+
/** AI handler registration */
|
|
15
|
+
AI_REGISTER_HANDLER: "ai-register-handler",
|
|
16
|
+
/** AI handler unregistration */
|
|
17
|
+
AI_UNREGISTER_HANDLER: "ai-unregister-handler",
|
|
18
|
+
/** File browser tab registration */
|
|
19
|
+
FILE_BROWSER_REGISTER: "file-browser-register",
|
|
20
|
+
/** File browser fetch content response */
|
|
21
|
+
FILE_BROWSER_FETCH_CONTENT_RESPONSE: "file-browser-fetch-content-response",
|
|
22
|
+
/** Stateless message send */
|
|
23
|
+
STATELESS_SEND: "stateless-send",
|
|
24
|
+
/** Stateless subscription */
|
|
25
|
+
STATELESS_SUBSCRIBE: "stateless-subscribe",
|
|
26
|
+
/** Stateless unsubscription */
|
|
27
|
+
STATELESS_UNSUBSCRIBE: "stateless-unsubscribe",
|
|
28
|
+
/** App state subscription */
|
|
29
|
+
APP_STATE_SUBSCRIBE: "app-state-subscribe",
|
|
30
|
+
/** App state unsubscription */
|
|
31
|
+
APP_STATE_UNSUBSCRIBE: "app-state-unsubscribe",
|
|
32
|
+
/** Batch creation */
|
|
33
|
+
BATCH_CREATE: "batch-create",
|
|
34
|
+
/** Batch commit */
|
|
35
|
+
BATCH_COMMIT: "batch-commit",
|
|
36
|
+
/** OAuth flow start */
|
|
37
|
+
AUTH_START: "auth-start",
|
|
38
|
+
/** OAuth token exchange */
|
|
39
|
+
AUTH_EXCHANGE: "auth-exchange",
|
|
40
|
+
/** Get OAuth token */
|
|
41
|
+
AUTH_GET_TOKEN: "auth-get-token",
|
|
42
|
+
/** Refresh OAuth token */
|
|
43
|
+
AUTH_REFRESH: "auth-refresh",
|
|
44
|
+
/** OAuth logout */
|
|
45
|
+
AUTH_LOGOUT: "auth-logout",
|
|
46
|
+
/** Get user token for authentication */
|
|
47
|
+
AUTH_GET_USER_TOKEN: "auth-get-user-token",
|
|
48
|
+
/** Context subscription */
|
|
49
|
+
CONTEXT_SUBSCRIBE: "context-subscribe",
|
|
50
|
+
/** Context unsubscription */
|
|
51
|
+
CONTEXT_UNSUBSCRIBE: "context-unsubscribe",
|
|
52
|
+
/** Design state subscription */
|
|
53
|
+
DESIGN_STATE_SUBSCRIBE: "design-state-subscribe",
|
|
54
|
+
/** Design state unsubscription */
|
|
55
|
+
DESIGN_STATE_UNSUBSCRIBE: "design-state-unsubscribe",
|
|
56
|
+
/** Extension loaded notification */
|
|
57
|
+
LOADED: "loaded"
|
|
58
|
+
};
|
|
59
|
+
var TO_EXTENSION_COMMANDS = {
|
|
60
|
+
/** Callback payload for generator or pending-set subscriptions. */
|
|
61
|
+
AI_GENERATOR_UPDATE: "ai-generator-update",
|
|
62
|
+
/** SDK API response */
|
|
63
|
+
SDK_RESPONSE: "sdk-response",
|
|
64
|
+
/** File browser fetch content request */
|
|
65
|
+
FILE_BROWSER_FETCH_CONTENT_REQUEST: "file-browser-fetch-content-request",
|
|
66
|
+
/** Stateless message push */
|
|
67
|
+
STATELESS_MESSAGE: "stateless-message",
|
|
68
|
+
/** Context update push */
|
|
69
|
+
CONTEXT_UPDATE: "context-update",
|
|
70
|
+
/** AI generation update push */
|
|
71
|
+
AI_GENERATION_UPDATE: "ai-generation-update",
|
|
72
|
+
/** Design state update push */
|
|
73
|
+
DESIGN_STATE_UPDATE: "design-state-update",
|
|
74
|
+
/** App state update push */
|
|
75
|
+
APP_STATE_UPDATE: "app-state-update"
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
function isAIGeneratorUpdateMessage(data) {
|
|
79
|
+
return !!data && typeof data === "object" && "command" in data && data.command === "ai-generator-update" && "subscriptionId" in data && typeof data.subscriptionId === "string";
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
var isSDKResponseMessage = (data) => {
|
|
83
|
+
return typeof data === "object" && data !== null && "command" in data && data.command === TO_EXTENSION_COMMANDS.SDK_RESPONSE && "messageId" in data && typeof data.messageId === "string";
|
|
84
|
+
};
|
|
85
|
+
var isStatelessPushMessage = (data) => {
|
|
86
|
+
return typeof data === "object" && data !== null && "command" in data && data.command === TO_EXTENSION_COMMANDS.STATELESS_MESSAGE && "type" in data && typeof data.type === "string" && "payload" in data && typeof data.payload === "object" && data.payload !== null;
|
|
87
|
+
};
|
|
88
|
+
var isAIGenerationUpdatePushMessage = (data) => {
|
|
89
|
+
return typeof data === "object" && data !== null && "command" in data && data.command === TO_EXTENSION_COMMANDS.AI_GENERATION_UPDATE && "subscriptionId" in data && typeof data.subscriptionId === "string" && "update" in data && typeof data.update === "object" && data.update !== null;
|
|
90
|
+
};
|
|
91
|
+
var isDesignStateUpdatePushMessage = (data) => {
|
|
92
|
+
return typeof data === "object" && data !== null && "command" in data && data.command === TO_EXTENSION_COMMANDS.DESIGN_STATE_UPDATE && "updates" in data && Array.isArray(data.updates);
|
|
93
|
+
};
|
|
94
|
+
var isAppStateUpdatePushMessage = (data) => {
|
|
95
|
+
return typeof data === "object" && data !== null && "command" in data && data.command === TO_EXTENSION_COMMANDS.APP_STATE_UPDATE && "updates" in data && Array.isArray(data.updates);
|
|
96
|
+
};
|
|
97
|
+
var isContextUpdatePushMessage = (data) => {
|
|
98
|
+
return typeof data === "object" && data !== null && "command" in data && data.command === TO_EXTENSION_COMMANDS.CONTEXT_UPDATE && "subscriptionId" in data && typeof data.subscriptionId === "string" && "context" in data && typeof data.context === "object" && data.context !== null;
|
|
99
|
+
};
|
|
100
|
+
var isFileBrowserFetchContentRequestMessage = (data) => {
|
|
101
|
+
return typeof data === "object" && data !== null && "command" in data && data.command === TO_EXTENSION_COMMANDS.FILE_BROWSER_FETCH_CONTENT_REQUEST && "requestId" in data && typeof data.requestId === "string" && "subscriptionId" in data && typeof data.subscriptionId === "string";
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
var generateMessageId = () => {
|
|
105
|
+
if (crypto?.randomUUID && typeof crypto.randomUUID === "function") {
|
|
106
|
+
return crypto.randomUUID();
|
|
107
|
+
}
|
|
108
|
+
return Math.random().toString(36).substring(7);
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
var buildMethodPath = (rootPrefix, pathSegments) => {
|
|
112
|
+
if (!rootPrefix) {
|
|
113
|
+
return pathSegments.join(".");
|
|
114
|
+
}
|
|
115
|
+
if (pathSegments.length === 0) {
|
|
116
|
+
return rootPrefix;
|
|
117
|
+
}
|
|
118
|
+
return `${rootPrefix}.${pathSegments.join(".")}`;
|
|
119
|
+
};
|
|
120
|
+
var createCallablePathProxy = (options) => {
|
|
121
|
+
const createNode = (pathSegments) => {
|
|
122
|
+
const target = () => {
|
|
123
|
+
};
|
|
124
|
+
const handler = {
|
|
125
|
+
get: (_target, prop) => {
|
|
126
|
+
if (typeof prop === "symbol") {
|
|
127
|
+
return Reflect.get(target, prop);
|
|
128
|
+
}
|
|
129
|
+
return createNode([...pathSegments, String(prop)]);
|
|
130
|
+
},
|
|
131
|
+
apply: (_target, _thisArg, args) => {
|
|
132
|
+
const context = {
|
|
133
|
+
pathSegments,
|
|
134
|
+
methodPath: buildMethodPath(options.rootPrefix ?? "", pathSegments),
|
|
135
|
+
args
|
|
136
|
+
};
|
|
137
|
+
options.beforeInvoke?.(context);
|
|
138
|
+
return options.onInvoke(context);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
return new Proxy(target, handler);
|
|
142
|
+
};
|
|
143
|
+
return createNode([]);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
var parentDomain;
|
|
147
|
+
var APPROVED_EXTENSION_COMMUNICATION_DOMAINS = [
|
|
148
|
+
"https://app.stagingdesigner.com",
|
|
149
|
+
"https://*.stagingdesigner.com",
|
|
150
|
+
"http://localhost:3000",
|
|
151
|
+
"https://app.kittl.com",
|
|
152
|
+
// website, for sandboxed standalone dashboard pages
|
|
153
|
+
"http://localhost:3003",
|
|
154
|
+
"https://www.kittl.com"
|
|
155
|
+
];
|
|
156
|
+
var toOrigin = (value) => {
|
|
157
|
+
if (!value) {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
try {
|
|
161
|
+
return new URL(value).origin;
|
|
162
|
+
} catch (_error) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
var escapeRegex = (value) => {
|
|
167
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
168
|
+
};
|
|
169
|
+
var matchesApprovedDomain = (origin, approvedDomain) => {
|
|
170
|
+
const normalized = approvedDomain.trim();
|
|
171
|
+
if (!normalized) {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
if (normalized.includes("*")) {
|
|
175
|
+
const wildcardRegex = new RegExp(
|
|
176
|
+
// because we use wildcards only in the middle of the string
|
|
177
|
+
// we know that our list must start with the regex and end with the regex
|
|
178
|
+
// so we add the ^ and $ to the regex too
|
|
179
|
+
`^${escapeRegex(normalized).replace(/\\\*/g, ".*")}$`
|
|
180
|
+
);
|
|
181
|
+
return wildcardRegex.test(origin);
|
|
182
|
+
}
|
|
183
|
+
return origin === normalized;
|
|
184
|
+
};
|
|
185
|
+
var getParentDomain = () => {
|
|
186
|
+
if (parentDomain) {
|
|
187
|
+
return parentDomain;
|
|
188
|
+
}
|
|
189
|
+
const referrer = window.document.referrer;
|
|
190
|
+
const ancestorOrigins = window.location.ancestorOrigins;
|
|
191
|
+
const ancestorOrigin = ancestorOrigins && ancestorOrigins.length > 0 ? ancestorOrigins[ancestorOrigins.length - 1] : void 0;
|
|
192
|
+
const currentDomainOrigin = toOrigin(referrer) ?? toOrigin(ancestorOrigin);
|
|
193
|
+
if (!currentDomainOrigin) {
|
|
194
|
+
throw new Error("No current domain origin found");
|
|
195
|
+
}
|
|
196
|
+
const approvedParentDomain = APPROVED_EXTENSION_COMMUNICATION_DOMAINS.find(
|
|
197
|
+
(domain) => {
|
|
198
|
+
return matchesApprovedDomain(currentDomainOrigin, domain);
|
|
199
|
+
}
|
|
200
|
+
);
|
|
201
|
+
if (!approvedParentDomain) {
|
|
202
|
+
throw new Error("No approved parent domain found");
|
|
203
|
+
}
|
|
204
|
+
parentDomain = currentDomainOrigin;
|
|
205
|
+
return parentDomain;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
var pendingRequests = /* @__PURE__ */ new Map();
|
|
209
|
+
var sdkVersion;
|
|
210
|
+
function setSDKVersion(version2) {
|
|
211
|
+
sdkVersion = version2;
|
|
212
|
+
}
|
|
213
|
+
var postMessageToParent = (message) => {
|
|
214
|
+
window.parent.postMessage(
|
|
215
|
+
sdkVersion === void 0 ? message : { ...message, sdkVersion },
|
|
216
|
+
getParentDomain()
|
|
217
|
+
);
|
|
218
|
+
};
|
|
219
|
+
var sendMessage = (message) => {
|
|
220
|
+
postMessageToParent(message);
|
|
221
|
+
return new Promise((resolve, reject) => {
|
|
222
|
+
pendingRequests.set(message.messageId, {
|
|
223
|
+
resolve: (value) => {
|
|
224
|
+
resolve(value);
|
|
225
|
+
},
|
|
226
|
+
reject
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
};
|
|
230
|
+
var sendLoaded = () => {
|
|
231
|
+
const parent = window.parent;
|
|
232
|
+
if (!parent || parent === window) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
const message = { command: FROM_EXTENSION_COMMANDS.LOADED };
|
|
236
|
+
postMessageToParent(message);
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
var createSDKCallMessage = {
|
|
240
|
+
aiGenerator: (dots, args, messageId) => ({
|
|
241
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
242
|
+
dots,
|
|
243
|
+
args,
|
|
244
|
+
messageId,
|
|
245
|
+
apiType: "aiGenerator"
|
|
246
|
+
}),
|
|
247
|
+
mockup: (dots, args, messageId) => ({
|
|
248
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
249
|
+
dots,
|
|
250
|
+
args,
|
|
251
|
+
messageId,
|
|
252
|
+
apiType: "mockup"
|
|
253
|
+
}),
|
|
254
|
+
fileBrowser: (dots, args, messageId) => ({
|
|
255
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
256
|
+
dots,
|
|
257
|
+
args,
|
|
258
|
+
messageId,
|
|
259
|
+
apiType: "fileBrowser"
|
|
260
|
+
}),
|
|
261
|
+
ai: (dots, args, messageId) => ({
|
|
262
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
263
|
+
dots,
|
|
264
|
+
args,
|
|
265
|
+
messageId,
|
|
266
|
+
apiType: "ai"
|
|
267
|
+
}),
|
|
268
|
+
context: (dots, args, messageId) => ({
|
|
269
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
270
|
+
dots,
|
|
271
|
+
args,
|
|
272
|
+
messageId,
|
|
273
|
+
apiType: "context"
|
|
274
|
+
}),
|
|
275
|
+
design: (dots, args, messageId) => ({
|
|
276
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
277
|
+
dots,
|
|
278
|
+
args,
|
|
279
|
+
messageId,
|
|
280
|
+
apiType: "design"
|
|
281
|
+
}),
|
|
282
|
+
export: (dots, args, messageId) => ({
|
|
283
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
284
|
+
dots,
|
|
285
|
+
args,
|
|
286
|
+
messageId,
|
|
287
|
+
apiType: "export"
|
|
288
|
+
}),
|
|
289
|
+
font: (dots, args, messageId) => ({
|
|
290
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
291
|
+
dots,
|
|
292
|
+
args,
|
|
293
|
+
messageId,
|
|
294
|
+
apiType: "font"
|
|
295
|
+
}),
|
|
296
|
+
project: (dots, args, messageId) => ({
|
|
297
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
298
|
+
dots,
|
|
299
|
+
args,
|
|
300
|
+
messageId,
|
|
301
|
+
apiType: "project"
|
|
302
|
+
}),
|
|
303
|
+
state: (dots, args, messageId) => ({
|
|
304
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
305
|
+
dots,
|
|
306
|
+
args,
|
|
307
|
+
messageId,
|
|
308
|
+
apiType: "state"
|
|
309
|
+
}),
|
|
310
|
+
upload: (dots, args, messageId) => ({
|
|
311
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
312
|
+
dots,
|
|
313
|
+
args,
|
|
314
|
+
messageId,
|
|
315
|
+
apiType: "upload"
|
|
316
|
+
}),
|
|
317
|
+
data: (dots, args, messageId) => ({
|
|
318
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
319
|
+
dots,
|
|
320
|
+
args,
|
|
321
|
+
messageId,
|
|
322
|
+
apiType: "data"
|
|
323
|
+
}),
|
|
324
|
+
brandKit: (dots, args, messageId) => ({
|
|
325
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
326
|
+
dots,
|
|
327
|
+
args,
|
|
328
|
+
messageId,
|
|
329
|
+
apiType: "brandKit"
|
|
330
|
+
}),
|
|
331
|
+
openMicroEditor: (dots, args, messageId) => ({
|
|
332
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
333
|
+
dots,
|
|
334
|
+
args,
|
|
335
|
+
messageId,
|
|
336
|
+
apiType: "openMicroEditor"
|
|
337
|
+
}),
|
|
338
|
+
openMainEditor: (dots, args, messageId) => ({
|
|
339
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
340
|
+
dots,
|
|
341
|
+
args,
|
|
342
|
+
messageId,
|
|
343
|
+
apiType: "openMainEditor"
|
|
344
|
+
})
|
|
345
|
+
};
|
|
346
|
+
function createApiProxy(apiType) {
|
|
347
|
+
return createCallablePathProxy({
|
|
348
|
+
onInvoke: ({ pathSegments, args }) => {
|
|
349
|
+
return sendMessage(
|
|
350
|
+
createSDKCallMessage[apiType](
|
|
351
|
+
[...pathSegments],
|
|
352
|
+
[...args],
|
|
353
|
+
generateMessageId()
|
|
354
|
+
)
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function createAIGeneratorBridgeApi() {
|
|
361
|
+
const callbacks = /* @__PURE__ */ new Map();
|
|
362
|
+
const proxy = createApiProxy("aiGenerator");
|
|
363
|
+
async function subscribe(request, callback) {
|
|
364
|
+
const subscriptionId = generateMessageId();
|
|
365
|
+
callbacks.set(subscriptionId, callback);
|
|
366
|
+
let response;
|
|
367
|
+
try {
|
|
368
|
+
response = await sendMessage({
|
|
369
|
+
command: "ai-generator-subscribe",
|
|
370
|
+
...request,
|
|
371
|
+
subscriptionId,
|
|
372
|
+
messageId: generateMessageId()
|
|
373
|
+
});
|
|
374
|
+
} catch (error) {
|
|
375
|
+
callbacks.delete(subscriptionId);
|
|
376
|
+
throw error;
|
|
377
|
+
}
|
|
378
|
+
if (!response.isOk) {
|
|
379
|
+
callbacks.delete(subscriptionId);
|
|
380
|
+
throw new Error(response.error.message);
|
|
381
|
+
}
|
|
382
|
+
return () => {
|
|
383
|
+
callbacks.delete(subscriptionId);
|
|
384
|
+
postMessageToParent({
|
|
385
|
+
command: "ai-generator-unsubscribe",
|
|
386
|
+
subscriptionId
|
|
387
|
+
});
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
const methods = {
|
|
391
|
+
registerGenerator: (id, callback) => subscribe({ method: "registerGenerator", args: [id] }, (update) => {
|
|
392
|
+
if (update) callback(update);
|
|
393
|
+
}),
|
|
394
|
+
subscribeToGenerationUpdates: (ids, callback) => subscribe(
|
|
395
|
+
{ method: "subscribeToGenerationUpdates", args: [ids] },
|
|
396
|
+
(update) => {
|
|
397
|
+
if (update) callback(update);
|
|
398
|
+
}
|
|
399
|
+
),
|
|
400
|
+
subscribeToPendingGenerations: (callback) => subscribe(
|
|
401
|
+
{ method: "subscribeToPendingGenerations", args: [] },
|
|
402
|
+
() => callback()
|
|
403
|
+
),
|
|
404
|
+
/** Callers may reuse richer internal submission objects; never send their local abort callbacks. */
|
|
405
|
+
cancelGenerations: (submission) => proxy.cancelGenerations({
|
|
406
|
+
generationIds: submission.generationIds,
|
|
407
|
+
until: submission.until
|
|
408
|
+
})
|
|
409
|
+
};
|
|
410
|
+
return {
|
|
411
|
+
api: new Proxy(proxy, {
|
|
412
|
+
get: (target, property, receiver) => property in methods ? methods[property] : Reflect.get(target, property, receiver)
|
|
413
|
+
}),
|
|
414
|
+
dispatch: (message) => callbacks.get(message.subscriptionId)?.(message.update)
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
var generationHandlers = /* @__PURE__ */ new Map();
|
|
419
|
+
var generationSubscriptions = /* @__PURE__ */ new Map();
|
|
420
|
+
var dispatchAIGenerationUpdate = (subscriptionId, update) => {
|
|
421
|
+
const handler = generationHandlers.get(subscriptionId);
|
|
422
|
+
if (!handler) {
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
void handler(update);
|
|
426
|
+
};
|
|
427
|
+
function createAIApiProxy() {
|
|
428
|
+
const unregisterGenerationHandler = (generatorId) => {
|
|
429
|
+
const subscriptionId = generationSubscriptions.get(generatorId);
|
|
430
|
+
if (!subscriptionId) {
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
generationHandlers.delete(subscriptionId);
|
|
434
|
+
generationSubscriptions.delete(generatorId);
|
|
435
|
+
const unregisterMessage = {
|
|
436
|
+
command: FROM_EXTENSION_COMMANDS.AI_UNREGISTER_HANDLER,
|
|
437
|
+
generatorId,
|
|
438
|
+
subscriptionId
|
|
439
|
+
};
|
|
440
|
+
postMessageToParent(unregisterMessage);
|
|
441
|
+
};
|
|
442
|
+
return {
|
|
443
|
+
spendCredits: async (options) => {
|
|
444
|
+
const { onAccept, onDecline, ...serializable } = options;
|
|
445
|
+
const message = {
|
|
446
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
447
|
+
dots: ["spendCredits"],
|
|
448
|
+
args: [serializable],
|
|
449
|
+
messageId: generateMessageId(),
|
|
450
|
+
apiType: "ai"
|
|
451
|
+
};
|
|
452
|
+
const response = await sendMessage(message);
|
|
453
|
+
if (response.isOk && response.result.success) {
|
|
454
|
+
onAccept?.();
|
|
455
|
+
} else {
|
|
456
|
+
onDecline?.();
|
|
457
|
+
}
|
|
458
|
+
return response;
|
|
459
|
+
},
|
|
460
|
+
startGeneration: (generatorId, inputSettings, output) => {
|
|
461
|
+
const message = {
|
|
462
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
463
|
+
dots: ["startGeneration"],
|
|
464
|
+
args: [generatorId, inputSettings, output],
|
|
465
|
+
messageId: generateMessageId(),
|
|
466
|
+
apiType: "ai"
|
|
467
|
+
};
|
|
468
|
+
return sendMessage(message);
|
|
469
|
+
},
|
|
470
|
+
registerHandler: async (generatorId, onStatusUpdate) => {
|
|
471
|
+
if (generationSubscriptions.has(generatorId)) {
|
|
472
|
+
return {
|
|
473
|
+
isOk: false,
|
|
474
|
+
error: {
|
|
475
|
+
message: `AI handler for generator "${generatorId}" is already registered`,
|
|
476
|
+
name: "SdkInternalError"
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
const subscriptionId = generateMessageId();
|
|
481
|
+
generationHandlers.set(subscriptionId, onStatusUpdate);
|
|
482
|
+
generationSubscriptions.set(generatorId, subscriptionId);
|
|
483
|
+
const registerMessage = {
|
|
484
|
+
command: FROM_EXTENSION_COMMANDS.AI_REGISTER_HANDLER,
|
|
485
|
+
messageId: generateMessageId(),
|
|
486
|
+
generatorId,
|
|
487
|
+
subscriptionId
|
|
488
|
+
};
|
|
489
|
+
try {
|
|
490
|
+
const response = await sendMessage(registerMessage);
|
|
491
|
+
if (!response.isOk) {
|
|
492
|
+
generationHandlers.delete(subscriptionId);
|
|
493
|
+
generationSubscriptions.delete(generatorId);
|
|
494
|
+
return response;
|
|
495
|
+
}
|
|
496
|
+
return {
|
|
497
|
+
isOk: true,
|
|
498
|
+
result: () => unregisterGenerationHandler(generatorId)
|
|
499
|
+
};
|
|
500
|
+
} catch {
|
|
501
|
+
generationHandlers.delete(subscriptionId);
|
|
502
|
+
generationSubscriptions.delete(generatorId);
|
|
503
|
+
return {
|
|
504
|
+
isOk: false,
|
|
505
|
+
error: {
|
|
506
|
+
message: "Failed to register AI handler",
|
|
507
|
+
name: "SdkInternalError"
|
|
508
|
+
}
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
},
|
|
512
|
+
unregisterHandler: async (generatorId) => {
|
|
513
|
+
unregisterGenerationHandler(generatorId);
|
|
514
|
+
return { isOk: true, result: void 0 };
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
var fetchContentHandlers = /* @__PURE__ */ new Map();
|
|
520
|
+
var tabIdToSubscriptionId = /* @__PURE__ */ new Map();
|
|
521
|
+
var removeSubscriptionHandlers = (subscriptionId) => {
|
|
522
|
+
fetchContentHandlers.delete(subscriptionId);
|
|
523
|
+
};
|
|
524
|
+
var dispatchFileBrowserFetchContentRequest = (requestId, subscriptionId, params) => {
|
|
525
|
+
const handler = fetchContentHandlers.get(subscriptionId);
|
|
526
|
+
if (!handler) {
|
|
527
|
+
const responseMessage = {
|
|
528
|
+
command: FROM_EXTENSION_COMMANDS.FILE_BROWSER_FETCH_CONTENT_RESPONSE,
|
|
529
|
+
requestId,
|
|
530
|
+
content: []
|
|
531
|
+
};
|
|
532
|
+
postMessageToParent(responseMessage);
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
void handler(params).then((result) => {
|
|
536
|
+
const responseMessage = {
|
|
537
|
+
command: FROM_EXTENSION_COMMANDS.FILE_BROWSER_FETCH_CONTENT_RESPONSE,
|
|
538
|
+
requestId,
|
|
539
|
+
content: result.content,
|
|
540
|
+
next: result.next
|
|
541
|
+
};
|
|
542
|
+
postMessageToParent(responseMessage);
|
|
543
|
+
}).catch((error) => {
|
|
544
|
+
const responseMessage = {
|
|
545
|
+
command: FROM_EXTENSION_COMMANDS.FILE_BROWSER_FETCH_CONTENT_RESPONSE,
|
|
546
|
+
requestId,
|
|
547
|
+
content: [],
|
|
548
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
549
|
+
};
|
|
550
|
+
postMessageToParent(responseMessage);
|
|
551
|
+
});
|
|
552
|
+
};
|
|
553
|
+
function createFileBrowserApiProxy() {
|
|
554
|
+
return {
|
|
555
|
+
registerUploadBrowser: async (tab) => {
|
|
556
|
+
const subscriptionId = generateMessageId();
|
|
557
|
+
const existingSubscriptionId = tabIdToSubscriptionId.get(tab.id);
|
|
558
|
+
if (existingSubscriptionId) {
|
|
559
|
+
removeSubscriptionHandlers(existingSubscriptionId);
|
|
560
|
+
}
|
|
561
|
+
fetchContentHandlers.set(subscriptionId, tab.fetchContent);
|
|
562
|
+
tabIdToSubscriptionId.set(tab.id, subscriptionId);
|
|
563
|
+
const registerMessage = {
|
|
564
|
+
command: FROM_EXTENSION_COMMANDS.FILE_BROWSER_REGISTER,
|
|
565
|
+
messageId: generateMessageId(),
|
|
566
|
+
tabId: tab.id,
|
|
567
|
+
label: tab.label,
|
|
568
|
+
order: tab.order,
|
|
569
|
+
emptyState: tab.emptyState,
|
|
570
|
+
subscriptionId
|
|
571
|
+
};
|
|
572
|
+
try {
|
|
573
|
+
const response = await sendMessage(registerMessage);
|
|
574
|
+
if (!response.isOk) {
|
|
575
|
+
removeSubscriptionHandlers(subscriptionId);
|
|
576
|
+
tabIdToSubscriptionId.delete(tab.id);
|
|
577
|
+
return {
|
|
578
|
+
isOk: false,
|
|
579
|
+
error: response.error
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
return {
|
|
583
|
+
isOk: true,
|
|
584
|
+
result: void 0
|
|
585
|
+
};
|
|
586
|
+
} catch {
|
|
587
|
+
removeSubscriptionHandlers(subscriptionId);
|
|
588
|
+
tabIdToSubscriptionId.delete(tab.id);
|
|
589
|
+
return {
|
|
590
|
+
isOk: false,
|
|
591
|
+
error: {
|
|
592
|
+
message: "Failed to register upload browser",
|
|
593
|
+
name: "SdkInternalError"
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
var sendUnsubscribe = (selectorIds) => {
|
|
602
|
+
const message = {
|
|
603
|
+
command: FROM_EXTENSION_COMMANDS.APP_STATE_UNSUBSCRIBE,
|
|
604
|
+
selectorIds
|
|
605
|
+
};
|
|
606
|
+
postMessageToParent(message);
|
|
607
|
+
};
|
|
608
|
+
var createAppStateBridgeApi = () => {
|
|
609
|
+
const localSubscriptions = /* @__PURE__ */ new Map();
|
|
610
|
+
async function subscribe(paths, callback) {
|
|
611
|
+
if (paths.length === 0) {
|
|
612
|
+
return () => {
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
const values = new Array(paths.length).fill(void 0);
|
|
616
|
+
const selectorIds = [];
|
|
617
|
+
const pathArrays = [];
|
|
618
|
+
for (const dotPath of paths) {
|
|
619
|
+
const segments = dotPath.split(".");
|
|
620
|
+
if (segments.some((s) => s === "")) {
|
|
621
|
+
throw new Error(
|
|
622
|
+
`Invalid app state path: '${dotPath}'. Path must be a non-empty dot-separated string.`
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
selectorIds.push(generateMessageId());
|
|
626
|
+
pathArrays.push(segments);
|
|
627
|
+
}
|
|
628
|
+
const messageId = generateMessageId();
|
|
629
|
+
const subscribeMessage = {
|
|
630
|
+
command: FROM_EXTENSION_COMMANDS.APP_STATE_SUBSCRIBE,
|
|
631
|
+
messageId,
|
|
632
|
+
selectorIds,
|
|
633
|
+
paths: pathArrays
|
|
634
|
+
};
|
|
635
|
+
const response = await sendMessage(subscribeMessage);
|
|
636
|
+
if (!response.isOk) {
|
|
637
|
+
throw new Error(`app-state-subscribe failed: ${response.error.message}`);
|
|
638
|
+
}
|
|
639
|
+
for (let i = 0; i < selectorIds.length; i++) {
|
|
640
|
+
localSubscriptions.set(selectorIds[i], {
|
|
641
|
+
callback: (value) => {
|
|
642
|
+
values[i] = value;
|
|
643
|
+
callback(...values);
|
|
644
|
+
}
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
return () => {
|
|
648
|
+
for (const selectorId of selectorIds) {
|
|
649
|
+
localSubscriptions.delete(selectorId);
|
|
650
|
+
}
|
|
651
|
+
sendUnsubscribe(selectorIds);
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
const dispatch = (updates) => {
|
|
655
|
+
for (const { selectorId, value } of updates) {
|
|
656
|
+
const entry = localSubscriptions.get(selectorId);
|
|
657
|
+
if (entry) {
|
|
658
|
+
entry.callback(value);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
};
|
|
662
|
+
return { subscribe, dispatch };
|
|
663
|
+
};
|
|
664
|
+
|
|
665
|
+
var SandboxedAuthClient = class {
|
|
666
|
+
/**
|
|
667
|
+
* Binds the public start method because the exported SDK API may pass it
|
|
668
|
+
* around without its client object as the receiver.
|
|
669
|
+
*/
|
|
670
|
+
constructor() {
|
|
671
|
+
this.startAuth = this.startAuth.bind(this);
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Starts provider authentication and optionally adds an RFC 7636 PKCE
|
|
675
|
+
* challenge to the request. Successful responses include the verifier that
|
|
676
|
+
* the caller must pass to {@link exchangeCode}.
|
|
677
|
+
*/
|
|
678
|
+
async startAuth(request) {
|
|
679
|
+
const state = generateMessageId();
|
|
680
|
+
let pkceCode = "";
|
|
681
|
+
let code_verifier = "";
|
|
682
|
+
if (request.generatePKCE) {
|
|
683
|
+
code_verifier = this.generatePKCECode();
|
|
684
|
+
pkceCode = await this.hashPKCECode(code_verifier);
|
|
685
|
+
}
|
|
686
|
+
const message = {
|
|
687
|
+
command: FROM_EXTENSION_COMMANDS.AUTH_START,
|
|
688
|
+
messageId: generateMessageId(),
|
|
689
|
+
state,
|
|
690
|
+
provider: request.provider,
|
|
691
|
+
params: {
|
|
692
|
+
...request.params,
|
|
693
|
+
...pkceCode ? {
|
|
694
|
+
code_challenge: pkceCode,
|
|
695
|
+
code_challenge_method: "S256"
|
|
696
|
+
} : {}
|
|
697
|
+
}
|
|
698
|
+
};
|
|
699
|
+
const response = await sendMessage(message);
|
|
700
|
+
if (!response.isOk) {
|
|
701
|
+
return response;
|
|
702
|
+
}
|
|
703
|
+
return {
|
|
704
|
+
...response,
|
|
705
|
+
result: {
|
|
706
|
+
...response.result,
|
|
707
|
+
code_verifier
|
|
708
|
+
}
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
/** Exchanges the provider authorization code for an auth token. */
|
|
712
|
+
exchangeCode(request) {
|
|
713
|
+
const message = {
|
|
714
|
+
command: FROM_EXTENSION_COMMANDS.AUTH_EXCHANGE,
|
|
715
|
+
messageId: generateMessageId(),
|
|
716
|
+
code: request.code,
|
|
717
|
+
code_verifier: request.code_verifier,
|
|
718
|
+
provider: request.provider,
|
|
719
|
+
params: request.params,
|
|
720
|
+
headers: request.headers
|
|
721
|
+
};
|
|
722
|
+
return sendMessage(message);
|
|
723
|
+
}
|
|
724
|
+
/** Requests the current auth token for a provider. */
|
|
725
|
+
getAuthToken(request) {
|
|
726
|
+
const message = {
|
|
727
|
+
command: FROM_EXTENSION_COMMANDS.AUTH_GET_TOKEN,
|
|
728
|
+
messageId: generateMessageId(),
|
|
729
|
+
provider: request.provider
|
|
730
|
+
};
|
|
731
|
+
return sendMessage(message);
|
|
732
|
+
}
|
|
733
|
+
/** Refreshes the auth token for a provider. */
|
|
734
|
+
refreshToken(request) {
|
|
735
|
+
const message = {
|
|
736
|
+
command: FROM_EXTENSION_COMMANDS.AUTH_REFRESH,
|
|
737
|
+
messageId: generateMessageId(),
|
|
738
|
+
provider: request.provider
|
|
739
|
+
};
|
|
740
|
+
return sendMessage(message);
|
|
741
|
+
}
|
|
742
|
+
/** Logs the current user out of a provider. */
|
|
743
|
+
logout(request) {
|
|
744
|
+
const message = {
|
|
745
|
+
command: FROM_EXTENSION_COMMANDS.AUTH_LOGOUT,
|
|
746
|
+
messageId: generateMessageId(),
|
|
747
|
+
provider: request.provider
|
|
748
|
+
};
|
|
749
|
+
return sendMessage(message);
|
|
750
|
+
}
|
|
751
|
+
/** Requests the authenticated user's user token from the parent window. */
|
|
752
|
+
getUserToken() {
|
|
753
|
+
const message = {
|
|
754
|
+
command: FROM_EXTENSION_COMMANDS.AUTH_GET_USER_TOKEN,
|
|
755
|
+
messageId: generateMessageId()
|
|
756
|
+
};
|
|
757
|
+
return sendMessage(message);
|
|
758
|
+
}
|
|
759
|
+
/** Hashes a PKCE verifier and encodes the SHA-256 digest as Base64URL. */
|
|
760
|
+
async hashPKCECode(input) {
|
|
761
|
+
const subtle = window.crypto?.subtle;
|
|
762
|
+
if (!subtle) {
|
|
763
|
+
throw new Error("Web Crypto SubtleCrypto API not available");
|
|
764
|
+
}
|
|
765
|
+
const textAsBuffer = new TextEncoder().encode(input);
|
|
766
|
+
const hashBuffer = await subtle.digest("SHA-256", textAsBuffer);
|
|
767
|
+
const hashArray = new Uint8Array(hashBuffer);
|
|
768
|
+
const binaryString = String.fromCharCode(...hashArray);
|
|
769
|
+
const base64 = btoa(binaryString);
|
|
770
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
771
|
+
}
|
|
772
|
+
/** Generates a high-entropy RFC 7636-compatible PKCE verifier. */
|
|
773
|
+
generatePKCECode() {
|
|
774
|
+
if (!window.crypto) {
|
|
775
|
+
throw new Error("Crypto API not available");
|
|
776
|
+
}
|
|
777
|
+
const array = new Uint32Array(56);
|
|
778
|
+
window.crypto.getRandomValues(array);
|
|
779
|
+
return Array.from(array, (dec) => `0${dec.toString(16)}`.slice(-2)).join(
|
|
780
|
+
""
|
|
781
|
+
);
|
|
782
|
+
}
|
|
783
|
+
};
|
|
784
|
+
|
|
785
|
+
var createBatchFor = async (apiType) => {
|
|
786
|
+
const response = await sendMessage({
|
|
787
|
+
command: FROM_EXTENSION_COMMANDS.BATCH_CREATE,
|
|
788
|
+
messageId: generateMessageId()
|
|
789
|
+
});
|
|
790
|
+
if (!response.isOk) {
|
|
791
|
+
throw response.error;
|
|
792
|
+
}
|
|
793
|
+
const { batchKey } = response.result;
|
|
794
|
+
const sendDesignCall = (dots, args) => {
|
|
795
|
+
const message = {
|
|
796
|
+
command: FROM_EXTENSION_COMMANDS.SDK_CALL,
|
|
797
|
+
dots: apiType === "project" ? ["design", "api", ...dots] : dots,
|
|
798
|
+
args,
|
|
799
|
+
messageId: generateMessageId(),
|
|
800
|
+
apiType,
|
|
801
|
+
batchKey
|
|
802
|
+
};
|
|
803
|
+
return sendMessage(message);
|
|
804
|
+
};
|
|
805
|
+
const commit = async () => {
|
|
806
|
+
const res = await sendMessage({
|
|
807
|
+
command: FROM_EXTENSION_COMMANDS.BATCH_COMMIT,
|
|
808
|
+
messageId: generateMessageId(),
|
|
809
|
+
batchKey
|
|
810
|
+
});
|
|
811
|
+
if (!res.isOk) {
|
|
812
|
+
throw res.error;
|
|
813
|
+
}
|
|
814
|
+
};
|
|
815
|
+
const buildNode = (pathSegments) => {
|
|
816
|
+
const target = () => {
|
|
817
|
+
};
|
|
818
|
+
return new Proxy(target, {
|
|
819
|
+
get: (_t, prop) => {
|
|
820
|
+
if (typeof prop === "symbol" || prop === "then") return void 0;
|
|
821
|
+
if (prop === "commit") return commit;
|
|
822
|
+
return buildNode([...pathSegments, prop]);
|
|
823
|
+
},
|
|
824
|
+
apply: (_t, _this, args) => {
|
|
825
|
+
return sendDesignCall(pathSegments, args);
|
|
826
|
+
}
|
|
827
|
+
});
|
|
828
|
+
};
|
|
829
|
+
return buildNode([]);
|
|
830
|
+
};
|
|
831
|
+
var createBatch = () => createBatchFor("design");
|
|
832
|
+
var createProjectBatch = () => createBatchFor("project");
|
|
833
|
+
|
|
834
|
+
var createContextBridgeApi = () => {
|
|
835
|
+
const contextProxy = createApiProxy("context");
|
|
836
|
+
const subscriptionCallbacks = /* @__PURE__ */ new Map();
|
|
837
|
+
const dispatch = (message) => {
|
|
838
|
+
const cb = subscriptionCallbacks.get(message.subscriptionId);
|
|
839
|
+
cb?.(message.context);
|
|
840
|
+
};
|
|
841
|
+
const subscribeImpl = async (callback) => {
|
|
842
|
+
const subscriptionId = generateMessageId();
|
|
843
|
+
const messageId = generateMessageId();
|
|
844
|
+
subscriptionCallbacks.set(subscriptionId, callback);
|
|
845
|
+
let response;
|
|
846
|
+
try {
|
|
847
|
+
response = await sendMessage({
|
|
848
|
+
command: FROM_EXTENSION_COMMANDS.CONTEXT_SUBSCRIBE,
|
|
849
|
+
messageId,
|
|
850
|
+
subscriptionId
|
|
851
|
+
});
|
|
852
|
+
} catch (error) {
|
|
853
|
+
subscriptionCallbacks.delete(subscriptionId);
|
|
854
|
+
throw error;
|
|
855
|
+
}
|
|
856
|
+
if (!response.isOk) {
|
|
857
|
+
subscriptionCallbacks.delete(subscriptionId);
|
|
858
|
+
throw new Error(`context-subscribe failed: ${response.error.message}`);
|
|
859
|
+
}
|
|
860
|
+
return () => {
|
|
861
|
+
subscriptionCallbacks.delete(subscriptionId);
|
|
862
|
+
const message = {
|
|
863
|
+
command: FROM_EXTENSION_COMMANDS.CONTEXT_UNSUBSCRIBE,
|
|
864
|
+
subscriptionId
|
|
865
|
+
};
|
|
866
|
+
postMessageToParent(message);
|
|
867
|
+
};
|
|
868
|
+
};
|
|
869
|
+
const api = new Proxy(contextProxy, {
|
|
870
|
+
get(target, prop, receiver) {
|
|
871
|
+
if (prop === "subscribe") {
|
|
872
|
+
return subscribeImpl;
|
|
873
|
+
}
|
|
874
|
+
return Reflect.get(target, prop, receiver);
|
|
875
|
+
}
|
|
876
|
+
});
|
|
877
|
+
return { api, dispatch };
|
|
878
|
+
};
|
|
879
|
+
|
|
880
|
+
var sendUnsubscribe2 = (selectorIds) => {
|
|
881
|
+
const message = {
|
|
882
|
+
command: FROM_EXTENSION_COMMANDS.DESIGN_STATE_UNSUBSCRIBE,
|
|
883
|
+
selectorIds
|
|
884
|
+
};
|
|
885
|
+
postMessageToParent(message);
|
|
886
|
+
};
|
|
887
|
+
var createDesignStateBridgeApi = () => {
|
|
888
|
+
const localSubscriptions = /* @__PURE__ */ new Map();
|
|
889
|
+
async function subscribe(paths, callback) {
|
|
890
|
+
if (paths.length === 0) {
|
|
891
|
+
return () => {
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
const values = new Array(paths.length).fill(void 0);
|
|
895
|
+
const selectorIds = [];
|
|
896
|
+
const pathArrays = [];
|
|
897
|
+
for (const dotPath of paths) {
|
|
898
|
+
const segments = dotPath.split(".");
|
|
899
|
+
if (segments.some((s) => s === "")) {
|
|
900
|
+
throw new Error(
|
|
901
|
+
`Invalid design state path: '${dotPath}'. Path must be a non-empty dot-separated string.`
|
|
902
|
+
);
|
|
903
|
+
}
|
|
904
|
+
selectorIds.push(generateMessageId());
|
|
905
|
+
pathArrays.push(segments);
|
|
906
|
+
}
|
|
907
|
+
const messageId = generateMessageId();
|
|
908
|
+
const subscribeMessage = {
|
|
909
|
+
command: FROM_EXTENSION_COMMANDS.DESIGN_STATE_SUBSCRIBE,
|
|
910
|
+
messageId,
|
|
911
|
+
selectorIds,
|
|
912
|
+
paths: pathArrays
|
|
913
|
+
};
|
|
914
|
+
const response = await sendMessage(subscribeMessage);
|
|
915
|
+
if (!response.isOk) {
|
|
916
|
+
throw new Error(
|
|
917
|
+
`design-state-subscribe failed: ${response.error.message}`
|
|
918
|
+
);
|
|
919
|
+
}
|
|
920
|
+
for (let i = 0; i < selectorIds.length; i++) {
|
|
921
|
+
localSubscriptions.set(selectorIds[i], {
|
|
922
|
+
callback: (value) => {
|
|
923
|
+
values[i] = value;
|
|
924
|
+
callback(...values);
|
|
925
|
+
}
|
|
926
|
+
});
|
|
927
|
+
}
|
|
928
|
+
return () => {
|
|
929
|
+
for (const selectorId of selectorIds) {
|
|
930
|
+
localSubscriptions.delete(selectorId);
|
|
931
|
+
}
|
|
932
|
+
sendUnsubscribe2(selectorIds);
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
const dispatch = (updates) => {
|
|
936
|
+
for (const { selectorId, value } of updates) {
|
|
937
|
+
const entry = localSubscriptions.get(selectorId);
|
|
938
|
+
if (entry) {
|
|
939
|
+
entry.callback(value);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
};
|
|
943
|
+
return { subscribe, dispatch };
|
|
944
|
+
};
|
|
945
|
+
|
|
946
|
+
var createStatelessBridgeApi = () => {
|
|
947
|
+
const subscribers = /* @__PURE__ */ new Map();
|
|
948
|
+
return {
|
|
949
|
+
send: (message) => {
|
|
950
|
+
const messageId = generateMessageId();
|
|
951
|
+
const bridgeMessage = {
|
|
952
|
+
command: FROM_EXTENSION_COMMANDS.STATELESS_SEND,
|
|
953
|
+
messageId,
|
|
954
|
+
type: message.type,
|
|
955
|
+
payload: message.payload
|
|
956
|
+
};
|
|
957
|
+
return sendMessage(bridgeMessage);
|
|
958
|
+
},
|
|
959
|
+
subscribe: async (key, handler) => {
|
|
960
|
+
let handlers = subscribers.get(key);
|
|
961
|
+
if (!handlers) {
|
|
962
|
+
handlers = /* @__PURE__ */ new Set();
|
|
963
|
+
subscribers.set(key, handlers);
|
|
964
|
+
}
|
|
965
|
+
handlers.add(handler);
|
|
966
|
+
const messageId = generateMessageId();
|
|
967
|
+
const subscribeMessage = {
|
|
968
|
+
command: FROM_EXTENSION_COMMANDS.STATELESS_SUBSCRIBE,
|
|
969
|
+
messageId,
|
|
970
|
+
key
|
|
971
|
+
};
|
|
972
|
+
return sendMessage(subscribeMessage);
|
|
973
|
+
},
|
|
974
|
+
unsubscribe: async (key) => {
|
|
975
|
+
subscribers.delete(key);
|
|
976
|
+
const messageId = generateMessageId();
|
|
977
|
+
const unsubscribeMessage = {
|
|
978
|
+
command: FROM_EXTENSION_COMMANDS.STATELESS_UNSUBSCRIBE,
|
|
979
|
+
messageId,
|
|
980
|
+
key
|
|
981
|
+
};
|
|
982
|
+
return sendMessage(unsubscribeMessage);
|
|
983
|
+
},
|
|
984
|
+
dispatch: (type, payload) => {
|
|
985
|
+
const handlers = subscribers.get(type);
|
|
986
|
+
if (handlers) {
|
|
987
|
+
for (const handler of handlers) {
|
|
988
|
+
handler(payload);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
};
|
|
993
|
+
};
|
|
994
|
+
|
|
995
|
+
var statelessApi = createStatelessBridgeApi();
|
|
996
|
+
var designStateApi = createDesignStateBridgeApi();
|
|
997
|
+
var appStateApi = createAppStateBridgeApi();
|
|
998
|
+
var { api: contextApi, dispatch: dispatchContextUpdate } = createContextBridgeApi();
|
|
999
|
+
var authClient = new SandboxedAuthClient();
|
|
1000
|
+
var aiGeneratorBridge = createAIGeneratorBridgeApi();
|
|
1001
|
+
var handleIncomingMessage = (event) => {
|
|
1002
|
+
const parent = window.parent;
|
|
1003
|
+
if (!parent || parent === window) {
|
|
1004
|
+
return;
|
|
1005
|
+
}
|
|
1006
|
+
if (event.source !== parent) {
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
const { data } = event;
|
|
1010
|
+
if (isSDKResponseMessage(data)) {
|
|
1011
|
+
const resolver = pendingRequests.get(data.messageId);
|
|
1012
|
+
if (resolver) {
|
|
1013
|
+
pendingRequests.delete(data.messageId);
|
|
1014
|
+
const response = data.response;
|
|
1015
|
+
resolver.resolve(response);
|
|
1016
|
+
}
|
|
1017
|
+
return;
|
|
1018
|
+
}
|
|
1019
|
+
if (isStatelessPushMessage(data)) {
|
|
1020
|
+
statelessApi.dispatch(data.type, data.payload);
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
1023
|
+
if (isAIGeneratorUpdateMessage(data)) {
|
|
1024
|
+
aiGeneratorBridge.dispatch(data);
|
|
1025
|
+
return;
|
|
1026
|
+
}
|
|
1027
|
+
if (isAIGenerationUpdatePushMessage(data)) {
|
|
1028
|
+
dispatchAIGenerationUpdate(data.subscriptionId, data.update);
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
1031
|
+
if (isDesignStateUpdatePushMessage(data)) {
|
|
1032
|
+
designStateApi.dispatch(data.updates);
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
if (isAppStateUpdatePushMessage(data)) {
|
|
1036
|
+
appStateApi.dispatch(data.updates);
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
1039
|
+
if (isContextUpdatePushMessage(data)) {
|
|
1040
|
+
dispatchContextUpdate(data);
|
|
1041
|
+
return;
|
|
1042
|
+
}
|
|
1043
|
+
if (isFileBrowserFetchContentRequestMessage(data)) {
|
|
1044
|
+
dispatchFileBrowserFetchContentRequest(
|
|
1045
|
+
data.requestId,
|
|
1046
|
+
data.subscriptionId,
|
|
1047
|
+
data.params
|
|
1048
|
+
);
|
|
1049
|
+
}
|
|
1050
|
+
};
|
|
1051
|
+
var projectProxy = createApiProxy("project");
|
|
1052
|
+
var projectApi = {
|
|
1053
|
+
design: {
|
|
1054
|
+
state: {
|
|
1055
|
+
getState: projectProxy.design.state.getState,
|
|
1056
|
+
subscribe: designStateApi.subscribe
|
|
1057
|
+
},
|
|
1058
|
+
api: projectProxy.design.api,
|
|
1059
|
+
createBatch: createProjectBatch
|
|
1060
|
+
},
|
|
1061
|
+
app: {
|
|
1062
|
+
state: {
|
|
1063
|
+
getState: projectProxy.app.state.getState,
|
|
1064
|
+
subscribe: appStateApi.subscribe
|
|
1065
|
+
},
|
|
1066
|
+
api: projectProxy.app.api
|
|
1067
|
+
}
|
|
1068
|
+
};
|
|
1069
|
+
var bridgeHandlers = {
|
|
1070
|
+
aiGenerator: aiGeneratorBridge.api,
|
|
1071
|
+
brandKit: createApiProxy("brandKit"),
|
|
1072
|
+
mockup: createApiProxy("mockup"),
|
|
1073
|
+
ai: createAIApiProxy(),
|
|
1074
|
+
context: contextApi,
|
|
1075
|
+
data: createApiProxy("data"),
|
|
1076
|
+
design: createApiProxy("design"),
|
|
1077
|
+
designStore: designStateApi,
|
|
1078
|
+
appStore: appStateApi,
|
|
1079
|
+
export: createApiProxy("export"),
|
|
1080
|
+
font: createApiProxy("font"),
|
|
1081
|
+
project: projectApi,
|
|
1082
|
+
state: createApiProxy("state"),
|
|
1083
|
+
upload: createApiProxy("upload"),
|
|
1084
|
+
fileBrowser: { getFiles: createApiProxy("fileBrowser").getFiles },
|
|
1085
|
+
fileBrowserRegistration: createFileBrowserApiProxy(),
|
|
1086
|
+
openMicroEditor: createApiProxy("openMicroEditor"),
|
|
1087
|
+
openMainEditor: createApiProxy("openMainEditor"),
|
|
1088
|
+
auth: authClient,
|
|
1089
|
+
stateless: statelessApi,
|
|
1090
|
+
createBatch,
|
|
1091
|
+
createProjectBatch
|
|
1092
|
+
};
|
|
1093
|
+
|
|
1094
|
+
// src/api/utils.ts
|
|
1095
|
+
function unwrapResult(result) {
|
|
1096
|
+
if (result.isOk) {
|
|
1097
|
+
return result.result;
|
|
1098
|
+
}
|
|
1099
|
+
throw result.error;
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
// package.json
|
|
1103
|
+
var version = "1.0.0";
|
|
1104
|
+
|
|
1105
|
+
// src/utils/syncHtmlDataThemeFromHostContext.ts
|
|
1106
|
+
async function syncHtmlDataThemeFromHostContext(kittl2) {
|
|
1107
|
+
if (typeof document === "undefined") {
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
const parent = window.parent;
|
|
1111
|
+
if (!parent || parent === window) {
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
const contextResponse = await kittl2.context.get();
|
|
1115
|
+
if (contextResponse.isOk) {
|
|
1116
|
+
document.documentElement.dataset.theme = contextResponse.result.colorScheme;
|
|
1117
|
+
}
|
|
1118
|
+
await kittl2.context.subscribe((ctx) => {
|
|
1119
|
+
document.documentElement.dataset.theme = ctx.colorScheme;
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
// src/createKittlSDK.ts
|
|
1124
|
+
function createKittlSDK(apis) {
|
|
1125
|
+
const kittl2 = {
|
|
1126
|
+
onLoadedCallback: null,
|
|
1127
|
+
loaded: false,
|
|
1128
|
+
onReady: (callback) => {
|
|
1129
|
+
if (kittl2.loaded) {
|
|
1130
|
+
callback();
|
|
1131
|
+
return;
|
|
1132
|
+
}
|
|
1133
|
+
kittl2.onLoadedCallback = callback;
|
|
1134
|
+
},
|
|
1135
|
+
...apis
|
|
1136
|
+
};
|
|
1137
|
+
const initSdk = () => {
|
|
1138
|
+
kittl2.loaded = true;
|
|
1139
|
+
window.addEventListener(
|
|
1140
|
+
"message",
|
|
1141
|
+
(event) => {
|
|
1142
|
+
handleIncomingMessage(event);
|
|
1143
|
+
}
|
|
1144
|
+
);
|
|
1145
|
+
const { context } = apis;
|
|
1146
|
+
const themeSynced = context?.get && context.subscribe ? syncHtmlDataThemeFromHostContext({
|
|
1147
|
+
context
|
|
1148
|
+
}) : Promise.resolve();
|
|
1149
|
+
void themeSynced.catch(() => void 0).then(() => {
|
|
1150
|
+
kittl2.onLoadedCallback?.();
|
|
1151
|
+
sendLoaded();
|
|
1152
|
+
});
|
|
1153
|
+
};
|
|
1154
|
+
if (typeof document !== "undefined" && typeof window !== "undefined") {
|
|
1155
|
+
setSDKVersion(version);
|
|
1156
|
+
window.kittl = kittl2;
|
|
1157
|
+
if (document.readyState === "loading") {
|
|
1158
|
+
document.addEventListener("DOMContentLoaded", initSdk);
|
|
1159
|
+
} else {
|
|
1160
|
+
initSdk();
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
return kittl2;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
// src/dashboardStandalonePage.ts
|
|
1167
|
+
var kittl = createKittlSDK({
|
|
1168
|
+
auth: bridgeHandlers.auth,
|
|
1169
|
+
context: bridgeHandlers.context,
|
|
1170
|
+
upload: bridgeHandlers.upload,
|
|
1171
|
+
brandKit: bridgeHandlers.brandKit,
|
|
1172
|
+
openMicroEditor: bridgeHandlers.openMicroEditor,
|
|
1173
|
+
openMainEditor: bridgeHandlers.openMainEditor,
|
|
1174
|
+
fileBrowser: bridgeHandlers.fileBrowser
|
|
1175
|
+
});
|
|
1176
|
+
})();
|