@storyblok/api-client 0.2.3 → 0.2.4

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.
@@ -3,6 +3,18 @@ const require_fetch_rel_uuids = require('./fetch-rel-uuids.cjs');
3
3
  //#region src/utils/inline-relations.ts
4
4
  const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
5
5
  const isComponentNode = (value) => typeof value.component === "string" && typeof value._uid === "string";
6
+ /**
7
+ * Decodes a string if it appears to be URL-encoded.
8
+ * Detects common encoded characters (%2C for comma, %20 for space, etc.)
9
+ */
10
+ const decodeIfEncoded = (value) => {
11
+ if (/%[0-9A-F]{2}/i.test(value)) try {
12
+ return decodeURIComponent(value);
13
+ } catch {
14
+ return value;
15
+ }
16
+ return value;
17
+ };
6
18
  const inlineStoryContentInternal = (story, relationPaths, relationMap, resolved) => {
7
19
  const existingStory = resolved.get(story.uuid);
8
20
  if (existingStory) return existingStory;
@@ -27,7 +39,7 @@ function resolveNode(value, relationMap, relationPaths, resolved) {
27
39
  }
28
40
  const parseResolveRelations = (query) => {
29
41
  if (typeof query.resolve_relations !== "string") return [];
30
- return query.resolve_relations.split(",").map((path) => path.trim()).filter((path) => {
42
+ return decodeIfEncoded(query.resolve_relations).split(",").map((path) => path.trim()).filter((path) => {
31
43
  const [component = "", field = "", ...rest] = path.split(".");
32
44
  return component.length > 0 && field.length > 0 && rest.length === 0;
33
45
  });
@@ -1 +1 @@
1
- {"version":3,"file":"inline-relations.cjs","names":["fetchMissingRelations"],"sources":["../../src/utils/inline-relations.ts"],"sourcesContent":["import type { Client } from '../generated/shared/client';\nimport type { StoryCapi } from '../generated/stories';\nimport type { StoryWithInlinedRelations } from '../resources/stories';\nimport { fetchMissingRelations } from './fetch-rel-uuids';\nimport type { ThrottleManager } from './rate-limit';\n\ntype RelationPath = `${string}.${string}`;\n\ninterface ComponentNode {\n _uid: string;\n component: string;\n [key: string]: unknown;\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === 'object' && !Array.isArray(value);\n\nconst isComponentNode = (value: Record<string, unknown>): value is ComponentNode =>\n typeof value.component === 'string' && typeof value._uid === 'string';\n\nconst inlineStoryContentInternal = <TStory extends StoryCapi | StoryWithInlinedRelations>(\n story: TStory,\n relationPaths: ReadonlySet<RelationPath>,\n relationMap: ReadonlyMap<string, TStory>,\n resolved: Map<string, TStory>,\n): TStory => {\n const existingStory = resolved.get(story.uuid);\n if (existingStory) {\n return existingStory;\n }\n\n const clonedStory = structuredClone(story);\n resolved.set(story.uuid, clonedStory);\n // resolveNode returns `unknown` to handle arbitrary JSON trees; shape is preserved at runtime.\n clonedStory.content = resolveNode(clonedStory.content, relationMap, relationPaths, resolved) as StoryCapi['content'];\n return clonedStory;\n};\n\nfunction resolveNode<TStory extends StoryCapi | StoryWithInlinedRelations>(\n value: unknown,\n relationMap: ReadonlyMap<string, TStory>,\n relationPaths: ReadonlySet<RelationPath>,\n resolved: Map<string, TStory>,\n): unknown {\n if (Array.isArray(value)) {\n return value.map(item => resolveNode(item, relationMap, relationPaths, resolved));\n }\n\n if (!isRecord(value)) {\n return value;\n }\n\n if (isComponentNode(value)) {\n for (const [fieldName, fieldValue] of Object.entries(value)) {\n if (fieldName === 'component' || fieldName === '_uid') {\n continue;\n }\n\n const relationPath: RelationPath = `${value.component}.${fieldName}`;\n value[fieldName] = relationPaths.has(relationPath)\n ? resolveFieldValue(fieldValue, relationMap, relationPaths, resolved)\n : resolveNode(fieldValue, relationMap, relationPaths, resolved);\n }\n\n return value;\n }\n\n for (const [fieldName, fieldValue] of Object.entries(value)) {\n value[fieldName] = resolveNode(fieldValue, relationMap, relationPaths, resolved);\n }\n\n return value;\n}\n\nexport const parseResolveRelations = (query: Record<string, unknown>): RelationPath[] => {\n if (typeof query.resolve_relations !== 'string') {\n return [];\n }\n\n return query.resolve_relations\n .split(',')\n .map(path => path.trim())\n .filter((path): path is RelationPath => {\n const [component = '', field = '', ...rest] = path.split('.');\n return component.length > 0 && field.length > 0 && rest.length === 0;\n });\n};\n\nexport const buildRelationMap = (rels: Array<StoryCapi> | undefined): Map<string, StoryCapi> => {\n const relationMap = new Map<string, StoryCapi>();\n\n for (const story of rels ?? []) {\n relationMap.set(story.uuid, story);\n }\n\n return relationMap;\n};\n\nfunction resolveFieldValue<TStory extends StoryCapi | StoryWithInlinedRelations>(\n value: unknown,\n relationMap: ReadonlyMap<string, TStory>,\n relationPaths: ReadonlySet<RelationPath>,\n resolved: Map<string, TStory>,\n): unknown {\n if (typeof value === 'string') {\n const relatedStory = relationMap.get(value);\n if (!relatedStory) {\n return value;\n }\n\n return inlineStoryContentInternal(relatedStory, relationPaths, relationMap, resolved);\n }\n\n if (Array.isArray(value)) {\n return value.map(item => resolveFieldValue(item, relationMap, relationPaths, resolved));\n }\n\n return resolveNode(value, relationMap, relationPaths, resolved);\n}\n\nexport const inlineStoryContent = <TStory extends StoryCapi | StoryWithInlinedRelations>(\n story: TStory,\n relationPaths: RelationPath[],\n relationMap: ReadonlyMap<string, TStory>,\n): TStory => {\n const normalizedPaths = new Set(relationPaths);\n const resolved = new Map<string, TStory>();\n return inlineStoryContentInternal(story, normalizedPaths, relationMap, resolved);\n};\n\nexport const inlineStoriesContent = <TStory extends StoryCapi | StoryWithInlinedRelations>(\n stories: Array<TStory>,\n relationPaths: RelationPath[],\n relationMap: ReadonlyMap<string, TStory>,\n): Array<TStory> => {\n const normalizedPaths = new Set(relationPaths);\n const resolved = new Map<string, TStory>();\n return stories.map(story => inlineStoryContentInternal(story, normalizedPaths, relationMap, resolved));\n};\n\ninterface ResolveRelationMapOptions {\n client: Client;\n throttleManager: ThrottleManager;\n}\n\nexport interface ResolvedRelations {\n relationPaths: RelationPath[];\n relationMap: Map<string, StoryCapi>;\n}\n\n/**\n * Parses relation paths from the request query, builds a relation map from the\n * response's `rels`, and fetches any additional relations referenced by `rel_uuids`.\n *\n * Returns `null` when there is nothing to inline (no `resolve_relations` in the query).\n */\nexport const resolveRelationMap = async (\n responseData: { rels?: StoryCapi[]; rel_uuids?: string[] },\n requestQuery: Record<string, unknown>,\n { client, throttleManager }: ResolveRelationMapOptions,\n): Promise<ResolvedRelations | null> => {\n const relationPaths = parseResolveRelations(requestQuery);\n if (relationPaths.length === 0) {\n return null;\n }\n\n const relationMap = buildRelationMap(responseData.rels);\n if (responseData.rel_uuids?.length) {\n const missingUuids = responseData.rel_uuids.filter(uuid => !relationMap.has(uuid));\n if (missingUuids.length > 0) {\n const fetchedRelations = await fetchMissingRelations({\n client,\n uuids: missingUuids,\n baseQuery: requestQuery,\n throttleManager,\n });\n for (const relationStory of fetchedRelations) {\n relationMap.set(relationStory.uuid, relationStory);\n }\n }\n }\n\n return { relationPaths, relationMap };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"inline-relations.cjs","names":["fetchMissingRelations"],"sources":["../../src/utils/inline-relations.ts"],"sourcesContent":["import type { Client } from '../generated/shared/client';\nimport type { StoryCapi } from '../generated/stories';\nimport type { StoryWithInlinedRelations } from '../resources/stories';\nimport { fetchMissingRelations } from './fetch-rel-uuids';\nimport type { ThrottleManager } from './rate-limit';\n\ntype RelationPath = `${string}.${string}`;\n\ninterface ComponentNode {\n _uid: string;\n component: string;\n [key: string]: unknown;\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === 'object' && !Array.isArray(value);\n\nconst isComponentNode = (value: Record<string, unknown>): value is ComponentNode =>\n typeof value.component === 'string' && typeof value._uid === 'string';\n\n/**\n * Decodes a string if it appears to be URL-encoded.\n * Detects common encoded characters (%2C for comma, %20 for space, etc.)\n */\nconst decodeIfEncoded = (value: string): string => {\n // Check if the string contains URL-encoded characters (% followed by hex digits)\n if (/%[0-9A-F]{2}/i.test(value)) {\n try {\n return decodeURIComponent(value);\n }\n catch {\n // If decoding fails (malformed encoding), return original\n return value;\n }\n }\n return value;\n};\n\nconst inlineStoryContentInternal = <TStory extends StoryCapi | StoryWithInlinedRelations>(\n story: TStory,\n relationPaths: ReadonlySet<RelationPath>,\n relationMap: ReadonlyMap<string, TStory>,\n resolved: Map<string, TStory>,\n): TStory => {\n const existingStory = resolved.get(story.uuid);\n if (existingStory) {\n return existingStory;\n }\n\n const clonedStory = structuredClone(story);\n resolved.set(story.uuid, clonedStory);\n // resolveNode returns `unknown` to handle arbitrary JSON trees; shape is preserved at runtime.\n clonedStory.content = resolveNode(clonedStory.content, relationMap, relationPaths, resolved) as StoryCapi['content'];\n return clonedStory;\n};\n\nfunction resolveNode<TStory extends StoryCapi | StoryWithInlinedRelations>(\n value: unknown,\n relationMap: ReadonlyMap<string, TStory>,\n relationPaths: ReadonlySet<RelationPath>,\n resolved: Map<string, TStory>,\n): unknown {\n if (Array.isArray(value)) {\n return value.map(item => resolveNode(item, relationMap, relationPaths, resolved));\n }\n\n if (!isRecord(value)) {\n return value;\n }\n\n if (isComponentNode(value)) {\n for (const [fieldName, fieldValue] of Object.entries(value)) {\n if (fieldName === 'component' || fieldName === '_uid') {\n continue;\n }\n\n const relationPath: RelationPath = `${value.component}.${fieldName}`;\n value[fieldName] = relationPaths.has(relationPath)\n ? resolveFieldValue(fieldValue, relationMap, relationPaths, resolved)\n : resolveNode(fieldValue, relationMap, relationPaths, resolved);\n }\n\n return value;\n }\n\n for (const [fieldName, fieldValue] of Object.entries(value)) {\n value[fieldName] = resolveNode(fieldValue, relationMap, relationPaths, resolved);\n }\n\n return value;\n}\n\nexport const parseResolveRelations = (query: Record<string, unknown>): RelationPath[] => {\n if (typeof query.resolve_relations !== 'string') {\n return [];\n }\n\n // Decode URL-encoded strings to handle pre-encoded input\n const resolveRelations = decodeIfEncoded(query.resolve_relations);\n\n return resolveRelations\n .split(',')\n .map(path => path.trim())\n .filter((path): path is RelationPath => {\n const [component = '', field = '', ...rest] = path.split('.');\n return component.length > 0 && field.length > 0 && rest.length === 0;\n });\n};\n\nexport const buildRelationMap = (rels: Array<StoryCapi> | undefined): Map<string, StoryCapi> => {\n const relationMap = new Map<string, StoryCapi>();\n\n for (const story of rels ?? []) {\n relationMap.set(story.uuid, story);\n }\n\n return relationMap;\n};\n\nfunction resolveFieldValue<TStory extends StoryCapi | StoryWithInlinedRelations>(\n value: unknown,\n relationMap: ReadonlyMap<string, TStory>,\n relationPaths: ReadonlySet<RelationPath>,\n resolved: Map<string, TStory>,\n): unknown {\n if (typeof value === 'string') {\n const relatedStory = relationMap.get(value);\n if (!relatedStory) {\n return value;\n }\n\n return inlineStoryContentInternal(relatedStory, relationPaths, relationMap, resolved);\n }\n\n if (Array.isArray(value)) {\n return value.map(item => resolveFieldValue(item, relationMap, relationPaths, resolved));\n }\n\n return resolveNode(value, relationMap, relationPaths, resolved);\n}\n\nexport const inlineStoryContent = <TStory extends StoryCapi | StoryWithInlinedRelations>(\n story: TStory,\n relationPaths: RelationPath[],\n relationMap: ReadonlyMap<string, TStory>,\n): TStory => {\n const normalizedPaths = new Set(relationPaths);\n const resolved = new Map<string, TStory>();\n return inlineStoryContentInternal(story, normalizedPaths, relationMap, resolved);\n};\n\nexport const inlineStoriesContent = <TStory extends StoryCapi | StoryWithInlinedRelations>(\n stories: Array<TStory>,\n relationPaths: RelationPath[],\n relationMap: ReadonlyMap<string, TStory>,\n): Array<TStory> => {\n const normalizedPaths = new Set(relationPaths);\n const resolved = new Map<string, TStory>();\n return stories.map(story => inlineStoryContentInternal(story, normalizedPaths, relationMap, resolved));\n};\n\ninterface ResolveRelationMapOptions {\n client: Client;\n throttleManager: ThrottleManager;\n}\n\nexport interface ResolvedRelations {\n relationPaths: RelationPath[];\n relationMap: Map<string, StoryCapi>;\n}\n\n/**\n * Parses relation paths from the request query, builds a relation map from the\n * response's `rels`, and fetches any additional relations referenced by `rel_uuids`.\n *\n * Returns `null` when there is nothing to inline (no `resolve_relations` in the query).\n */\nexport const resolveRelationMap = async (\n responseData: { rels?: StoryCapi[]; rel_uuids?: string[] },\n requestQuery: Record<string, unknown>,\n { client, throttleManager }: ResolveRelationMapOptions,\n): Promise<ResolvedRelations | null> => {\n const relationPaths = parseResolveRelations(requestQuery);\n if (relationPaths.length === 0) {\n return null;\n }\n\n const relationMap = buildRelationMap(responseData.rels);\n if (responseData.rel_uuids?.length) {\n const missingUuids = responseData.rel_uuids.filter(uuid => !relationMap.has(uuid));\n if (missingUuids.length > 0) {\n const fetchedRelations = await fetchMissingRelations({\n client,\n uuids: missingUuids,\n baseQuery: requestQuery,\n throttleManager,\n });\n for (const relationStory of fetchedRelations) {\n relationMap.set(relationStory.uuid, relationStory);\n }\n }\n }\n\n return { relationPaths, relationMap };\n};\n"],"mappings":"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"}
@@ -3,6 +3,18 @@ import { fetchMissingRelations } from "./fetch-rel-uuids.mjs";
3
3
  //#region src/utils/inline-relations.ts
4
4
  const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
5
5
  const isComponentNode = (value) => typeof value.component === "string" && typeof value._uid === "string";
6
+ /**
7
+ * Decodes a string if it appears to be URL-encoded.
8
+ * Detects common encoded characters (%2C for comma, %20 for space, etc.)
9
+ */
10
+ const decodeIfEncoded = (value) => {
11
+ if (/%[0-9A-F]{2}/i.test(value)) try {
12
+ return decodeURIComponent(value);
13
+ } catch {
14
+ return value;
15
+ }
16
+ return value;
17
+ };
6
18
  const inlineStoryContentInternal = (story, relationPaths, relationMap, resolved) => {
7
19
  const existingStory = resolved.get(story.uuid);
8
20
  if (existingStory) return existingStory;
@@ -27,7 +39,7 @@ function resolveNode(value, relationMap, relationPaths, resolved) {
27
39
  }
28
40
  const parseResolveRelations = (query) => {
29
41
  if (typeof query.resolve_relations !== "string") return [];
30
- return query.resolve_relations.split(",").map((path) => path.trim()).filter((path) => {
42
+ return decodeIfEncoded(query.resolve_relations).split(",").map((path) => path.trim()).filter((path) => {
31
43
  const [component = "", field = "", ...rest] = path.split(".");
32
44
  return component.length > 0 && field.length > 0 && rest.length === 0;
33
45
  });
@@ -1 +1 @@
1
- {"version":3,"file":"inline-relations.mjs","names":[],"sources":["../../src/utils/inline-relations.ts"],"sourcesContent":["import type { Client } from '../generated/shared/client';\nimport type { StoryCapi } from '../generated/stories';\nimport type { StoryWithInlinedRelations } from '../resources/stories';\nimport { fetchMissingRelations } from './fetch-rel-uuids';\nimport type { ThrottleManager } from './rate-limit';\n\ntype RelationPath = `${string}.${string}`;\n\ninterface ComponentNode {\n _uid: string;\n component: string;\n [key: string]: unknown;\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === 'object' && !Array.isArray(value);\n\nconst isComponentNode = (value: Record<string, unknown>): value is ComponentNode =>\n typeof value.component === 'string' && typeof value._uid === 'string';\n\nconst inlineStoryContentInternal = <TStory extends StoryCapi | StoryWithInlinedRelations>(\n story: TStory,\n relationPaths: ReadonlySet<RelationPath>,\n relationMap: ReadonlyMap<string, TStory>,\n resolved: Map<string, TStory>,\n): TStory => {\n const existingStory = resolved.get(story.uuid);\n if (existingStory) {\n return existingStory;\n }\n\n const clonedStory = structuredClone(story);\n resolved.set(story.uuid, clonedStory);\n // resolveNode returns `unknown` to handle arbitrary JSON trees; shape is preserved at runtime.\n clonedStory.content = resolveNode(clonedStory.content, relationMap, relationPaths, resolved) as StoryCapi['content'];\n return clonedStory;\n};\n\nfunction resolveNode<TStory extends StoryCapi | StoryWithInlinedRelations>(\n value: unknown,\n relationMap: ReadonlyMap<string, TStory>,\n relationPaths: ReadonlySet<RelationPath>,\n resolved: Map<string, TStory>,\n): unknown {\n if (Array.isArray(value)) {\n return value.map(item => resolveNode(item, relationMap, relationPaths, resolved));\n }\n\n if (!isRecord(value)) {\n return value;\n }\n\n if (isComponentNode(value)) {\n for (const [fieldName, fieldValue] of Object.entries(value)) {\n if (fieldName === 'component' || fieldName === '_uid') {\n continue;\n }\n\n const relationPath: RelationPath = `${value.component}.${fieldName}`;\n value[fieldName] = relationPaths.has(relationPath)\n ? resolveFieldValue(fieldValue, relationMap, relationPaths, resolved)\n : resolveNode(fieldValue, relationMap, relationPaths, resolved);\n }\n\n return value;\n }\n\n for (const [fieldName, fieldValue] of Object.entries(value)) {\n value[fieldName] = resolveNode(fieldValue, relationMap, relationPaths, resolved);\n }\n\n return value;\n}\n\nexport const parseResolveRelations = (query: Record<string, unknown>): RelationPath[] => {\n if (typeof query.resolve_relations !== 'string') {\n return [];\n }\n\n return query.resolve_relations\n .split(',')\n .map(path => path.trim())\n .filter((path): path is RelationPath => {\n const [component = '', field = '', ...rest] = path.split('.');\n return component.length > 0 && field.length > 0 && rest.length === 0;\n });\n};\n\nexport const buildRelationMap = (rels: Array<StoryCapi> | undefined): Map<string, StoryCapi> => {\n const relationMap = new Map<string, StoryCapi>();\n\n for (const story of rels ?? []) {\n relationMap.set(story.uuid, story);\n }\n\n return relationMap;\n};\n\nfunction resolveFieldValue<TStory extends StoryCapi | StoryWithInlinedRelations>(\n value: unknown,\n relationMap: ReadonlyMap<string, TStory>,\n relationPaths: ReadonlySet<RelationPath>,\n resolved: Map<string, TStory>,\n): unknown {\n if (typeof value === 'string') {\n const relatedStory = relationMap.get(value);\n if (!relatedStory) {\n return value;\n }\n\n return inlineStoryContentInternal(relatedStory, relationPaths, relationMap, resolved);\n }\n\n if (Array.isArray(value)) {\n return value.map(item => resolveFieldValue(item, relationMap, relationPaths, resolved));\n }\n\n return resolveNode(value, relationMap, relationPaths, resolved);\n}\n\nexport const inlineStoryContent = <TStory extends StoryCapi | StoryWithInlinedRelations>(\n story: TStory,\n relationPaths: RelationPath[],\n relationMap: ReadonlyMap<string, TStory>,\n): TStory => {\n const normalizedPaths = new Set(relationPaths);\n const resolved = new Map<string, TStory>();\n return inlineStoryContentInternal(story, normalizedPaths, relationMap, resolved);\n};\n\nexport const inlineStoriesContent = <TStory extends StoryCapi | StoryWithInlinedRelations>(\n stories: Array<TStory>,\n relationPaths: RelationPath[],\n relationMap: ReadonlyMap<string, TStory>,\n): Array<TStory> => {\n const normalizedPaths = new Set(relationPaths);\n const resolved = new Map<string, TStory>();\n return stories.map(story => inlineStoryContentInternal(story, normalizedPaths, relationMap, resolved));\n};\n\ninterface ResolveRelationMapOptions {\n client: Client;\n throttleManager: ThrottleManager;\n}\n\nexport interface ResolvedRelations {\n relationPaths: RelationPath[];\n relationMap: Map<string, StoryCapi>;\n}\n\n/**\n * Parses relation paths from the request query, builds a relation map from the\n * response's `rels`, and fetches any additional relations referenced by `rel_uuids`.\n *\n * Returns `null` when there is nothing to inline (no `resolve_relations` in the query).\n */\nexport const resolveRelationMap = async (\n responseData: { rels?: StoryCapi[]; rel_uuids?: string[] },\n requestQuery: Record<string, unknown>,\n { client, throttleManager }: ResolveRelationMapOptions,\n): Promise<ResolvedRelations | null> => {\n const relationPaths = parseResolveRelations(requestQuery);\n if (relationPaths.length === 0) {\n return null;\n }\n\n const relationMap = buildRelationMap(responseData.rels);\n if (responseData.rel_uuids?.length) {\n const missingUuids = responseData.rel_uuids.filter(uuid => !relationMap.has(uuid));\n if (missingUuids.length > 0) {\n const fetchedRelations = await fetchMissingRelations({\n client,\n uuids: missingUuids,\n baseQuery: requestQuery,\n throttleManager,\n });\n for (const relationStory of fetchedRelations) {\n relationMap.set(relationStory.uuid, relationStory);\n }\n }\n }\n\n return { relationPaths, relationMap };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"inline-relations.mjs","names":[],"sources":["../../src/utils/inline-relations.ts"],"sourcesContent":["import type { Client } from '../generated/shared/client';\nimport type { StoryCapi } from '../generated/stories';\nimport type { StoryWithInlinedRelations } from '../resources/stories';\nimport { fetchMissingRelations } from './fetch-rel-uuids';\nimport type { ThrottleManager } from './rate-limit';\n\ntype RelationPath = `${string}.${string}`;\n\ninterface ComponentNode {\n _uid: string;\n component: string;\n [key: string]: unknown;\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === 'object' && !Array.isArray(value);\n\nconst isComponentNode = (value: Record<string, unknown>): value is ComponentNode =>\n typeof value.component === 'string' && typeof value._uid === 'string';\n\n/**\n * Decodes a string if it appears to be URL-encoded.\n * Detects common encoded characters (%2C for comma, %20 for space, etc.)\n */\nconst decodeIfEncoded = (value: string): string => {\n // Check if the string contains URL-encoded characters (% followed by hex digits)\n if (/%[0-9A-F]{2}/i.test(value)) {\n try {\n return decodeURIComponent(value);\n }\n catch {\n // If decoding fails (malformed encoding), return original\n return value;\n }\n }\n return value;\n};\n\nconst inlineStoryContentInternal = <TStory extends StoryCapi | StoryWithInlinedRelations>(\n story: TStory,\n relationPaths: ReadonlySet<RelationPath>,\n relationMap: ReadonlyMap<string, TStory>,\n resolved: Map<string, TStory>,\n): TStory => {\n const existingStory = resolved.get(story.uuid);\n if (existingStory) {\n return existingStory;\n }\n\n const clonedStory = structuredClone(story);\n resolved.set(story.uuid, clonedStory);\n // resolveNode returns `unknown` to handle arbitrary JSON trees; shape is preserved at runtime.\n clonedStory.content = resolveNode(clonedStory.content, relationMap, relationPaths, resolved) as StoryCapi['content'];\n return clonedStory;\n};\n\nfunction resolveNode<TStory extends StoryCapi | StoryWithInlinedRelations>(\n value: unknown,\n relationMap: ReadonlyMap<string, TStory>,\n relationPaths: ReadonlySet<RelationPath>,\n resolved: Map<string, TStory>,\n): unknown {\n if (Array.isArray(value)) {\n return value.map(item => resolveNode(item, relationMap, relationPaths, resolved));\n }\n\n if (!isRecord(value)) {\n return value;\n }\n\n if (isComponentNode(value)) {\n for (const [fieldName, fieldValue] of Object.entries(value)) {\n if (fieldName === 'component' || fieldName === '_uid') {\n continue;\n }\n\n const relationPath: RelationPath = `${value.component}.${fieldName}`;\n value[fieldName] = relationPaths.has(relationPath)\n ? resolveFieldValue(fieldValue, relationMap, relationPaths, resolved)\n : resolveNode(fieldValue, relationMap, relationPaths, resolved);\n }\n\n return value;\n }\n\n for (const [fieldName, fieldValue] of Object.entries(value)) {\n value[fieldName] = resolveNode(fieldValue, relationMap, relationPaths, resolved);\n }\n\n return value;\n}\n\nexport const parseResolveRelations = (query: Record<string, unknown>): RelationPath[] => {\n if (typeof query.resolve_relations !== 'string') {\n return [];\n }\n\n // Decode URL-encoded strings to handle pre-encoded input\n const resolveRelations = decodeIfEncoded(query.resolve_relations);\n\n return resolveRelations\n .split(',')\n .map(path => path.trim())\n .filter((path): path is RelationPath => {\n const [component = '', field = '', ...rest] = path.split('.');\n return component.length > 0 && field.length > 0 && rest.length === 0;\n });\n};\n\nexport const buildRelationMap = (rels: Array<StoryCapi> | undefined): Map<string, StoryCapi> => {\n const relationMap = new Map<string, StoryCapi>();\n\n for (const story of rels ?? []) {\n relationMap.set(story.uuid, story);\n }\n\n return relationMap;\n};\n\nfunction resolveFieldValue<TStory extends StoryCapi | StoryWithInlinedRelations>(\n value: unknown,\n relationMap: ReadonlyMap<string, TStory>,\n relationPaths: ReadonlySet<RelationPath>,\n resolved: Map<string, TStory>,\n): unknown {\n if (typeof value === 'string') {\n const relatedStory = relationMap.get(value);\n if (!relatedStory) {\n return value;\n }\n\n return inlineStoryContentInternal(relatedStory, relationPaths, relationMap, resolved);\n }\n\n if (Array.isArray(value)) {\n return value.map(item => resolveFieldValue(item, relationMap, relationPaths, resolved));\n }\n\n return resolveNode(value, relationMap, relationPaths, resolved);\n}\n\nexport const inlineStoryContent = <TStory extends StoryCapi | StoryWithInlinedRelations>(\n story: TStory,\n relationPaths: RelationPath[],\n relationMap: ReadonlyMap<string, TStory>,\n): TStory => {\n const normalizedPaths = new Set(relationPaths);\n const resolved = new Map<string, TStory>();\n return inlineStoryContentInternal(story, normalizedPaths, relationMap, resolved);\n};\n\nexport const inlineStoriesContent = <TStory extends StoryCapi | StoryWithInlinedRelations>(\n stories: Array<TStory>,\n relationPaths: RelationPath[],\n relationMap: ReadonlyMap<string, TStory>,\n): Array<TStory> => {\n const normalizedPaths = new Set(relationPaths);\n const resolved = new Map<string, TStory>();\n return stories.map(story => inlineStoryContentInternal(story, normalizedPaths, relationMap, resolved));\n};\n\ninterface ResolveRelationMapOptions {\n client: Client;\n throttleManager: ThrottleManager;\n}\n\nexport interface ResolvedRelations {\n relationPaths: RelationPath[];\n relationMap: Map<string, StoryCapi>;\n}\n\n/**\n * Parses relation paths from the request query, builds a relation map from the\n * response's `rels`, and fetches any additional relations referenced by `rel_uuids`.\n *\n * Returns `null` when there is nothing to inline (no `resolve_relations` in the query).\n */\nexport const resolveRelationMap = async (\n responseData: { rels?: StoryCapi[]; rel_uuids?: string[] },\n requestQuery: Record<string, unknown>,\n { client, throttleManager }: ResolveRelationMapOptions,\n): Promise<ResolvedRelations | null> => {\n const relationPaths = parseResolveRelations(requestQuery);\n if (relationPaths.length === 0) {\n return null;\n }\n\n const relationMap = buildRelationMap(responseData.rels);\n if (responseData.rel_uuids?.length) {\n const missingUuids = responseData.rel_uuids.filter(uuid => !relationMap.has(uuid));\n if (missingUuids.length > 0) {\n const fetchedRelations = await fetchMissingRelations({\n client,\n uuids: missingUuids,\n baseQuery: requestQuery,\n throttleManager,\n });\n for (const relationStory of fetchedRelations) {\n relationMap.set(relationStory.uuid, relationStory);\n }\n }\n }\n\n return { relationPaths, relationMap };\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@storyblok/api-client",
3
3
  "type": "module",
4
- "version": "0.2.3",
4
+ "version": "0.2.4",
5
5
  "private": false,
6
6
  "description": "Storyblok Content Delivery API Client",
7
7
  "author": "",