@joai/core 4.16.0 → 5.0.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/index.d.mts +342 -151
- package/dist/index.mjs +238 -2
- package/package.json +2 -13
- package/dist/react/index.d.mts +0 -362
- package/dist/react/index.mjs +0 -729
package/dist/index.mjs
CHANGED
|
@@ -410,6 +410,63 @@ function integrationSlugForChannel(channel) {
|
|
|
410
410
|
return channel === "sms" ? "twilio" : channel;
|
|
411
411
|
}
|
|
412
412
|
//#endregion
|
|
413
|
+
//#region src/content/image-processing.ts
|
|
414
|
+
const positiveFinite = (value) => typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
415
|
+
const validateImageDimensions = (dimensions, rules) => {
|
|
416
|
+
if (!positiveFinite(dimensions.width) || !positiveFinite(dimensions.height)) return "too-small";
|
|
417
|
+
if (rules.minWidth && dimensions.width < rules.minWidth || rules.minHeight && dimensions.height < rules.minHeight) return "too-small";
|
|
418
|
+
if (rules.maxWidth && dimensions.width > rules.maxWidth || rules.maxHeight && dimensions.height > rules.maxHeight || rules.maxPixels && dimensions.width * dimensions.height > rules.maxPixels) return "too-large";
|
|
419
|
+
return null;
|
|
420
|
+
};
|
|
421
|
+
const imageCropRectangle = (dimensions, aspectRatio, crop) => {
|
|
422
|
+
if (!positiveFinite(aspectRatio)) throw new RangeError("Crop aspect ratio must be a positive finite number.");
|
|
423
|
+
if (!positiveFinite(dimensions.width) || !positiveFinite(dimensions.height)) throw new RangeError("Image dimensions must be positive finite numbers.");
|
|
424
|
+
const sourceAspect = dimensions.width / dimensions.height;
|
|
425
|
+
const baseWidth = sourceAspect > aspectRatio ? dimensions.height * aspectRatio : dimensions.width;
|
|
426
|
+
const baseHeight = sourceAspect > aspectRatio ? dimensions.height : dimensions.width / aspectRatio;
|
|
427
|
+
const zoom = Number.isFinite(crop.zoom) ? Math.max(1, crop.zoom) : 1;
|
|
428
|
+
const positionX = Number.isFinite(crop.x) ? Math.max(-1, Math.min(1, crop.x)) : 0;
|
|
429
|
+
const positionY = Number.isFinite(crop.y) ? Math.max(-1, Math.min(1, crop.y)) : 0;
|
|
430
|
+
const width = baseWidth / zoom;
|
|
431
|
+
const height = baseHeight / zoom;
|
|
432
|
+
const availableX = dimensions.width - width;
|
|
433
|
+
const availableY = dimensions.height - height;
|
|
434
|
+
return {
|
|
435
|
+
x: availableX * ((positionX + 1) / 2),
|
|
436
|
+
y: availableY * ((positionY + 1) / 2),
|
|
437
|
+
width,
|
|
438
|
+
height
|
|
439
|
+
};
|
|
440
|
+
};
|
|
441
|
+
const containedImageDimensions = (source, options) => {
|
|
442
|
+
if (!positiveFinite(source.width) || !positiveFinite(source.height)) throw new RangeError("Image dimensions must be positive finite numbers.");
|
|
443
|
+
const maxWidth = positiveFinite(options.maxWidth) ? options.maxWidth : source.width;
|
|
444
|
+
const maxHeight = positiveFinite(options.maxHeight) ? options.maxHeight : source.height;
|
|
445
|
+
const scale = Math.min(1, maxWidth / source.width, maxHeight / source.height);
|
|
446
|
+
return {
|
|
447
|
+
width: Math.max(1, Math.round(source.width * scale)),
|
|
448
|
+
height: Math.max(1, Math.round(source.height * scale))
|
|
449
|
+
};
|
|
450
|
+
};
|
|
451
|
+
const cropOutputDimensions = (source, options, compression) => {
|
|
452
|
+
if (!positiveFinite(options.aspectRatio)) throw new RangeError("Crop aspect ratio must be a positive finite number.");
|
|
453
|
+
const width = positiveFinite(options.outputWidth) ? options.outputWidth : void 0;
|
|
454
|
+
const height = positiveFinite(options.outputHeight) ? options.outputHeight : void 0;
|
|
455
|
+
if (width && height) return {
|
|
456
|
+
width: Math.max(1, Math.round(width)),
|
|
457
|
+
height: Math.max(1, Math.round(height))
|
|
458
|
+
};
|
|
459
|
+
if (width) return {
|
|
460
|
+
width: Math.max(1, Math.round(width)),
|
|
461
|
+
height: Math.max(1, Math.round(width / options.aspectRatio))
|
|
462
|
+
};
|
|
463
|
+
if (height) return {
|
|
464
|
+
width: Math.max(1, Math.round(height * options.aspectRatio)),
|
|
465
|
+
height: Math.max(1, Math.round(height))
|
|
466
|
+
};
|
|
467
|
+
return containedImageDimensions(source, compression);
|
|
468
|
+
};
|
|
469
|
+
//#endregion
|
|
413
470
|
//#region src/address/enums.ts
|
|
414
471
|
const AddressTypes = {
|
|
415
472
|
Billing: "billing",
|
|
@@ -629,6 +686,173 @@ const cartLineTotal = (items) => items.reduce((total, item) => total + item.pric
|
|
|
629
686
|
const cartPayableTotal = (items, discountCents = 0) => Math.max(0, cartLineTotal(items) - Math.max(0, discountCents));
|
|
630
687
|
const isCompleteAddressInput = (address) => Boolean(address.name.trim() && address.addressOne.trim() && address.city.trim() && address.zipCode.trim() && address.country.trim());
|
|
631
688
|
//#endregion
|
|
689
|
+
//#region src/commerce/returns.ts
|
|
690
|
+
/** Pickup "collected" is `delivered`; goods must have left the shop before a return makes sense. */
|
|
691
|
+
const RETURNABLE_FULFILLMENT_STATUSES = ["shipped", "delivered"];
|
|
692
|
+
const resolveOrderItemId = (item) => typeof item.orderItemId === "number" && Number.isFinite(item.orderItemId) ? item.orderItemId : Number(item.id);
|
|
693
|
+
const resolveFulfillmentId = (value) => {
|
|
694
|
+
if (value === null || value === void 0 || value === "") return null;
|
|
695
|
+
return String(value);
|
|
696
|
+
};
|
|
697
|
+
/** Physical quantities of a paid order that were shipped/delivered and are not yet in a non-rejected return. */
|
|
698
|
+
const getReturnableItems = (order, returns = order.returns ?? []) => {
|
|
699
|
+
if (!isOrderInFulfillment(order.status)) return [];
|
|
700
|
+
const shippedByItem = /* @__PURE__ */ new Map();
|
|
701
|
+
(order.fulfillments ?? []).filter((fulfillment) => RETURNABLE_FULFILLMENT_STATUSES.includes(fulfillment.status)).forEach((fulfillment) => {
|
|
702
|
+
const fulfillmentId = resolveFulfillmentId(fulfillment.id);
|
|
703
|
+
if (fulfillmentId === null) return;
|
|
704
|
+
fulfillment.items.forEach((item) => {
|
|
705
|
+
const byFulfillment = shippedByItem.get(item.orderItemId) ?? /* @__PURE__ */ new Map();
|
|
706
|
+
byFulfillment.set(fulfillmentId, (byFulfillment.get(fulfillmentId) ?? 0) + item.quantity);
|
|
707
|
+
shippedByItem.set(item.orderItemId, byFulfillment);
|
|
708
|
+
});
|
|
709
|
+
});
|
|
710
|
+
returns.filter((request) => request.status !== "rejected").forEach((request) => {
|
|
711
|
+
const preferredFulfillmentId = resolveFulfillmentId(request.fulfillmentId);
|
|
712
|
+
request.items.forEach((item) => {
|
|
713
|
+
const byFulfillment = shippedByItem.get(item.orderItemId);
|
|
714
|
+
if (!byFulfillment) return;
|
|
715
|
+
let remaining = item.quantity;
|
|
716
|
+
if (preferredFulfillmentId !== null && byFulfillment.has(preferredFulfillmentId)) {
|
|
717
|
+
const available = byFulfillment.get(preferredFulfillmentId) ?? 0;
|
|
718
|
+
const used = Math.min(available, remaining);
|
|
719
|
+
byFulfillment.set(preferredFulfillmentId, available - used);
|
|
720
|
+
remaining -= used;
|
|
721
|
+
}
|
|
722
|
+
for (const [fulfillmentId, available] of byFulfillment) {
|
|
723
|
+
if (remaining <= 0) break;
|
|
724
|
+
if (preferredFulfillmentId !== null && fulfillmentId === preferredFulfillmentId) continue;
|
|
725
|
+
const used = Math.min(available, remaining);
|
|
726
|
+
byFulfillment.set(fulfillmentId, available - used);
|
|
727
|
+
remaining -= used;
|
|
728
|
+
}
|
|
729
|
+
});
|
|
730
|
+
});
|
|
731
|
+
return order.items.filter((item) => !item.digital && item.type !== "coupon").map((item) => {
|
|
732
|
+
const orderItemId = resolveOrderItemId(item);
|
|
733
|
+
const byFulfillment = shippedByItem.get(orderItemId) ?? /* @__PURE__ */ new Map();
|
|
734
|
+
const quantity = Math.min(item.quantity, [...byFulfillment.values()].reduce((sum, value) => sum + value, 0));
|
|
735
|
+
const fulfillmentIds = [...byFulfillment.entries()].filter(([, available]) => available > 0).map(([id]) => id);
|
|
736
|
+
return {
|
|
737
|
+
item,
|
|
738
|
+
orderItemId,
|
|
739
|
+
quantity,
|
|
740
|
+
fulfillmentId: fulfillmentIds.length === 1 ? fulfillmentIds[0] : null
|
|
741
|
+
};
|
|
742
|
+
}).filter(({ orderItemId, quantity }) => Number.isFinite(orderItemId) && quantity > 0);
|
|
743
|
+
};
|
|
744
|
+
/**
|
|
745
|
+
* Split selected return quantities into create payloads, one per fulfillment when possible.
|
|
746
|
+
* Quantities without a single fulfillment go in an unscoped payload.
|
|
747
|
+
*/
|
|
748
|
+
const buildReturnCreatePayloads = (order, selected, returns = order.returns ?? []) => {
|
|
749
|
+
const returnable = getReturnableItems(order, returns);
|
|
750
|
+
const remainingByItem = new Map(returnable.map((item) => [item.orderItemId, item.quantity]));
|
|
751
|
+
const fulfillmentPools = /* @__PURE__ */ new Map();
|
|
752
|
+
(order.fulfillments ?? []).filter((fulfillment) => RETURNABLE_FULFILLMENT_STATUSES.includes(fulfillment.status)).forEach((fulfillment) => {
|
|
753
|
+
const fulfillmentId = resolveFulfillmentId(fulfillment.id);
|
|
754
|
+
if (fulfillmentId === null) return;
|
|
755
|
+
const pool = /* @__PURE__ */ new Map();
|
|
756
|
+
fulfillment.items.forEach((item) => pool.set(item.orderItemId, (pool.get(item.orderItemId) ?? 0) + item.quantity));
|
|
757
|
+
fulfillmentPools.set(fulfillmentId, pool);
|
|
758
|
+
});
|
|
759
|
+
returns.filter((request) => request.status !== "rejected").forEach((request) => {
|
|
760
|
+
const preferredFulfillmentId = resolveFulfillmentId(request.fulfillmentId);
|
|
761
|
+
request.items.forEach((item) => {
|
|
762
|
+
let remaining = item.quantity;
|
|
763
|
+
if (preferredFulfillmentId !== null) {
|
|
764
|
+
const pool = fulfillmentPools.get(preferredFulfillmentId);
|
|
765
|
+
if (pool) {
|
|
766
|
+
const available = pool.get(item.orderItemId) ?? 0;
|
|
767
|
+
const used = Math.min(available, remaining);
|
|
768
|
+
pool.set(item.orderItemId, available - used);
|
|
769
|
+
remaining -= used;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
for (const pool of fulfillmentPools.values()) {
|
|
773
|
+
if (remaining <= 0) break;
|
|
774
|
+
const available = pool.get(item.orderItemId) ?? 0;
|
|
775
|
+
const used = Math.min(available, remaining);
|
|
776
|
+
pool.set(item.orderItemId, available - used);
|
|
777
|
+
remaining -= used;
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
});
|
|
781
|
+
const payloads = /* @__PURE__ */ new Map();
|
|
782
|
+
selected.filter((item) => item.quantity > 0).forEach((item) => {
|
|
783
|
+
let remaining = Math.min(item.quantity, remainingByItem.get(item.orderItemId) ?? 0);
|
|
784
|
+
remainingByItem.set(item.orderItemId, (remainingByItem.get(item.orderItemId) ?? 0) - remaining);
|
|
785
|
+
const preferred = returnable.find((candidate) => candidate.orderItemId === item.orderItemId)?.fulfillmentId;
|
|
786
|
+
if (preferred !== null && preferred !== void 0) {
|
|
787
|
+
const pool = fulfillmentPools.get(preferred);
|
|
788
|
+
const available = pool?.get(item.orderItemId) ?? 0;
|
|
789
|
+
const used = Math.min(available, remaining);
|
|
790
|
+
if (used > 0) {
|
|
791
|
+
pool?.set(item.orderItemId, available - used);
|
|
792
|
+
const key = preferred;
|
|
793
|
+
const payload = payloads.get(key) ?? {
|
|
794
|
+
fulfillmentId: preferred,
|
|
795
|
+
items: []
|
|
796
|
+
};
|
|
797
|
+
payload.items.push({
|
|
798
|
+
orderItemId: item.orderItemId,
|
|
799
|
+
quantity: used,
|
|
800
|
+
condition: item.condition
|
|
801
|
+
});
|
|
802
|
+
payloads.set(key, payload);
|
|
803
|
+
remaining -= used;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
for (const [fulfillmentId, pool] of fulfillmentPools) {
|
|
807
|
+
if (remaining <= 0) break;
|
|
808
|
+
if (preferred !== null && preferred !== void 0 && fulfillmentId === preferred) continue;
|
|
809
|
+
const available = pool.get(item.orderItemId) ?? 0;
|
|
810
|
+
const used = Math.min(available, remaining);
|
|
811
|
+
if (used <= 0) continue;
|
|
812
|
+
pool.set(item.orderItemId, available - used);
|
|
813
|
+
const payload = payloads.get(fulfillmentId) ?? {
|
|
814
|
+
fulfillmentId,
|
|
815
|
+
items: []
|
|
816
|
+
};
|
|
817
|
+
payload.items.push({
|
|
818
|
+
orderItemId: item.orderItemId,
|
|
819
|
+
quantity: used,
|
|
820
|
+
condition: item.condition
|
|
821
|
+
});
|
|
822
|
+
payloads.set(fulfillmentId, payload);
|
|
823
|
+
remaining -= used;
|
|
824
|
+
}
|
|
825
|
+
if (remaining > 0) {
|
|
826
|
+
const payload = payloads.get("unscoped") ?? { items: [] };
|
|
827
|
+
payload.items.push({
|
|
828
|
+
orderItemId: item.orderItemId,
|
|
829
|
+
quantity: remaining,
|
|
830
|
+
condition: item.condition
|
|
831
|
+
});
|
|
832
|
+
payloads.set("unscoped", payload);
|
|
833
|
+
}
|
|
834
|
+
});
|
|
835
|
+
return [...payloads.values()].filter((payload) => payload.items.length > 0);
|
|
836
|
+
};
|
|
837
|
+
/** Customer-paid amount for returned units (includes proportional tax when prices are net). */
|
|
838
|
+
const getReturnRefundAmount = (order, request, alreadyRefunded = 0) => {
|
|
839
|
+
if (typeof request.suggestedRefundAmount === "number" && Number.isFinite(request.suggestedRefundAmount)) return Math.max(0, request.suggestedRefundAmount);
|
|
840
|
+
if (typeof request.refundAmount === "number" && request.refundAmount > 0) return request.refundAmount;
|
|
841
|
+
const amount = request.items.reduce((sum, returnItem) => {
|
|
842
|
+
const orderItem = order.items.find((item) => resolveOrderItemId(item) === returnItem.orderItemId);
|
|
843
|
+
if (!orderItem || orderItem.quantity < 1) return sum;
|
|
844
|
+
const quantity = Math.min(returnItem.quantity, orderItem.quantity);
|
|
845
|
+
const line = orderItem.unitPrice * quantity;
|
|
846
|
+
if ((order.priceMode ?? "gross") === "net") {
|
|
847
|
+
const tax = Math.round((orderItem.taxAmount ?? 0) * quantity / orderItem.quantity);
|
|
848
|
+
return sum + line + tax;
|
|
849
|
+
}
|
|
850
|
+
return sum + line;
|
|
851
|
+
}, 0);
|
|
852
|
+
const remaining = typeof order.total === "number" ? Math.max(0, order.total - alreadyRefunded) : amount;
|
|
853
|
+
return Math.max(0, Math.min(amount, remaining));
|
|
854
|
+
};
|
|
855
|
+
//#endregion
|
|
632
856
|
//#region src/budget/types.ts
|
|
633
857
|
const PeriodTypeLabels = {
|
|
634
858
|
0: "One-time",
|
|
@@ -878,7 +1102,8 @@ const NativeApps = {
|
|
|
878
1102
|
Artifacts: "artifacts",
|
|
879
1103
|
Social: "social",
|
|
880
1104
|
Studio: "studio",
|
|
881
|
-
Loyalty: "loyalty"
|
|
1105
|
+
Loyalty: "loyalty",
|
|
1106
|
+
Documents: "documents"
|
|
882
1107
|
};
|
|
883
1108
|
const nativeAppSlugs = Object.values(NativeApps);
|
|
884
1109
|
const isNativeApp = (value) => typeof value === "string" && nativeAppSlugs.includes(value);
|
|
@@ -893,6 +1118,7 @@ const UserPermissions = {
|
|
|
893
1118
|
ContentPublish: "content-publish",
|
|
894
1119
|
TeamMemberInvite: "team-member-invite",
|
|
895
1120
|
TeamMemberRemove: "team-member-remove",
|
|
1121
|
+
TeamMemberRole: "team-member-role",
|
|
896
1122
|
TeamSecretView: "team-secret-view",
|
|
897
1123
|
TeamSecretManage: "team-secret-manage",
|
|
898
1124
|
AgentExecute: "agent-execute",
|
|
@@ -917,6 +1143,7 @@ const PermissionPresetNames = {
|
|
|
917
1143
|
SecretManage: "secretManage",
|
|
918
1144
|
TeamMemberInvite: "teamMemberInvite",
|
|
919
1145
|
TeamMemberRemove: "teamMemberRemove",
|
|
1146
|
+
TeamMemberRole: "teamMemberRole",
|
|
920
1147
|
AgentWalletManage: "agentWalletManage",
|
|
921
1148
|
SwarmCreate: "swarmCreate"
|
|
922
1149
|
};
|
|
@@ -930,6 +1157,7 @@ const permissionPresetRules = {
|
|
|
930
1157
|
secretManage: teamManageOr(UserPermissions.TeamSecretManage),
|
|
931
1158
|
teamMemberInvite: teamManageOr(UserPermissions.TeamMemberInvite),
|
|
932
1159
|
teamMemberRemove: teamManageOr(UserPermissions.TeamMemberRemove),
|
|
1160
|
+
teamMemberRole: teamManageOr(UserPermissions.TeamMemberRole),
|
|
933
1161
|
agentWalletManage: teamManageOr(UserPermissions.AgentWalletManage),
|
|
934
1162
|
swarmCreate: teamManageOr(UserPermissions.SwarmCreate)
|
|
935
1163
|
};
|
|
@@ -974,6 +1202,14 @@ const InviteableTeamRoles = [
|
|
|
974
1202
|
];
|
|
975
1203
|
const DefaultInviteTeamRole = UserRoles.Member;
|
|
976
1204
|
const inviteableTeamRoles = () => [...InviteableTeamRoles];
|
|
1205
|
+
/** Roles assignable to an existing member — unlike invites, ownership can be transferred. */
|
|
1206
|
+
const AssignableTeamRoles = [
|
|
1207
|
+
UserRoles.Owner,
|
|
1208
|
+
UserRoles.Admin,
|
|
1209
|
+
UserRoles.Developer,
|
|
1210
|
+
UserRoles.Member
|
|
1211
|
+
];
|
|
1212
|
+
const assignableTeamRoles = () => [...AssignableTeamRoles];
|
|
977
1213
|
const defaultInviteTeamRole = () => DefaultInviteTeamRole;
|
|
978
1214
|
//#endregion
|
|
979
|
-
export { AUTOMATION_SEND_CHANNELS, AddressTypes, AgentToolingAccess, BillingManageAccess, CAMPAIGN_CHANNELS, CONTACT_MESSAGE_SEND_WARP, ContractCategoryDisplayNames, DefaultAppLocale, DefaultCodeMetadata, DefaultInviteTeamRole, FulfillmentMethods, FulfillmentStatuses, HttpService, InviteableTeamRoles, JoaiUrls, NATIVE_AUTH_TOKEN_PARAM, NativeApps, OG_IMAGE_CONFIG, OG_IMAGE_HEIGHT, OG_IMAGE_WIDTH, ORDER_FULFILLMENT_STATUSES, ORDER_POST_CHECKOUT_STATUSES, OUTBOUND_CHANNELS, OgImageColors, PLATFORM_CURRENCY, PeriodTypeLabels, PeriodTypeOptions, PermissionPresetNames, ReturnStatuses, ReturnUpdateStatuses, SkillMediaBindingRole, SkillScope, SkillType, SupportedAppLocales, TeamManageAccess, TeamViewAccess, UNIFIED_MCP_SERVER_NAME, UserPermissions, UserRoles, abbreviateNumber, addressTypeValues, automationSendChannel, buildAgentMcpServerName, buildAgentSetupClipboardText, buildAppSetupClipboardText, buildFeatureSetupClipboardText, buildMcpServerName, canOpenFulfillmentFlow, canTransitionOrderStatus, cartLineTotal, cartPayableTotal, createCursorMcpInstallLink, defaultInviteTeamRole, documentShareUrl, firstValidationMessage, formatAddressSnapshotLines, fulfillmentMethodValues, fulfillmentStatusValues, getAgentSetupPromptUrl, getAgentsBaseUrl, getApiBaseUrl, getAppBaseUrl, getAssetAppLogoUrl, getAssetChainLogoUrl, getAssetPartnerLogoUrl, getAssetTokenLogoUrl, getAssetWalletLogoUrl, getCortexBaseUrl, getDigestBaseUrl, getDocumentsBaseUrl, getEditableOrderStatuses, getFormsBaseUrl, getFulfillmentFlowAction, getFulfillmentFlowStepperIndex, getGenBaseUrl, getInvoiceEditableStatuses, getLoginUrl, getMcpServerAgentUrl, getMcpServerUrl, getPickupEditableStatuses, getPickupNextAction, getShippingEditableStatuses, getSiteUrl, getSitesBaseUrl, getSitesRootDomain, getStoreBaseUrl, getWarpScreenshotUrl, hasAllPermissions, hasAllTeamPermissions, hasAnyPermissions, hasPermission, hasTeamPermission, integrationSlugForChannel, inviteableTeamRoles, isAutomationSendChannelId, isCampaignChannelId, isCompleteAddressInput, isContactMessageAction, isContactMessageWarpId, isFileFormatAudio, isFileFormatImage, isFileFormatVideo, isNativeApp, isNativeAppAccessible, isNativeAppGated, isNativeAppLocked, isOrderCanceled, isOrderInFulfillment, isOrderPending, isOrderPostCheckout, isPickupOrderReady, isPickupReady, isSupportedAppLocale, isTeamFeatureAccessible, isTeamFeatureGated, isTeamFeatureLocked, isUnifiedMcpUrl, isUserRole, localize, nativeAppSlugs, normalizeAutomationActionType, ogImageUrl, outboundChannel, permissionPresetRules, resolveAccessCatalog, resolveAgentMcpUrl, resolveConnectMcpUrl, resolveFulfillmentFlowStep, resolveOrderStatusDisplay, resolveTeamCurrency, resolveWarpText, returnStatusValues, returnUpdateStatusValues, sanitizeAlphanumeric, sanitizeNumeric, slugifyMcpSegment, teamCategories, toCurrencyDisplay, toHexEncodedNonce, toNameInitials, toNftId, toPreviewText, userPermissionValues, userRoleValues, validationMessageFor, withRetry };
|
|
1215
|
+
export { AUTOMATION_SEND_CHANNELS, AddressTypes, AgentToolingAccess, AssignableTeamRoles, BillingManageAccess, CAMPAIGN_CHANNELS, CONTACT_MESSAGE_SEND_WARP, ContractCategoryDisplayNames, DefaultAppLocale, DefaultCodeMetadata, DefaultInviteTeamRole, FulfillmentMethods, FulfillmentStatuses, HttpService, InviteableTeamRoles, JoaiUrls, NATIVE_AUTH_TOKEN_PARAM, NativeApps, OG_IMAGE_CONFIG, OG_IMAGE_HEIGHT, OG_IMAGE_WIDTH, ORDER_FULFILLMENT_STATUSES, ORDER_POST_CHECKOUT_STATUSES, OUTBOUND_CHANNELS, OgImageColors, PLATFORM_CURRENCY, PeriodTypeLabels, PeriodTypeOptions, PermissionPresetNames, RETURNABLE_FULFILLMENT_STATUSES, ReturnStatuses, ReturnUpdateStatuses, SkillMediaBindingRole, SkillScope, SkillType, SupportedAppLocales, TeamManageAccess, TeamViewAccess, UNIFIED_MCP_SERVER_NAME, UserPermissions, UserRoles, abbreviateNumber, addressTypeValues, assignableTeamRoles, automationSendChannel, buildAgentMcpServerName, buildAgentSetupClipboardText, buildAppSetupClipboardText, buildFeatureSetupClipboardText, buildMcpServerName, buildReturnCreatePayloads, canOpenFulfillmentFlow, canTransitionOrderStatus, cartLineTotal, cartPayableTotal, containedImageDimensions, createCursorMcpInstallLink, cropOutputDimensions, defaultInviteTeamRole, documentShareUrl, firstValidationMessage, formatAddressSnapshotLines, fulfillmentMethodValues, fulfillmentStatusValues, getAgentSetupPromptUrl, getAgentsBaseUrl, getApiBaseUrl, getAppBaseUrl, getAssetAppLogoUrl, getAssetChainLogoUrl, getAssetPartnerLogoUrl, getAssetTokenLogoUrl, getAssetWalletLogoUrl, getCortexBaseUrl, getDigestBaseUrl, getDocumentsBaseUrl, getEditableOrderStatuses, getFormsBaseUrl, getFulfillmentFlowAction, getFulfillmentFlowStepperIndex, getGenBaseUrl, getInvoiceEditableStatuses, getLoginUrl, getMcpServerAgentUrl, getMcpServerUrl, getPickupEditableStatuses, getPickupNextAction, getReturnRefundAmount, getReturnableItems, getShippingEditableStatuses, getSiteUrl, getSitesBaseUrl, getSitesRootDomain, getStoreBaseUrl, getWarpScreenshotUrl, hasAllPermissions, hasAllTeamPermissions, hasAnyPermissions, hasPermission, hasTeamPermission, imageCropRectangle, integrationSlugForChannel, inviteableTeamRoles, isAutomationSendChannelId, isCampaignChannelId, isCompleteAddressInput, isContactMessageAction, isContactMessageWarpId, isFileFormatAudio, isFileFormatImage, isFileFormatVideo, isNativeApp, isNativeAppAccessible, isNativeAppGated, isNativeAppLocked, isOrderCanceled, isOrderInFulfillment, isOrderPending, isOrderPostCheckout, isPickupOrderReady, isPickupReady, isSupportedAppLocale, isTeamFeatureAccessible, isTeamFeatureGated, isTeamFeatureLocked, isUnifiedMcpUrl, isUserRole, localize, nativeAppSlugs, normalizeAutomationActionType, ogImageUrl, outboundChannel, permissionPresetRules, resolveAccessCatalog, resolveAgentMcpUrl, resolveConnectMcpUrl, resolveFulfillmentFlowStep, resolveOrderStatusDisplay, resolveTeamCurrency, resolveWarpText, returnStatusValues, returnUpdateStatusValues, sanitizeAlphanumeric, sanitizeNumeric, slugifyMcpSegment, teamCategories, toCurrencyDisplay, toHexEncodedNonce, toNameInitials, toNftId, toPreviewText, userPermissionValues, userRoleValues, validateImageDimensions, validationMessageFor, withRetry };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@joai/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.1",
|
|
4
4
|
"description": "JoAi shared types, HTTP service, and config",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -10,10 +10,6 @@
|
|
|
10
10
|
".": {
|
|
11
11
|
"import": "./dist/index.mjs",
|
|
12
12
|
"types": "./dist/index.d.mts"
|
|
13
|
-
},
|
|
14
|
-
"./react": {
|
|
15
|
-
"import": "./dist/react/index.mjs",
|
|
16
|
-
"types": "./dist/react/index.d.mts"
|
|
17
13
|
}
|
|
18
14
|
},
|
|
19
15
|
"files": [
|
|
@@ -26,17 +22,10 @@
|
|
|
26
22
|
"test:watch": "jest --watch"
|
|
27
23
|
},
|
|
28
24
|
"peerDependencies": {
|
|
29
|
-
"@joai/warps": ">=4.0.0"
|
|
30
|
-
"react": ">=18.0.0"
|
|
31
|
-
},
|
|
32
|
-
"peerDependenciesMeta": {
|
|
33
|
-
"react": {
|
|
34
|
-
"optional": true
|
|
35
|
-
}
|
|
25
|
+
"@joai/warps": ">=4.0.0"
|
|
36
26
|
},
|
|
37
27
|
"devDependencies": {
|
|
38
28
|
"@types/jest": "^30.0.0",
|
|
39
|
-
"@types/react": "^19.2.14",
|
|
40
29
|
"jest": "^30.3.0",
|
|
41
30
|
"ts-jest": "^29.4.6",
|
|
42
31
|
"tsdown": "^0.21.0",
|
package/dist/react/index.d.mts
DELETED
|
@@ -1,362 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import * as _$react from "react";
|
|
3
|
-
import { ReactNode } from "react";
|
|
4
|
-
|
|
5
|
-
//#region src/react/types.d.ts
|
|
6
|
-
type EmbedChatItem = {
|
|
7
|
-
content: string;
|
|
8
|
-
byUser: boolean;
|
|
9
|
-
streaming?: boolean;
|
|
10
|
-
error?: boolean;
|
|
11
|
-
};
|
|
12
|
-
//#endregion
|
|
13
|
-
//#region src/react/guest.d.ts
|
|
14
|
-
declare function getOrCreateGuestId(storageKey?: string): string;
|
|
15
|
-
declare function loadRoom(storageKey: string): string | null;
|
|
16
|
-
declare function saveRoom(storageKey: string, roomId: string): void;
|
|
17
|
-
declare function clearRoom(storageKey: string): void;
|
|
18
|
-
//#endregion
|
|
19
|
-
//#region src/react/stream-connection.d.ts
|
|
20
|
-
type StreamDataHandler = (data: unknown) => void;
|
|
21
|
-
declare function openEventSourceStream(url: string, onData: StreamDataHandler, options?: {
|
|
22
|
-
withCredentials?: boolean;
|
|
23
|
-
onError?: (e: unknown) => void;
|
|
24
|
-
onConnectionError?: (e: Event | null) => void;
|
|
25
|
-
}): () => void;
|
|
26
|
-
//#endregion
|
|
27
|
-
//#region src/react/components.d.ts
|
|
28
|
-
type ListClassNames = {
|
|
29
|
-
container?: string;
|
|
30
|
-
userBubble?: string;
|
|
31
|
-
agentBubble?: string;
|
|
32
|
-
errorBubble?: string;
|
|
33
|
-
thinkingWrapper?: string;
|
|
34
|
-
dot?: string;
|
|
35
|
-
};
|
|
36
|
-
type EmbedChatListProps = {
|
|
37
|
-
items: EmbedChatItem[];
|
|
38
|
-
agentName: string;
|
|
39
|
-
awaitingResponse: boolean;
|
|
40
|
-
classNames?: ListClassNames;
|
|
41
|
-
renderEmptyState?: () => ReactNode;
|
|
42
|
-
renderAgentContent?: (item: EmbedChatItem) => ReactNode;
|
|
43
|
-
};
|
|
44
|
-
declare function EmbedChatList({
|
|
45
|
-
items,
|
|
46
|
-
agentName,
|
|
47
|
-
awaitingResponse,
|
|
48
|
-
classNames,
|
|
49
|
-
renderEmptyState,
|
|
50
|
-
renderAgentContent
|
|
51
|
-
}: EmbedChatListProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | _$react.ReactPortal | _$react.ReactElement<unknown, string | _$react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | _$react.JSX.Element | null | undefined;
|
|
52
|
-
type EmbedChatInputProps = {
|
|
53
|
-
onSend: (message: string) => void;
|
|
54
|
-
disabled: boolean;
|
|
55
|
-
placeholder?: string;
|
|
56
|
-
maxLength?: number;
|
|
57
|
-
classNames?: {
|
|
58
|
-
container?: string;
|
|
59
|
-
textarea?: string;
|
|
60
|
-
};
|
|
61
|
-
renderSendButton: (props: {
|
|
62
|
-
onClick: () => void;
|
|
63
|
-
disabled: boolean;
|
|
64
|
-
}) => ReactNode;
|
|
65
|
-
};
|
|
66
|
-
declare function EmbedChatInput({
|
|
67
|
-
onSend,
|
|
68
|
-
disabled,
|
|
69
|
-
placeholder,
|
|
70
|
-
maxLength,
|
|
71
|
-
classNames,
|
|
72
|
-
renderSendButton
|
|
73
|
-
}: EmbedChatInputProps): _$react.JSX.Element;
|
|
74
|
-
//#endregion
|
|
75
|
-
//#region src/http/types.d.ts
|
|
76
|
-
interface IHttpService {
|
|
77
|
-
readonly baseUrl: string;
|
|
78
|
-
readonly authToken: string | null;
|
|
79
|
-
onNetworkError: (error: Error) => void;
|
|
80
|
-
onUnauthorized: (response: IAppResponse<any>) => void;
|
|
81
|
-
onSuccessfulResponse: (response: IAppResponse<any>) => void;
|
|
82
|
-
onMaintenanceMode: (response: IAppResponse<any>) => void;
|
|
83
|
-
onTooManyRequests: (response: IAppResponse<any>) => void;
|
|
84
|
-
get: <T>(url: string, options?: IRequestOptions) => Promise<IAppResponse<T>>;
|
|
85
|
-
post: <T>(url: string, data?: any, options?: IRequestOptions) => Promise<IAppResponse<T>>;
|
|
86
|
-
put: <T>(url: string, data?: any, options?: IRequestOptions) => Promise<IAppResponse<T>>;
|
|
87
|
-
patch: <T>(url: string, data?: any, options?: IRequestOptions) => Promise<IAppResponse<T>>;
|
|
88
|
-
delete: <T>(url: string, options?: IRequestOptions) => Promise<IAppResponse<T>>;
|
|
89
|
-
}
|
|
90
|
-
interface IAppResponse<T> {
|
|
91
|
-
data: T;
|
|
92
|
-
meta?: any;
|
|
93
|
-
body: any;
|
|
94
|
-
errors: any;
|
|
95
|
-
ok: boolean;
|
|
96
|
-
paymentRequired: boolean;
|
|
97
|
-
noContent: boolean;
|
|
98
|
-
original: Response;
|
|
99
|
-
}
|
|
100
|
-
interface IRequestOptions {
|
|
101
|
-
isJson?: boolean;
|
|
102
|
-
headers?: {
|
|
103
|
-
[name: string]: string;
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
//#endregion
|
|
107
|
-
//#region src/react/use-embed-chat.d.ts
|
|
108
|
-
type Options = {
|
|
109
|
-
agentUuid: string | null;
|
|
110
|
-
http: IHttpService;
|
|
111
|
-
cortexBaseUrl: string;
|
|
112
|
-
guestId: string;
|
|
113
|
-
roomStorageKey: string;
|
|
114
|
-
enabled?: boolean;
|
|
115
|
-
extraPayload?: Record<string, unknown>;
|
|
116
|
-
};
|
|
117
|
-
declare function useEmbedChat({
|
|
118
|
-
agentUuid,
|
|
119
|
-
http,
|
|
120
|
-
cortexBaseUrl,
|
|
121
|
-
guestId,
|
|
122
|
-
roomStorageKey,
|
|
123
|
-
enabled,
|
|
124
|
-
extraPayload
|
|
125
|
-
}: Options): {
|
|
126
|
-
items: EmbedChatItem[];
|
|
127
|
-
setItems: _$react.Dispatch<_$react.SetStateAction<EmbedChatItem[]>>;
|
|
128
|
-
sending: boolean;
|
|
129
|
-
awaitingResponse: boolean;
|
|
130
|
-
roomId: string | null;
|
|
131
|
-
setRoomId: _$react.Dispatch<_$react.SetStateAction<string | null>>;
|
|
132
|
-
send: (message: string) => Promise<void>;
|
|
133
|
-
connectionError: boolean;
|
|
134
|
-
};
|
|
135
|
-
//#endregion
|
|
136
|
-
//#region src/content/types.d.ts
|
|
137
|
-
type ContentStatus = 'draft' | 'published' | 'archived';
|
|
138
|
-
type ContentFieldType = 'text' | 'richText' | 'number' | 'boolean' | 'url' | 'image' | 'media' | 'list' | 'object' | 'reference';
|
|
139
|
-
type ContentField = {
|
|
140
|
-
key: string;
|
|
141
|
-
type: ContentFieldType;
|
|
142
|
-
label?: string;
|
|
143
|
-
required?: boolean;
|
|
144
|
-
};
|
|
145
|
-
type ContentDefinition = {
|
|
146
|
-
fields: ContentField[];
|
|
147
|
-
};
|
|
148
|
-
type ContentValue = string | number | boolean | null | ContentValue[] | {
|
|
149
|
-
[key: string]: ContentValue;
|
|
150
|
-
};
|
|
151
|
-
type ContentEntry = {
|
|
152
|
-
key: string;
|
|
153
|
-
value: ContentValue;
|
|
154
|
-
updatedAt: string;
|
|
155
|
-
};
|
|
156
|
-
type ContentVersion = {
|
|
157
|
-
id: string;
|
|
158
|
-
number: number;
|
|
159
|
-
status: ContentStatus;
|
|
160
|
-
entries: ContentEntry[];
|
|
161
|
-
snapshotHash: string;
|
|
162
|
-
origin: string;
|
|
163
|
-
createdAt: string;
|
|
164
|
-
updatedAt: string;
|
|
165
|
-
publishedAt: string | null;
|
|
166
|
-
};
|
|
167
|
-
type Content = {
|
|
168
|
-
id: string;
|
|
169
|
-
name: string;
|
|
170
|
-
slug: string;
|
|
171
|
-
schema: string | null;
|
|
172
|
-
definition: ContentDefinition;
|
|
173
|
-
metadata: Record<string, ContentValue>;
|
|
174
|
-
version: ContentVersion | null;
|
|
175
|
-
createdAt: string;
|
|
176
|
-
updatedAt: string;
|
|
177
|
-
};
|
|
178
|
-
type ContentPatch = {
|
|
179
|
-
key: string;
|
|
180
|
-
value: ContentValue;
|
|
181
|
-
};
|
|
182
|
-
type PatchContentInput = {
|
|
183
|
-
expectedVersion: number;
|
|
184
|
-
patches: ContentPatch[];
|
|
185
|
-
origin?: 'api' | 'inlineEditor' | 'joai' | 'mcp';
|
|
186
|
-
publish?: boolean;
|
|
187
|
-
};
|
|
188
|
-
//#endregion
|
|
189
|
-
//#region src/json/types.d.ts
|
|
190
|
-
type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
191
|
-
[key: string]: JsonValue;
|
|
192
|
-
};
|
|
193
|
-
//#endregion
|
|
194
|
-
//#region src/media/types.d.ts
|
|
195
|
-
type MediaLibraryAttributes = {
|
|
196
|
-
uuid: string;
|
|
197
|
-
order: number;
|
|
198
|
-
name: string;
|
|
199
|
-
custom_properties: {
|
|
200
|
-
[key: string]: JsonValue;
|
|
201
|
-
};
|
|
202
|
-
preview_url: null | string;
|
|
203
|
-
original_url: null | string;
|
|
204
|
-
extension?: string;
|
|
205
|
-
size?: number;
|
|
206
|
-
};
|
|
207
|
-
type MediaMime = 'image/png' | 'image/jpeg' | 'image/gif' | 'image/webp' | 'video/mp4' | 'video/webm' | 'video/quicktime' | 'video/x-msvideo' | 'audio/mpeg' | 'audio/mp3' | 'audio/ogg' | 'audio/wav' | 'audio/webm' | 'audio/aac' | 'audio/m4a' | 'audio/m4b' | 'audio/m4p' | 'audio/m4v' | 'application/pdf' | 'application/json';
|
|
208
|
-
type Media = {
|
|
209
|
-
id: string;
|
|
210
|
-
name: string;
|
|
211
|
-
mime: MediaMime;
|
|
212
|
-
url: string;
|
|
213
|
-
library: MediaLibraryAttributes;
|
|
214
|
-
tags?: string[];
|
|
215
|
-
copyright?: string | null;
|
|
216
|
-
aiGenerated?: boolean;
|
|
217
|
-
};
|
|
218
|
-
//#endregion
|
|
219
|
-
//#region src/react/content/types.d.ts
|
|
220
|
-
type ContentResource = {
|
|
221
|
-
get: (contentId: string) => Promise<{
|
|
222
|
-
ok: boolean;
|
|
223
|
-
data?: Content;
|
|
224
|
-
}>;
|
|
225
|
-
getPublic: (slug: string) => Promise<{
|
|
226
|
-
ok: boolean;
|
|
227
|
-
data?: Content;
|
|
228
|
-
}>;
|
|
229
|
-
patch: (contentId: string, input: PatchContentInput) => Promise<{
|
|
230
|
-
ok: boolean;
|
|
231
|
-
data?: ContentVersion;
|
|
232
|
-
}>;
|
|
233
|
-
publish: (contentId: string, expectedVersion: number) => Promise<{
|
|
234
|
-
ok: boolean;
|
|
235
|
-
data?: ContentVersion;
|
|
236
|
-
}>;
|
|
237
|
-
};
|
|
238
|
-
type ContentClient = {
|
|
239
|
-
content: ContentResource;
|
|
240
|
-
media?: {
|
|
241
|
-
list: (team: string, params?: {
|
|
242
|
-
page?: number;
|
|
243
|
-
mime?: string;
|
|
244
|
-
}) => Promise<{
|
|
245
|
-
ok: boolean;
|
|
246
|
-
data?: Media[];
|
|
247
|
-
}>;
|
|
248
|
-
upload: (data: {
|
|
249
|
-
team: string;
|
|
250
|
-
file: File;
|
|
251
|
-
type: 'output';
|
|
252
|
-
label?: string;
|
|
253
|
-
}) => Promise<{
|
|
254
|
-
ok: boolean;
|
|
255
|
-
data?: Media;
|
|
256
|
-
}>;
|
|
257
|
-
};
|
|
258
|
-
};
|
|
259
|
-
type ContentContextValue = {
|
|
260
|
-
content: Content | null;
|
|
261
|
-
values: Record<string, ContentValue>;
|
|
262
|
-
isLoading: boolean;
|
|
263
|
-
isSaving: boolean;
|
|
264
|
-
isEditing: boolean;
|
|
265
|
-
isDirty: boolean;
|
|
266
|
-
canEdit: boolean;
|
|
267
|
-
canPublish: boolean;
|
|
268
|
-
teamSlug?: string;
|
|
269
|
-
media?: ContentClient['media'];
|
|
270
|
-
error: string | null;
|
|
271
|
-
setEditing: (editing: boolean) => void;
|
|
272
|
-
setValue: (key: string, value: ContentValue) => void;
|
|
273
|
-
save: () => Promise<boolean>;
|
|
274
|
-
publish: () => Promise<boolean>;
|
|
275
|
-
};
|
|
276
|
-
type ContentProviderProp = {
|
|
277
|
-
children: ReactNode;
|
|
278
|
-
client: ContentClient;
|
|
279
|
-
contentId?: string;
|
|
280
|
-
publicSlug?: string;
|
|
281
|
-
initialContent?: Content;
|
|
282
|
-
canEdit?: boolean;
|
|
283
|
-
canPublish?: boolean;
|
|
284
|
-
teamSlug?: string;
|
|
285
|
-
};
|
|
286
|
-
type EditableContentProp = {
|
|
287
|
-
field: string;
|
|
288
|
-
as?: 'span' | 'p' | 'div' | 'h1' | 'h2' | 'h3';
|
|
289
|
-
className?: string;
|
|
290
|
-
placeholder?: string;
|
|
291
|
-
multiline?: boolean;
|
|
292
|
-
};
|
|
293
|
-
type EditableImageProp = {
|
|
294
|
-
field: string;
|
|
295
|
-
alt?: string;
|
|
296
|
-
className?: string;
|
|
297
|
-
onSelect?: () => void;
|
|
298
|
-
inputClassName?: string;
|
|
299
|
-
placeholder?: string;
|
|
300
|
-
};
|
|
301
|
-
type ContentToolbarProp = {
|
|
302
|
-
className?: string;
|
|
303
|
-
confirmPublish?: () => boolean | Promise<boolean>;
|
|
304
|
-
labels?: {
|
|
305
|
-
edit?: string;
|
|
306
|
-
save?: string;
|
|
307
|
-
publish?: string;
|
|
308
|
-
cancel?: string;
|
|
309
|
-
};
|
|
310
|
-
};
|
|
311
|
-
//#endregion
|
|
312
|
-
//#region src/react/content/provider.d.ts
|
|
313
|
-
declare function ContentProvider({
|
|
314
|
-
children,
|
|
315
|
-
client,
|
|
316
|
-
contentId,
|
|
317
|
-
publicSlug,
|
|
318
|
-
initialContent,
|
|
319
|
-
canEdit,
|
|
320
|
-
canPublish,
|
|
321
|
-
teamSlug
|
|
322
|
-
}: ContentProviderProp): _$react.JSX.Element;
|
|
323
|
-
//#endregion
|
|
324
|
-
//#region src/react/content/editable-content.d.ts
|
|
325
|
-
declare function EditableContent({
|
|
326
|
-
field,
|
|
327
|
-
as: Tag,
|
|
328
|
-
className,
|
|
329
|
-
placeholder,
|
|
330
|
-
multiline
|
|
331
|
-
}: EditableContentProp): _$react.JSX.Element;
|
|
332
|
-
declare function useContentValue<T extends ContentValue = ContentValue>(key: string): T | undefined;
|
|
333
|
-
//#endregion
|
|
334
|
-
//#region src/react/content/editable-image.d.ts
|
|
335
|
-
declare function EditableImage({
|
|
336
|
-
field,
|
|
337
|
-
alt,
|
|
338
|
-
className,
|
|
339
|
-
inputClassName,
|
|
340
|
-
placeholder,
|
|
341
|
-
onSelect
|
|
342
|
-
}: EditableImageProp): _$react.JSX.Element | null;
|
|
343
|
-
//#endregion
|
|
344
|
-
//#region src/react/content/toolbar.d.ts
|
|
345
|
-
declare function ContentToolbar({
|
|
346
|
-
className,
|
|
347
|
-
labels,
|
|
348
|
-
confirmPublish
|
|
349
|
-
}: ContentToolbarProp): _$react.JSX.Element | null;
|
|
350
|
-
//#endregion
|
|
351
|
-
//#region src/react/content/content-editor.d.ts
|
|
352
|
-
type Prop = ContentProviderProp & {
|
|
353
|
-
children: ReactNode;
|
|
354
|
-
title?: string;
|
|
355
|
-
};
|
|
356
|
-
declare function ContentEditor({
|
|
357
|
-
children,
|
|
358
|
-
title,
|
|
359
|
-
...provider
|
|
360
|
-
}: Prop): _$react.JSX.Element;
|
|
361
|
-
//#endregion
|
|
362
|
-
export { ContentClient, ContentContextValue, ContentEditor, ContentProvider, ContentProviderProp, ContentResource, ContentToolbar, ContentToolbarProp, EditableContent, EditableContentProp, EditableImage, EditableImageProp, EmbedChatInput, EmbedChatItem, EmbedChatList, StreamDataHandler, clearRoom, getOrCreateGuestId, loadRoom, openEventSourceStream, saveRoom, useContentValue, useEmbedChat };
|