@axcode/axcloud-sdk 0.1.5 → 0.1.6
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 +41 -1
- package/dist/index.d.ts +41 -1
- package/dist/index.js +94 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +92 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -216,6 +216,8 @@ interface ContentTranslation {
|
|
|
216
216
|
slug: string;
|
|
217
217
|
description?: string;
|
|
218
218
|
blocks: ContentBlock[];
|
|
219
|
+
/** Structured website/template fields for this language. */
|
|
220
|
+
fields?: Record<string, unknown>;
|
|
219
221
|
metaTitle?: string;
|
|
220
222
|
metaDescription?: string;
|
|
221
223
|
keywords?: string[];
|
|
@@ -232,6 +234,10 @@ interface ContentItem {
|
|
|
232
234
|
content?: string;
|
|
233
235
|
description?: string;
|
|
234
236
|
blocks?: ContentBlock[];
|
|
237
|
+
/** Template identifier used by websites, e.g. "home" or "landing". */
|
|
238
|
+
template?: string;
|
|
239
|
+
/** Structured website/template fields. Frontends own layout and read these values by key. */
|
|
240
|
+
fields?: Record<string, unknown>;
|
|
235
241
|
excerpt?: string;
|
|
236
242
|
author?: {
|
|
237
243
|
id: string;
|
|
@@ -361,6 +367,24 @@ interface MediaListResponse {
|
|
|
361
367
|
prefix: string;
|
|
362
368
|
}
|
|
363
369
|
|
|
370
|
+
type ContentSlotValue = string | number | boolean | null | undefined | string[] | Record<string, unknown> | unknown[];
|
|
371
|
+
type ContentSlotMap = Record<string, ContentSlotValue>;
|
|
372
|
+
interface ContentSlotImage {
|
|
373
|
+
url: string;
|
|
374
|
+
alt?: string;
|
|
375
|
+
caption?: string;
|
|
376
|
+
}
|
|
377
|
+
interface ContentSlotReader {
|
|
378
|
+
fields: ContentSlotMap;
|
|
379
|
+
value<T = ContentSlotValue>(key: string, fallback?: T): ContentSlotValue | T;
|
|
380
|
+
text(key: string, fallback?: string): string;
|
|
381
|
+
html(key: string, fallback?: string): string;
|
|
382
|
+
list(key: string, fallback?: string[]): string[];
|
|
383
|
+
image(key: string, fallback?: ContentSlotImage): ContentSlotImage | undefined;
|
|
384
|
+
}
|
|
385
|
+
declare function getContentSlotMap(content?: Pick<ContentItem, 'fields' | 'blocks'> | null): ContentSlotMap;
|
|
386
|
+
declare function createContentSlotReader(content?: Pick<ContentItem, 'fields' | 'blocks'> | null): ContentSlotReader;
|
|
387
|
+
|
|
364
388
|
/**
|
|
365
389
|
* AxCloud Forms Module
|
|
366
390
|
*
|
|
@@ -896,6 +920,22 @@ declare function useContentItem<T extends ContentItem = ContentItem>(contentType
|
|
|
896
920
|
error: Error | null;
|
|
897
921
|
refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<_tanstack_react_query.NoInfer<T>, Error>>;
|
|
898
922
|
};
|
|
923
|
+
interface PageContentState<T extends ContentItem = ContentItem> extends ContentSlotReader {
|
|
924
|
+
page: T | null;
|
|
925
|
+
data: T | null;
|
|
926
|
+
isLoading: boolean;
|
|
927
|
+
isError: boolean;
|
|
928
|
+
error: Error | null;
|
|
929
|
+
refetch: () => unknown;
|
|
930
|
+
}
|
|
931
|
+
/**
|
|
932
|
+
* usePageContent - Fetch a website page and expose structured template fields.
|
|
933
|
+
*
|
|
934
|
+
* Use `page.content`/`page.blocks` for article-like rich text pages. Use
|
|
935
|
+
* `text('hero.title')`, `list('benefits.items')`, etc. for designed website templates
|
|
936
|
+
* where the frontend owns layout and AxCloud owns content.
|
|
937
|
+
*/
|
|
938
|
+
declare function usePageContent<T extends ContentItem = ContentItem>(slug: string, options?: ContentItemOptions): PageContentState<T>;
|
|
899
939
|
|
|
900
940
|
interface SectionWithMembers extends Section {
|
|
901
941
|
members?: User[];
|
|
@@ -1529,4 +1569,4 @@ interface LinkedAccountsListProps {
|
|
|
1529
1569
|
*/
|
|
1530
1570
|
declare function LinkedAccountsList({ providers, showConnectButtons, className, onUnlink, onLinkInitiated, renderIdentity, renderAvailableProvider, }: LinkedAccountsListProps): react_jsx_runtime.JSX.Element;
|
|
1531
1571
|
|
|
1532
|
-
export { type AvailableProvider, AxCloudClient, type AxCloudConfig, AxCloudError, type AxCloudErrorCode, type AxCloudModule, AxCloudProvider, type BaseRole, type ContentItem, type ContentQueryOptions, type CustomRole, type FormStatsResponse, type FormSubmission, type FormSubmissionRecord, type FormSubmissionResponse, type FormSubmissionsResponse, LinkedAccountsList, type LinkedAccountsListProps, type LinkedIdentity, LoginButton, LogoutButton, type MediaItem, type MediaListResponse, type Membership, ModuleGate, type NewsItem, type Organization, type OrganizationBranding, type OrganizationSettings, type Page, type PaginatedResponse, ProtectedRoute, type Section, type SectionPermissions, type SignedMediaUrl, type SystemRole, type UseLinkedAccountsReturn, type User, type UserRole, createClient, createFormHelper, getClient, isAxCloudError, submitForm, useAuth, useAvatar, useAxCloudContext, useBranding, useContent, useContentItem, useFormStats, useForms, useLinkedAccounts, useLogo, useMedia, useMediaList, useModuleAccess, useMySection, useNews, useOrg, useSections, useUpdateFormSubmission, useUser, userHasAllPermissions, userHasAnyPermission, userHasPermission };
|
|
1572
|
+
export { type AvailableProvider, AxCloudClient, type AxCloudConfig, AxCloudError, type AxCloudErrorCode, type AxCloudModule, AxCloudProvider, type BaseRole, type ContentItem, type ContentQueryOptions, type ContentSlotImage, type ContentSlotMap, type ContentSlotReader, type ContentSlotValue, type CustomRole, type FormStatsResponse, type FormSubmission, type FormSubmissionRecord, type FormSubmissionResponse, type FormSubmissionsResponse, LinkedAccountsList, type LinkedAccountsListProps, type LinkedIdentity, LoginButton, LogoutButton, type MediaItem, type MediaListResponse, type Membership, ModuleGate, type NewsItem, type Organization, type OrganizationBranding, type OrganizationSettings, type Page, type PageContentState, type PaginatedResponse, ProtectedRoute, type Section, type SectionPermissions, type SignedMediaUrl, type SystemRole, type UseLinkedAccountsReturn, type User, type UserRole, createClient, createContentSlotReader, createFormHelper, getClient, getContentSlotMap, isAxCloudError, submitForm, useAuth, useAvatar, useAxCloudContext, useBranding, useContent, useContentItem, useFormStats, useForms, useLinkedAccounts, useLogo, useMedia, useMediaList, useModuleAccess, useMySection, useNews, useOrg, usePageContent, useSections, useUpdateFormSubmission, useUser, userHasAllPermissions, userHasAnyPermission, userHasPermission };
|
package/dist/index.d.ts
CHANGED
|
@@ -216,6 +216,8 @@ interface ContentTranslation {
|
|
|
216
216
|
slug: string;
|
|
217
217
|
description?: string;
|
|
218
218
|
blocks: ContentBlock[];
|
|
219
|
+
/** Structured website/template fields for this language. */
|
|
220
|
+
fields?: Record<string, unknown>;
|
|
219
221
|
metaTitle?: string;
|
|
220
222
|
metaDescription?: string;
|
|
221
223
|
keywords?: string[];
|
|
@@ -232,6 +234,10 @@ interface ContentItem {
|
|
|
232
234
|
content?: string;
|
|
233
235
|
description?: string;
|
|
234
236
|
blocks?: ContentBlock[];
|
|
237
|
+
/** Template identifier used by websites, e.g. "home" or "landing". */
|
|
238
|
+
template?: string;
|
|
239
|
+
/** Structured website/template fields. Frontends own layout and read these values by key. */
|
|
240
|
+
fields?: Record<string, unknown>;
|
|
235
241
|
excerpt?: string;
|
|
236
242
|
author?: {
|
|
237
243
|
id: string;
|
|
@@ -361,6 +367,24 @@ interface MediaListResponse {
|
|
|
361
367
|
prefix: string;
|
|
362
368
|
}
|
|
363
369
|
|
|
370
|
+
type ContentSlotValue = string | number | boolean | null | undefined | string[] | Record<string, unknown> | unknown[];
|
|
371
|
+
type ContentSlotMap = Record<string, ContentSlotValue>;
|
|
372
|
+
interface ContentSlotImage {
|
|
373
|
+
url: string;
|
|
374
|
+
alt?: string;
|
|
375
|
+
caption?: string;
|
|
376
|
+
}
|
|
377
|
+
interface ContentSlotReader {
|
|
378
|
+
fields: ContentSlotMap;
|
|
379
|
+
value<T = ContentSlotValue>(key: string, fallback?: T): ContentSlotValue | T;
|
|
380
|
+
text(key: string, fallback?: string): string;
|
|
381
|
+
html(key: string, fallback?: string): string;
|
|
382
|
+
list(key: string, fallback?: string[]): string[];
|
|
383
|
+
image(key: string, fallback?: ContentSlotImage): ContentSlotImage | undefined;
|
|
384
|
+
}
|
|
385
|
+
declare function getContentSlotMap(content?: Pick<ContentItem, 'fields' | 'blocks'> | null): ContentSlotMap;
|
|
386
|
+
declare function createContentSlotReader(content?: Pick<ContentItem, 'fields' | 'blocks'> | null): ContentSlotReader;
|
|
387
|
+
|
|
364
388
|
/**
|
|
365
389
|
* AxCloud Forms Module
|
|
366
390
|
*
|
|
@@ -896,6 +920,22 @@ declare function useContentItem<T extends ContentItem = ContentItem>(contentType
|
|
|
896
920
|
error: Error | null;
|
|
897
921
|
refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<_tanstack_react_query.NoInfer<T>, Error>>;
|
|
898
922
|
};
|
|
923
|
+
interface PageContentState<T extends ContentItem = ContentItem> extends ContentSlotReader {
|
|
924
|
+
page: T | null;
|
|
925
|
+
data: T | null;
|
|
926
|
+
isLoading: boolean;
|
|
927
|
+
isError: boolean;
|
|
928
|
+
error: Error | null;
|
|
929
|
+
refetch: () => unknown;
|
|
930
|
+
}
|
|
931
|
+
/**
|
|
932
|
+
* usePageContent - Fetch a website page and expose structured template fields.
|
|
933
|
+
*
|
|
934
|
+
* Use `page.content`/`page.blocks` for article-like rich text pages. Use
|
|
935
|
+
* `text('hero.title')`, `list('benefits.items')`, etc. for designed website templates
|
|
936
|
+
* where the frontend owns layout and AxCloud owns content.
|
|
937
|
+
*/
|
|
938
|
+
declare function usePageContent<T extends ContentItem = ContentItem>(slug: string, options?: ContentItemOptions): PageContentState<T>;
|
|
899
939
|
|
|
900
940
|
interface SectionWithMembers extends Section {
|
|
901
941
|
members?: User[];
|
|
@@ -1529,4 +1569,4 @@ interface LinkedAccountsListProps {
|
|
|
1529
1569
|
*/
|
|
1530
1570
|
declare function LinkedAccountsList({ providers, showConnectButtons, className, onUnlink, onLinkInitiated, renderIdentity, renderAvailableProvider, }: LinkedAccountsListProps): react_jsx_runtime.JSX.Element;
|
|
1531
1571
|
|
|
1532
|
-
export { type AvailableProvider, AxCloudClient, type AxCloudConfig, AxCloudError, type AxCloudErrorCode, type AxCloudModule, AxCloudProvider, type BaseRole, type ContentItem, type ContentQueryOptions, type CustomRole, type FormStatsResponse, type FormSubmission, type FormSubmissionRecord, type FormSubmissionResponse, type FormSubmissionsResponse, LinkedAccountsList, type LinkedAccountsListProps, type LinkedIdentity, LoginButton, LogoutButton, type MediaItem, type MediaListResponse, type Membership, ModuleGate, type NewsItem, type Organization, type OrganizationBranding, type OrganizationSettings, type Page, type PaginatedResponse, ProtectedRoute, type Section, type SectionPermissions, type SignedMediaUrl, type SystemRole, type UseLinkedAccountsReturn, type User, type UserRole, createClient, createFormHelper, getClient, isAxCloudError, submitForm, useAuth, useAvatar, useAxCloudContext, useBranding, useContent, useContentItem, useFormStats, useForms, useLinkedAccounts, useLogo, useMedia, useMediaList, useModuleAccess, useMySection, useNews, useOrg, useSections, useUpdateFormSubmission, useUser, userHasAllPermissions, userHasAnyPermission, userHasPermission };
|
|
1572
|
+
export { type AvailableProvider, AxCloudClient, type AxCloudConfig, AxCloudError, type AxCloudErrorCode, type AxCloudModule, AxCloudProvider, type BaseRole, type ContentItem, type ContentQueryOptions, type ContentSlotImage, type ContentSlotMap, type ContentSlotReader, type ContentSlotValue, type CustomRole, type FormStatsResponse, type FormSubmission, type FormSubmissionRecord, type FormSubmissionResponse, type FormSubmissionsResponse, LinkedAccountsList, type LinkedAccountsListProps, type LinkedIdentity, LoginButton, LogoutButton, type MediaItem, type MediaListResponse, type Membership, ModuleGate, type NewsItem, type Organization, type OrganizationBranding, type OrganizationSettings, type Page, type PageContentState, type PaginatedResponse, ProtectedRoute, type Section, type SectionPermissions, type SignedMediaUrl, type SystemRole, type UseLinkedAccountsReturn, type User, type UserRole, createClient, createContentSlotReader, createFormHelper, getClient, getContentSlotMap, isAxCloudError, submitForm, useAuth, useAvatar, useAxCloudContext, useBranding, useContent, useContentItem, useFormStats, useForms, useLinkedAccounts, useLogo, useMedia, useMediaList, useModuleAccess, useMySection, useNews, useOrg, usePageContent, useSections, useUpdateFormSubmission, useUser, userHasAllPermissions, userHasAnyPermission, userHasPermission };
|
package/dist/index.js
CHANGED
|
@@ -238,6 +238,88 @@ function getClient(key) {
|
|
|
238
238
|
throw new Error("AxCloud client not found. Make sure AxCloudProvider is mounted and use useAxCloudContext() to get the client.");
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
+
// src/core/contentSlots.ts
|
|
242
|
+
var SLOT_ATTRIBUTE_KEYS = ["slot", "field", "key", "name"];
|
|
243
|
+
function getContentSlotMap(content) {
|
|
244
|
+
const fields = isRecord(content?.fields) ? { ...content?.fields } : {};
|
|
245
|
+
for (const block of content?.blocks || []) {
|
|
246
|
+
const slot = getBlockSlot(block);
|
|
247
|
+
if (!slot) continue;
|
|
248
|
+
fields[slot] = blockToSlotValue(block);
|
|
249
|
+
}
|
|
250
|
+
return fields;
|
|
251
|
+
}
|
|
252
|
+
function createContentSlotReader(content) {
|
|
253
|
+
const fields = getContentSlotMap(content);
|
|
254
|
+
const value = (key, fallback) => {
|
|
255
|
+
return key in fields ? fields[key] : fallback;
|
|
256
|
+
};
|
|
257
|
+
return {
|
|
258
|
+
fields,
|
|
259
|
+
value,
|
|
260
|
+
text: (key, fallback = "") => stringifySlotValue(value(key, fallback)),
|
|
261
|
+
html: (key, fallback = "") => stringifySlotValue(value(key, fallback)),
|
|
262
|
+
list: (key, fallback = []) => slotValueToList(value(key, fallback)),
|
|
263
|
+
image: (key, fallback) => slotValueToImage(value(key, fallback))
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function getBlockSlot(block) {
|
|
267
|
+
const attributes = block.attributes || {};
|
|
268
|
+
for (const key of SLOT_ATTRIBUTE_KEYS) {
|
|
269
|
+
const value = attributes[key];
|
|
270
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
271
|
+
}
|
|
272
|
+
return void 0;
|
|
273
|
+
}
|
|
274
|
+
function blockToSlotValue(block) {
|
|
275
|
+
if (block.attributes && "value" in block.attributes) {
|
|
276
|
+
return block.attributes.value;
|
|
277
|
+
}
|
|
278
|
+
if (block.type === "list") {
|
|
279
|
+
return Array.isArray(block.items) ? block.items : [];
|
|
280
|
+
}
|
|
281
|
+
if (block.type === "image" && block.url) {
|
|
282
|
+
return {
|
|
283
|
+
url: block.url,
|
|
284
|
+
alt: block.alt,
|
|
285
|
+
caption: block.caption
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
return block.content ?? "";
|
|
289
|
+
}
|
|
290
|
+
function stringifySlotValue(value) {
|
|
291
|
+
if (value === void 0 || value === null) return "";
|
|
292
|
+
if (typeof value === "string") return value;
|
|
293
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
294
|
+
if (Array.isArray(value)) return value.map((item) => stringifySlotValue(item)).filter(Boolean).join("\n");
|
|
295
|
+
return "";
|
|
296
|
+
}
|
|
297
|
+
function slotValueToList(value) {
|
|
298
|
+
if (Array.isArray(value)) {
|
|
299
|
+
return value.map((item) => stringifySlotValue(item)).filter(Boolean);
|
|
300
|
+
}
|
|
301
|
+
if (typeof value === "string") {
|
|
302
|
+
return value.split(/\r?\n/).map((item) => item.trim()).filter(Boolean);
|
|
303
|
+
}
|
|
304
|
+
return [];
|
|
305
|
+
}
|
|
306
|
+
function slotValueToImage(value) {
|
|
307
|
+
if (isRecord(value) && typeof value.url === "string") {
|
|
308
|
+
return {
|
|
309
|
+
url: value.url,
|
|
310
|
+
alt: typeof value.alt === "string" ? value.alt : void 0,
|
|
311
|
+
caption: typeof value.caption === "string" ? value.caption : void 0
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
if (typeof value === "string" && value) {
|
|
315
|
+
return { url: value };
|
|
316
|
+
}
|
|
317
|
+
return void 0;
|
|
318
|
+
}
|
|
319
|
+
function isRecord(value) {
|
|
320
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
321
|
+
}
|
|
322
|
+
|
|
241
323
|
// src/core/types.ts
|
|
242
324
|
function userHasPermission(user, permission) {
|
|
243
325
|
if (user.permissions && user.permissions.length > 0) {
|
|
@@ -791,6 +873,15 @@ function useContentItem(contentType, idOrSlug, options = {}) {
|
|
|
791
873
|
refetch: query.refetch
|
|
792
874
|
};
|
|
793
875
|
}
|
|
876
|
+
function usePageContent(slug, options = {}) {
|
|
877
|
+
const state = useContentItem("pages", slug, options);
|
|
878
|
+
const reader = react.useMemo(() => createContentSlotReader(state.data), [state.data]);
|
|
879
|
+
return {
|
|
880
|
+
...state,
|
|
881
|
+
page: state.data,
|
|
882
|
+
...reader
|
|
883
|
+
};
|
|
884
|
+
}
|
|
794
885
|
function useMySection(options = {}) {
|
|
795
886
|
const { includeMembers = true } = options;
|
|
796
887
|
const { isAuthenticated } = auth0React.useAuth0();
|
|
@@ -1319,8 +1410,10 @@ exports.LogoutButton = LogoutButton;
|
|
|
1319
1410
|
exports.ModuleGate = ModuleGate;
|
|
1320
1411
|
exports.ProtectedRoute = ProtectedRoute;
|
|
1321
1412
|
exports.createClient = createClient;
|
|
1413
|
+
exports.createContentSlotReader = createContentSlotReader;
|
|
1322
1414
|
exports.createFormHelper = createFormHelper;
|
|
1323
1415
|
exports.getClient = getClient;
|
|
1416
|
+
exports.getContentSlotMap = getContentSlotMap;
|
|
1324
1417
|
exports.isAxCloudError = isAxCloudError;
|
|
1325
1418
|
exports.submitForm = submitForm;
|
|
1326
1419
|
exports.useAuth = useAuth;
|
|
@@ -1339,6 +1432,7 @@ exports.useModuleAccess = useModuleAccess;
|
|
|
1339
1432
|
exports.useMySection = useMySection;
|
|
1340
1433
|
exports.useNews = useNews;
|
|
1341
1434
|
exports.useOrg = useOrg;
|
|
1435
|
+
exports.usePageContent = usePageContent;
|
|
1342
1436
|
exports.useSections = useSections;
|
|
1343
1437
|
exports.useUpdateFormSubmission = useUpdateFormSubmission;
|
|
1344
1438
|
exports.useUser = useUser;
|