@shadowob/sdk 1.1.7 → 1.1.9

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/index.js CHANGED
@@ -1,3 +1,33 @@
1
+ import {
2
+ ShadowBridge
3
+ } from "./chunk-5QQ7ZR6B.js";
4
+ import {
5
+ SHADOW_SERVER_APP_COMMAND_COMPLETED_EVENT,
6
+ SHADOW_SERVER_APP_COMMAND_EVENTS,
7
+ SHADOW_SERVER_APP_COMMAND_FAILED_EVENT,
8
+ SHADOW_SERVER_APP_PROTOCOL,
9
+ ShadowServerAppCommandError,
10
+ ShadowServerAppOutbox,
11
+ ShadowServerAppRuntime,
12
+ buildShadowServerAppInboxDelivery,
13
+ buildShadowServerAppInboxTaskRequest,
14
+ createShadowServerAppManifest,
15
+ defineShadowServerApp,
16
+ extractShadowServerAppBearerToken,
17
+ getShadowServerAppChannelMessageDeliveries,
18
+ getShadowServerAppChannelMessageErrors,
19
+ getShadowServerAppTaskCardId,
20
+ introspectShadowServerAppToken,
21
+ normalizeShadowServerAppCommandInput,
22
+ parseShadowServerAppCommandRequest,
23
+ shadowServerAppActorAvatarUrl,
24
+ shadowServerAppActorDisplayName,
25
+ shadowServerAppActorRef,
26
+ shadowServerAppError,
27
+ shadowServerAppInboxTaskEndpoint,
28
+ validateShadowServerAppJsonSchema
29
+ } from "./chunk-OMTGSMTQ.js";
30
+
1
31
  // src/client.ts
2
32
  function sanitizeErrorBody(body) {
3
33
  if (!body) return "(empty response)";
@@ -28,6 +58,9 @@ var ShadowClient = class {
28
58
  this.baseUrl = baseUrl.replace(/\/api\/?$/, "");
29
59
  }
30
60
  baseUrl;
61
+ serverAppEventStreamUrl(eventStreamPath) {
62
+ return new URL(eventStreamPath, `${this.baseUrl}/`).toString();
63
+ }
31
64
  isShadowPrivateMediaUrl(value) {
32
65
  if (value.startsWith("/shadow/uploads/") || value.startsWith("/api/media/signed/")) {
33
66
  return true;
@@ -118,6 +151,18 @@ var ShadowClient = class {
118
151
  body: JSON.stringify(data)
119
152
  });
120
153
  }
154
+ async startPasswordReset(data) {
155
+ return this.request("/api/auth/password-reset/start", {
156
+ method: "POST",
157
+ body: JSON.stringify(data)
158
+ });
159
+ }
160
+ async completePasswordReset(data) {
161
+ return this.request("/api/auth/password-reset/complete", {
162
+ method: "POST",
163
+ body: JSON.stringify(data)
164
+ });
165
+ }
121
166
  async refreshToken(refreshToken) {
122
167
  return this.request("/api/auth/refresh", {
123
168
  method: "POST",
@@ -203,6 +248,27 @@ var ShadowClient = class {
203
248
  async generateAgentToken(agentId) {
204
249
  return this.request(`/api/agents/${agentId}/token`, { method: "POST" });
205
250
  }
251
+ async listConnectorComputers() {
252
+ return this.request("/api/connector/computers");
253
+ }
254
+ async createConnectorBootstrap(data) {
255
+ return this.request("/api/connector/computers/bootstrap", {
256
+ method: "POST",
257
+ body: JSON.stringify(data)
258
+ });
259
+ }
260
+ async createAgentOnConnectorComputer(computerId, data) {
261
+ return this.request(`/api/connector/computers/${computerId}/buddies`, {
262
+ method: "POST",
263
+ body: JSON.stringify(data)
264
+ });
265
+ }
266
+ async configureAgentOnConnectorComputer(computerId, agentId, data) {
267
+ return this.request(`/api/connector/computers/${computerId}/buddies/${agentId}/configure`, {
268
+ method: "POST",
269
+ body: JSON.stringify(data)
270
+ });
271
+ }
206
272
  async startAgent(agentId) {
207
273
  return this.request(`/api/agents/${agentId}/start`, { method: "POST" });
208
274
  }
@@ -248,6 +314,7 @@ var ShadowClient = class {
248
314
  const policy = {
249
315
  serverId,
250
316
  ...data.channelId !== void 0 ? { channelId: data.channelId } : {},
317
+ ...data.listen !== void 0 ? { listen: data.listen } : {},
251
318
  ...data.mentionOnly !== void 0 ? { mentionOnly: data.mentionOnly } : {},
252
319
  ...data.reply !== void 0 ? { reply: data.reply } : {},
253
320
  ...data.config !== void 0 ? { config: data.config } : {}
@@ -404,6 +471,7 @@ var ShadowClient = class {
404
471
  const form = new FormData();
405
472
  form.set("input", JSON.stringify(data.input ?? {}));
406
473
  if (data.channelId) form.set("channelId", data.channelId);
474
+ if (data.task) form.set("task", JSON.stringify(data.task));
407
475
  form.set(data.field ?? "file", data.file, data.filename);
408
476
  return this.request(
409
477
  `/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(appKey)}/commands/${encodeURIComponent(
@@ -626,6 +694,83 @@ var ShadowClient = class {
626
694
  async getMessage(messageId) {
627
695
  return this.request(`/api/messages/${messageId}`);
628
696
  }
697
+ async listBuddyInboxes() {
698
+ return this.request("/api/buddy-inboxes");
699
+ }
700
+ async listServerBuddyInboxes(serverIdOrSlug) {
701
+ return this.request(`/api/servers/${serverIdOrSlug}/inboxes`);
702
+ }
703
+ async ensureBuddyInbox(serverIdOrSlug, agentId) {
704
+ return this.request(`/api/servers/${serverIdOrSlug}/inboxes/${agentId}`, {
705
+ method: "POST"
706
+ });
707
+ }
708
+ async getBuddyInboxAdmissionPolicy(serverIdOrSlug, agentId) {
709
+ return this.request(`/api/servers/${serverIdOrSlug}/inboxes/${agentId}/admission-policy`);
710
+ }
711
+ async updateBuddyInboxAdmissionPolicy(serverIdOrSlug, agentId, policy) {
712
+ return this.request(`/api/servers/${serverIdOrSlug}/inboxes/${agentId}/admission-policy`, {
713
+ method: "PUT",
714
+ body: JSON.stringify(policy)
715
+ });
716
+ }
717
+ async listBuddyInboxAdmissionPending(serverIdOrSlug, agentId) {
718
+ return this.request(`/api/servers/${serverIdOrSlug}/inboxes/${agentId}/admission-pending`);
719
+ }
720
+ async approveBuddyInboxAdmissionPending(serverIdOrSlug, agentId, pendingId) {
721
+ return this.request(
722
+ `/api/servers/${serverIdOrSlug}/inboxes/${agentId}/admission-pending/${pendingId}/approve`,
723
+ { method: "POST" }
724
+ );
725
+ }
726
+ async rejectBuddyInboxAdmissionPending(serverIdOrSlug, agentId, pendingId) {
727
+ return this.request(
728
+ `/api/servers/${serverIdOrSlug}/inboxes/${agentId}/admission-pending/${pendingId}/reject`,
729
+ { method: "POST" }
730
+ );
731
+ }
732
+ async enqueueInboxTaskForAgent(serverIdOrSlug, agentId, task) {
733
+ return this.request(`/api/servers/${serverIdOrSlug}/inboxes/${agentId}/tasks`, {
734
+ method: "POST",
735
+ body: JSON.stringify(task)
736
+ });
737
+ }
738
+ async enqueueInboxTask(channelId, task) {
739
+ return this.request(`/api/channels/${channelId}/inbox/tasks`, {
740
+ method: "POST",
741
+ body: JSON.stringify(task)
742
+ });
743
+ }
744
+ async claimTaskCard(messageId, cardId, data = {}) {
745
+ return this.request(`/api/messages/${messageId}/cards/${cardId}/claim`, {
746
+ method: "POST",
747
+ body: JSON.stringify(data)
748
+ });
749
+ }
750
+ async updateTaskCard(messageId, cardId, data) {
751
+ return this.request(`/api/messages/${messageId}/cards/${cardId}`, {
752
+ method: "PATCH",
753
+ body: JSON.stringify(data)
754
+ });
755
+ }
756
+ async retryTaskCard(messageId, cardId, data = {}) {
757
+ return this.request(`/api/messages/${messageId}/cards/${cardId}/retry`, {
758
+ method: "POST",
759
+ body: JSON.stringify(data)
760
+ });
761
+ }
762
+ async claimNextInboxTask(serverIdOrSlug, agentId, data = {}) {
763
+ return this.request(`/api/servers/${serverIdOrSlug}/inboxes/${agentId}/claim-next`, {
764
+ method: "POST",
765
+ body: JSON.stringify(data)
766
+ });
767
+ }
768
+ async promoteMessageToInboxTask(messageId, data) {
769
+ return this.request(`/api/messages/${messageId}/inbox/tasks`, {
770
+ method: "POST",
771
+ body: JSON.stringify(data)
772
+ });
773
+ }
629
774
  async submitInteractiveAction(messageId, input) {
630
775
  return this.request(`/api/messages/${messageId}/interactive`, {
631
776
  method: "POST",
@@ -777,6 +922,19 @@ var ShadowClient = class {
777
922
  formData.append("messageId", messageId);
778
923
  } else if (messageId) {
779
924
  if (messageId.messageId) formData.append("messageId", messageId.messageId);
925
+ if (messageId.kind) formData.append("kind", messageId.kind);
926
+ if (typeof messageId.durationMs === "number") {
927
+ formData.append("durationMs", String(messageId.durationMs));
928
+ }
929
+ if (messageId.waveformPeaks) {
930
+ formData.append("waveformPeaks", JSON.stringify(messageId.waveformPeaks));
931
+ }
932
+ if (messageId.transcriptText) formData.append("transcriptText", messageId.transcriptText);
933
+ if (messageId.transcriptLanguage) {
934
+ formData.append("transcriptLanguage", messageId.transcriptLanguage);
935
+ }
936
+ if (messageId.transcriptSource)
937
+ formData.append("transcriptSource", messageId.transcriptSource);
780
938
  }
781
939
  const url = `${this.baseUrl}/api/media/upload`;
782
940
  const res = await fetch(url, {
@@ -792,6 +950,43 @@ var ShadowClient = class {
792
950
  }
793
951
  return res.json();
794
952
  }
953
+ async sendVoiceMessage(channelId, file, filename, contentType, opts) {
954
+ const message = await this.sendMessage(channelId, "\u200B", {
955
+ threadId: opts.threadId,
956
+ replyToId: opts.replyToId
957
+ });
958
+ await this.uploadMedia(file, filename, contentType, {
959
+ messageId: message.id,
960
+ kind: "voice",
961
+ durationMs: opts.durationMs,
962
+ waveformPeaks: opts.waveformPeaks,
963
+ transcriptText: opts.transcriptText,
964
+ transcriptLanguage: opts.transcriptLanguage,
965
+ transcriptSource: opts.transcriptSource
966
+ });
967
+ return this.getMessage(message.id);
968
+ }
969
+ async markVoicePlayed(attachmentId, input) {
970
+ return this.request(`/api/attachments/${attachmentId}/voice-playback`, {
971
+ method: "PUT",
972
+ body: JSON.stringify(input ?? {})
973
+ });
974
+ }
975
+ async requestVoiceTranscript(attachmentId, input) {
976
+ return this.request(`/api/attachments/${attachmentId}/transcript`, {
977
+ method: "POST",
978
+ body: JSON.stringify({
979
+ mode: "server",
980
+ ...input?.language ? { language: input.language } : {}
981
+ })
982
+ });
983
+ }
984
+ async updateVoiceTranscript(attachmentId, input) {
985
+ return this.request(`/api/attachments/${attachmentId}/transcript`, {
986
+ method: "PUT",
987
+ body: JSON.stringify(input)
988
+ });
989
+ }
795
990
  async resolveAttachmentMediaUrl(attachmentId, options) {
796
991
  const params = new URLSearchParams();
797
992
  params.set("disposition", options?.disposition ?? "inline");
@@ -1047,9 +1242,14 @@ var ShadowClient = class {
1047
1242
  return this.request(`/api/auth/sessions/${sessionId}`, { method: "DELETE" });
1048
1243
  }
1049
1244
  async changePassword(data) {
1245
+ const oldPassword = data.oldPassword ?? data.currentPassword;
1050
1246
  return this.request("/api/auth/password", {
1051
1247
  method: "PUT",
1052
- body: JSON.stringify(data)
1248
+ body: JSON.stringify({
1249
+ oldPassword,
1250
+ newPassword: data.newPassword,
1251
+ confirmPassword: data.confirmPassword ?? data.newPassword
1252
+ })
1053
1253
  });
1054
1254
  }
1055
1255
  async getDashboard() {
@@ -1058,7 +1258,13 @@ var ShadowClient = class {
1058
1258
  async loginWithGoogleIdToken(idToken) {
1059
1259
  return this.request("/api/auth/google/id-token", {
1060
1260
  method: "POST",
1061
- body: JSON.stringify({ idToken })
1261
+ body: JSON.stringify({ credential: idToken })
1262
+ });
1263
+ }
1264
+ async loginWithAppleIdentityToken(data) {
1265
+ return this.request("/api/auth/oauth/apple/mobile", {
1266
+ method: "POST",
1267
+ body: JSON.stringify(data)
1062
1268
  });
1063
1269
  }
1064
1270
  // ── Friendships ───────────────────────────────────────────────────────
@@ -1807,6 +2013,24 @@ var ShadowClient = class {
1807
2013
  const suffix = qs.toString();
1808
2014
  return this.request(`/api/discover/business${suffix ? `?${suffix}` : ""}`);
1809
2015
  }
2016
+ async discoverMarketplaceProducts(params) {
2017
+ const qs = new URLSearchParams();
2018
+ if (params?.q) qs.set("q", params.q);
2019
+ if (params?.tag) qs.set("tag", params.tag);
2020
+ if (params?.category) qs.set("category", params.category);
2021
+ if (params?.scope) qs.set("scope", params.scope);
2022
+ if (params?.limit) qs.set("limit", String(params.limit));
2023
+ if (params?.offset) qs.set("offset", String(params.offset));
2024
+ const suffix = qs.toString();
2025
+ return this.request(`/api/discover/marketplace/products${suffix ? `?${suffix}` : ""}`);
2026
+ }
2027
+ async discoverMarketplaceCategories(params) {
2028
+ const qs = new URLSearchParams();
2029
+ if (params?.q) qs.set("q", params.q);
2030
+ if (params?.limit) qs.set("limit", String(params.limit));
2031
+ const suffix = qs.toString();
2032
+ return this.request(`/api/discover/marketplace/categories${suffix ? `?${suffix}` : ""}`);
2033
+ }
1810
2034
  async discoverBusinessHub(params) {
1811
2035
  return this.discoverCommerce(params);
1812
2036
  }
@@ -2273,10 +2497,35 @@ var ShadowVoiceConsumer = class {
2273
2497
  export {
2274
2498
  CLIENT_EVENTS,
2275
2499
  SERVER_EVENTS,
2500
+ SHADOW_SERVER_APP_COMMAND_COMPLETED_EVENT,
2501
+ SHADOW_SERVER_APP_COMMAND_EVENTS,
2502
+ SHADOW_SERVER_APP_COMMAND_FAILED_EVENT,
2503
+ SHADOW_SERVER_APP_PROTOCOL,
2504
+ ShadowBridge,
2276
2505
  ShadowClient,
2506
+ ShadowServerAppCommandError,
2507
+ ShadowServerAppOutbox,
2508
+ ShadowServerAppRuntime,
2277
2509
  ShadowSocket,
2278
2510
  ShadowVoiceConsumer,
2511
+ buildShadowServerAppInboxDelivery,
2512
+ buildShadowServerAppInboxTaskRequest,
2279
2513
  channelRoom,
2514
+ createShadowServerAppManifest,
2515
+ defineShadowServerApp,
2516
+ extractShadowServerAppBearerToken,
2517
+ getShadowServerAppChannelMessageDeliveries,
2518
+ getShadowServerAppChannelMessageErrors,
2519
+ getShadowServerAppTaskCardId,
2520
+ introspectShadowServerAppToken,
2521
+ normalizeShadowServerAppCommandInput,
2522
+ parseShadowServerAppCommandRequest,
2523
+ shadowServerAppActorAvatarUrl,
2524
+ shadowServerAppActorDisplayName,
2525
+ shadowServerAppActorRef,
2526
+ shadowServerAppError,
2527
+ shadowServerAppInboxTaskEndpoint,
2280
2528
  threadRoom,
2281
- userRoom
2529
+ userRoom,
2530
+ validateShadowServerAppJsonSchema
2282
2531
  };
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/server-app-node.ts
21
+ var server_app_node_exports = {};
22
+ __export(server_app_node_exports, {
23
+ ShadowServerAppJsonStore: () => ShadowServerAppJsonStore,
24
+ createShadowServerAppJsonStore: () => createShadowServerAppJsonStore
25
+ });
26
+ module.exports = __toCommonJS(server_app_node_exports);
27
+ var import_node_fs = require("fs");
28
+ var import_node_path = require("path");
29
+ var ShadowServerAppJsonStore = class {
30
+ constructor(options) {
31
+ this.options = options;
32
+ }
33
+ read() {
34
+ if (!(0, import_node_fs.existsSync)(this.options.filePath)) {
35
+ const value = this.defaultValue();
36
+ if (this.options.persistDefault !== false) this.write(value);
37
+ return value;
38
+ }
39
+ try {
40
+ const parsed = JSON.parse((0, import_node_fs.readFileSync)(this.options.filePath, "utf8"));
41
+ if (this.options.validate && !this.options.validate(parsed)) return this.defaultValue();
42
+ return this.normalize(parsed);
43
+ } catch {
44
+ return this.defaultValue();
45
+ }
46
+ }
47
+ write(value) {
48
+ const normalized = this.normalize(value);
49
+ (0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(this.options.filePath), { recursive: true });
50
+ const tempPath = `${this.options.filePath}.${process.pid}.${Date.now()}.tmp`;
51
+ (0, import_node_fs.writeFileSync)(tempPath, `${JSON.stringify(normalized, null, 2)}
52
+ `);
53
+ (0, import_node_fs.renameSync)(tempPath, this.options.filePath);
54
+ return normalized;
55
+ }
56
+ update(mutator) {
57
+ const current = this.clone(this.read());
58
+ const next = mutator(current) ?? current;
59
+ return this.write(next);
60
+ }
61
+ reset(nextValue) {
62
+ return this.write(nextValue ?? this.defaultValue());
63
+ }
64
+ defaultValue() {
65
+ const value = typeof this.options.defaultValue === "function" ? this.options.defaultValue() : this.options.defaultValue;
66
+ return this.normalize(this.clone(value));
67
+ }
68
+ normalize(value) {
69
+ return this.options.normalize ? this.options.normalize(value) : value;
70
+ }
71
+ clone(value) {
72
+ return structuredClone(value);
73
+ }
74
+ };
75
+ function createShadowServerAppJsonStore(options) {
76
+ return new ShadowServerAppJsonStore(options);
77
+ }
78
+ // Annotate the CommonJS export names for ESM import in node:
79
+ 0 && (module.exports = {
80
+ ShadowServerAppJsonStore,
81
+ createShadowServerAppJsonStore
82
+ });
@@ -0,0 +1,21 @@
1
+ interface ShadowServerAppJsonStoreOptions<T> {
2
+ filePath: string;
3
+ defaultValue: T | (() => T);
4
+ validate?: (value: unknown) => value is T;
5
+ normalize?: (value: T) => T;
6
+ persistDefault?: boolean;
7
+ }
8
+ declare class ShadowServerAppJsonStore<T> {
9
+ private readonly options;
10
+ constructor(options: ShadowServerAppJsonStoreOptions<T>);
11
+ read(): T;
12
+ write(value: T): T;
13
+ update(mutator: (value: T) => T | void): T;
14
+ reset(nextValue?: T): T;
15
+ private defaultValue;
16
+ private normalize;
17
+ private clone;
18
+ }
19
+ declare function createShadowServerAppJsonStore<T>(options: ShadowServerAppJsonStoreOptions<T>): ShadowServerAppJsonStore<T>;
20
+
21
+ export { ShadowServerAppJsonStore, type ShadowServerAppJsonStoreOptions, createShadowServerAppJsonStore };
@@ -0,0 +1,21 @@
1
+ interface ShadowServerAppJsonStoreOptions<T> {
2
+ filePath: string;
3
+ defaultValue: T | (() => T);
4
+ validate?: (value: unknown) => value is T;
5
+ normalize?: (value: T) => T;
6
+ persistDefault?: boolean;
7
+ }
8
+ declare class ShadowServerAppJsonStore<T> {
9
+ private readonly options;
10
+ constructor(options: ShadowServerAppJsonStoreOptions<T>);
11
+ read(): T;
12
+ write(value: T): T;
13
+ update(mutator: (value: T) => T | void): T;
14
+ reset(nextValue?: T): T;
15
+ private defaultValue;
16
+ private normalize;
17
+ private clone;
18
+ }
19
+ declare function createShadowServerAppJsonStore<T>(options: ShadowServerAppJsonStoreOptions<T>): ShadowServerAppJsonStore<T>;
20
+
21
+ export { ShadowServerAppJsonStore, type ShadowServerAppJsonStoreOptions, createShadowServerAppJsonStore };
@@ -0,0 +1,56 @@
1
+ // src/server-app-node.ts
2
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "fs";
3
+ import { dirname } from "path";
4
+ var ShadowServerAppJsonStore = class {
5
+ constructor(options) {
6
+ this.options = options;
7
+ }
8
+ read() {
9
+ if (!existsSync(this.options.filePath)) {
10
+ const value = this.defaultValue();
11
+ if (this.options.persistDefault !== false) this.write(value);
12
+ return value;
13
+ }
14
+ try {
15
+ const parsed = JSON.parse(readFileSync(this.options.filePath, "utf8"));
16
+ if (this.options.validate && !this.options.validate(parsed)) return this.defaultValue();
17
+ return this.normalize(parsed);
18
+ } catch {
19
+ return this.defaultValue();
20
+ }
21
+ }
22
+ write(value) {
23
+ const normalized = this.normalize(value);
24
+ mkdirSync(dirname(this.options.filePath), { recursive: true });
25
+ const tempPath = `${this.options.filePath}.${process.pid}.${Date.now()}.tmp`;
26
+ writeFileSync(tempPath, `${JSON.stringify(normalized, null, 2)}
27
+ `);
28
+ renameSync(tempPath, this.options.filePath);
29
+ return normalized;
30
+ }
31
+ update(mutator) {
32
+ const current = this.clone(this.read());
33
+ const next = mutator(current) ?? current;
34
+ return this.write(next);
35
+ }
36
+ reset(nextValue) {
37
+ return this.write(nextValue ?? this.defaultValue());
38
+ }
39
+ defaultValue() {
40
+ const value = typeof this.options.defaultValue === "function" ? this.options.defaultValue() : this.options.defaultValue;
41
+ return this.normalize(this.clone(value));
42
+ }
43
+ normalize(value) {
44
+ return this.options.normalize ? this.options.normalize(value) : value;
45
+ }
46
+ clone(value) {
47
+ return structuredClone(value);
48
+ }
49
+ };
50
+ function createShadowServerAppJsonStore(options) {
51
+ return new ShadowServerAppJsonStore(options);
52
+ }
53
+ export {
54
+ ShadowServerAppJsonStore,
55
+ createShadowServerAppJsonStore
56
+ };