@plasmicpkgs/strapi 0.0.18 → 0.0.19

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.esm.js CHANGED
@@ -351,6 +351,7 @@ var queryStrapiMeta = {
351
351
  displayName: "Query Strapi",
352
352
  description: "Query a Strapi collection",
353
353
  importPath: "@plasmicpkgs/strapi",
354
+ isQuery: true,
354
355
  params: [
355
356
  {
356
357
  name: "opts",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../src/query-strapi.tsx", "../src/strapi-compat.ts", "../src/utils.ts", "../src/where.ts"],
4
- "sourcesContent": ["import registerFunction, {\n CustomFunctionMeta,\n} from \"@plasmicapp/host/registerFunction\";\nimport { _queryStrapi, queryStrapi, queryStrapiMeta } from \"./query-strapi\";\n\nexport function registerStrapi(loader?: { registerFunction: any }) {\n function _registerFunction<T extends (...args: any[]) => any>(\n fn: T,\n meta: CustomFunctionMeta<T>\n ) {\n if (loader) {\n loader.registerFunction(fn, meta);\n } else {\n registerFunction(fn, meta);\n }\n }\n\n _registerFunction(queryStrapi, queryStrapiMeta);\n}\n\nexport {\n // used by @plasmicpkgs/plasmic-strapi\n _queryStrapi,\n queryStrapi,\n};\n\n// used by @plasmicpkgs/plasmic-strapi\nexport {\n getItemKeys as _getFieldKeys,\n getFieldValue as _getFieldValue,\n getId as _getId,\n getMediaAttributes as _getMediaAttributes,\n isStrapiItem as _isStrapiItem,\n isStrapiItemArray as _isStrapiItemArray,\n isStrapiPrimitive as _isStrapiPrimitive,\n} from \"./strapi-compat\";\nexport {\n extractDisplayableFields as _extractDisplayableFields,\n extractFilterableFields as _extractFilterableFields,\n isImage as _isImage,\n queryParameters as _queryParameters,\n} from \"./utils\";\n", "import { CustomFunctionMeta } from \"@plasmicapp/host/registerFunction\";\nimport type { RulesLogic } from \"json-logic-js\";\nimport qs from \"qs\";\nimport { getFieldValue, StrapiQueryResponse } from \"./strapi-compat\";\nimport {\n extractFilterableFields,\n normalizeUrl,\n transformMediaUrls,\n} from \"./utils\";\nimport {\n rulesLogicToStrapiFilters,\n strapiFieldsToQueryBuilderConfig,\n} from \"./where\";\n\nexport const queryStrapiMeta: CustomFunctionMeta<typeof queryStrapi> = {\n name: \"queryStrapi\",\n displayName: \"Query Strapi\",\n description: \"Query a Strapi collection\",\n importPath: \"@plasmicpkgs/strapi\",\n params: [\n {\n name: \"opts\",\n type: \"object\",\n display: \"flatten\",\n fields: {\n host: {\n type: \"string\",\n description: \"The Strapi host URL (e.g., https://example.com)\",\n },\n token: {\n type: \"string\",\n description:\n \"The Strapi API token (optional, for authenticated requests)\",\n },\n collection: {\n type: \"string\",\n description: \"The name of the Strapi collection to query\",\n },\n filterLogic: {\n type: \"queryBuilder\",\n description: \"Filter fetched entries. Defaults to fetch all entries.\",\n config: (_: any, ctx: any) => {\n const fields = ctx?.strapiFields || [];\n return strapiFieldsToQueryBuilderConfig(fields, ctx?.sampleData);\n },\n },\n },\n },\n ],\n fnContext: (strapiOpts?: QueryStrapiOpts) => {\n if (!strapiOpts?.host) {\n return {\n dataKey: \"\",\n fetcher: async () => {\n return {};\n },\n };\n }\n // Exclude filterLogic from dataKey to prevent refetching when user types in query builder\n // The fields and sampleData should only depend on host, token, and collection\n const fetchOpts: QueryStrapiOpts = {\n host: strapiOpts.host,\n token: strapiOpts.token,\n collection: strapiOpts.collection,\n };\n return {\n dataKey: JSON.stringify(fetchOpts),\n fetcher: async () => {\n const resp = await queryStrapi(fetchOpts);\n const collectionData = resp?.data;\n if (!collectionData) {\n return { strapiFields: [] };\n }\n\n // Extract field values from multiple items for type inference\n // Check up to 10 items to find non-null values for each field\n const sampleData: Record<string, any> = {};\n const fields = extractFilterableFields(collectionData);\n const itemsToCheck = collectionData.slice(0, 10);\n // For each field, find the first non-null value across multiple items\n for (const field of fields) {\n for (const item of itemsToCheck) {\n if (item) {\n const value = getFieldValue(item, field);\n if (value !== null && value !== undefined) {\n sampleData[field] = value;\n break;\n }\n }\n }\n }\n\n return {\n strapiFields: fields,\n sampleData,\n };\n },\n };\n },\n};\n\n// Simplified filter props only intended for use by the deprecated StrapiCollection component\nexport interface StrapiQueryOldFilterProps {\n filterField?: string;\n filterValue?: string;\n filterParameter?: string;\n}\n\nexport interface QueryStrapiOpts {\n host?: string;\n token?: string;\n collection?: string;\n /**\n * Filter logic using JSON Logic format to filter Strapi entries.\n * See {@link https://www.npmjs.com/package/@types/json-logic-js?activeTab=readme}\n */\n filterLogic?: RulesLogic;\n}\n\n/**\n * Query a Strapi collection with optional filtering.\n *\n * @param opts - Query options including host, token, collection, and filter logic\n * @returns Promise resolving to the Strapi query response or null if required params are missing\n *\n * @example\n * ```ts\n * // Fetch all entries\n * const result = await queryStrapi({\n * host: 'https://api.example.com',\n * token: 'your-api-token',\n * collection: 'articles'\n * });\n *\n * // Fetch with filter\n * const filtered = await queryStrapi({\n * host: 'https://api.example.com',\n * token: 'your-api-token',\n * collection: 'articles',\n * filterLogic: { \"==\": [{ var: \"status\" }, \"published\"] }\n * });\n * ```\n */\nexport async function queryStrapi({\n host,\n token,\n collection,\n filterLogic,\n}: QueryStrapiOpts): Promise<StrapiQueryResponse | null> {\n return _queryStrapi({ host, token, collection, filterLogic });\n}\n\n/**\n * Query Strapi with simplified filter props.\n *\n * @deprecated Use {@link queryStrapi} with `filterLogic` parameter instead.\n *\n * @example\n * ```ts\n * // Old way (deprecated)\n * _queryStrapi({ filterField: 'name', filterValue: 'John' })\n *\n * // New way\n * queryStrapi({\n * filterLogic: {\"==\": [{ var: \"name\" }, \"John\"]}\n * })\n * ```\n */\nexport async function _queryStrapi({\n host,\n token,\n collection,\n filterLogic,\n filterField,\n filterValue,\n filterParameter,\n}: QueryStrapiOpts &\n StrapiQueryOldFilterProps): Promise<StrapiQueryResponse | null> {\n if (!host || !collection) {\n return null;\n }\n\n const query = normalizeUrl(host) + \"/api/\" + collection.trim();\n\n const requestInit: RequestInit = { method: \"GET\" };\n if (token) {\n requestInit.headers = { Authorization: \"Bearer \" + token };\n }\n\n let filters: Record<string, any> = {};\n if (filterLogic) {\n filters = rulesLogicToStrapiFilters(filterLogic);\n } else if (filterField && filterParameter && filterValue) {\n filters = {\n [filterField]: {\n [filterParameter]: filterValue,\n },\n };\n }\n\n // Build query parameters for Strapi REST API\n // Strapi uses nested query parameters like: filters[$and][0][field][$eq]=value\n const queryParams = qs.stringify({\n filters,\n populate: \"*\",\n });\n\n const resp = await fetch(`${query}?${queryParams}`, requestInit);\n const data = await resp.json();\n\n // Transform all relative media URLs to absolute URLs\n return transformMediaUrls(data, host);\n}\n", "// This file contains Strapi code for handling v4/v5 compatibility.\n// https://docs.strapi.io/cms/migration/v4-to-v5/breaking-changes/new-response-format\n\nexport interface StrapiQueryResponse {\n data: StrapiItem[];\n meta: {\n pagination: {\n page: number;\n pageSize: number;\n pageCount: number;\n total: number;\n };\n };\n}\n\n/** A primitive, item, item array, or null (for optional fields). */\nexport type StrapiValue =\n | boolean\n | number\n | string\n | StrapiItem\n | ReadonlyArray<StrapiItem>\n | ReadonlyArray<any> // For rich text content, JSON fields, etc.\n | Record<string, any> // For JSON fields, metadata objects, etc.\n | null;\ntype StrapiValueV4 =\n | boolean\n | number\n | string\n | { data: StrapiItemV4 | ReadonlyArray<StrapiItemV4> }\n | ReadonlyArray<any> // For rich text content, JSON fields, etc.\n | Record<string, any> // For JSON fields, metadata objects, etc.\n | null;\ntype StrapiValueV5 =\n | boolean\n | number\n | string\n | StrapiItemV5\n | ReadonlyArray<StrapiItemV5>\n | ReadonlyArray<any> // For rich text content, JSON fields, etc.\n | Record<string, any> // For JSON fields, metadata objects, etc.\n | null;\n\n/** A content item or media item. */\nexport type StrapiItem = StrapiItemV4 | StrapiItemV5;\nexport interface StrapiItemV4 {\n id: number;\n attributes: {\n [attribute: string]: StrapiValueV4;\n };\n}\nexport interface StrapiItemV5 {\n documentId: string;\n [attribute: string]: StrapiValueV5;\n}\nfunction isV5Item(item: StrapiItem): item is StrapiItemV5 {\n return \"documentId\" in item;\n}\n\nfunction isV4Item(item: StrapiItem): item is StrapiItemV5 {\n return \"id\" in item && \"attributes\" in item;\n}\n\n/** @internal */\nexport function isStrapiPrimitive(\n value: StrapiValue | undefined\n): value is boolean | number | string {\n const type = typeof value;\n return type === \"boolean\" || type === \"number\" || type === \"string\";\n}\n/** @internal */\nexport function isStrapiItem(\n item: StrapiValue | undefined\n): item is StrapiItem {\n if (typeof item !== \"object\" || item === null || Array.isArray(item)) {\n return false;\n }\n // The object must be a valid v5 or v4 item\n return isV5Item(item as any) || isV4Item(item as any);\n}\n/** @internal */\nexport function isStrapiItemArray(\n value: StrapiValue | undefined\n): value is ReadonlyArray<StrapiItem> {\n return typeof value === \"object\" && value !== null && Array.isArray(value);\n}\n\n/** @internal */\nexport function getId(item: StrapiItem): string {\n if (isV5Item(item)) {\n return item.documentId;\n } else {\n // v4\n return item.id.toString();\n }\n}\n\n/** @internal */\nexport function getItemKeys(item: StrapiItem) {\n if (isV5Item(item)) {\n return Object.keys(item).filter((key) => key !== \"documentId\");\n } else {\n // v4\n return Object.keys(item.attributes);\n }\n}\n\n/**\n * Gets the value, or undefined if the field key does not exist.\n * @internal\n */\nexport function getFieldValue(\n item: StrapiItem,\n key: string\n): StrapiValue | undefined {\n if (isV5Item(item)) {\n return item[key];\n } else {\n // v4\n const value = item.attributes[key];\n if (value === null || value === undefined) {\n return value;\n }\n switch (typeof value) {\n case \"boolean\":\n case \"number\":\n case \"string\":\n return value;\n case \"object\":\n if (value && \"data\" in value) {\n return value.data;\n } else {\n return undefined;\n }\n default:\n return undefined;\n }\n }\n}\n\n/** This includes any asset such as image, video, audio, file */\nexport interface StrapiMediaAttributes {\n url: string;\n mime: string;\n ext: string;\n size: number;\n // width and height are null for non-image media (e.g. audio files)\n width: number | null;\n height: number | null;\n formats?: { [key: string]: Omit<StrapiMediaAttributes, \"formats\"> };\n // Added by transformMediaUrls - absolute URL with host prepended\n absoluteUrl?: string;\n}\n\nexport interface StrapiImageAttribute extends StrapiMediaAttributes {\n width: number;\n height: number;\n}\n/**\n * Gets media attributes if it's a media item.\n *\n * This is the small subset of the fields that we care about.\n *\n * @internal\n */\nexport function getMediaAttributes(\n value: StrapiItem\n): StrapiMediaAttributes | undefined {\n const attributes = isV5Item(value) ? value : value.attributes;\n if (\n \"url\" in attributes &&\n \"mime\" in attributes &&\n \"ext\" in attributes &&\n \"size\" in attributes\n ) {\n return attributes as { [attribute: string]: any } as StrapiMediaAttributes;\n } else {\n return undefined;\n }\n}\n", "import {\n StrapiImageAttribute,\n StrapiItem,\n StrapiMediaAttributes,\n StrapiQueryResponse,\n getFieldValue,\n getItemKeys,\n getMediaAttributes,\n isStrapiItem,\n isStrapiPrimitive,\n} from \"./strapi-compat\";\n\n/**\n * https://docs-v4.strapi.io/dev-docs/api/entity-service/filter\n * @internal\n */\nexport const queryParameters = [\n {\n value: \"$eq\",\n label: \"Equal\",\n },\n {\n value: \"$ne\",\n label: \"Not equal\",\n },\n {\n value: \"$lt\",\n label: \"Less than\",\n },\n {\n value: \"$lte\",\n label: \"Less than or equal to\",\n },\n {\n value: \"$gt\",\n label: \"Greater than\",\n },\n {\n value: \"$gte\",\n label: \"Greater than or equal to\",\n },\n {\n value: \"$in\",\n label: \"Included in an array\",\n },\n {\n value: \"$notIn\",\n label: \"Not included in an array\",\n },\n {\n value: \"$contains\",\n label: \"Contains\",\n },\n {\n value: \"$notContains\",\n label: \"Does not contain\",\n },\n];\n\n/**\n * Checks if the media attribute contains an image media\n * @internal\n */\nexport function isImage(\n mediaAttr: StrapiMediaAttributes\n): mediaAttr is StrapiImageAttribute {\n return mediaAttr?.mime.startsWith(\"image\");\n}\n\n/**\n * Removes leading and trailing slash and whitespace characters from a URL\n * @internal\n */\nexport function normalizeUrl(url: string): string {\n return (\n url\n .trim()\n // remove leading slash\n .replace(/^\\/+/, \"\")\n // remove leading trailing\n .replace(/\\/+$/, \"\")\n );\n}\n\n/**\n * Extracts fields whose types can be filtered in Plasmic.\n * @internal\n */\nexport function extractFilterableFields(\n items: StrapiItem | StrapiItem[]\n): string[] {\n if (Array.isArray(items)) {\n return Array.from(new Set(items.flatMap(filterableFields)));\n } else {\n return filterableFields(items);\n }\n}\n\nfunction filterableFields(item: StrapiItem): string[] {\n return getItemKeys(item).filter((key) => {\n const value = getFieldValue(item, key);\n return isStrapiPrimitive(value);\n });\n}\n\n/**\n * Extracts fields whose types can be displayed in Plasmic.\n * @internal\n */\nexport function extractDisplayableFields(\n items: StrapiItem | StrapiItem[]\n): string[] {\n if (Array.isArray(items)) {\n return Array.from(new Set(items.flatMap(displayableFields)));\n } else {\n return displayableFields(items);\n }\n}\n\nfunction displayableFields(item: StrapiItem): string[] {\n return getItemKeys(item).filter((key) => {\n const value = getFieldValue(item, key);\n return (\n isStrapiPrimitive(value) ||\n (isStrapiItem(value) && getMediaAttributes(value))\n );\n });\n}\n\n/**\n * Traverses @param data and adds an absoluteUrl field to all media items by prepending the @param host to the url\n * @internal\n */\nexport function transformMediaUrls(\n data: StrapiQueryResponse,\n host: string\n): StrapiQueryResponse {\n if (data === null || data === undefined) {\n return data;\n }\n\n const normalizedHost = normalizeUrl(host);\n\n /**\n * Converts a relative URL to absolute by prepending the host.\n * If URL is already absolute, returns it unchanged.\n */\n function makeAbsoluteUrl(url: string): string {\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\")) {\n return url;\n }\n return normalizedHost + \"/\" + normalizeUrl(url);\n }\n\n /**\n * Adds absoluteUrl to a media item and its format variations\n */\n function transformMediaItem(mediaAttrs: StrapiMediaAttributes): void {\n mediaAttrs.absoluteUrl = makeAbsoluteUrl(mediaAttrs.url);\n\n // Transform format variations (thumbnail, small, medium, large, etc.)\n if (mediaAttrs.formats && typeof mediaAttrs.formats === \"object\") {\n for (const formatKey of Object.keys(mediaAttrs.formats)) {\n transformMediaItem(mediaAttrs.formats[formatKey]);\n }\n }\n }\n\n /**\n * Recursively traverses a Strapi item and transforms all nested media\n */\n function transformStrapiItem(item: StrapiItem): void {\n const mediaAttrs = getMediaAttributes(item);\n\n if (mediaAttrs) {\n // This item is itself a media item\n transformMediaItem(mediaAttrs);\n } else {\n // This item contains other fields that might be media\n for (const key of getItemKeys(item)) {\n const fieldValue = getFieldValue(item, key);\n transformValue(fieldValue);\n }\n }\n }\n\n /**\n * Recursively traverses and transforms media URLs in any value\n */\n function transformValue(value: any): any {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (isStrapiPrimitive(value)) {\n return value;\n }\n\n if (Array.isArray(value)) {\n value.forEach(transformValue);\n return value;\n }\n\n if (isStrapiItem(value)) {\n transformStrapiItem(value);\n } else if (typeof value === \"object\") {\n // Plain object - traverse its properties\n for (const key of Object.keys(value)) {\n transformValue(value[key]);\n }\n }\n\n return value;\n }\n\n return transformValue(data);\n}\n", "import type {\n Config,\n Field,\n FieldOrGroup,\n} from \"@react-awesome-query-builder/core\";\nimport type { RulesLogic } from \"json-logic-js\";\n\n/**\n * Maps Strapi collection fields to react-awesome-query-builder config.\n *\n * The result will be handled by {@link rulesLogicToStrapiFilters}.\n * Make sure it supports all operators defined here.\n */\nexport function strapiFieldsToQueryBuilderConfig(\n fields: string[],\n sampleData?: any\n): Pick<Config, \"fields\"> {\n const qbFields: { [key: string]: FieldOrGroup } = {};\n for (const field of fields) {\n // Try to get sample value from sampleData to infer type\n const sampleValue = sampleData?.[field];\n const qbField = strapiFieldToQueryBuilderField(field, sampleValue);\n if (qbField) {\n qbFields[field] = qbField;\n }\n }\n return {\n fields: qbFields,\n };\n}\n\n/**\n * Maps a Strapi field name to a query builder field configuration.\n *\n * Infers field type from field name patterns and sample values if provided.\n */\nfunction strapiFieldToQueryBuilderField(\n fieldName: string,\n sampleValue?: unknown\n): Field | undefined {\n const label = fieldName;\n\n // Infer type from sample value if provided\n if (typeof sampleValue === \"number\") {\n return {\n type: \"number\",\n label,\n operators: [\n \"equal\",\n \"not_equal\",\n \"less\",\n \"less_or_equal\",\n \"greater\",\n \"greater_or_equal\",\n \"is_null\",\n \"is_not_null\",\n ],\n };\n }\n if (typeof sampleValue === \"boolean\") {\n return {\n type: \"boolean\",\n label,\n };\n }\n if (typeof sampleValue === \"string\") {\n if (!isNaN(new Date(sampleValue).getTime())) {\n return {\n type: \"datetime\",\n label,\n operators: [\n \"equal\",\n \"not_equal\",\n \"less\",\n \"less_or_equal\",\n \"greater\",\n \"greater_or_equal\",\n \"is_null\",\n \"is_not_null\",\n ],\n };\n }\n\n return {\n type: \"text\",\n label,\n operators: [\n \"equal\",\n \"not_equal\",\n \"like\",\n \"not_like\",\n \"is_null\",\n \"is_not_null\",\n ],\n };\n }\n\n return undefined;\n}\n\n/**\n * Maps JsonLogic to Strapi API filters format.\n *\n * See also:\n * - https://docs.strapi.io/cms/api/rest/filters\n */\nexport function rulesLogicToStrapiFilters(logic: RulesLogic | undefined): any {\n if (logic === null || logic === undefined) {\n return undefined;\n } else if (typeof logic !== \"object\") {\n throw new Error(`unexpected logic: ${JSON.stringify(logic)}`);\n } else if (\"and\" in logic) {\n return {\n $and: logic[\"and\"].map(rulesLogicToStrapiFilters),\n };\n } else if (\"or\" in logic) {\n return {\n $or: logic[\"or\"].map(rulesLogicToStrapiFilters),\n };\n } else if (\"!\" in logic) {\n return {\n $not: rulesLogicToStrapiFilters(logic[\"!\"]),\n };\n } else if (\"==\" in logic) {\n const [{ var: field }, operand] = logic[\"==\"] as [{ var: string }, unknown];\n if (operand === null) {\n return { [field]: { $null: true } };\n }\n return {\n [field]: { $eq: operand },\n };\n } else if (\"!=\" in logic) {\n const [{ var: field }, operand] = logic[\"!=\"] as [{ var: string }, unknown];\n if (operand === null) {\n return { [field]: { $notNull: true } };\n }\n return {\n [field]: { $ne: operand },\n };\n // Map in operator to Strapi filters format:\n // JsonLogic: { \"in\": [\"Mairi\", { \"var\": \"name\" }] }\n // Strapi filters: { \"name\": { $contains: \"Mairi\" } }\n } else if (\"in\" in logic) {\n const [operand, { var: field }] = logic[\"in\"] as [string, { var: string }];\n return {\n [field]: { $contains: operand },\n };\n } else {\n // Map JsonLogic to Strapi filters format:\n // JsonLogic: { \"<=\": [{ \"var\": \"age\" }, 18] }\n // Strapi filters: { \"age\": { \"$lte\": 18 } }\n const [key, value] = Object.entries(logic)[0];\n const apiOp: string | undefined = operatorMapping[key];\n if (apiOp) {\n const [{ var: field }, operand] = value as [{ var: string }, unknown];\n return { [field]: { [apiOp]: operand } };\n }\n\n throw new Error(`unexpected logic: ${JSON.stringify(logic)}`);\n }\n}\n\n/** Maps JsonLogic operator to Strapi filter operator. */\nconst operatorMapping: Record<string, string> = {\n \"<\": \"$lt\",\n \"<=\": \"$lte\",\n \">\": \"$gt\",\n \">=\": \"$gte\",\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import registerFunction, {\n CustomFunctionMeta,\n} from \"@plasmicapp/host/registerFunction\";\nimport { _queryStrapi, queryStrapi, queryStrapiMeta } from \"./query-strapi\";\n\nexport function registerStrapi(loader?: { registerFunction: any }) {\n function _registerFunction<T extends (...args: any[]) => any>(\n fn: T,\n meta: CustomFunctionMeta<T>\n ) {\n if (loader) {\n loader.registerFunction(fn, meta);\n } else {\n registerFunction(fn, meta);\n }\n }\n\n _registerFunction(queryStrapi, queryStrapiMeta);\n}\n\nexport {\n // used by @plasmicpkgs/plasmic-strapi\n _queryStrapi,\n queryStrapi,\n};\n\n// used by @plasmicpkgs/plasmic-strapi\nexport {\n getItemKeys as _getFieldKeys,\n getFieldValue as _getFieldValue,\n getId as _getId,\n getMediaAttributes as _getMediaAttributes,\n isStrapiItem as _isStrapiItem,\n isStrapiItemArray as _isStrapiItemArray,\n isStrapiPrimitive as _isStrapiPrimitive,\n} from \"./strapi-compat\";\nexport {\n extractDisplayableFields as _extractDisplayableFields,\n extractFilterableFields as _extractFilterableFields,\n isImage as _isImage,\n queryParameters as _queryParameters,\n} from \"./utils\";\n", "import { CustomFunctionMeta } from \"@plasmicapp/host/registerFunction\";\nimport type { RulesLogic } from \"json-logic-js\";\nimport qs from \"qs\";\nimport { getFieldValue, StrapiQueryResponse } from \"./strapi-compat\";\nimport {\n extractFilterableFields,\n normalizeUrl,\n transformMediaUrls,\n} from \"./utils\";\nimport {\n rulesLogicToStrapiFilters,\n strapiFieldsToQueryBuilderConfig,\n} from \"./where\";\n\nexport const queryStrapiMeta: CustomFunctionMeta<typeof queryStrapi> = {\n name: \"queryStrapi\",\n displayName: \"Query Strapi\",\n description: \"Query a Strapi collection\",\n importPath: \"@plasmicpkgs/strapi\",\n isQuery: true,\n params: [\n {\n name: \"opts\",\n type: \"object\",\n display: \"flatten\",\n fields: {\n host: {\n type: \"string\",\n description: \"The Strapi host URL (e.g., https://example.com)\",\n },\n token: {\n type: \"string\",\n description:\n \"The Strapi API token (optional, for authenticated requests)\",\n },\n collection: {\n type: \"string\",\n description: \"The name of the Strapi collection to query\",\n },\n filterLogic: {\n type: \"queryBuilder\",\n description: \"Filter fetched entries. Defaults to fetch all entries.\",\n config: (_: any, ctx: any) => {\n const fields = ctx?.strapiFields || [];\n return strapiFieldsToQueryBuilderConfig(fields, ctx?.sampleData);\n },\n },\n },\n },\n ],\n fnContext: (strapiOpts?: QueryStrapiOpts) => {\n if (!strapiOpts?.host) {\n return {\n dataKey: \"\",\n fetcher: async () => {\n return {};\n },\n };\n }\n // Exclude filterLogic from dataKey to prevent refetching when user types in query builder\n // The fields and sampleData should only depend on host, token, and collection\n const fetchOpts: QueryStrapiOpts = {\n host: strapiOpts.host,\n token: strapiOpts.token,\n collection: strapiOpts.collection,\n };\n return {\n dataKey: JSON.stringify(fetchOpts),\n fetcher: async () => {\n const resp = await queryStrapi(fetchOpts);\n const collectionData = resp?.data;\n if (!collectionData) {\n return { strapiFields: [] };\n }\n\n // Extract field values from multiple items for type inference\n // Check up to 10 items to find non-null values for each field\n const sampleData: Record<string, any> = {};\n const fields = extractFilterableFields(collectionData);\n const itemsToCheck = collectionData.slice(0, 10);\n // For each field, find the first non-null value across multiple items\n for (const field of fields) {\n for (const item of itemsToCheck) {\n if (item) {\n const value = getFieldValue(item, field);\n if (value !== null && value !== undefined) {\n sampleData[field] = value;\n break;\n }\n }\n }\n }\n\n return {\n strapiFields: fields,\n sampleData,\n };\n },\n };\n },\n};\n\n// Simplified filter props only intended for use by the deprecated StrapiCollection component\nexport interface StrapiQueryOldFilterProps {\n filterField?: string;\n filterValue?: string;\n filterParameter?: string;\n}\n\nexport interface QueryStrapiOpts {\n host?: string;\n token?: string;\n collection?: string;\n /**\n * Filter logic using JSON Logic format to filter Strapi entries.\n * See {@link https://www.npmjs.com/package/@types/json-logic-js?activeTab=readme}\n */\n filterLogic?: RulesLogic;\n}\n\n/**\n * Query a Strapi collection with optional filtering.\n *\n * @param opts - Query options including host, token, collection, and filter logic\n * @returns Promise resolving to the Strapi query response or null if required params are missing\n *\n * @example\n * ```ts\n * // Fetch all entries\n * const result = await queryStrapi({\n * host: 'https://api.example.com',\n * token: 'your-api-token',\n * collection: 'articles'\n * });\n *\n * // Fetch with filter\n * const filtered = await queryStrapi({\n * host: 'https://api.example.com',\n * token: 'your-api-token',\n * collection: 'articles',\n * filterLogic: { \"==\": [{ var: \"status\" }, \"published\"] }\n * });\n * ```\n */\nexport async function queryStrapi({\n host,\n token,\n collection,\n filterLogic,\n}: QueryStrapiOpts): Promise<StrapiQueryResponse | null> {\n return _queryStrapi({ host, token, collection, filterLogic });\n}\n\n/**\n * Query Strapi with simplified filter props.\n *\n * @deprecated Use {@link queryStrapi} with `filterLogic` parameter instead.\n *\n * @example\n * ```ts\n * // Old way (deprecated)\n * _queryStrapi({ filterField: 'name', filterValue: 'John' })\n *\n * // New way\n * queryStrapi({\n * filterLogic: {\"==\": [{ var: \"name\" }, \"John\"]}\n * })\n * ```\n */\nexport async function _queryStrapi({\n host,\n token,\n collection,\n filterLogic,\n filterField,\n filterValue,\n filterParameter,\n}: QueryStrapiOpts &\n StrapiQueryOldFilterProps): Promise<StrapiQueryResponse | null> {\n if (!host || !collection) {\n return null;\n }\n\n const query = normalizeUrl(host) + \"/api/\" + collection.trim();\n\n const requestInit: RequestInit = { method: \"GET\" };\n if (token) {\n requestInit.headers = { Authorization: \"Bearer \" + token };\n }\n\n let filters: Record<string, any> = {};\n if (filterLogic) {\n filters = rulesLogicToStrapiFilters(filterLogic);\n } else if (filterField && filterParameter && filterValue) {\n filters = {\n [filterField]: {\n [filterParameter]: filterValue,\n },\n };\n }\n\n // Build query parameters for Strapi REST API\n // Strapi uses nested query parameters like: filters[$and][0][field][$eq]=value\n const queryParams = qs.stringify({\n filters,\n populate: \"*\",\n });\n\n const resp = await fetch(`${query}?${queryParams}`, requestInit);\n const data = await resp.json();\n\n // Transform all relative media URLs to absolute URLs\n return transformMediaUrls(data, host);\n}\n", "// This file contains Strapi code for handling v4/v5 compatibility.\n// https://docs.strapi.io/cms/migration/v4-to-v5/breaking-changes/new-response-format\n\nexport interface StrapiQueryResponse {\n data: StrapiItem[];\n meta: {\n pagination: {\n page: number;\n pageSize: number;\n pageCount: number;\n total: number;\n };\n };\n}\n\n/** A primitive, item, item array, or null (for optional fields). */\nexport type StrapiValue =\n | boolean\n | number\n | string\n | StrapiItem\n | ReadonlyArray<StrapiItem>\n | ReadonlyArray<any> // For rich text content, JSON fields, etc.\n | Record<string, any> // For JSON fields, metadata objects, etc.\n | null;\ntype StrapiValueV4 =\n | boolean\n | number\n | string\n | { data: StrapiItemV4 | ReadonlyArray<StrapiItemV4> }\n | ReadonlyArray<any> // For rich text content, JSON fields, etc.\n | Record<string, any> // For JSON fields, metadata objects, etc.\n | null;\ntype StrapiValueV5 =\n | boolean\n | number\n | string\n | StrapiItemV5\n | ReadonlyArray<StrapiItemV5>\n | ReadonlyArray<any> // For rich text content, JSON fields, etc.\n | Record<string, any> // For JSON fields, metadata objects, etc.\n | null;\n\n/** A content item or media item. */\nexport type StrapiItem = StrapiItemV4 | StrapiItemV5;\nexport interface StrapiItemV4 {\n id: number;\n attributes: {\n [attribute: string]: StrapiValueV4;\n };\n}\nexport interface StrapiItemV5 {\n documentId: string;\n [attribute: string]: StrapiValueV5;\n}\nfunction isV5Item(item: StrapiItem): item is StrapiItemV5 {\n return \"documentId\" in item;\n}\n\nfunction isV4Item(item: StrapiItem): item is StrapiItemV5 {\n return \"id\" in item && \"attributes\" in item;\n}\n\n/** @internal */\nexport function isStrapiPrimitive(\n value: StrapiValue | undefined\n): value is boolean | number | string {\n const type = typeof value;\n return type === \"boolean\" || type === \"number\" || type === \"string\";\n}\n/** @internal */\nexport function isStrapiItem(\n item: StrapiValue | undefined\n): item is StrapiItem {\n if (typeof item !== \"object\" || item === null || Array.isArray(item)) {\n return false;\n }\n // The object must be a valid v5 or v4 item\n return isV5Item(item as any) || isV4Item(item as any);\n}\n/** @internal */\nexport function isStrapiItemArray(\n value: StrapiValue | undefined\n): value is ReadonlyArray<StrapiItem> {\n return typeof value === \"object\" && value !== null && Array.isArray(value);\n}\n\n/** @internal */\nexport function getId(item: StrapiItem): string {\n if (isV5Item(item)) {\n return item.documentId;\n } else {\n // v4\n return item.id.toString();\n }\n}\n\n/** @internal */\nexport function getItemKeys(item: StrapiItem) {\n if (isV5Item(item)) {\n return Object.keys(item).filter((key) => key !== \"documentId\");\n } else {\n // v4\n return Object.keys(item.attributes);\n }\n}\n\n/**\n * Gets the value, or undefined if the field key does not exist.\n * @internal\n */\nexport function getFieldValue(\n item: StrapiItem,\n key: string\n): StrapiValue | undefined {\n if (isV5Item(item)) {\n return item[key];\n } else {\n // v4\n const value = item.attributes[key];\n if (value === null || value === undefined) {\n return value;\n }\n switch (typeof value) {\n case \"boolean\":\n case \"number\":\n case \"string\":\n return value;\n case \"object\":\n if (value && \"data\" in value) {\n return value.data;\n } else {\n return undefined;\n }\n default:\n return undefined;\n }\n }\n}\n\n/** This includes any asset such as image, video, audio, file */\nexport interface StrapiMediaAttributes {\n url: string;\n mime: string;\n ext: string;\n size: number;\n // width and height are null for non-image media (e.g. audio files)\n width: number | null;\n height: number | null;\n formats?: { [key: string]: Omit<StrapiMediaAttributes, \"formats\"> };\n // Added by transformMediaUrls - absolute URL with host prepended\n absoluteUrl?: string;\n}\n\nexport interface StrapiImageAttribute extends StrapiMediaAttributes {\n width: number;\n height: number;\n}\n/**\n * Gets media attributes if it's a media item.\n *\n * This is the small subset of the fields that we care about.\n *\n * @internal\n */\nexport function getMediaAttributes(\n value: StrapiItem\n): StrapiMediaAttributes | undefined {\n const attributes = isV5Item(value) ? value : value.attributes;\n if (\n \"url\" in attributes &&\n \"mime\" in attributes &&\n \"ext\" in attributes &&\n \"size\" in attributes\n ) {\n return attributes as { [attribute: string]: any } as StrapiMediaAttributes;\n } else {\n return undefined;\n }\n}\n", "import {\n StrapiImageAttribute,\n StrapiItem,\n StrapiMediaAttributes,\n StrapiQueryResponse,\n getFieldValue,\n getItemKeys,\n getMediaAttributes,\n isStrapiItem,\n isStrapiPrimitive,\n} from \"./strapi-compat\";\n\n/**\n * https://docs-v4.strapi.io/dev-docs/api/entity-service/filter\n * @internal\n */\nexport const queryParameters = [\n {\n value: \"$eq\",\n label: \"Equal\",\n },\n {\n value: \"$ne\",\n label: \"Not equal\",\n },\n {\n value: \"$lt\",\n label: \"Less than\",\n },\n {\n value: \"$lte\",\n label: \"Less than or equal to\",\n },\n {\n value: \"$gt\",\n label: \"Greater than\",\n },\n {\n value: \"$gte\",\n label: \"Greater than or equal to\",\n },\n {\n value: \"$in\",\n label: \"Included in an array\",\n },\n {\n value: \"$notIn\",\n label: \"Not included in an array\",\n },\n {\n value: \"$contains\",\n label: \"Contains\",\n },\n {\n value: \"$notContains\",\n label: \"Does not contain\",\n },\n];\n\n/**\n * Checks if the media attribute contains an image media\n * @internal\n */\nexport function isImage(\n mediaAttr: StrapiMediaAttributes\n): mediaAttr is StrapiImageAttribute {\n return mediaAttr?.mime.startsWith(\"image\");\n}\n\n/**\n * Removes leading and trailing slash and whitespace characters from a URL\n * @internal\n */\nexport function normalizeUrl(url: string): string {\n return (\n url\n .trim()\n // remove leading slash\n .replace(/^\\/+/, \"\")\n // remove leading trailing\n .replace(/\\/+$/, \"\")\n );\n}\n\n/**\n * Extracts fields whose types can be filtered in Plasmic.\n * @internal\n */\nexport function extractFilterableFields(\n items: StrapiItem | StrapiItem[]\n): string[] {\n if (Array.isArray(items)) {\n return Array.from(new Set(items.flatMap(filterableFields)));\n } else {\n return filterableFields(items);\n }\n}\n\nfunction filterableFields(item: StrapiItem): string[] {\n return getItemKeys(item).filter((key) => {\n const value = getFieldValue(item, key);\n return isStrapiPrimitive(value);\n });\n}\n\n/**\n * Extracts fields whose types can be displayed in Plasmic.\n * @internal\n */\nexport function extractDisplayableFields(\n items: StrapiItem | StrapiItem[]\n): string[] {\n if (Array.isArray(items)) {\n return Array.from(new Set(items.flatMap(displayableFields)));\n } else {\n return displayableFields(items);\n }\n}\n\nfunction displayableFields(item: StrapiItem): string[] {\n return getItemKeys(item).filter((key) => {\n const value = getFieldValue(item, key);\n return (\n isStrapiPrimitive(value) ||\n (isStrapiItem(value) && getMediaAttributes(value))\n );\n });\n}\n\n/**\n * Traverses @param data and adds an absoluteUrl field to all media items by prepending the @param host to the url\n * @internal\n */\nexport function transformMediaUrls(\n data: StrapiQueryResponse,\n host: string\n): StrapiQueryResponse {\n if (data === null || data === undefined) {\n return data;\n }\n\n const normalizedHost = normalizeUrl(host);\n\n /**\n * Converts a relative URL to absolute by prepending the host.\n * If URL is already absolute, returns it unchanged.\n */\n function makeAbsoluteUrl(url: string): string {\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\")) {\n return url;\n }\n return normalizedHost + \"/\" + normalizeUrl(url);\n }\n\n /**\n * Adds absoluteUrl to a media item and its format variations\n */\n function transformMediaItem(mediaAttrs: StrapiMediaAttributes): void {\n mediaAttrs.absoluteUrl = makeAbsoluteUrl(mediaAttrs.url);\n\n // Transform format variations (thumbnail, small, medium, large, etc.)\n if (mediaAttrs.formats && typeof mediaAttrs.formats === \"object\") {\n for (const formatKey of Object.keys(mediaAttrs.formats)) {\n transformMediaItem(mediaAttrs.formats[formatKey]);\n }\n }\n }\n\n /**\n * Recursively traverses a Strapi item and transforms all nested media\n */\n function transformStrapiItem(item: StrapiItem): void {\n const mediaAttrs = getMediaAttributes(item);\n\n if (mediaAttrs) {\n // This item is itself a media item\n transformMediaItem(mediaAttrs);\n } else {\n // This item contains other fields that might be media\n for (const key of getItemKeys(item)) {\n const fieldValue = getFieldValue(item, key);\n transformValue(fieldValue);\n }\n }\n }\n\n /**\n * Recursively traverses and transforms media URLs in any value\n */\n function transformValue(value: any): any {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (isStrapiPrimitive(value)) {\n return value;\n }\n\n if (Array.isArray(value)) {\n value.forEach(transformValue);\n return value;\n }\n\n if (isStrapiItem(value)) {\n transformStrapiItem(value);\n } else if (typeof value === \"object\") {\n // Plain object - traverse its properties\n for (const key of Object.keys(value)) {\n transformValue(value[key]);\n }\n }\n\n return value;\n }\n\n return transformValue(data);\n}\n", "import type {\n Config,\n Field,\n FieldOrGroup,\n} from \"@react-awesome-query-builder/core\";\nimport type { RulesLogic } from \"json-logic-js\";\n\n/**\n * Maps Strapi collection fields to react-awesome-query-builder config.\n *\n * The result will be handled by {@link rulesLogicToStrapiFilters}.\n * Make sure it supports all operators defined here.\n */\nexport function strapiFieldsToQueryBuilderConfig(\n fields: string[],\n sampleData?: any\n): Pick<Config, \"fields\"> {\n const qbFields: { [key: string]: FieldOrGroup } = {};\n for (const field of fields) {\n // Try to get sample value from sampleData to infer type\n const sampleValue = sampleData?.[field];\n const qbField = strapiFieldToQueryBuilderField(field, sampleValue);\n if (qbField) {\n qbFields[field] = qbField;\n }\n }\n return {\n fields: qbFields,\n };\n}\n\n/**\n * Maps a Strapi field name to a query builder field configuration.\n *\n * Infers field type from field name patterns and sample values if provided.\n */\nfunction strapiFieldToQueryBuilderField(\n fieldName: string,\n sampleValue?: unknown\n): Field | undefined {\n const label = fieldName;\n\n // Infer type from sample value if provided\n if (typeof sampleValue === \"number\") {\n return {\n type: \"number\",\n label,\n operators: [\n \"equal\",\n \"not_equal\",\n \"less\",\n \"less_or_equal\",\n \"greater\",\n \"greater_or_equal\",\n \"is_null\",\n \"is_not_null\",\n ],\n };\n }\n if (typeof sampleValue === \"boolean\") {\n return {\n type: \"boolean\",\n label,\n };\n }\n if (typeof sampleValue === \"string\") {\n if (!isNaN(new Date(sampleValue).getTime())) {\n return {\n type: \"datetime\",\n label,\n operators: [\n \"equal\",\n \"not_equal\",\n \"less\",\n \"less_or_equal\",\n \"greater\",\n \"greater_or_equal\",\n \"is_null\",\n \"is_not_null\",\n ],\n };\n }\n\n return {\n type: \"text\",\n label,\n operators: [\n \"equal\",\n \"not_equal\",\n \"like\",\n \"not_like\",\n \"is_null\",\n \"is_not_null\",\n ],\n };\n }\n\n return undefined;\n}\n\n/**\n * Maps JsonLogic to Strapi API filters format.\n *\n * See also:\n * - https://docs.strapi.io/cms/api/rest/filters\n */\nexport function rulesLogicToStrapiFilters(logic: RulesLogic | undefined): any {\n if (logic === null || logic === undefined) {\n return undefined;\n } else if (typeof logic !== \"object\") {\n throw new Error(`unexpected logic: ${JSON.stringify(logic)}`);\n } else if (\"and\" in logic) {\n return {\n $and: logic[\"and\"].map(rulesLogicToStrapiFilters),\n };\n } else if (\"or\" in logic) {\n return {\n $or: logic[\"or\"].map(rulesLogicToStrapiFilters),\n };\n } else if (\"!\" in logic) {\n return {\n $not: rulesLogicToStrapiFilters(logic[\"!\"]),\n };\n } else if (\"==\" in logic) {\n const [{ var: field }, operand] = logic[\"==\"] as [{ var: string }, unknown];\n if (operand === null) {\n return { [field]: { $null: true } };\n }\n return {\n [field]: { $eq: operand },\n };\n } else if (\"!=\" in logic) {\n const [{ var: field }, operand] = logic[\"!=\"] as [{ var: string }, unknown];\n if (operand === null) {\n return { [field]: { $notNull: true } };\n }\n return {\n [field]: { $ne: operand },\n };\n // Map in operator to Strapi filters format:\n // JsonLogic: { \"in\": [\"Mairi\", { \"var\": \"name\" }] }\n // Strapi filters: { \"name\": { $contains: \"Mairi\" } }\n } else if (\"in\" in logic) {\n const [operand, { var: field }] = logic[\"in\"] as [string, { var: string }];\n return {\n [field]: { $contains: operand },\n };\n } else {\n // Map JsonLogic to Strapi filters format:\n // JsonLogic: { \"<=\": [{ \"var\": \"age\" }, 18] }\n // Strapi filters: { \"age\": { \"$lte\": 18 } }\n const [key, value] = Object.entries(logic)[0];\n const apiOp: string | undefined = operatorMapping[key];\n if (apiOp) {\n const [{ var: field }, operand] = value as [{ var: string }, unknown];\n return { [field]: { [apiOp]: operand } };\n }\n\n throw new Error(`unexpected logic: ${JSON.stringify(logic)}`);\n }\n}\n\n/** Maps JsonLogic operator to Strapi filter operator. */\nconst operatorMapping: Record<string, string> = {\n \"<\": \"$lt\",\n \"<=\": \"$lte\",\n \">\": \"$gt\",\n \">=\": \"$gte\",\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/dist/index.js CHANGED
@@ -397,6 +397,7 @@ var queryStrapiMeta = {
397
397
  displayName: "Query Strapi",
398
398
  description: "Query a Strapi collection",
399
399
  importPath: "@plasmicpkgs/strapi",
400
+ isQuery: true,
400
401
  params: [
401
402
  {
402
403
  name: "opts",
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../src/query-strapi.tsx", "../src/strapi-compat.ts", "../src/utils.ts", "../src/where.ts"],
4
- "sourcesContent": ["import registerFunction, {\n CustomFunctionMeta,\n} from \"@plasmicapp/host/registerFunction\";\nimport { _queryStrapi, queryStrapi, queryStrapiMeta } from \"./query-strapi\";\n\nexport function registerStrapi(loader?: { registerFunction: any }) {\n function _registerFunction<T extends (...args: any[]) => any>(\n fn: T,\n meta: CustomFunctionMeta<T>\n ) {\n if (loader) {\n loader.registerFunction(fn, meta);\n } else {\n registerFunction(fn, meta);\n }\n }\n\n _registerFunction(queryStrapi, queryStrapiMeta);\n}\n\nexport {\n // used by @plasmicpkgs/plasmic-strapi\n _queryStrapi,\n queryStrapi,\n};\n\n// used by @plasmicpkgs/plasmic-strapi\nexport {\n getItemKeys as _getFieldKeys,\n getFieldValue as _getFieldValue,\n getId as _getId,\n getMediaAttributes as _getMediaAttributes,\n isStrapiItem as _isStrapiItem,\n isStrapiItemArray as _isStrapiItemArray,\n isStrapiPrimitive as _isStrapiPrimitive,\n} from \"./strapi-compat\";\nexport {\n extractDisplayableFields as _extractDisplayableFields,\n extractFilterableFields as _extractFilterableFields,\n isImage as _isImage,\n queryParameters as _queryParameters,\n} from \"./utils\";\n", "import { CustomFunctionMeta } from \"@plasmicapp/host/registerFunction\";\nimport type { RulesLogic } from \"json-logic-js\";\nimport qs from \"qs\";\nimport { getFieldValue, StrapiQueryResponse } from \"./strapi-compat\";\nimport {\n extractFilterableFields,\n normalizeUrl,\n transformMediaUrls,\n} from \"./utils\";\nimport {\n rulesLogicToStrapiFilters,\n strapiFieldsToQueryBuilderConfig,\n} from \"./where\";\n\nexport const queryStrapiMeta: CustomFunctionMeta<typeof queryStrapi> = {\n name: \"queryStrapi\",\n displayName: \"Query Strapi\",\n description: \"Query a Strapi collection\",\n importPath: \"@plasmicpkgs/strapi\",\n params: [\n {\n name: \"opts\",\n type: \"object\",\n display: \"flatten\",\n fields: {\n host: {\n type: \"string\",\n description: \"The Strapi host URL (e.g., https://example.com)\",\n },\n token: {\n type: \"string\",\n description:\n \"The Strapi API token (optional, for authenticated requests)\",\n },\n collection: {\n type: \"string\",\n description: \"The name of the Strapi collection to query\",\n },\n filterLogic: {\n type: \"queryBuilder\",\n description: \"Filter fetched entries. Defaults to fetch all entries.\",\n config: (_: any, ctx: any) => {\n const fields = ctx?.strapiFields || [];\n return strapiFieldsToQueryBuilderConfig(fields, ctx?.sampleData);\n },\n },\n },\n },\n ],\n fnContext: (strapiOpts?: QueryStrapiOpts) => {\n if (!strapiOpts?.host) {\n return {\n dataKey: \"\",\n fetcher: async () => {\n return {};\n },\n };\n }\n // Exclude filterLogic from dataKey to prevent refetching when user types in query builder\n // The fields and sampleData should only depend on host, token, and collection\n const fetchOpts: QueryStrapiOpts = {\n host: strapiOpts.host,\n token: strapiOpts.token,\n collection: strapiOpts.collection,\n };\n return {\n dataKey: JSON.stringify(fetchOpts),\n fetcher: async () => {\n const resp = await queryStrapi(fetchOpts);\n const collectionData = resp?.data;\n if (!collectionData) {\n return { strapiFields: [] };\n }\n\n // Extract field values from multiple items for type inference\n // Check up to 10 items to find non-null values for each field\n const sampleData: Record<string, any> = {};\n const fields = extractFilterableFields(collectionData);\n const itemsToCheck = collectionData.slice(0, 10);\n // For each field, find the first non-null value across multiple items\n for (const field of fields) {\n for (const item of itemsToCheck) {\n if (item) {\n const value = getFieldValue(item, field);\n if (value !== null && value !== undefined) {\n sampleData[field] = value;\n break;\n }\n }\n }\n }\n\n return {\n strapiFields: fields,\n sampleData,\n };\n },\n };\n },\n};\n\n// Simplified filter props only intended for use by the deprecated StrapiCollection component\nexport interface StrapiQueryOldFilterProps {\n filterField?: string;\n filterValue?: string;\n filterParameter?: string;\n}\n\nexport interface QueryStrapiOpts {\n host?: string;\n token?: string;\n collection?: string;\n /**\n * Filter logic using JSON Logic format to filter Strapi entries.\n * See {@link https://www.npmjs.com/package/@types/json-logic-js?activeTab=readme}\n */\n filterLogic?: RulesLogic;\n}\n\n/**\n * Query a Strapi collection with optional filtering.\n *\n * @param opts - Query options including host, token, collection, and filter logic\n * @returns Promise resolving to the Strapi query response or null if required params are missing\n *\n * @example\n * ```ts\n * // Fetch all entries\n * const result = await queryStrapi({\n * host: 'https://api.example.com',\n * token: 'your-api-token',\n * collection: 'articles'\n * });\n *\n * // Fetch with filter\n * const filtered = await queryStrapi({\n * host: 'https://api.example.com',\n * token: 'your-api-token',\n * collection: 'articles',\n * filterLogic: { \"==\": [{ var: \"status\" }, \"published\"] }\n * });\n * ```\n */\nexport async function queryStrapi({\n host,\n token,\n collection,\n filterLogic,\n}: QueryStrapiOpts): Promise<StrapiQueryResponse | null> {\n return _queryStrapi({ host, token, collection, filterLogic });\n}\n\n/**\n * Query Strapi with simplified filter props.\n *\n * @deprecated Use {@link queryStrapi} with `filterLogic` parameter instead.\n *\n * @example\n * ```ts\n * // Old way (deprecated)\n * _queryStrapi({ filterField: 'name', filterValue: 'John' })\n *\n * // New way\n * queryStrapi({\n * filterLogic: {\"==\": [{ var: \"name\" }, \"John\"]}\n * })\n * ```\n */\nexport async function _queryStrapi({\n host,\n token,\n collection,\n filterLogic,\n filterField,\n filterValue,\n filterParameter,\n}: QueryStrapiOpts &\n StrapiQueryOldFilterProps): Promise<StrapiQueryResponse | null> {\n if (!host || !collection) {\n return null;\n }\n\n const query = normalizeUrl(host) + \"/api/\" + collection.trim();\n\n const requestInit: RequestInit = { method: \"GET\" };\n if (token) {\n requestInit.headers = { Authorization: \"Bearer \" + token };\n }\n\n let filters: Record<string, any> = {};\n if (filterLogic) {\n filters = rulesLogicToStrapiFilters(filterLogic);\n } else if (filterField && filterParameter && filterValue) {\n filters = {\n [filterField]: {\n [filterParameter]: filterValue,\n },\n };\n }\n\n // Build query parameters for Strapi REST API\n // Strapi uses nested query parameters like: filters[$and][0][field][$eq]=value\n const queryParams = qs.stringify({\n filters,\n populate: \"*\",\n });\n\n const resp = await fetch(`${query}?${queryParams}`, requestInit);\n const data = await resp.json();\n\n // Transform all relative media URLs to absolute URLs\n return transformMediaUrls(data, host);\n}\n", "// This file contains Strapi code for handling v4/v5 compatibility.\n// https://docs.strapi.io/cms/migration/v4-to-v5/breaking-changes/new-response-format\n\nexport interface StrapiQueryResponse {\n data: StrapiItem[];\n meta: {\n pagination: {\n page: number;\n pageSize: number;\n pageCount: number;\n total: number;\n };\n };\n}\n\n/** A primitive, item, item array, or null (for optional fields). */\nexport type StrapiValue =\n | boolean\n | number\n | string\n | StrapiItem\n | ReadonlyArray<StrapiItem>\n | ReadonlyArray<any> // For rich text content, JSON fields, etc.\n | Record<string, any> // For JSON fields, metadata objects, etc.\n | null;\ntype StrapiValueV4 =\n | boolean\n | number\n | string\n | { data: StrapiItemV4 | ReadonlyArray<StrapiItemV4> }\n | ReadonlyArray<any> // For rich text content, JSON fields, etc.\n | Record<string, any> // For JSON fields, metadata objects, etc.\n | null;\ntype StrapiValueV5 =\n | boolean\n | number\n | string\n | StrapiItemV5\n | ReadonlyArray<StrapiItemV5>\n | ReadonlyArray<any> // For rich text content, JSON fields, etc.\n | Record<string, any> // For JSON fields, metadata objects, etc.\n | null;\n\n/** A content item or media item. */\nexport type StrapiItem = StrapiItemV4 | StrapiItemV5;\nexport interface StrapiItemV4 {\n id: number;\n attributes: {\n [attribute: string]: StrapiValueV4;\n };\n}\nexport interface StrapiItemV5 {\n documentId: string;\n [attribute: string]: StrapiValueV5;\n}\nfunction isV5Item(item: StrapiItem): item is StrapiItemV5 {\n return \"documentId\" in item;\n}\n\nfunction isV4Item(item: StrapiItem): item is StrapiItemV5 {\n return \"id\" in item && \"attributes\" in item;\n}\n\n/** @internal */\nexport function isStrapiPrimitive(\n value: StrapiValue | undefined\n): value is boolean | number | string {\n const type = typeof value;\n return type === \"boolean\" || type === \"number\" || type === \"string\";\n}\n/** @internal */\nexport function isStrapiItem(\n item: StrapiValue | undefined\n): item is StrapiItem {\n if (typeof item !== \"object\" || item === null || Array.isArray(item)) {\n return false;\n }\n // The object must be a valid v5 or v4 item\n return isV5Item(item as any) || isV4Item(item as any);\n}\n/** @internal */\nexport function isStrapiItemArray(\n value: StrapiValue | undefined\n): value is ReadonlyArray<StrapiItem> {\n return typeof value === \"object\" && value !== null && Array.isArray(value);\n}\n\n/** @internal */\nexport function getId(item: StrapiItem): string {\n if (isV5Item(item)) {\n return item.documentId;\n } else {\n // v4\n return item.id.toString();\n }\n}\n\n/** @internal */\nexport function getItemKeys(item: StrapiItem) {\n if (isV5Item(item)) {\n return Object.keys(item).filter((key) => key !== \"documentId\");\n } else {\n // v4\n return Object.keys(item.attributes);\n }\n}\n\n/**\n * Gets the value, or undefined if the field key does not exist.\n * @internal\n */\nexport function getFieldValue(\n item: StrapiItem,\n key: string\n): StrapiValue | undefined {\n if (isV5Item(item)) {\n return item[key];\n } else {\n // v4\n const value = item.attributes[key];\n if (value === null || value === undefined) {\n return value;\n }\n switch (typeof value) {\n case \"boolean\":\n case \"number\":\n case \"string\":\n return value;\n case \"object\":\n if (value && \"data\" in value) {\n return value.data;\n } else {\n return undefined;\n }\n default:\n return undefined;\n }\n }\n}\n\n/** This includes any asset such as image, video, audio, file */\nexport interface StrapiMediaAttributes {\n url: string;\n mime: string;\n ext: string;\n size: number;\n // width and height are null for non-image media (e.g. audio files)\n width: number | null;\n height: number | null;\n formats?: { [key: string]: Omit<StrapiMediaAttributes, \"formats\"> };\n // Added by transformMediaUrls - absolute URL with host prepended\n absoluteUrl?: string;\n}\n\nexport interface StrapiImageAttribute extends StrapiMediaAttributes {\n width: number;\n height: number;\n}\n/**\n * Gets media attributes if it's a media item.\n *\n * This is the small subset of the fields that we care about.\n *\n * @internal\n */\nexport function getMediaAttributes(\n value: StrapiItem\n): StrapiMediaAttributes | undefined {\n const attributes = isV5Item(value) ? value : value.attributes;\n if (\n \"url\" in attributes &&\n \"mime\" in attributes &&\n \"ext\" in attributes &&\n \"size\" in attributes\n ) {\n return attributes as { [attribute: string]: any } as StrapiMediaAttributes;\n } else {\n return undefined;\n }\n}\n", "import {\n StrapiImageAttribute,\n StrapiItem,\n StrapiMediaAttributes,\n StrapiQueryResponse,\n getFieldValue,\n getItemKeys,\n getMediaAttributes,\n isStrapiItem,\n isStrapiPrimitive,\n} from \"./strapi-compat\";\n\n/**\n * https://docs-v4.strapi.io/dev-docs/api/entity-service/filter\n * @internal\n */\nexport const queryParameters = [\n {\n value: \"$eq\",\n label: \"Equal\",\n },\n {\n value: \"$ne\",\n label: \"Not equal\",\n },\n {\n value: \"$lt\",\n label: \"Less than\",\n },\n {\n value: \"$lte\",\n label: \"Less than or equal to\",\n },\n {\n value: \"$gt\",\n label: \"Greater than\",\n },\n {\n value: \"$gte\",\n label: \"Greater than or equal to\",\n },\n {\n value: \"$in\",\n label: \"Included in an array\",\n },\n {\n value: \"$notIn\",\n label: \"Not included in an array\",\n },\n {\n value: \"$contains\",\n label: \"Contains\",\n },\n {\n value: \"$notContains\",\n label: \"Does not contain\",\n },\n];\n\n/**\n * Checks if the media attribute contains an image media\n * @internal\n */\nexport function isImage(\n mediaAttr: StrapiMediaAttributes\n): mediaAttr is StrapiImageAttribute {\n return mediaAttr?.mime.startsWith(\"image\");\n}\n\n/**\n * Removes leading and trailing slash and whitespace characters from a URL\n * @internal\n */\nexport function normalizeUrl(url: string): string {\n return (\n url\n .trim()\n // remove leading slash\n .replace(/^\\/+/, \"\")\n // remove leading trailing\n .replace(/\\/+$/, \"\")\n );\n}\n\n/**\n * Extracts fields whose types can be filtered in Plasmic.\n * @internal\n */\nexport function extractFilterableFields(\n items: StrapiItem | StrapiItem[]\n): string[] {\n if (Array.isArray(items)) {\n return Array.from(new Set(items.flatMap(filterableFields)));\n } else {\n return filterableFields(items);\n }\n}\n\nfunction filterableFields(item: StrapiItem): string[] {\n return getItemKeys(item).filter((key) => {\n const value = getFieldValue(item, key);\n return isStrapiPrimitive(value);\n });\n}\n\n/**\n * Extracts fields whose types can be displayed in Plasmic.\n * @internal\n */\nexport function extractDisplayableFields(\n items: StrapiItem | StrapiItem[]\n): string[] {\n if (Array.isArray(items)) {\n return Array.from(new Set(items.flatMap(displayableFields)));\n } else {\n return displayableFields(items);\n }\n}\n\nfunction displayableFields(item: StrapiItem): string[] {\n return getItemKeys(item).filter((key) => {\n const value = getFieldValue(item, key);\n return (\n isStrapiPrimitive(value) ||\n (isStrapiItem(value) && getMediaAttributes(value))\n );\n });\n}\n\n/**\n * Traverses @param data and adds an absoluteUrl field to all media items by prepending the @param host to the url\n * @internal\n */\nexport function transformMediaUrls(\n data: StrapiQueryResponse,\n host: string\n): StrapiQueryResponse {\n if (data === null || data === undefined) {\n return data;\n }\n\n const normalizedHost = normalizeUrl(host);\n\n /**\n * Converts a relative URL to absolute by prepending the host.\n * If URL is already absolute, returns it unchanged.\n */\n function makeAbsoluteUrl(url: string): string {\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\")) {\n return url;\n }\n return normalizedHost + \"/\" + normalizeUrl(url);\n }\n\n /**\n * Adds absoluteUrl to a media item and its format variations\n */\n function transformMediaItem(mediaAttrs: StrapiMediaAttributes): void {\n mediaAttrs.absoluteUrl = makeAbsoluteUrl(mediaAttrs.url);\n\n // Transform format variations (thumbnail, small, medium, large, etc.)\n if (mediaAttrs.formats && typeof mediaAttrs.formats === \"object\") {\n for (const formatKey of Object.keys(mediaAttrs.formats)) {\n transformMediaItem(mediaAttrs.formats[formatKey]);\n }\n }\n }\n\n /**\n * Recursively traverses a Strapi item and transforms all nested media\n */\n function transformStrapiItem(item: StrapiItem): void {\n const mediaAttrs = getMediaAttributes(item);\n\n if (mediaAttrs) {\n // This item is itself a media item\n transformMediaItem(mediaAttrs);\n } else {\n // This item contains other fields that might be media\n for (const key of getItemKeys(item)) {\n const fieldValue = getFieldValue(item, key);\n transformValue(fieldValue);\n }\n }\n }\n\n /**\n * Recursively traverses and transforms media URLs in any value\n */\n function transformValue(value: any): any {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (isStrapiPrimitive(value)) {\n return value;\n }\n\n if (Array.isArray(value)) {\n value.forEach(transformValue);\n return value;\n }\n\n if (isStrapiItem(value)) {\n transformStrapiItem(value);\n } else if (typeof value === \"object\") {\n // Plain object - traverse its properties\n for (const key of Object.keys(value)) {\n transformValue(value[key]);\n }\n }\n\n return value;\n }\n\n return transformValue(data);\n}\n", "import type {\n Config,\n Field,\n FieldOrGroup,\n} from \"@react-awesome-query-builder/core\";\nimport type { RulesLogic } from \"json-logic-js\";\n\n/**\n * Maps Strapi collection fields to react-awesome-query-builder config.\n *\n * The result will be handled by {@link rulesLogicToStrapiFilters}.\n * Make sure it supports all operators defined here.\n */\nexport function strapiFieldsToQueryBuilderConfig(\n fields: string[],\n sampleData?: any\n): Pick<Config, \"fields\"> {\n const qbFields: { [key: string]: FieldOrGroup } = {};\n for (const field of fields) {\n // Try to get sample value from sampleData to infer type\n const sampleValue = sampleData?.[field];\n const qbField = strapiFieldToQueryBuilderField(field, sampleValue);\n if (qbField) {\n qbFields[field] = qbField;\n }\n }\n return {\n fields: qbFields,\n };\n}\n\n/**\n * Maps a Strapi field name to a query builder field configuration.\n *\n * Infers field type from field name patterns and sample values if provided.\n */\nfunction strapiFieldToQueryBuilderField(\n fieldName: string,\n sampleValue?: unknown\n): Field | undefined {\n const label = fieldName;\n\n // Infer type from sample value if provided\n if (typeof sampleValue === \"number\") {\n return {\n type: \"number\",\n label,\n operators: [\n \"equal\",\n \"not_equal\",\n \"less\",\n \"less_or_equal\",\n \"greater\",\n \"greater_or_equal\",\n \"is_null\",\n \"is_not_null\",\n ],\n };\n }\n if (typeof sampleValue === \"boolean\") {\n return {\n type: \"boolean\",\n label,\n };\n }\n if (typeof sampleValue === \"string\") {\n if (!isNaN(new Date(sampleValue).getTime())) {\n return {\n type: \"datetime\",\n label,\n operators: [\n \"equal\",\n \"not_equal\",\n \"less\",\n \"less_or_equal\",\n \"greater\",\n \"greater_or_equal\",\n \"is_null\",\n \"is_not_null\",\n ],\n };\n }\n\n return {\n type: \"text\",\n label,\n operators: [\n \"equal\",\n \"not_equal\",\n \"like\",\n \"not_like\",\n \"is_null\",\n \"is_not_null\",\n ],\n };\n }\n\n return undefined;\n}\n\n/**\n * Maps JsonLogic to Strapi API filters format.\n *\n * See also:\n * - https://docs.strapi.io/cms/api/rest/filters\n */\nexport function rulesLogicToStrapiFilters(logic: RulesLogic | undefined): any {\n if (logic === null || logic === undefined) {\n return undefined;\n } else if (typeof logic !== \"object\") {\n throw new Error(`unexpected logic: ${JSON.stringify(logic)}`);\n } else if (\"and\" in logic) {\n return {\n $and: logic[\"and\"].map(rulesLogicToStrapiFilters),\n };\n } else if (\"or\" in logic) {\n return {\n $or: logic[\"or\"].map(rulesLogicToStrapiFilters),\n };\n } else if (\"!\" in logic) {\n return {\n $not: rulesLogicToStrapiFilters(logic[\"!\"]),\n };\n } else if (\"==\" in logic) {\n const [{ var: field }, operand] = logic[\"==\"] as [{ var: string }, unknown];\n if (operand === null) {\n return { [field]: { $null: true } };\n }\n return {\n [field]: { $eq: operand },\n };\n } else if (\"!=\" in logic) {\n const [{ var: field }, operand] = logic[\"!=\"] as [{ var: string }, unknown];\n if (operand === null) {\n return { [field]: { $notNull: true } };\n }\n return {\n [field]: { $ne: operand },\n };\n // Map in operator to Strapi filters format:\n // JsonLogic: { \"in\": [\"Mairi\", { \"var\": \"name\" }] }\n // Strapi filters: { \"name\": { $contains: \"Mairi\" } }\n } else if (\"in\" in logic) {\n const [operand, { var: field }] = logic[\"in\"] as [string, { var: string }];\n return {\n [field]: { $contains: operand },\n };\n } else {\n // Map JsonLogic to Strapi filters format:\n // JsonLogic: { \"<=\": [{ \"var\": \"age\" }, 18] }\n // Strapi filters: { \"age\": { \"$lte\": 18 } }\n const [key, value] = Object.entries(logic)[0];\n const apiOp: string | undefined = operatorMapping[key];\n if (apiOp) {\n const [{ var: field }, operand] = value as [{ var: string }, unknown];\n return { [field]: { [apiOp]: operand } };\n }\n\n throw new Error(`unexpected logic: ${JSON.stringify(logic)}`);\n }\n}\n\n/** Maps JsonLogic operator to Strapi filter operator. */\nconst operatorMapping: Record<string, string> = {\n \"<\": \"$lt\",\n \"<=\": \"$lte\",\n \">\": \"$gt\",\n \">=\": \"$gte\",\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import registerFunction, {\n CustomFunctionMeta,\n} from \"@plasmicapp/host/registerFunction\";\nimport { _queryStrapi, queryStrapi, queryStrapiMeta } from \"./query-strapi\";\n\nexport function registerStrapi(loader?: { registerFunction: any }) {\n function _registerFunction<T extends (...args: any[]) => any>(\n fn: T,\n meta: CustomFunctionMeta<T>\n ) {\n if (loader) {\n loader.registerFunction(fn, meta);\n } else {\n registerFunction(fn, meta);\n }\n }\n\n _registerFunction(queryStrapi, queryStrapiMeta);\n}\n\nexport {\n // used by @plasmicpkgs/plasmic-strapi\n _queryStrapi,\n queryStrapi,\n};\n\n// used by @plasmicpkgs/plasmic-strapi\nexport {\n getItemKeys as _getFieldKeys,\n getFieldValue as _getFieldValue,\n getId as _getId,\n getMediaAttributes as _getMediaAttributes,\n isStrapiItem as _isStrapiItem,\n isStrapiItemArray as _isStrapiItemArray,\n isStrapiPrimitive as _isStrapiPrimitive,\n} from \"./strapi-compat\";\nexport {\n extractDisplayableFields as _extractDisplayableFields,\n extractFilterableFields as _extractFilterableFields,\n isImage as _isImage,\n queryParameters as _queryParameters,\n} from \"./utils\";\n", "import { CustomFunctionMeta } from \"@plasmicapp/host/registerFunction\";\nimport type { RulesLogic } from \"json-logic-js\";\nimport qs from \"qs\";\nimport { getFieldValue, StrapiQueryResponse } from \"./strapi-compat\";\nimport {\n extractFilterableFields,\n normalizeUrl,\n transformMediaUrls,\n} from \"./utils\";\nimport {\n rulesLogicToStrapiFilters,\n strapiFieldsToQueryBuilderConfig,\n} from \"./where\";\n\nexport const queryStrapiMeta: CustomFunctionMeta<typeof queryStrapi> = {\n name: \"queryStrapi\",\n displayName: \"Query Strapi\",\n description: \"Query a Strapi collection\",\n importPath: \"@plasmicpkgs/strapi\",\n isQuery: true,\n params: [\n {\n name: \"opts\",\n type: \"object\",\n display: \"flatten\",\n fields: {\n host: {\n type: \"string\",\n description: \"The Strapi host URL (e.g., https://example.com)\",\n },\n token: {\n type: \"string\",\n description:\n \"The Strapi API token (optional, for authenticated requests)\",\n },\n collection: {\n type: \"string\",\n description: \"The name of the Strapi collection to query\",\n },\n filterLogic: {\n type: \"queryBuilder\",\n description: \"Filter fetched entries. Defaults to fetch all entries.\",\n config: (_: any, ctx: any) => {\n const fields = ctx?.strapiFields || [];\n return strapiFieldsToQueryBuilderConfig(fields, ctx?.sampleData);\n },\n },\n },\n },\n ],\n fnContext: (strapiOpts?: QueryStrapiOpts) => {\n if (!strapiOpts?.host) {\n return {\n dataKey: \"\",\n fetcher: async () => {\n return {};\n },\n };\n }\n // Exclude filterLogic from dataKey to prevent refetching when user types in query builder\n // The fields and sampleData should only depend on host, token, and collection\n const fetchOpts: QueryStrapiOpts = {\n host: strapiOpts.host,\n token: strapiOpts.token,\n collection: strapiOpts.collection,\n };\n return {\n dataKey: JSON.stringify(fetchOpts),\n fetcher: async () => {\n const resp = await queryStrapi(fetchOpts);\n const collectionData = resp?.data;\n if (!collectionData) {\n return { strapiFields: [] };\n }\n\n // Extract field values from multiple items for type inference\n // Check up to 10 items to find non-null values for each field\n const sampleData: Record<string, any> = {};\n const fields = extractFilterableFields(collectionData);\n const itemsToCheck = collectionData.slice(0, 10);\n // For each field, find the first non-null value across multiple items\n for (const field of fields) {\n for (const item of itemsToCheck) {\n if (item) {\n const value = getFieldValue(item, field);\n if (value !== null && value !== undefined) {\n sampleData[field] = value;\n break;\n }\n }\n }\n }\n\n return {\n strapiFields: fields,\n sampleData,\n };\n },\n };\n },\n};\n\n// Simplified filter props only intended for use by the deprecated StrapiCollection component\nexport interface StrapiQueryOldFilterProps {\n filterField?: string;\n filterValue?: string;\n filterParameter?: string;\n}\n\nexport interface QueryStrapiOpts {\n host?: string;\n token?: string;\n collection?: string;\n /**\n * Filter logic using JSON Logic format to filter Strapi entries.\n * See {@link https://www.npmjs.com/package/@types/json-logic-js?activeTab=readme}\n */\n filterLogic?: RulesLogic;\n}\n\n/**\n * Query a Strapi collection with optional filtering.\n *\n * @param opts - Query options including host, token, collection, and filter logic\n * @returns Promise resolving to the Strapi query response or null if required params are missing\n *\n * @example\n * ```ts\n * // Fetch all entries\n * const result = await queryStrapi({\n * host: 'https://api.example.com',\n * token: 'your-api-token',\n * collection: 'articles'\n * });\n *\n * // Fetch with filter\n * const filtered = await queryStrapi({\n * host: 'https://api.example.com',\n * token: 'your-api-token',\n * collection: 'articles',\n * filterLogic: { \"==\": [{ var: \"status\" }, \"published\"] }\n * });\n * ```\n */\nexport async function queryStrapi({\n host,\n token,\n collection,\n filterLogic,\n}: QueryStrapiOpts): Promise<StrapiQueryResponse | null> {\n return _queryStrapi({ host, token, collection, filterLogic });\n}\n\n/**\n * Query Strapi with simplified filter props.\n *\n * @deprecated Use {@link queryStrapi} with `filterLogic` parameter instead.\n *\n * @example\n * ```ts\n * // Old way (deprecated)\n * _queryStrapi({ filterField: 'name', filterValue: 'John' })\n *\n * // New way\n * queryStrapi({\n * filterLogic: {\"==\": [{ var: \"name\" }, \"John\"]}\n * })\n * ```\n */\nexport async function _queryStrapi({\n host,\n token,\n collection,\n filterLogic,\n filterField,\n filterValue,\n filterParameter,\n}: QueryStrapiOpts &\n StrapiQueryOldFilterProps): Promise<StrapiQueryResponse | null> {\n if (!host || !collection) {\n return null;\n }\n\n const query = normalizeUrl(host) + \"/api/\" + collection.trim();\n\n const requestInit: RequestInit = { method: \"GET\" };\n if (token) {\n requestInit.headers = { Authorization: \"Bearer \" + token };\n }\n\n let filters: Record<string, any> = {};\n if (filterLogic) {\n filters = rulesLogicToStrapiFilters(filterLogic);\n } else if (filterField && filterParameter && filterValue) {\n filters = {\n [filterField]: {\n [filterParameter]: filterValue,\n },\n };\n }\n\n // Build query parameters for Strapi REST API\n // Strapi uses nested query parameters like: filters[$and][0][field][$eq]=value\n const queryParams = qs.stringify({\n filters,\n populate: \"*\",\n });\n\n const resp = await fetch(`${query}?${queryParams}`, requestInit);\n const data = await resp.json();\n\n // Transform all relative media URLs to absolute URLs\n return transformMediaUrls(data, host);\n}\n", "// This file contains Strapi code for handling v4/v5 compatibility.\n// https://docs.strapi.io/cms/migration/v4-to-v5/breaking-changes/new-response-format\n\nexport interface StrapiQueryResponse {\n data: StrapiItem[];\n meta: {\n pagination: {\n page: number;\n pageSize: number;\n pageCount: number;\n total: number;\n };\n };\n}\n\n/** A primitive, item, item array, or null (for optional fields). */\nexport type StrapiValue =\n | boolean\n | number\n | string\n | StrapiItem\n | ReadonlyArray<StrapiItem>\n | ReadonlyArray<any> // For rich text content, JSON fields, etc.\n | Record<string, any> // For JSON fields, metadata objects, etc.\n | null;\ntype StrapiValueV4 =\n | boolean\n | number\n | string\n | { data: StrapiItemV4 | ReadonlyArray<StrapiItemV4> }\n | ReadonlyArray<any> // For rich text content, JSON fields, etc.\n | Record<string, any> // For JSON fields, metadata objects, etc.\n | null;\ntype StrapiValueV5 =\n | boolean\n | number\n | string\n | StrapiItemV5\n | ReadonlyArray<StrapiItemV5>\n | ReadonlyArray<any> // For rich text content, JSON fields, etc.\n | Record<string, any> // For JSON fields, metadata objects, etc.\n | null;\n\n/** A content item or media item. */\nexport type StrapiItem = StrapiItemV4 | StrapiItemV5;\nexport interface StrapiItemV4 {\n id: number;\n attributes: {\n [attribute: string]: StrapiValueV4;\n };\n}\nexport interface StrapiItemV5 {\n documentId: string;\n [attribute: string]: StrapiValueV5;\n}\nfunction isV5Item(item: StrapiItem): item is StrapiItemV5 {\n return \"documentId\" in item;\n}\n\nfunction isV4Item(item: StrapiItem): item is StrapiItemV5 {\n return \"id\" in item && \"attributes\" in item;\n}\n\n/** @internal */\nexport function isStrapiPrimitive(\n value: StrapiValue | undefined\n): value is boolean | number | string {\n const type = typeof value;\n return type === \"boolean\" || type === \"number\" || type === \"string\";\n}\n/** @internal */\nexport function isStrapiItem(\n item: StrapiValue | undefined\n): item is StrapiItem {\n if (typeof item !== \"object\" || item === null || Array.isArray(item)) {\n return false;\n }\n // The object must be a valid v5 or v4 item\n return isV5Item(item as any) || isV4Item(item as any);\n}\n/** @internal */\nexport function isStrapiItemArray(\n value: StrapiValue | undefined\n): value is ReadonlyArray<StrapiItem> {\n return typeof value === \"object\" && value !== null && Array.isArray(value);\n}\n\n/** @internal */\nexport function getId(item: StrapiItem): string {\n if (isV5Item(item)) {\n return item.documentId;\n } else {\n // v4\n return item.id.toString();\n }\n}\n\n/** @internal */\nexport function getItemKeys(item: StrapiItem) {\n if (isV5Item(item)) {\n return Object.keys(item).filter((key) => key !== \"documentId\");\n } else {\n // v4\n return Object.keys(item.attributes);\n }\n}\n\n/**\n * Gets the value, or undefined if the field key does not exist.\n * @internal\n */\nexport function getFieldValue(\n item: StrapiItem,\n key: string\n): StrapiValue | undefined {\n if (isV5Item(item)) {\n return item[key];\n } else {\n // v4\n const value = item.attributes[key];\n if (value === null || value === undefined) {\n return value;\n }\n switch (typeof value) {\n case \"boolean\":\n case \"number\":\n case \"string\":\n return value;\n case \"object\":\n if (value && \"data\" in value) {\n return value.data;\n } else {\n return undefined;\n }\n default:\n return undefined;\n }\n }\n}\n\n/** This includes any asset such as image, video, audio, file */\nexport interface StrapiMediaAttributes {\n url: string;\n mime: string;\n ext: string;\n size: number;\n // width and height are null for non-image media (e.g. audio files)\n width: number | null;\n height: number | null;\n formats?: { [key: string]: Omit<StrapiMediaAttributes, \"formats\"> };\n // Added by transformMediaUrls - absolute URL with host prepended\n absoluteUrl?: string;\n}\n\nexport interface StrapiImageAttribute extends StrapiMediaAttributes {\n width: number;\n height: number;\n}\n/**\n * Gets media attributes if it's a media item.\n *\n * This is the small subset of the fields that we care about.\n *\n * @internal\n */\nexport function getMediaAttributes(\n value: StrapiItem\n): StrapiMediaAttributes | undefined {\n const attributes = isV5Item(value) ? value : value.attributes;\n if (\n \"url\" in attributes &&\n \"mime\" in attributes &&\n \"ext\" in attributes &&\n \"size\" in attributes\n ) {\n return attributes as { [attribute: string]: any } as StrapiMediaAttributes;\n } else {\n return undefined;\n }\n}\n", "import {\n StrapiImageAttribute,\n StrapiItem,\n StrapiMediaAttributes,\n StrapiQueryResponse,\n getFieldValue,\n getItemKeys,\n getMediaAttributes,\n isStrapiItem,\n isStrapiPrimitive,\n} from \"./strapi-compat\";\n\n/**\n * https://docs-v4.strapi.io/dev-docs/api/entity-service/filter\n * @internal\n */\nexport const queryParameters = [\n {\n value: \"$eq\",\n label: \"Equal\",\n },\n {\n value: \"$ne\",\n label: \"Not equal\",\n },\n {\n value: \"$lt\",\n label: \"Less than\",\n },\n {\n value: \"$lte\",\n label: \"Less than or equal to\",\n },\n {\n value: \"$gt\",\n label: \"Greater than\",\n },\n {\n value: \"$gte\",\n label: \"Greater than or equal to\",\n },\n {\n value: \"$in\",\n label: \"Included in an array\",\n },\n {\n value: \"$notIn\",\n label: \"Not included in an array\",\n },\n {\n value: \"$contains\",\n label: \"Contains\",\n },\n {\n value: \"$notContains\",\n label: \"Does not contain\",\n },\n];\n\n/**\n * Checks if the media attribute contains an image media\n * @internal\n */\nexport function isImage(\n mediaAttr: StrapiMediaAttributes\n): mediaAttr is StrapiImageAttribute {\n return mediaAttr?.mime.startsWith(\"image\");\n}\n\n/**\n * Removes leading and trailing slash and whitespace characters from a URL\n * @internal\n */\nexport function normalizeUrl(url: string): string {\n return (\n url\n .trim()\n // remove leading slash\n .replace(/^\\/+/, \"\")\n // remove leading trailing\n .replace(/\\/+$/, \"\")\n );\n}\n\n/**\n * Extracts fields whose types can be filtered in Plasmic.\n * @internal\n */\nexport function extractFilterableFields(\n items: StrapiItem | StrapiItem[]\n): string[] {\n if (Array.isArray(items)) {\n return Array.from(new Set(items.flatMap(filterableFields)));\n } else {\n return filterableFields(items);\n }\n}\n\nfunction filterableFields(item: StrapiItem): string[] {\n return getItemKeys(item).filter((key) => {\n const value = getFieldValue(item, key);\n return isStrapiPrimitive(value);\n });\n}\n\n/**\n * Extracts fields whose types can be displayed in Plasmic.\n * @internal\n */\nexport function extractDisplayableFields(\n items: StrapiItem | StrapiItem[]\n): string[] {\n if (Array.isArray(items)) {\n return Array.from(new Set(items.flatMap(displayableFields)));\n } else {\n return displayableFields(items);\n }\n}\n\nfunction displayableFields(item: StrapiItem): string[] {\n return getItemKeys(item).filter((key) => {\n const value = getFieldValue(item, key);\n return (\n isStrapiPrimitive(value) ||\n (isStrapiItem(value) && getMediaAttributes(value))\n );\n });\n}\n\n/**\n * Traverses @param data and adds an absoluteUrl field to all media items by prepending the @param host to the url\n * @internal\n */\nexport function transformMediaUrls(\n data: StrapiQueryResponse,\n host: string\n): StrapiQueryResponse {\n if (data === null || data === undefined) {\n return data;\n }\n\n const normalizedHost = normalizeUrl(host);\n\n /**\n * Converts a relative URL to absolute by prepending the host.\n * If URL is already absolute, returns it unchanged.\n */\n function makeAbsoluteUrl(url: string): string {\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\")) {\n return url;\n }\n return normalizedHost + \"/\" + normalizeUrl(url);\n }\n\n /**\n * Adds absoluteUrl to a media item and its format variations\n */\n function transformMediaItem(mediaAttrs: StrapiMediaAttributes): void {\n mediaAttrs.absoluteUrl = makeAbsoluteUrl(mediaAttrs.url);\n\n // Transform format variations (thumbnail, small, medium, large, etc.)\n if (mediaAttrs.formats && typeof mediaAttrs.formats === \"object\") {\n for (const formatKey of Object.keys(mediaAttrs.formats)) {\n transformMediaItem(mediaAttrs.formats[formatKey]);\n }\n }\n }\n\n /**\n * Recursively traverses a Strapi item and transforms all nested media\n */\n function transformStrapiItem(item: StrapiItem): void {\n const mediaAttrs = getMediaAttributes(item);\n\n if (mediaAttrs) {\n // This item is itself a media item\n transformMediaItem(mediaAttrs);\n } else {\n // This item contains other fields that might be media\n for (const key of getItemKeys(item)) {\n const fieldValue = getFieldValue(item, key);\n transformValue(fieldValue);\n }\n }\n }\n\n /**\n * Recursively traverses and transforms media URLs in any value\n */\n function transformValue(value: any): any {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (isStrapiPrimitive(value)) {\n return value;\n }\n\n if (Array.isArray(value)) {\n value.forEach(transformValue);\n return value;\n }\n\n if (isStrapiItem(value)) {\n transformStrapiItem(value);\n } else if (typeof value === \"object\") {\n // Plain object - traverse its properties\n for (const key of Object.keys(value)) {\n transformValue(value[key]);\n }\n }\n\n return value;\n }\n\n return transformValue(data);\n}\n", "import type {\n Config,\n Field,\n FieldOrGroup,\n} from \"@react-awesome-query-builder/core\";\nimport type { RulesLogic } from \"json-logic-js\";\n\n/**\n * Maps Strapi collection fields to react-awesome-query-builder config.\n *\n * The result will be handled by {@link rulesLogicToStrapiFilters}.\n * Make sure it supports all operators defined here.\n */\nexport function strapiFieldsToQueryBuilderConfig(\n fields: string[],\n sampleData?: any\n): Pick<Config, \"fields\"> {\n const qbFields: { [key: string]: FieldOrGroup } = {};\n for (const field of fields) {\n // Try to get sample value from sampleData to infer type\n const sampleValue = sampleData?.[field];\n const qbField = strapiFieldToQueryBuilderField(field, sampleValue);\n if (qbField) {\n qbFields[field] = qbField;\n }\n }\n return {\n fields: qbFields,\n };\n}\n\n/**\n * Maps a Strapi field name to a query builder field configuration.\n *\n * Infers field type from field name patterns and sample values if provided.\n */\nfunction strapiFieldToQueryBuilderField(\n fieldName: string,\n sampleValue?: unknown\n): Field | undefined {\n const label = fieldName;\n\n // Infer type from sample value if provided\n if (typeof sampleValue === \"number\") {\n return {\n type: \"number\",\n label,\n operators: [\n \"equal\",\n \"not_equal\",\n \"less\",\n \"less_or_equal\",\n \"greater\",\n \"greater_or_equal\",\n \"is_null\",\n \"is_not_null\",\n ],\n };\n }\n if (typeof sampleValue === \"boolean\") {\n return {\n type: \"boolean\",\n label,\n };\n }\n if (typeof sampleValue === \"string\") {\n if (!isNaN(new Date(sampleValue).getTime())) {\n return {\n type: \"datetime\",\n label,\n operators: [\n \"equal\",\n \"not_equal\",\n \"less\",\n \"less_or_equal\",\n \"greater\",\n \"greater_or_equal\",\n \"is_null\",\n \"is_not_null\",\n ],\n };\n }\n\n return {\n type: \"text\",\n label,\n operators: [\n \"equal\",\n \"not_equal\",\n \"like\",\n \"not_like\",\n \"is_null\",\n \"is_not_null\",\n ],\n };\n }\n\n return undefined;\n}\n\n/**\n * Maps JsonLogic to Strapi API filters format.\n *\n * See also:\n * - https://docs.strapi.io/cms/api/rest/filters\n */\nexport function rulesLogicToStrapiFilters(logic: RulesLogic | undefined): any {\n if (logic === null || logic === undefined) {\n return undefined;\n } else if (typeof logic !== \"object\") {\n throw new Error(`unexpected logic: ${JSON.stringify(logic)}`);\n } else if (\"and\" in logic) {\n return {\n $and: logic[\"and\"].map(rulesLogicToStrapiFilters),\n };\n } else if (\"or\" in logic) {\n return {\n $or: logic[\"or\"].map(rulesLogicToStrapiFilters),\n };\n } else if (\"!\" in logic) {\n return {\n $not: rulesLogicToStrapiFilters(logic[\"!\"]),\n };\n } else if (\"==\" in logic) {\n const [{ var: field }, operand] = logic[\"==\"] as [{ var: string }, unknown];\n if (operand === null) {\n return { [field]: { $null: true } };\n }\n return {\n [field]: { $eq: operand },\n };\n } else if (\"!=\" in logic) {\n const [{ var: field }, operand] = logic[\"!=\"] as [{ var: string }, unknown];\n if (operand === null) {\n return { [field]: { $notNull: true } };\n }\n return {\n [field]: { $ne: operand },\n };\n // Map in operator to Strapi filters format:\n // JsonLogic: { \"in\": [\"Mairi\", { \"var\": \"name\" }] }\n // Strapi filters: { \"name\": { $contains: \"Mairi\" } }\n } else if (\"in\" in logic) {\n const [operand, { var: field }] = logic[\"in\"] as [string, { var: string }];\n return {\n [field]: { $contains: operand },\n };\n } else {\n // Map JsonLogic to Strapi filters format:\n // JsonLogic: { \"<=\": [{ \"var\": \"age\" }, 18] }\n // Strapi filters: { \"age\": { \"$lte\": 18 } }\n const [key, value] = Object.entries(logic)[0];\n const apiOp: string | undefined = operatorMapping[key];\n if (apiOp) {\n const [{ var: field }, operand] = value as [{ var: string }, unknown];\n return { [field]: { [apiOp]: operand } };\n }\n\n throw new Error(`unexpected logic: ${JSON.stringify(logic)}`);\n }\n}\n\n/** Maps JsonLogic operator to Strapi filter operator. */\nconst operatorMapping: Record<string, string> = {\n \"<\": \"$lt\",\n \"<=\": \"$lte\",\n \">\": \"$gt\",\n \">=\": \"$gte\",\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8BAEO;;;ACAP,gBAAe;;;ACqDf,SAAS,SAAS,MAAwC;AACxD,SAAO,gBAAgB;AACzB;AAEA,SAAS,SAAS,MAAwC;AACxD,SAAO,QAAQ,QAAQ,gBAAgB;AACzC;AAGO,SAAS,kBACd,OACoC;AACpC,QAAM,OAAO,OAAO;AACpB,SAAO,SAAS,aAAa,SAAS,YAAY,SAAS;AAC7D;AAEO,SAAS,aACd,MACoB;AACpB,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,MAAM,QAAQ,IAAI,GAAG;AACpE,WAAO;AAAA,EACT;AAEA,SAAO,SAAS,IAAW,KAAK,SAAS,IAAW;AACtD;AAEO,SAAS,kBACd,OACoC;AACpC,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK;AAC3E;AAGO,SAAS,MAAM,MAA0B;AAC9C,MAAI,SAAS,IAAI,GAAG;AAClB,WAAO,KAAK;AAAA,EACd,OAAO;AAEL,WAAO,KAAK,GAAG,SAAS;AAAA,EAC1B;AACF;AAGO,SAAS,YAAY,MAAkB;AAC5C,MAAI,SAAS,IAAI,GAAG;AAClB,WAAO,OAAO,KAAK,IAAI,EAAE,OAAO,CAAC,QAAQ,QAAQ,YAAY;AAAA,EAC/D,OAAO;AAEL,WAAO,OAAO,KAAK,KAAK,UAAU;AAAA,EACpC;AACF;AAMO,SAAS,cACd,MACA,KACyB;AACzB,MAAI,SAAS,IAAI,GAAG;AAClB,WAAO,KAAK,GAAG;AAAA,EACjB,OAAO;AAEL,UAAM,QAAQ,KAAK,WAAW,GAAG;AACjC,QAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,aAAO;AAAA,IACT;AACA,YAAQ,OAAO,OAAO;AAAA,MACpB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,YAAI,SAAS,UAAU,OAAO;AAC5B,iBAAO,MAAM;AAAA,QACf,OAAO;AACL,iBAAO;AAAA,QACT;AAAA,MACF;AACE,eAAO;AAAA,IACX;AAAA,EACF;AACF;AA2BO,SAAS,mBACd,OACmC;AACnC,QAAM,aAAa,SAAS,KAAK,IAAI,QAAQ,MAAM;AACnD,MACE,SAAS,cACT,UAAU,cACV,SAAS,cACT,UAAU,YACV;AACA,WAAO;AAAA,EACT,OAAO;AACL,WAAO;AAAA,EACT;AACF;;;ACnKO,IAAM,kBAAkB;AAAA,EAC7B;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AACF;AAMO,SAAS,QACd,WACmC;AACnC,SAAO,uCAAW,KAAK,WAAW;AACpC;AAMO,SAAS,aAAa,KAAqB;AAChD,SACE,IACG,KAAK,EAEL,QAAQ,QAAQ,EAAE,EAElB,QAAQ,QAAQ,EAAE;AAEzB;AAMO,SAAS,wBACd,OACU;AACV,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,KAAK,IAAI,IAAI,MAAM,QAAQ,gBAAgB,CAAC,CAAC;AAAA,EAC5D,OAAO;AACL,WAAO,iBAAiB,KAAK;AAAA,EAC/B;AACF;AAEA,SAAS,iBAAiB,MAA4B;AACpD,SAAO,YAAY,IAAI,EAAE,OAAO,CAAC,QAAQ;AACvC,UAAM,QAAQ,cAAc,MAAM,GAAG;AACrC,WAAO,kBAAkB,KAAK;AAAA,EAChC,CAAC;AACH;AAMO,SAAS,yBACd,OACU;AACV,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,KAAK,IAAI,IAAI,MAAM,QAAQ,iBAAiB,CAAC,CAAC;AAAA,EAC7D,OAAO;AACL,WAAO,kBAAkB,KAAK;AAAA,EAChC;AACF;AAEA,SAAS,kBAAkB,MAA4B;AACrD,SAAO,YAAY,IAAI,EAAE,OAAO,CAAC,QAAQ;AACvC,UAAM,QAAQ,cAAc,MAAM,GAAG;AACrC,WACE,kBAAkB,KAAK,KACtB,aAAa,KAAK,KAAK,mBAAmB,KAAK;AAAA,EAEpD,CAAC;AACH;AAMO,SAAS,mBACd,MACA,MACqB;AACrB,MAAI,SAAS,QAAQ,SAAS,QAAW;AACvC,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB,aAAa,IAAI;AAMxC,WAAS,gBAAgB,KAAqB;AAC5C,QAAI,IAAI,WAAW,SAAS,KAAK,IAAI,WAAW,UAAU,GAAG;AAC3D,aAAO;AAAA,IACT;AACA,WAAO,iBAAiB,MAAM,aAAa,GAAG;AAAA,EAChD;AAKA,WAAS,mBAAmB,YAAyC;AACnE,eAAW,cAAc,gBAAgB,WAAW,GAAG;AAGvD,QAAI,WAAW,WAAW,OAAO,WAAW,YAAY,UAAU;AAChE,iBAAW,aAAa,OAAO,KAAK,WAAW,OAAO,GAAG;AACvD,2BAAmB,WAAW,QAAQ,SAAS,CAAC;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AAKA,WAAS,oBAAoB,MAAwB;AACnD,UAAM,aAAa,mBAAmB,IAAI;AAE1C,QAAI,YAAY;AAEd,yBAAmB,UAAU;AAAA,IAC/B,OAAO;AAEL,iBAAW,OAAO,YAAY,IAAI,GAAG;AACnC,cAAM,aAAa,cAAc,MAAM,GAAG;AAC1C,uBAAe,UAAU;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAKA,WAAS,eAAe,OAAiB;AACvC,QAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,aAAO;AAAA,IACT;AAEA,QAAI,kBAAkB,KAAK,GAAG;AAC5B,aAAO;AAAA,IACT;AAEA,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,YAAM,QAAQ,cAAc;AAC5B,aAAO;AAAA,IACT;AAEA,QAAI,aAAa,KAAK,GAAG;AACvB,0BAAoB,KAAK;AAAA,IAC3B,WAAW,OAAO,UAAU,UAAU;AAEpC,iBAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AACpC,uBAAe,MAAM,GAAG,CAAC;AAAA,MAC3B;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,SAAO,eAAe,IAAI;AAC5B;;;AC3MO,SAAS,iCACd,QACA,YACwB;AACxB,QAAM,WAA4C,CAAC;AACnD,aAAW,SAAS,QAAQ;AAE1B,UAAM,cAAc,yCAAa;AACjC,UAAM,UAAU,+BAA+B,OAAO,WAAW;AACjE,QAAI,SAAS;AACX,eAAS,KAAK,IAAI;AAAA,IACpB;AAAA,EACF;AACA,SAAO;AAAA,IACL,QAAQ;AAAA,EACV;AACF;AAOA,SAAS,+BACP,WACA,aACmB;AACnB,QAAM,QAAQ;AAGd,MAAI,OAAO,gBAAgB,UAAU;AACnC,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,OAAO,gBAAgB,WAAW;AACpC,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACA,MAAI,OAAO,gBAAgB,UAAU;AACnC,QAAI,CAAC,MAAM,IAAI,KAAK,WAAW,EAAE,QAAQ,CAAC,GAAG;AAC3C,aAAO;AAAA,QACL,MAAM;AAAA,QACN;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAQO,SAAS,0BAA0B,OAAoC;AAC5E,MAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,WAAO;AAAA,EACT,WAAW,OAAO,UAAU,UAAU;AACpC,UAAM,IAAI,MAAM,qBAAqB,KAAK,UAAU,KAAK,GAAG;AAAA,EAC9D,WAAW,SAAS,OAAO;AACzB,WAAO;AAAA,MACL,MAAM,MAAM,KAAK,EAAE,IAAI,yBAAyB;AAAA,IAClD;AAAA,EACF,WAAW,QAAQ,OAAO;AACxB,WAAO;AAAA,MACL,KAAK,MAAM,IAAI,EAAE,IAAI,yBAAyB;AAAA,IAChD;AAAA,EACF,WAAW,OAAO,OAAO;AACvB,WAAO;AAAA,MACL,MAAM,0BAA0B,MAAM,GAAG,CAAC;AAAA,IAC5C;AAAA,EACF,WAAW,QAAQ,OAAO;AACxB,UAAM,CAAC,EAAE,KAAK,MAAM,GAAG,OAAO,IAAI,MAAM,IAAI;AAC5C,QAAI,YAAY,MAAM;AACpB,aAAO,EAAE,CAAC,KAAK,GAAG,EAAE,OAAO,KAAK,EAAE;AAAA,IACpC;AACA,WAAO;AAAA,MACL,CAAC,KAAK,GAAG,EAAE,KAAK,QAAQ;AAAA,IAC1B;AAAA,EACF,WAAW,QAAQ,OAAO;AACxB,UAAM,CAAC,EAAE,KAAK,MAAM,GAAG,OAAO,IAAI,MAAM,IAAI;AAC5C,QAAI,YAAY,MAAM;AACpB,aAAO,EAAE,CAAC,KAAK,GAAG,EAAE,UAAU,KAAK,EAAE;AAAA,IACvC;AACA,WAAO;AAAA,MACL,CAAC,KAAK,GAAG,EAAE,KAAK,QAAQ;AAAA,IAC1B;AAAA,EAIF,WAAW,QAAQ,OAAO;AACxB,UAAM,CAAC,SAAS,EAAE,KAAK,MAAM,CAAC,IAAI,MAAM,IAAI;AAC5C,WAAO;AAAA,MACL,CAAC,KAAK,GAAG,EAAE,WAAW,QAAQ;AAAA,IAChC;AAAA,EACF,OAAO;AAIL,UAAM,CAAC,KAAK,KAAK,IAAI,OAAO,QAAQ,KAAK,EAAE,CAAC;AAC5C,UAAM,QAA4B,gBAAgB,GAAG;AACrD,QAAI,OAAO;AACT,YAAM,CAAC,EAAE,KAAK,MAAM,GAAG,OAAO,IAAI;AAClC,aAAO,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,GAAG,QAAQ,EAAE;AAAA,IACzC;AAEA,UAAM,IAAI,MAAM,qBAAqB,KAAK,UAAU,KAAK,GAAG;AAAA,EAC9D;AACF;AAGA,IAAM,kBAA0C;AAAA,EAC9C,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AACR;;;AH1JO,IAAM,kBAA0D;AAAA,EACrE,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,QAAQ;AAAA,IACN;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aACE;AAAA,QACJ;AAAA,QACA,YAAY;AAAA,UACV,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,aAAa;AAAA,UACX,MAAM;AAAA,UACN,aAAa;AAAA,UACb,QAAQ,CAAC,GAAQ,QAAa;AAC5B,kBAAM,UAAS,2BAAK,iBAAgB,CAAC;AACrC,mBAAO,iCAAiC,QAAQ,2BAAK,UAAU;AAAA,UACjE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,WAAW,CAAC,eAAiC;AAC3C,QAAI,EAAC,yCAAY,OAAM;AACrB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,MAAY;AACnB,iBAAO,CAAC;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAGA,UAAM,YAA6B;AAAA,MACjC,MAAM,WAAW;AAAA,MACjB,OAAO,WAAW;AAAA,MAClB,YAAY,WAAW;AAAA,IACzB;AACA,WAAO;AAAA,MACL,SAAS,KAAK,UAAU,SAAS;AAAA,MACjC,SAAS,MAAY;AACnB,cAAM,OAAO,MAAM,YAAY,SAAS;AACxC,cAAM,iBAAiB,6BAAM;AAC7B,YAAI,CAAC,gBAAgB;AACnB,iBAAO,EAAE,cAAc,CAAC,EAAE;AAAA,QAC5B;AAIA,cAAM,aAAkC,CAAC;AACzC,cAAM,SAAS,wBAAwB,cAAc;AACrD,cAAM,eAAe,eAAe,MAAM,GAAG,EAAE;AAE/C,mBAAW,SAAS,QAAQ;AAC1B,qBAAW,QAAQ,cAAc;AAC/B,gBAAI,MAAM;AACR,oBAAM,QAAQ,cAAc,MAAM,KAAK;AACvC,kBAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,2BAAW,KAAK,IAAI;AACpB;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,eAAO;AAAA,UACL,cAAc;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AA4CA,SAAsB,YAAY,IAKuB;AAAA,6CALvB;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAyD;AACvD,WAAO,aAAa,EAAE,MAAM,OAAO,YAAY,YAAY,CAAC;AAAA,EAC9D;AAAA;AAkBA,SAAsB,aAAa,IAS+B;AAAA,6CAT/B;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GACkE;AAChE,QAAI,CAAC,QAAQ,CAAC,YAAY;AACxB,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,aAAa,IAAI,IAAI,UAAU,WAAW,KAAK;AAE7D,UAAM,cAA2B,EAAE,QAAQ,MAAM;AACjD,QAAI,OAAO;AACT,kBAAY,UAAU,EAAE,eAAe,YAAY,MAAM;AAAA,IAC3D;AAEA,QAAI,UAA+B,CAAC;AACpC,QAAI,aAAa;AACf,gBAAU,0BAA0B,WAAW;AAAA,IACjD,WAAW,eAAe,mBAAmB,aAAa;AACxD,gBAAU;AAAA,QACR,CAAC,WAAW,GAAG;AAAA,UACb,CAAC,eAAe,GAAG;AAAA,QACrB;AAAA,MACF;AAAA,IACF;AAIA,UAAM,cAAc,UAAAA,QAAG,UAAU;AAAA,MAC/B;AAAA,MACA,UAAU;AAAA,IACZ,CAAC;AAED,UAAM,OAAO,MAAM,MAAM,GAAG,SAAS,eAAe,WAAW;AAC/D,UAAM,OAAO,MAAM,KAAK,KAAK;AAG7B,WAAO,mBAAmB,MAAM,IAAI;AAAA,EACtC;AAAA;;;ADhNO,SAAS,eAAe,QAAoC;AACjE,WAAS,kBACP,IACA,MACA;AACA,QAAI,QAAQ;AACV,aAAO,iBAAiB,IAAI,IAAI;AAAA,IAClC,OAAO;AACL,kCAAAC,SAAiB,IAAI,IAAI;AAAA,IAC3B;AAAA,EACF;AAEA,oBAAkB,aAAa,eAAe;AAChD;",
6
6
  "names": ["qs", "registerFunction"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plasmicpkgs/strapi",
3
- "version": "0.0.18",
3
+ "version": "0.0.19",
4
4
  "description": "Plasmic registration for Strapi",
5
5
  "repository": {
6
6
  "type": "git",
@@ -35,7 +35,7 @@
35
35
  "qs": "^6.11.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@plasmicapp/host": "2.0.0",
38
+ "@plasmicapp/host": "2.0.1",
39
39
  "@react-awesome-query-builder/core": "^6.6.15",
40
40
  "@types/json-logic-js": "^2.0.8",
41
41
  "@types/qs": "^6.9.7",
@@ -44,5 +44,5 @@
44
44
  "peerDependencies": {
45
45
  "@plasmicapp/host": ">=1.0.211"
46
46
  },
47
- "gitHead": "cf4b7bfc318b5360730e4e080925370e37870858"
47
+ "gitHead": "dce377f1a8e9fafd7776e49acc077d4a218265e3"
48
48
  }