@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 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;