@joai/sdk 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +114 -3
- package/dist/index.mjs +161 -5
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -360,6 +360,7 @@ type Blueprint = {
|
|
|
360
360
|
description: string | null;
|
|
361
361
|
avatar: string | null;
|
|
362
362
|
settings: BlueprintSettings;
|
|
363
|
+
documentCount: number;
|
|
363
364
|
verified: boolean;
|
|
364
365
|
createdAt: string;
|
|
365
366
|
locales: WarpLocale[];
|
|
@@ -489,6 +490,7 @@ type Contact = {
|
|
|
489
490
|
socials: Record<string, string> | null;
|
|
490
491
|
notes: string | null;
|
|
491
492
|
tags: string[] | null;
|
|
493
|
+
userId: string | null;
|
|
492
494
|
props?: Record<string, string> | null;
|
|
493
495
|
};
|
|
494
496
|
type ContactActivity = {
|
|
@@ -611,6 +613,8 @@ type Memory = {
|
|
|
611
613
|
name: string;
|
|
612
614
|
content: string;
|
|
613
615
|
createdAt: string;
|
|
616
|
+
contactId: string | null;
|
|
617
|
+
roomId: string | null;
|
|
614
618
|
}; //#endregion
|
|
615
619
|
//#region src/peerme/types.d.ts
|
|
616
620
|
type ChatClientAction = 'AGENT_DELEGATE' | 'WARP_EXECUTE' | 'WARP_VIEW' | 'WARP_CREATE' | 'WARP_TEST' | 'WARP_INPUT' | 'WARP_APPROVE' | 'WARP_SELECT' | 'WARP_BATCH' | 'WARP_BULK' | 'ENTITY_PROPOSE' | 'ENTITY_SIGN' | 'SECRET_SET' | 'SECRET_AUTHORIZE' | 'HEALTH_QUERY' | 'HEALTH_WRITE' | 'ITEM_VIEW' | 'BOARD_SUMMARY' | 'GOAL_PROGRESS' | 'CONTACT_VIEW' | 'MARKETPLACE_PURCHASE' | 'WARP_CLOUD_EXECUTE' | 'MISSION_VIEW' | 'ACTIVITY' | 'PERSONA_QUESTION' | 'NFC_WRITE' | 'twilio.sms';
|
|
@@ -698,6 +702,52 @@ type BrandSiteConfig = {
|
|
|
698
702
|
logoUrl?: string | null;
|
|
699
703
|
};
|
|
700
704
|
//#endregion
|
|
705
|
+
//#region src/store/types.d.ts
|
|
706
|
+
type StoreVisibility = 'private' | 'team' | 'public';
|
|
707
|
+
type StoreEntry = {
|
|
708
|
+
value: number | string | boolean;
|
|
709
|
+
label?: string;
|
|
710
|
+
at: string;
|
|
711
|
+
};
|
|
712
|
+
type Store = {
|
|
713
|
+
name: string;
|
|
714
|
+
description: string;
|
|
715
|
+
valueType: 'scalar' | 'series';
|
|
716
|
+
unit?: string;
|
|
717
|
+
visibility: StoreVisibility;
|
|
718
|
+
entryCount: number;
|
|
719
|
+
lastValue?: number | string | boolean;
|
|
720
|
+
lastAt?: string;
|
|
721
|
+
};
|
|
722
|
+
type StoreWithEntries = {
|
|
723
|
+
name: string;
|
|
724
|
+
description: string;
|
|
725
|
+
unit?: string;
|
|
726
|
+
entries: StoreEntry[];
|
|
727
|
+
};
|
|
728
|
+
type StoreCreatePayload = {
|
|
729
|
+
name: string;
|
|
730
|
+
description?: string;
|
|
731
|
+
valueType?: 'scalar' | 'series';
|
|
732
|
+
unit?: string;
|
|
733
|
+
visibility?: StoreVisibility;
|
|
734
|
+
};
|
|
735
|
+
type StoreEntryPayload = {
|
|
736
|
+
storeName?: string;
|
|
737
|
+
value: number | string | boolean;
|
|
738
|
+
label?: string;
|
|
739
|
+
};
|
|
740
|
+
type StoreEntryResult = {
|
|
741
|
+
name: string;
|
|
742
|
+
entryCount: number;
|
|
743
|
+
};
|
|
744
|
+
type StoreToggleResult = {
|
|
745
|
+
name: string;
|
|
746
|
+
value: number | string | boolean;
|
|
747
|
+
previous: number | string | boolean;
|
|
748
|
+
}; //#endregion
|
|
749
|
+
//#region src/swarm/types.d.ts
|
|
750
|
+
//#endregion
|
|
701
751
|
//#region src/resources/agents.d.ts
|
|
702
752
|
declare class AgentsResource {
|
|
703
753
|
private readonly http;
|
|
@@ -798,10 +848,18 @@ declare class ContactsResource {
|
|
|
798
848
|
declare class DocumentsResource {
|
|
799
849
|
private readonly http;
|
|
800
850
|
constructor(http: IHttpService);
|
|
801
|
-
|
|
851
|
+
list(agent: string, search?: string): Promise<IAppResponse<Document[]>>;
|
|
852
|
+
create(agent: string, data: {
|
|
802
853
|
title: string;
|
|
803
854
|
content: string;
|
|
855
|
+
blueprint?: string;
|
|
856
|
+
}): Promise<IAppResponse<Document>>;
|
|
857
|
+
get(id: string): Promise<IAppResponse<Document>>;
|
|
858
|
+
update(id: string, data: {
|
|
859
|
+
title?: string;
|
|
860
|
+
content?: string;
|
|
804
861
|
}): Promise<IAppResponse<Document>>;
|
|
862
|
+
delete(id: string): Promise<IAppResponse<unknown>>;
|
|
805
863
|
}
|
|
806
864
|
//#endregion
|
|
807
865
|
//#region src/resources/goals.d.ts
|
|
@@ -896,11 +954,12 @@ declare class SitesResource {
|
|
|
896
954
|
private readonly http;
|
|
897
955
|
constructor(http: IHttpService);
|
|
898
956
|
listMine(teamSlug: string): Promise<IAppResponse<Site[]>>;
|
|
899
|
-
resolve(teamSlug: string, brandSlug
|
|
957
|
+
resolve(teamSlug: string, brandSlug?: string): Promise<IAppResponse<Site>>;
|
|
900
958
|
resolveByDomain(domain: string): Promise<IAppResponse<Site>>;
|
|
901
959
|
update(siteSlug: string, data: {
|
|
902
960
|
customDomain?: string | null;
|
|
903
961
|
enabled?: boolean;
|
|
962
|
+
modules?: string[];
|
|
904
963
|
}): Promise<IAppResponse<{
|
|
905
964
|
updated: boolean;
|
|
906
965
|
}>>;
|
|
@@ -917,6 +976,26 @@ declare class TeamsResource {
|
|
|
917
976
|
}): Promise<IAppResponse<unknown>>;
|
|
918
977
|
}
|
|
919
978
|
//#endregion
|
|
979
|
+
//#region src/resources/stores.d.ts
|
|
980
|
+
declare class StoresResource {
|
|
981
|
+
private readonly http;
|
|
982
|
+
constructor(http: IHttpService);
|
|
983
|
+
list(): Promise<IAppResponse<{
|
|
984
|
+
data: Store[];
|
|
985
|
+
}>>;
|
|
986
|
+
create(payload: StoreCreatePayload): Promise<IAppResponse<Store>>;
|
|
987
|
+
entries(params?: {
|
|
988
|
+
storeName?: string;
|
|
989
|
+
since?: string;
|
|
990
|
+
until?: string;
|
|
991
|
+
last?: number;
|
|
992
|
+
}): Promise<IAppResponse<StoreWithEntries>>;
|
|
993
|
+
setEntry(payload: StoreEntryPayload): Promise<IAppResponse<StoreEntryResult>>;
|
|
994
|
+
appendEntry(payload: StoreEntryPayload): Promise<IAppResponse<StoreEntryResult>>;
|
|
995
|
+
toggle(storeName?: string): Promise<IAppResponse<StoreToggleResult>>;
|
|
996
|
+
delete(storeName: string): Promise<IAppResponse<unknown>>;
|
|
997
|
+
}
|
|
998
|
+
//#endregion
|
|
920
999
|
//#region src/resources/warps.d.ts
|
|
921
1000
|
type WarpResponseData = {
|
|
922
1001
|
id: string;
|
|
@@ -944,12 +1023,20 @@ declare class WarpsResource {
|
|
|
944
1023
|
destroy(identifier: string): Promise<IAppResponse<unknown>>;
|
|
945
1024
|
}
|
|
946
1025
|
//#endregion
|
|
1026
|
+
//#region src/cache/types.d.ts
|
|
1027
|
+
interface CacheConfig {
|
|
1028
|
+
enabled?: boolean;
|
|
1029
|
+
defaultTtl?: number;
|
|
1030
|
+
overrides?: Record<string, number>;
|
|
1031
|
+
}
|
|
1032
|
+
//#endregion
|
|
947
1033
|
//#region src/client.d.ts
|
|
948
1034
|
interface JoAiClientConfig {
|
|
949
1035
|
apiToken?: string;
|
|
950
1036
|
team?: string;
|
|
951
1037
|
env?: AppEnv;
|
|
952
1038
|
agentAuthKey?: string;
|
|
1039
|
+
cache?: CacheConfig;
|
|
953
1040
|
}
|
|
954
1041
|
declare class JoAiClient {
|
|
955
1042
|
readonly http: IHttpService;
|
|
@@ -972,16 +1059,40 @@ declare class JoAiClient {
|
|
|
972
1059
|
readonly sites: SitesResource;
|
|
973
1060
|
readonly documents: DocumentsResource;
|
|
974
1061
|
readonly meetings: MeetingsResource;
|
|
1062
|
+
readonly stores: StoresResource;
|
|
975
1063
|
readonly privateWarps: WarpsResource;
|
|
976
1064
|
constructor(config: JoAiClientConfig);
|
|
1065
|
+
clearCache(): void;
|
|
977
1066
|
warps(locale?: WarpLocale): WarpClient;
|
|
978
1067
|
}
|
|
979
1068
|
declare function createClient(config: JoAiClientConfig): JoAiClient;
|
|
980
1069
|
//#endregion
|
|
1070
|
+
//#region src/cache/cached-http.d.ts
|
|
1071
|
+
type TtlMap = Record<string, number>;
|
|
1072
|
+
declare class CachedHttpService implements IHttpService {
|
|
1073
|
+
private inner;
|
|
1074
|
+
readonly baseUrl: string;
|
|
1075
|
+
readonly authToken: string | null;
|
|
1076
|
+
private cache;
|
|
1077
|
+
private ttlMap;
|
|
1078
|
+
private defaultTtl;
|
|
1079
|
+
onNetworkError: (error: Error) => void;
|
|
1080
|
+
onUnauthorized: (response: IAppResponse<any>) => void;
|
|
1081
|
+
onSuccessfulResponse: (response: IAppResponse<any>) => void;
|
|
1082
|
+
onMaintenanceMode: (response: IAppResponse<any>) => void;
|
|
1083
|
+
onTooManyRequests: (response: IAppResponse<any>) => void;
|
|
1084
|
+
constructor(inner: IHttpService, overrides?: TtlMap, defaultTtl?: number);
|
|
1085
|
+
clearCache(): void;
|
|
1086
|
+
get<T>(url: string, options?: IRequestOptions): Promise<IAppResponse<T>>;
|
|
1087
|
+
post<T>(url: string, data?: any, options?: IRequestOptions): Promise<IAppResponse<T>>;
|
|
1088
|
+
put<T>(url: string, data?: any, options?: IRequestOptions): Promise<IAppResponse<T>>;
|
|
1089
|
+
delete<T>(url: string, options?: IRequestOptions): Promise<IAppResponse<T>>;
|
|
1090
|
+
}
|
|
1091
|
+
//#endregion
|
|
981
1092
|
//#region src/resources/distribution.d.ts
|
|
982
1093
|
declare class DistributionResource {
|
|
983
1094
|
getBrandSiteConfig(env: AppEnv, brandSlug: string): Promise<BrandSiteConfig | null>;
|
|
984
1095
|
private fetchDistribution;
|
|
985
1096
|
}
|
|
986
1097
|
//#endregion
|
|
987
|
-
export { BlueprintsResource, DistributionResource, FlowsResource, IngestionsResource, JoAiClient, type JoAiClientConfig, MarketplaceResource, MeetingsResource, ServicesResource, SitesResource, SkillsResource, createClient };
|
|
1098
|
+
export { BlueprintsResource, type CacheConfig, CachedHttpService, DistributionResource, FlowsResource, IngestionsResource, JoAiClient, type JoAiClientConfig, MarketplaceResource, MeetingsResource, ServicesResource, SitesResource, SkillsResource, StoresResource, createClient };
|
package/dist/index.mjs
CHANGED
|
@@ -288,8 +288,22 @@ var DocumentsResource = class {
|
|
|
288
288
|
constructor(http) {
|
|
289
289
|
this.http = http;
|
|
290
290
|
}
|
|
291
|
-
|
|
292
|
-
|
|
291
|
+
list(agent, search) {
|
|
292
|
+
const params = new URLSearchParams();
|
|
293
|
+
if (search) params.set("search", search);
|
|
294
|
+
return this.http.get(`agents/${agent}/documents?${params.toString()}`);
|
|
295
|
+
}
|
|
296
|
+
create(agent, data) {
|
|
297
|
+
return this.http.post(`agents/${agent}/documents`, data);
|
|
298
|
+
}
|
|
299
|
+
get(id) {
|
|
300
|
+
return this.http.get(`documents/${id}`);
|
|
301
|
+
}
|
|
302
|
+
update(id, data) {
|
|
303
|
+
return this.http.put(`documents/${id}`, data);
|
|
304
|
+
}
|
|
305
|
+
delete(id) {
|
|
306
|
+
return this.http.delete(`documents/${id}`);
|
|
293
307
|
}
|
|
294
308
|
};
|
|
295
309
|
//#endregion
|
|
@@ -420,7 +434,8 @@ var SitesResource = class {
|
|
|
420
434
|
return this.http.get(`sites/mine?team=${encodeURIComponent(teamSlug)}`);
|
|
421
435
|
}
|
|
422
436
|
resolve(teamSlug, brandSlug) {
|
|
423
|
-
|
|
437
|
+
const query = brandSlug ? `team=${encodeURIComponent(teamSlug)}&brand=${encodeURIComponent(brandSlug)}` : `team=${encodeURIComponent(teamSlug)}`;
|
|
438
|
+
return this.http.get(`sites/resolve?${query}`);
|
|
424
439
|
}
|
|
425
440
|
resolveByDomain(domain) {
|
|
426
441
|
return this.http.get(`sites/resolve?domain=${encodeURIComponent(domain)}`);
|
|
@@ -443,6 +458,40 @@ var TeamsResource = class {
|
|
|
443
458
|
}
|
|
444
459
|
};
|
|
445
460
|
//#endregion
|
|
461
|
+
//#region src/resources/stores.ts
|
|
462
|
+
var StoresResource = class {
|
|
463
|
+
constructor(http) {
|
|
464
|
+
this.http = http;
|
|
465
|
+
}
|
|
466
|
+
list() {
|
|
467
|
+
return this.http.get("stores");
|
|
468
|
+
}
|
|
469
|
+
create(payload) {
|
|
470
|
+
return this.http.post("stores", payload);
|
|
471
|
+
}
|
|
472
|
+
entries(params) {
|
|
473
|
+
const query = new URLSearchParams();
|
|
474
|
+
if (params?.storeName) query.set("storeName", params.storeName);
|
|
475
|
+
if (params?.since) query.set("since", params.since);
|
|
476
|
+
if (params?.until) query.set("until", params.until);
|
|
477
|
+
if (params?.last != null) query.set("last", String(params.last));
|
|
478
|
+
const qs = query.toString();
|
|
479
|
+
return this.http.get(`stores/entries${qs ? "?" + qs : ""}`);
|
|
480
|
+
}
|
|
481
|
+
setEntry(payload) {
|
|
482
|
+
return this.http.post("stores/entries", payload);
|
|
483
|
+
}
|
|
484
|
+
appendEntry(payload) {
|
|
485
|
+
return this.http.post("stores/entries/append", payload);
|
|
486
|
+
}
|
|
487
|
+
toggle(storeName) {
|
|
488
|
+
return this.http.post("stores/toggle", { storeName });
|
|
489
|
+
}
|
|
490
|
+
delete(storeName) {
|
|
491
|
+
return this.http.delete(`stores/${storeName}`);
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
//#endregion
|
|
446
495
|
//#region src/resources/warps.ts
|
|
447
496
|
var WarpsResource = class {
|
|
448
497
|
constructor(http) {
|
|
@@ -463,6 +512,107 @@ var WarpsResource = class {
|
|
|
463
512
|
}
|
|
464
513
|
};
|
|
465
514
|
//#endregion
|
|
515
|
+
//#region src/cache/memory-cache.ts
|
|
516
|
+
var MemoryCache = class {
|
|
517
|
+
constructor() {
|
|
518
|
+
this.store = /* @__PURE__ */ new Map();
|
|
519
|
+
}
|
|
520
|
+
get(key) {
|
|
521
|
+
const entry = this.store.get(key);
|
|
522
|
+
if (!entry) return void 0;
|
|
523
|
+
if (Date.now() > entry.expiresAt) {
|
|
524
|
+
this.store.delete(key);
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
return entry.data;
|
|
528
|
+
}
|
|
529
|
+
set(key, data, ttl) {
|
|
530
|
+
this.store.set(key, {
|
|
531
|
+
data,
|
|
532
|
+
expiresAt: Date.now() + ttl
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
clear() {
|
|
536
|
+
this.store.clear();
|
|
537
|
+
}
|
|
538
|
+
bust(prefix) {
|
|
539
|
+
for (const key of this.store.keys()) if (key.startsWith(prefix)) this.store.delete(key);
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
//#endregion
|
|
543
|
+
//#region src/cache/cached-http.ts
|
|
544
|
+
const DEFAULT_TTL = 15e3;
|
|
545
|
+
const DEFAULTS = {
|
|
546
|
+
blueprints: 3e5,
|
|
547
|
+
flows: 3e5,
|
|
548
|
+
marketplace: 3e5,
|
|
549
|
+
skills: 3e5,
|
|
550
|
+
sites: 3e5,
|
|
551
|
+
stores: 3e4,
|
|
552
|
+
contacts: 3e4,
|
|
553
|
+
items: 3e4,
|
|
554
|
+
goals: 3e4,
|
|
555
|
+
memories: 3e4,
|
|
556
|
+
reminders: 3e4,
|
|
557
|
+
services: 3e4,
|
|
558
|
+
documents: 3e4,
|
|
559
|
+
ingestions: 3e4,
|
|
560
|
+
agents: 1e4,
|
|
561
|
+
rooms: 1e4
|
|
562
|
+
};
|
|
563
|
+
function getTtl(url, ttlMap, defaultTtl) {
|
|
564
|
+
for (const [prefix, ttl] of Object.entries(ttlMap)) if (url.startsWith(prefix) || url.startsWith(`/${prefix}`)) return ttl;
|
|
565
|
+
return defaultTtl;
|
|
566
|
+
}
|
|
567
|
+
function getUrlPrefix(url) {
|
|
568
|
+
const clean = url.startsWith("/") ? url.slice(1) : url;
|
|
569
|
+
const slash = clean.indexOf("/");
|
|
570
|
+
return slash > 0 ? clean.slice(0, slash) : clean;
|
|
571
|
+
}
|
|
572
|
+
var CachedHttpService = class {
|
|
573
|
+
constructor(inner, overrides, defaultTtl) {
|
|
574
|
+
this.inner = inner;
|
|
575
|
+
this.cache = new MemoryCache();
|
|
576
|
+
this.onNetworkError = () => {};
|
|
577
|
+
this.onUnauthorized = () => {};
|
|
578
|
+
this.onSuccessfulResponse = () => {};
|
|
579
|
+
this.onMaintenanceMode = () => {};
|
|
580
|
+
this.onTooManyRequests = () => {};
|
|
581
|
+
this.baseUrl = inner.baseUrl;
|
|
582
|
+
this.authToken = inner.authToken;
|
|
583
|
+
this.ttlMap = {
|
|
584
|
+
...DEFAULTS,
|
|
585
|
+
...overrides
|
|
586
|
+
};
|
|
587
|
+
this.defaultTtl = defaultTtl ?? DEFAULT_TTL;
|
|
588
|
+
}
|
|
589
|
+
clearCache() {
|
|
590
|
+
this.cache.clear();
|
|
591
|
+
}
|
|
592
|
+
async get(url, options) {
|
|
593
|
+
const cached = this.cache.get(url);
|
|
594
|
+
if (cached !== void 0) return cached;
|
|
595
|
+
const response = await this.inner.get(url, options);
|
|
596
|
+
if (response.ok) this.cache.set(url, response, getTtl(url, this.ttlMap, this.defaultTtl));
|
|
597
|
+
return response;
|
|
598
|
+
}
|
|
599
|
+
async post(url, data, options) {
|
|
600
|
+
const response = await this.inner.post(url, data, options);
|
|
601
|
+
this.cache.bust(getUrlPrefix(url));
|
|
602
|
+
return response;
|
|
603
|
+
}
|
|
604
|
+
async put(url, data, options) {
|
|
605
|
+
const response = await this.inner.put(url, data, options);
|
|
606
|
+
this.cache.bust(getUrlPrefix(url));
|
|
607
|
+
return response;
|
|
608
|
+
}
|
|
609
|
+
async delete(url, options) {
|
|
610
|
+
const response = await this.inner.delete(url, options);
|
|
611
|
+
this.cache.bust(getUrlPrefix(url));
|
|
612
|
+
return response;
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
//#endregion
|
|
466
616
|
//#region src/client.ts
|
|
467
617
|
function toWarpEnv(env) {
|
|
468
618
|
if (env === "devnet") return "devnet";
|
|
@@ -475,7 +625,9 @@ var JoAiClient = class {
|
|
|
475
625
|
const headers = {};
|
|
476
626
|
if (config.team) headers["X-Team"] = config.team;
|
|
477
627
|
if (config.agentAuthKey) headers["X-Agent-Auth-Key"] = config.agentAuthKey;
|
|
478
|
-
|
|
628
|
+
const http = new HttpService(`${getApiBaseUrl(config.env ?? "mainnet")}/v1`, void 0, config.apiToken, { headers });
|
|
629
|
+
const cache = config.cache;
|
|
630
|
+
this.http = cache?.enabled !== false ? new CachedHttpService(http, cache?.overrides, cache?.defaultTtl) : http;
|
|
479
631
|
this.hub = new HubResource(this.http);
|
|
480
632
|
this.teams = new TeamsResource(this.http);
|
|
481
633
|
this.agents = new AgentsResource(this.http);
|
|
@@ -494,8 +646,12 @@ var JoAiClient = class {
|
|
|
494
646
|
this.sites = new SitesResource(this.http);
|
|
495
647
|
this.documents = new DocumentsResource(this.http);
|
|
496
648
|
this.meetings = new MeetingsResource(this.http);
|
|
649
|
+
this.stores = new StoresResource(this.http);
|
|
497
650
|
this.privateWarps = new WarpsResource(this.http);
|
|
498
651
|
}
|
|
652
|
+
clearCache() {
|
|
653
|
+
if (this.http instanceof CachedHttpService) this.http.clearCache();
|
|
654
|
+
}
|
|
499
655
|
warps(locale = "en") {
|
|
500
656
|
return new WarpClient({
|
|
501
657
|
env: toWarpEnv(this.env),
|
|
@@ -535,4 +691,4 @@ var DistributionResource = class {
|
|
|
535
691
|
}
|
|
536
692
|
};
|
|
537
693
|
//#endregion
|
|
538
|
-
export { BlueprintsResource, DistributionResource, FlowsResource, IngestionsResource, JoAiClient, MarketplaceResource, MeetingsResource, ServicesResource, SitesResource, SkillsResource, createClient };
|
|
694
|
+
export { BlueprintsResource, CachedHttpService, DistributionResource, FlowsResource, IngestionsResource, JoAiClient, MarketplaceResource, MeetingsResource, ServicesResource, SitesResource, SkillsResource, StoresResource, createClient };
|