@websolutespa/payload-plugin-bowl 3.0.0 → 3.0.2

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.
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { MinimalTemplate } from '@payloadcms/next/templates';
4
- import { Button, CheckboxInput, Form, SelectInput, XIcon, toast, useAuth, useConfig, useLocale, useModal, useTranslation } from '@payloadcms/ui';
4
+ import { Button, CheckboxInput, SelectInput, XIcon, toast, useAuth, useConfig, useLocale, useModal, useTranslation } from '@payloadcms/ui';
5
5
  import { getRouteResolver } from '@websolutespa/payload-utils';
6
6
  import * as Papa from 'papaparse';
7
7
  import React, { useCallback, useEffect, useState } from 'react';
@@ -354,8 +354,11 @@ export const ImportModal = ({ parser, slug })=>{
354
354
  }),
355
355
  /*#__PURE__*/ _jsx("main", {
356
356
  className: `${baseClass}__main`,
357
- children: /*#__PURE__*/ _jsxs(Form, {
358
- onSubmit: onSubmit,
357
+ children: /*#__PURE__*/ _jsxs("form", {
358
+ onSubmit: (e)=>{
359
+ e.preventDefault();
360
+ onSubmit();
361
+ },
359
362
  children: [
360
363
  /*#__PURE__*/ _jsxs("div", {
361
364
  className: "render-fields",
@@ -366,12 +369,14 @@ export const ImportModal = ({ parser, slug })=>{
366
369
  name: "importMode",
367
370
  path: 'importMode',
368
371
  options: importModes,
369
- onChange: onSelectDidChange
372
+ onChange: onSelectDidChange,
373
+ value: importMode
370
374
  }),
371
375
  typeof parser === 'function' && /*#__PURE__*/ _jsx(CheckboxInput, {
372
376
  label: t('importExport:enableDataParsing'),
373
- id: "importMode",
377
+ id: "dataParsing",
374
378
  name: "dataParsing",
379
+ checked: dataParsing,
375
380
  onToggle: onCheckboxkDidChange
376
381
  })
377
382
  ]
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ImportExport/ImportModal.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { MinimalTemplate } from '@payloadcms/next/templates';\r\nimport { Button, CheckboxInput, Form, SelectInput, XIcon, toast, useAuth, useConfig, useLocale, useModal, useTranslation } from '@payloadcms/ui';\r\nimport { IEntity, IEquatable } from '@websolutespa/bom-core';\r\nimport { getRouteResolver } from '@websolutespa/payload-utils';\r\nimport * as Papa from 'papaparse';\r\nimport type { ClientField } from 'payload';\r\nimport React, { useCallback, useEffect, useState } from 'react';\r\nimport { useDropzone } from 'react-dropzone';\r\nimport { ImportLogInvalidTypes, ImportLogType, ImportMode } from '../../core/api/types';\r\nimport './ImportModal.scss';\r\nimport { IImportItem } from './types';\r\n\r\ntype Option<TValue = unknown> = {\r\n [key: string]: unknown;\r\n id?: string;\r\n value: TValue;\r\n};\r\n\r\ntype IRow = Record<string, string>;\r\n\r\ntype ImportModalProps<T = any> = {\r\n parser?: (items: IImportItem[]) => T[];\r\n slug: string;\r\n};\r\n\r\ntype ILog = {\r\n count: number;\r\n id: IEquatable;\r\n invalid?: string;\r\n key: string;\r\n message: string;\r\n type: ImportLogType;\r\n};\r\n\r\nconst INITIAL_DATA = {\r\n importMode: ImportMode.Append,\r\n dataParsing: false,\r\n};\r\n\r\nconst baseClass = 'import-modal';\r\n\r\nexport const ImportModal: React.FC<ImportModalProps> = ({\r\n parser,\r\n slug,\r\n}) => {\r\n const { closeAllModals } = useModal();\r\n const { config, getEntityConfig } = useConfig();\r\n const collectionConfig = getEntityConfig({ collectionSlug: slug });\r\n\r\n const routeResolver = getRouteResolver(config);\r\n const collectionUrl = routeResolver.api(`/${collectionConfig.slug}?pagination=false&depth=0`);\r\n\r\n // !!! check translations\r\n const { t } = useTranslation<any, any>();\r\n\r\n const format = (text: string, ...rest: unknown[]) => {\r\n return text.replace(/\\{(\\d)\\}/g, (m, g) => {\r\n const i = parseInt(g);\r\n return (i >= 0 && i < rest.length) ? String(rest[i]) : '';\r\n });\r\n };\r\n\r\n const { code: locale } = useLocale();\r\n\r\n const user = useAuth();\r\n\r\n const [dirty, setDirty] = useState<boolean>(false);\r\n const [valid, setValid] = useState<boolean>(false);\r\n const [error, setError] = useState<Error>();\r\n const [name, setName] = useState<string | null>(null);\r\n const [csv, setCSV] = useState<string | null>(null);\r\n const [keys, setKeys] = useState<string[] | null>(null);\r\n const [data, setData] = useState<IRow[] | null>(null);\r\n const [items, setItems] = useState<IImportItem[]>([]);\r\n const [logs, setLogs] = useState<ILog[]>([]);\r\n const [importMode, setImportMode] = useState<ImportMode>(INITIAL_DATA.importMode);\r\n const [dataParsing, setDataParsing] = useState<boolean>(INITIAL_DATA.dataParsing);\r\n\r\n const importModes = Object.entries(ImportMode).map(([k, v]) => ({\r\n value: v,\r\n label: t(`importExport:mode${k}`),\r\n }));\r\n\r\n const onSelectDidChange = (option: Option | Option[]) => {\r\n // console.log('onSelectDidChange', option);\r\n if (Array.isArray(option)) {\r\n return;\r\n }\r\n if (importMode !== option.value) {\r\n setValid(false);\r\n setImportMode(option.value as ImportMode);\r\n }\r\n };\r\n\r\n const onCheckboxkDidChange = (event: React.ChangeEvent<HTMLInputElement>) => {\r\n // console.log('onCheckboxkDidChange', value);\r\n setValid(false);\r\n setDataParsing(!dataParsing);\r\n };\r\n\r\n const validate = useCallback(async (keys: string[], data: IRow[]) => {\r\n try {\r\n const messageByType = (key: string, type: ImportLogType) => {\r\n let message: string;\r\n switch (type) {\r\n case ImportLogType.Required:\r\n message = format(t('importExport:errorRequired'), key);\r\n break;\r\n case ImportLogType.Optional:\r\n message = format(t('importExport:errorOptional'), key);\r\n break;\r\n case ImportLogType.Invalid:\r\n message = format(t('importExport:errorInvalid'), key);\r\n break;\r\n case ImportLogType.Duplicate:\r\n message = format(t('importExport:errorDuplicate'), key);\r\n break;\r\n case ImportLogType.Unexpected:\r\n message = format(t('importExport:errorUnexpected'), key);\r\n break;\r\n }\r\n return message;\r\n };\r\n\r\n const addLog = (logs: ILog[], key: string, type: ImportLogType, invalid?: string): ILog => {\r\n const message = messageByType(key, type);\r\n const id = invalid ? `${key}-${type}-${invalid}` : `${key}-${type}`;\r\n const log = once<ILog>(logs, { id, key, type, message, invalid, count: 0 });\r\n log.count++;\r\n return log;\r\n };\r\n\r\n const itemOptionalKeys: string[] = [];\r\n const itemKeys = keys;\r\n\r\n // collecting model fields & keys\r\n const fields = collectionConfig.fields\r\n .filter(x => 'name' in x && x['name'] !== undefined && x.type !== 'ui') as (ClientField & { name: string })[];\r\n const fieldKeys = fields.map(x => x['name']);\r\n const requiredFields = fields.filter(x => {\r\n if (x['name'] === 'id' && importMode === ImportMode.Update) {\r\n return true;\r\n } else {\r\n return 'required' in x && x['required'] === true;\r\n }\r\n });\r\n const uniqueFields = fields.filter(x => x['unique'] === true);\r\n const requiredFieldKeys = requiredFields.map(x => x['name']);\r\n const optionalFieldKeys = fieldKeys.filter(x => !requiredFieldKeys.includes(x));\r\n const uniqueFieldKeys = uniqueFields.map(x => x['name']);\r\n\r\n let items: IImportItem[] = [];\r\n\r\n // parse values\r\n const valueParsers = itemKeys.map(key => {\r\n let parseValue = (item: IRow): string | number | boolean | Date | undefined => item[key];\r\n if (fieldKeys.includes(key)) {\r\n const field = collectionConfig.fields.find(x => 'name' in x && x['name'] === key);\r\n if (field) {\r\n switch (field.type) {\r\n case 'checkbox':\r\n parseValue = (item: IRow) => item[key] !== undefined ? Boolean(item[key]) : item[key];\r\n break;\r\n case 'date':\r\n parseValue = (item: IRow) => item[key] !== undefined ? new Date(item[key]) : item[key];\r\n break;\r\n case 'number':\r\n parseValue = (item: IRow) => item[key] !== undefined ? Number(item[key]) : item[key];\r\n break;\r\n }\r\n }\r\n }\r\n return parseValue;\r\n });\r\n\r\n for (const row of data) {\r\n const item = {};\r\n itemKeys.forEach((key, i) => {\r\n const parser = valueParsers[i];\r\n if (parser) {\r\n (item as any)[key] = parser(row);\r\n }\r\n });\r\n items.push(item);\r\n }\r\n\r\n if (dataParsing && typeof parser === 'function') {\r\n items = parser(items);\r\n }\r\n\r\n // console.log('data', data);\r\n // console.log('items', items);\r\n\r\n // collecting stored values\r\n const httpResponse = await fetch(collectionUrl, {\r\n method: 'GET',\r\n credentials: 'include',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n });\r\n if (!httpResponse.ok) {\r\n throw httpResponse;\r\n }\r\n const storedItems = await httpResponse.json();\r\n // console.log('rows', rows, 'data', result.data);\r\n\r\n // collecting logs\r\n const logs: ILog[] = [];\r\n // required fields\r\n requiredFieldKeys.forEach(key => {\r\n if (!itemKeys.includes(key) || itemOptionalKeys.includes(key)) {\r\n addLog(logs, key, ImportLogType.Required);\r\n }\r\n });\r\n // optional fields\r\n optionalFieldKeys.forEach(key => {\r\n if (!itemKeys.includes(key)) {\r\n addLog(logs, key, ImportLogType.Optional);\r\n }\r\n });\r\n // deep check values\r\n for (const key of itemKeys) {\r\n if (fieldKeys.includes(key)) {\r\n const field = collectionConfig.fields.find(x => 'name' in x && x['name'] === key);\r\n if (field) {\r\n const validate = 'validate' in field ? field['validate'] : undefined;\r\n const values: (string | number | boolean | Date | undefined)[] = [];\r\n const storedValues = uniqueFieldKeys.includes(key) ? storedItems.map((x: any) => x[key]) : [];\r\n for (const item of items) {\r\n const value = item[key];\r\n // validate field\r\n if (typeof validate === 'function') {\r\n const validation = await validate(value, {\r\n data: item,\r\n siblingData: item,\r\n operation: 'create',\r\n user,\r\n t,\r\n });\r\n if (validation !== true) {\r\n // console.log(key, value, validation, item);\r\n if (logs.find(x =>\r\n x.key === 'key' &&\r\n x.type === ImportLogType.Invalid\r\n ) === undefined) {\r\n addLog(logs, key, ImportLogType.Invalid, validation as string);\r\n }\r\n }\r\n }\r\n // unique field\r\n if (uniqueFieldKeys.includes(key) && (\r\n values.includes(value) ||\r\n (importMode === ImportMode.Append ? storedValues.includes(value) : false)\r\n )) {\r\n addLog(logs, key, ImportLogType.Duplicate, String(value));\r\n }\r\n values.push(value);\r\n }\r\n }\r\n } else {\r\n addLog(logs, key, ImportLogType.Unexpected);\r\n }\r\n }\r\n\r\n const sortOrder = Object.values(ImportLogType);\r\n logs.sort((a, b) => {\r\n return sortOrder.indexOf(a.type) - sortOrder.indexOf(b.type);\r\n });\r\n\r\n setItems(items);\r\n setLogs(logs);\r\n\r\n const errors = logs.filter(x => ImportLogInvalidTypes.includes(x.type));\r\n if (errors.length === 0) {\r\n setValid(true);\r\n }\r\n\r\n // console.log(logs, items, itemKeys, itemOptionalKeys, fieldKeys, requiredFieldKeys, optionalFieldKeys);\r\n\r\n } catch (error) {\r\n console.log('parse error', error);\r\n setError(error as Error);\r\n }\r\n }, [collectionUrl, importMode, dataParsing, parser, collectionConfig.fields, t, user]);\r\n\r\n useEffect(() => {\r\n if (keys && data) {\r\n validate(keys, data);\r\n }\r\n }, [keys, data, importMode, validate]);\r\n\r\n const onDrop = useCallback((acceptedFiles: File[]) => {\r\n const acceptedFile = acceptedFiles.find(() => true);\r\n if (acceptedFile) {\r\n const reader = new FileReader();\r\n reader.onabort = () => console.log('file reading was aborted');\r\n reader.onerror = () => console.log('file reading has failed');\r\n reader.onload = () => {\r\n // Do whatever you want with the file contents\r\n const csv = reader.result as string;\r\n // console.log('csv', csv);\r\n // parsing csv to { data:[][] }\r\n const result = Papa.parse(csv);\r\n const resultData: string[][] = result.data as string[][];\r\n // collecting imported keys & data\r\n let keys: string[] = [];\r\n const data: IRow[] = resultData.reduce((p, c, i) => {\r\n if (i === 0) {\r\n keys = c;\r\n } else {\r\n const item: Record<string, string> = {};\r\n keys.forEach((key, k) => {\r\n if (c[k] !== undefined) {\r\n item[key] = c[k];\r\n }\r\n });\r\n p.push(item);\r\n }\r\n return p;\r\n }, [] as IRow[]);\r\n setName(acceptedFile.name);\r\n setCSV(csv);\r\n setKeys(keys);\r\n setData(data);\r\n setDirty(true);\r\n };\r\n // reader.readAsArrayBuffer(file);\r\n reader.readAsText(acceptedFile);\r\n }\r\n }, []);\r\n\r\n const { getRootProps, getInputProps, isDragActive } = useDropzone({\r\n accept: {\r\n 'text/csv': [],\r\n },\r\n maxSize: 1048576 * 20,\r\n maxFiles: 1,\r\n onDrop,\r\n });\r\n\r\n const onSubmit = async () => {\r\n // console.log('ImportModal.onSubmit');\r\n try {\r\n const url = routeResolver.api(`/${collectionConfig.slug}/import?locale=${locale}&mode=${importMode}`);\r\n\r\n const httpResponse = await fetch(url, {\r\n method: 'POST',\r\n body: JSON.stringify({ items }),\r\n credentials: 'include',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n });\r\n\r\n if (!httpResponse.ok) {\r\n throw httpResponse;\r\n }\r\n\r\n const response = await httpResponse.json();\r\n // console.log('ImportModal.onSubmit', response);\r\n toast.success(t('importExport:success'));\r\n closeAllModals();\r\n\r\n } catch (error) {\r\n console.log('ImportModal.onSubmit.error', error);\r\n toast.error(format(t('importExport:failure'), collectionConfig.slug));\r\n }\r\n };\r\n\r\n const onClose = () => {\r\n // console.log('onClose');\r\n closeAllModals();\r\n };\r\n\r\n const onClear = () => {\r\n // console.log('onClear');\r\n setValid(false);\r\n setDirty(false);\r\n setName(null);\r\n setCSV(null);\r\n setKeys(null);\r\n setData(null);\r\n setItems([]);\r\n setLogs([]);\r\n };\r\n\r\n return (\r\n <MinimalTemplate>\r\n <header className={`${baseClass}__header`}>\r\n <h3>{t('importExport:modalTitle')}</h3>\r\n <Button buttonStyle=\"none\" onClick={onClose}><XIcon /></Button>\r\n </header>\r\n <main className={`${baseClass}__main`}>\r\n <Form onSubmit={onSubmit}>\r\n <div className=\"render-fields\">\r\n <SelectInput\r\n // isClearable={viewType === 'list'}\r\n label={t('importExport:importMode')}\r\n name=\"importMode\"\r\n path={'importMode'}\r\n options={importModes}\r\n onChange={onSelectDidChange}\r\n />\r\n {typeof parser === 'function' && (\r\n <CheckboxInput\r\n label={t('importExport:enableDataParsing')}\r\n id=\"importMode\"\r\n name=\"dataParsing\"\r\n onToggle={onCheckboxkDidChange}\r\n />\r\n )}\r\n </div>\r\n {data ? (\r\n <>\r\n <div dangerouslySetInnerHTML={{ __html: format(t('importExport:records'), items.length, name) }} ></div>\r\n {logs.length > 0 && (\r\n <ul className={`${baseClass}__logs`}>\r\n {logs.map((log, i) => (\r\n <li key={`log-${i}`} className={`${baseClass}__log ${baseClass}__log--${log.type}`}>\r\n {log.count} {log.message} <i>{log.invalid}</i>\r\n </li>\r\n ))}\r\n </ul>\r\n )}\r\n </>\r\n ) : (\r\n <div className={`${baseClass}__dropzone`} {...getRootProps()}>\r\n <input className={`${baseClass}__input`} {...getInputProps()} />\r\n {isDragActive ? (\r\n <div>{t('importExport:dropTitle')}</div>\r\n ) : (\r\n <div>{t('importExport:dropAbstract')}</div>\r\n )}\r\n </div>\r\n )}\r\n {error && (\r\n <>\r\n <div>{t('importExport:parseError')}</div>\r\n {error.message && <div>{error.message}</div>}\r\n </>\r\n )}\r\n <div className={`${baseClass}__foot`}>\r\n {dirty && <Button type=\"button\" buttonStyle=\"secondary\" onClick={onClear}>\r\n {t('importExport:clear')}\r\n </Button>}\r\n <Button type=\"submit\" disabled={!valid}>\r\n {t('importExport:submit')}\r\n </Button>\r\n </div>\r\n </Form>\r\n </main>\r\n </MinimalTemplate>\r\n );\r\n};\r\n\r\nfunction once<T extends IEntity = IEntity>(items: T[], item: T): T {\r\n const exhistingItem = items.find(x => x.id === item.id);\r\n if (exhistingItem) {\r\n return exhistingItem;\r\n }\r\n items.push(item);\r\n return item;\r\n}\r\n"],"names":["MinimalTemplate","Button","CheckboxInput","Form","SelectInput","XIcon","toast","useAuth","useConfig","useLocale","useModal","useTranslation","getRouteResolver","Papa","React","useCallback","useEffect","useState","useDropzone","ImportLogInvalidTypes","ImportLogType","ImportMode","INITIAL_DATA","importMode","Append","dataParsing","baseClass","ImportModal","parser","slug","closeAllModals","config","getEntityConfig","collectionConfig","collectionSlug","routeResolver","collectionUrl","api","t","format","text","rest","replace","m","g","i","parseInt","length","String","code","locale","user","dirty","setDirty","valid","setValid","error","setError","name","setName","csv","setCSV","keys","setKeys","data","setData","items","setItems","logs","setLogs","setImportMode","setDataParsing","importModes","Object","entries","map","k","v","value","label","onSelectDidChange","option","Array","isArray","onCheckboxkDidChange","event","validate","messageByType","key","type","message","Required","Optional","Invalid","Duplicate","Unexpected","addLog","invalid","id","log","once","count","itemOptionalKeys","itemKeys","fields","filter","x","undefined","fieldKeys","requiredFields","Update","uniqueFields","requiredFieldKeys","optionalFieldKeys","includes","uniqueFieldKeys","valueParsers","parseValue","item","field","find","Boolean","Date","Number","row","forEach","push","httpResponse","fetch","method","credentials","headers","ok","storedItems","json","values","storedValues","validation","siblingData","operation","sortOrder","sort","a","b","indexOf","errors","console","onDrop","acceptedFiles","acceptedFile","reader","FileReader","onabort","onerror","onload","result","parse","resultData","reduce","p","c","readAsText","getRootProps","getInputProps","isDragActive","accept","maxSize","maxFiles","onSubmit","url","body","JSON","stringify","response","success","onClose","onClear","header","className","h3","buttonStyle","onClick","main","div","path","options","onChange","onToggle","dangerouslySetInnerHTML","__html","ul","li","input","disabled","exhistingItem"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/ImportExport/ImportModal.tsx"],"sourcesContent":["'use client';\n\nimport { MinimalTemplate } from '@payloadcms/next/templates';\nimport { Button, CheckboxInput, SelectInput, XIcon, toast, useAuth, useConfig, useLocale, useModal, useTranslation } from '@payloadcms/ui';\nimport { IEntity, IEquatable } from '@websolutespa/bom-core';\nimport { getRouteResolver } from '@websolutespa/payload-utils';\nimport * as Papa from 'papaparse';\nimport type { ClientField } from 'payload';\nimport React, { useCallback, useEffect, useState } from 'react';\nimport { useDropzone } from 'react-dropzone';\nimport { ImportLogInvalidTypes, ImportLogType, ImportMode } from '../../core/api/types';\nimport './ImportModal.scss';\nimport { IImportItem } from './types';\n\ntype Option<TValue = unknown> = {\n [key: string]: unknown;\n id?: string;\n value: TValue;\n};\n\ntype IRow = Record<string, string>;\n\ntype ImportModalProps<T = any> = {\n parser?: (items: IImportItem[]) => T[];\n slug: string;\n};\n\ntype ILog = {\n count: number;\n id: IEquatable;\n invalid?: string;\n key: string;\n message: string;\n type: ImportLogType;\n};\n\nconst INITIAL_DATA = {\n importMode: ImportMode.Append,\n dataParsing: false,\n};\n\nconst baseClass = 'import-modal';\n\nexport const ImportModal: React.FC<ImportModalProps> = ({\n parser,\n slug,\n}) => {\n const { closeAllModals } = useModal();\n const { config, getEntityConfig } = useConfig();\n const collectionConfig = getEntityConfig({ collectionSlug: slug });\n\n const routeResolver = getRouteResolver(config);\n const collectionUrl = routeResolver.api(`/${collectionConfig.slug}?pagination=false&depth=0`);\n\n // !!! check translations\n const { t } = useTranslation<any, any>();\n\n const format = (text: string, ...rest: unknown[]) => {\n return text.replace(/\\{(\\d)\\}/g, (m, g) => {\n const i = parseInt(g);\n return (i >= 0 && i < rest.length) ? String(rest[i]) : '';\n });\n };\n\n const { code: locale } = useLocale();\n\n const user = useAuth();\n\n const [dirty, setDirty] = useState<boolean>(false);\n const [valid, setValid] = useState<boolean>(false);\n const [error, setError] = useState<Error>();\n const [name, setName] = useState<string | null>(null);\n const [csv, setCSV] = useState<string | null>(null);\n const [keys, setKeys] = useState<string[] | null>(null);\n const [data, setData] = useState<IRow[] | null>(null);\n const [items, setItems] = useState<IImportItem[]>([]);\n const [logs, setLogs] = useState<ILog[]>([]);\n const [importMode, setImportMode] = useState<ImportMode>(INITIAL_DATA.importMode);\n const [dataParsing, setDataParsing] = useState<boolean>(INITIAL_DATA.dataParsing);\n\n const importModes = Object.entries(ImportMode).map(([k, v]) => ({\n value: v,\n label: t(`importExport:mode${k}`),\n }));\n\n const onSelectDidChange = (option: Option | Option[]) => {\n // console.log('onSelectDidChange', option);\n if (Array.isArray(option)) {\n return;\n }\n if (importMode !== option.value) {\n setValid(false);\n setImportMode(option.value as ImportMode);\n }\n };\n\n const onCheckboxkDidChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n // console.log('onCheckboxkDidChange', value);\n setValid(false);\n setDataParsing(!dataParsing);\n };\n\n const validate = useCallback(async (keys: string[], data: IRow[]) => {\n try {\n const messageByType = (key: string, type: ImportLogType) => {\n let message: string;\n switch (type) {\n case ImportLogType.Required:\n message = format(t('importExport:errorRequired'), key);\n break;\n case ImportLogType.Optional:\n message = format(t('importExport:errorOptional'), key);\n break;\n case ImportLogType.Invalid:\n message = format(t('importExport:errorInvalid'), key);\n break;\n case ImportLogType.Duplicate:\n message = format(t('importExport:errorDuplicate'), key);\n break;\n case ImportLogType.Unexpected:\n message = format(t('importExport:errorUnexpected'), key);\n break;\n }\n return message;\n };\n\n const addLog = (logs: ILog[], key: string, type: ImportLogType, invalid?: string): ILog => {\n const message = messageByType(key, type);\n const id = invalid ? `${key}-${type}-${invalid}` : `${key}-${type}`;\n const log = once<ILog>(logs, { id, key, type, message, invalid, count: 0 });\n log.count++;\n return log;\n };\n\n const itemOptionalKeys: string[] = [];\n const itemKeys = keys;\n\n // collecting model fields & keys\n const fields = collectionConfig.fields\n .filter(x => 'name' in x && x['name'] !== undefined && x.type !== 'ui') as (ClientField & { name: string })[];\n const fieldKeys = fields.map(x => x['name']);\n const requiredFields = fields.filter(x => {\n if (x['name'] === 'id' && importMode === ImportMode.Update) {\n return true;\n } else {\n return 'required' in x && x['required'] === true;\n }\n });\n const uniqueFields = fields.filter(x => x['unique'] === true);\n const requiredFieldKeys = requiredFields.map(x => x['name']);\n const optionalFieldKeys = fieldKeys.filter(x => !requiredFieldKeys.includes(x));\n const uniqueFieldKeys = uniqueFields.map(x => x['name']);\n\n let items: IImportItem[] = [];\n\n // parse values\n const valueParsers = itemKeys.map(key => {\n let parseValue = (item: IRow): string | number | boolean | Date | undefined => item[key];\n if (fieldKeys.includes(key)) {\n const field = collectionConfig.fields.find(x => 'name' in x && x['name'] === key);\n if (field) {\n switch (field.type) {\n case 'checkbox':\n parseValue = (item: IRow) => item[key] !== undefined ? Boolean(item[key]) : item[key];\n break;\n case 'date':\n parseValue = (item: IRow) => item[key] !== undefined ? new Date(item[key]) : item[key];\n break;\n case 'number':\n parseValue = (item: IRow) => item[key] !== undefined ? Number(item[key]) : item[key];\n break;\n }\n }\n }\n return parseValue;\n });\n\n for (const row of data) {\n const item = {};\n itemKeys.forEach((key, i) => {\n const parser = valueParsers[i];\n if (parser) {\n (item as any)[key] = parser(row);\n }\n });\n items.push(item);\n }\n\n if (dataParsing && typeof parser === 'function') {\n items = parser(items);\n }\n\n // console.log('data', data);\n // console.log('items', items);\n\n // collecting stored values\n const httpResponse = await fetch(collectionUrl, {\n method: 'GET',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n if (!httpResponse.ok) {\n throw httpResponse;\n }\n const storedItems = await httpResponse.json();\n // console.log('rows', rows, 'data', result.data);\n\n // collecting logs\n const logs: ILog[] = [];\n // required fields\n requiredFieldKeys.forEach(key => {\n if (!itemKeys.includes(key) || itemOptionalKeys.includes(key)) {\n addLog(logs, key, ImportLogType.Required);\n }\n });\n // optional fields\n optionalFieldKeys.forEach(key => {\n if (!itemKeys.includes(key)) {\n addLog(logs, key, ImportLogType.Optional);\n }\n });\n // deep check values\n for (const key of itemKeys) {\n if (fieldKeys.includes(key)) {\n const field = collectionConfig.fields.find(x => 'name' in x && x['name'] === key);\n if (field) {\n const validate = 'validate' in field ? field['validate'] : undefined;\n const values: (string | number | boolean | Date | undefined)[] = [];\n const storedValues = uniqueFieldKeys.includes(key) ? storedItems.map((x: any) => x[key]) : [];\n for (const item of items) {\n const value = item[key];\n // validate field\n if (typeof validate === 'function') {\n const validation = await validate(value, {\n data: item,\n siblingData: item,\n operation: 'create',\n user,\n t,\n });\n if (validation !== true) {\n // console.log(key, value, validation, item);\n if (logs.find(x =>\n x.key === 'key' &&\n x.type === ImportLogType.Invalid\n ) === undefined) {\n addLog(logs, key, ImportLogType.Invalid, validation as string);\n }\n }\n }\n // unique field\n if (uniqueFieldKeys.includes(key) && (\n values.includes(value) ||\n (importMode === ImportMode.Append ? storedValues.includes(value) : false)\n )) {\n addLog(logs, key, ImportLogType.Duplicate, String(value));\n }\n values.push(value);\n }\n }\n } else {\n addLog(logs, key, ImportLogType.Unexpected);\n }\n }\n\n const sortOrder = Object.values(ImportLogType);\n logs.sort((a, b) => {\n return sortOrder.indexOf(a.type) - sortOrder.indexOf(b.type);\n });\n\n setItems(items);\n setLogs(logs);\n\n const errors = logs.filter(x => ImportLogInvalidTypes.includes(x.type));\n if (errors.length === 0) {\n setValid(true);\n }\n\n // console.log(logs, items, itemKeys, itemOptionalKeys, fieldKeys, requiredFieldKeys, optionalFieldKeys);\n\n } catch (error) {\n console.log('parse error', error);\n setError(error as Error);\n }\n }, [collectionUrl, importMode, dataParsing, parser, collectionConfig.fields, t, user]);\n\n useEffect(() => {\n if (keys && data) {\n validate(keys, data);\n }\n }, [keys, data, importMode, validate]);\n\n const onDrop = useCallback((acceptedFiles: File[]) => {\n const acceptedFile = acceptedFiles.find(() => true);\n if (acceptedFile) {\n const reader = new FileReader();\n reader.onabort = () => console.log('file reading was aborted');\n reader.onerror = () => console.log('file reading has failed');\n reader.onload = () => {\n // Do whatever you want with the file contents\n const csv = reader.result as string;\n // console.log('csv', csv);\n // parsing csv to { data:[][] }\n const result = Papa.parse(csv);\n const resultData: string[][] = result.data as string[][];\n // collecting imported keys & data\n let keys: string[] = [];\n const data: IRow[] = resultData.reduce((p, c, i) => {\n if (i === 0) {\n keys = c;\n } else {\n const item: Record<string, string> = {};\n keys.forEach((key, k) => {\n if (c[k] !== undefined) {\n item[key] = c[k];\n }\n });\n p.push(item);\n }\n return p;\n }, [] as IRow[]);\n setName(acceptedFile.name);\n setCSV(csv);\n setKeys(keys);\n setData(data);\n setDirty(true);\n };\n // reader.readAsArrayBuffer(file);\n reader.readAsText(acceptedFile);\n }\n }, []);\n\n const { getRootProps, getInputProps, isDragActive } = useDropzone({\n accept: {\n 'text/csv': [],\n },\n maxSize: 1048576 * 20,\n maxFiles: 1,\n onDrop,\n });\n\n const onSubmit = async () => {\n // console.log('ImportModal.onSubmit');\n try {\n const url = routeResolver.api(`/${collectionConfig.slug}/import?locale=${locale}&mode=${importMode}`);\n\n const httpResponse = await fetch(url, {\n method: 'POST',\n body: JSON.stringify({ items }),\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n if (!httpResponse.ok) {\n throw httpResponse;\n }\n\n const response = await httpResponse.json();\n // console.log('ImportModal.onSubmit', response);\n toast.success(t('importExport:success'));\n closeAllModals();\n\n } catch (error) {\n console.log('ImportModal.onSubmit.error', error);\n toast.error(format(t('importExport:failure'), collectionConfig.slug));\n }\n };\n\n const onClose = () => {\n // console.log('onClose');\n closeAllModals();\n };\n\n const onClear = () => {\n // console.log('onClear');\n setValid(false);\n setDirty(false);\n setName(null);\n setCSV(null);\n setKeys(null);\n setData(null);\n setItems([]);\n setLogs([]);\n };\n\n return (\n <MinimalTemplate>\n <header className={`${baseClass}__header`}>\n <h3>{t('importExport:modalTitle')}</h3>\n <Button buttonStyle=\"none\" onClick={onClose}><XIcon /></Button>\n </header>\n <main className={`${baseClass}__main`}>\n <form onSubmit={(e) => { e.preventDefault(); onSubmit(); }}>\n <div className=\"render-fields\">\n <SelectInput\n // isClearable={viewType === 'list'}\n label={t('importExport:importMode')}\n name=\"importMode\"\n path={'importMode'}\n options={importModes}\n onChange={onSelectDidChange}\n value={importMode}\n />\n {typeof parser === 'function' && (\n <CheckboxInput\n label={t('importExport:enableDataParsing')}\n id=\"dataParsing\"\n name=\"dataParsing\"\n checked={dataParsing}\n onToggle={onCheckboxkDidChange}\n />\n )}\n </div>\n {data ? (\n <>\n <div dangerouslySetInnerHTML={{ __html: format(t('importExport:records'), items.length, name) }} ></div>\n {logs.length > 0 && (\n <ul className={`${baseClass}__logs`}>\n {logs.map((log, i) => (\n <li key={`log-${i}`} className={`${baseClass}__log ${baseClass}__log--${log.type}`}>\n {log.count} {log.message} <i>{log.invalid}</i>\n </li>\n ))}\n </ul>\n )}\n </>\n ) : (\n <div className={`${baseClass}__dropzone`} {...getRootProps()}>\n <input className={`${baseClass}__input`} {...getInputProps()} />\n {isDragActive ? (\n <div>{t('importExport:dropTitle')}</div>\n ) : (\n <div>{t('importExport:dropAbstract')}</div>\n )}\n </div>\n )}\n {error && (\n <>\n <div>{t('importExport:parseError')}</div>\n {error.message && <div>{error.message}</div>}\n </>\n )}\n <div className={`${baseClass}__foot`}>\n {dirty && <Button type=\"button\" buttonStyle=\"secondary\" onClick={onClear}>\n {t('importExport:clear')}\n </Button>}\n <Button type=\"submit\" disabled={!valid}>\n {t('importExport:submit')}\n </Button>\n </div>\n </form>\n </main>\n </MinimalTemplate>\n );\n};\n\nfunction once<T extends IEntity = IEntity>(items: T[], item: T): T {\n const exhistingItem = items.find(x => x.id === item.id);\n if (exhistingItem) {\n return exhistingItem;\n }\n items.push(item);\n return item;\n}\n"],"names":["MinimalTemplate","Button","CheckboxInput","SelectInput","XIcon","toast","useAuth","useConfig","useLocale","useModal","useTranslation","getRouteResolver","Papa","React","useCallback","useEffect","useState","useDropzone","ImportLogInvalidTypes","ImportLogType","ImportMode","INITIAL_DATA","importMode","Append","dataParsing","baseClass","ImportModal","parser","slug","closeAllModals","config","getEntityConfig","collectionConfig","collectionSlug","routeResolver","collectionUrl","api","t","format","text","rest","replace","m","g","i","parseInt","length","String","code","locale","user","dirty","setDirty","valid","setValid","error","setError","name","setName","csv","setCSV","keys","setKeys","data","setData","items","setItems","logs","setLogs","setImportMode","setDataParsing","importModes","Object","entries","map","k","v","value","label","onSelectDidChange","option","Array","isArray","onCheckboxkDidChange","event","validate","messageByType","key","type","message","Required","Optional","Invalid","Duplicate","Unexpected","addLog","invalid","id","log","once","count","itemOptionalKeys","itemKeys","fields","filter","x","undefined","fieldKeys","requiredFields","Update","uniqueFields","requiredFieldKeys","optionalFieldKeys","includes","uniqueFieldKeys","valueParsers","parseValue","item","field","find","Boolean","Date","Number","row","forEach","push","httpResponse","fetch","method","credentials","headers","ok","storedItems","json","values","storedValues","validation","siblingData","operation","sortOrder","sort","a","b","indexOf","errors","console","onDrop","acceptedFiles","acceptedFile","reader","FileReader","onabort","onerror","onload","result","parse","resultData","reduce","p","c","readAsText","getRootProps","getInputProps","isDragActive","accept","maxSize","maxFiles","onSubmit","url","body","JSON","stringify","response","success","onClose","onClear","header","className","h3","buttonStyle","onClick","main","form","e","preventDefault","div","path","options","onChange","checked","onToggle","dangerouslySetInnerHTML","__html","ul","li","input","disabled","exhistingItem"],"mappings":"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"}
@@ -5,8 +5,8 @@ import { findHandler } from '../utils/findHandler';
5
5
  import { getCollectionItems } from './collection.service';
6
6
  import { collectPageRedirects } from './redirect.service';
7
7
  import { isMixerRequest } from './utils';
8
- /**
9
- * Rest api page collection get handler.
8
+ /**
9
+ * Rest api page collection get handler.
10
10
  */ export const pageIndexGet = (slug)=>({
11
11
  path: '/',
12
12
  method: 'get',
@@ -38,8 +38,8 @@ import { isMixerRequest } from './utils';
38
38
  }
39
39
  }
40
40
  });
41
- /**
42
- * Rest api page collection detail get handler.
41
+ /**
42
+ * Rest api page collection detail get handler.
43
43
  */ export const pageDetailGet = (slug)=>({
44
44
  path: '/:id',
45
45
  method: 'get',
@@ -65,11 +65,11 @@ import { isMixerRequest } from './utils';
65
65
  }
66
66
  }
67
67
  });
68
- /**
69
- * eg. PAYLOAD_PAGE_FIND = 'components'
68
+ /**
69
+ * eg. PAYLOAD_PAGE_FIND = 'components'
70
70
  */ const afterPageOperationFind = process.env.PAYLOAD_FILTER_FIND ? process.env.PAYLOAD_FILTER_FIND.split(',').map((x)=>x.trim()) : [];
71
- /**
72
- * Modify record for Mixer when queried by market and locale.
71
+ /**
72
+ * Modify record for Mixer when queried by market and locale.
73
73
  */ export const afterPageOperationHook = (collectionConfig)=>async ({ args, collection, req, operation, result })=>{
74
74
  if (afterPageOperationFind.length > 0 && isMixerRequest(req) && operation === 'find' && req.pathname !== '/store' && req.query.optimize !== 'false') {
75
75
  // console.log('withPage.afterPageOperationHook', operation, collection.slug, req.pathname);
@@ -78,8 +78,8 @@ import { isMixerRequest } from './utils';
78
78
  }
79
79
  return result;
80
80
  };
81
- /**
82
- * Decorate record for Mixer when queried by market and locale.
81
+ /**
82
+ * Decorate record for Mixer when queried by market and locale.
83
83
  */ export const afterPageReadHook = (collectionConfig)=>async ({ doc, req, context, findMany })=>{
84
84
  const { market, locale, routes, categories } = context;
85
85
  // console.log('afterPageReadHook', doc.title, query, market, locale);
@@ -92,13 +92,47 @@ import { isMixerRequest } from './utils';
92
92
  const withHref = await decorateHref_(withCategory, collectionConfig.slug, context);
93
93
  const withNav = await decorateNav_(withHref, collectionConfig.slug, context);
94
94
  return withNav;
95
- /*
96
- const withRichText = await decorateRichText_(withNav, collectionConfig.fields, context as Required<MixerContext>, req.payload.config);
97
- return withRichText;
95
+ /*
96
+ const withRichText = await decorateRichText_(withNav, collectionConfig.fields, context as Required<MixerContext>, req.payload.config);
97
+ return withRichText;
98
98
  */ };
99
- /**
100
- * Create a record of the pages collection related to the created document.
101
- */ export const afterPageChangeHook = async ({ doc, req, previousDoc, operation })=>{
99
+ /**
100
+ * Trigger revalidation in the Next.js Mixer app for a given page document.
101
+ */ async function triggerPageRevalidation(schema, pageId) {
102
+ if (!schema || !pageId) return;
103
+ // todo: dedicated envVar for mixerUrl
104
+ const mixerUrl = process.env.PAYLOAD_PUBLIC_PREVIEW_URL;
105
+ const mixerSecret = process.env.MIXER_SECRET;
106
+ if (!mixerUrl || !mixerSecret) {
107
+ console.warn(`[revalidation] Skipping revalidation for ${schema}:${pageId}: MIXER_SECRET or PAYLOAD_PUBLIC_PREVIEW_URL is missing.`);
108
+ return;
109
+ }
110
+ try {
111
+ // console.log(`[revalidation] Triggering revalidation for ${schema}:${pageId}`);
112
+ const response = await fetch(`${mixerUrl}/api/__revalidate`, {
113
+ method: 'POST',
114
+ headers: {
115
+ 'Authorization': `Bearer ${mixerSecret}`,
116
+ 'Content-Type': 'application/json'
117
+ },
118
+ body: JSON.stringify({
119
+ schema,
120
+ page: String(pageId)
121
+ })
122
+ });
123
+ if (!response.ok) {
124
+ const text = await response.text().catch(()=>'');
125
+ console.warn(`[revalidation] Failed to revalidate ${schema}:${pageId}`, response.status, text);
126
+ } else {
127
+ // console.log(`[revalidation] Successfully revalidated ${schema}:${pageId}`);
128
+ }
129
+ } catch (error) {
130
+ console.error(`[revalidation] Error triggering revalidation for ${schema}:${pageId}`, error);
131
+ }
132
+ }
133
+ /**
134
+ * Create a record of the pages collection related to the created document.
135
+ */ export const afterPageChangeHook = async ({ doc, req, previousDoc, operation, collection })=>{
102
136
  if (operation === 'update') {
103
137
  const { query = {} } = req;
104
138
  const { draft } = query;
@@ -108,10 +142,13 @@ import { isMixerRequest } from './utils';
108
142
  // console.log('redirects', redirects);
109
143
  }
110
144
  }
145
+ if (doc._status === 'published') {
146
+ triggerPageRevalidation(collection?.slug, doc.id);
147
+ }
111
148
  return doc;
112
149
  };
113
- /**
114
- * Delete records of the pages collection related to the deleted document.
150
+ /**
151
+ * Delete records of the pages collection related to the deleted document.
115
152
  */ export const afterPageDeleteHook = async ({ req, id, doc })=>{
116
153
  const { query = {} } = req;
117
154
  const { draft } = query;
@@ -119,16 +156,16 @@ import { isMixerRequest } from './utils';
119
156
  console.log('RedirectService.deletePage !!!');
120
157
  // !!! todo find and redirect to parentCategory connected to a page
121
158
  }
122
- }; /*
123
- export const beforeValidateHook: CollectionBeforeValidateHook = async ({
124
- data, // incoming data to update or create with
125
- req, // full express request
126
- operation, // name of the operation ie. 'create', 'update'
127
- originalDoc, // original document
128
- }) => {
129
- console.log(data, originalDoc, req.query);
130
- return data; // Return data to either create or update a document with
131
- };
159
+ }; /*
160
+ export const beforeValidateHook: CollectionBeforeValidateHook = async ({
161
+ data, // incoming data to update or create with
162
+ req, // full express request
163
+ operation, // name of the operation ie. 'create', 'update'
164
+ originalDoc, // original document
165
+ }) => {
166
+ console.log(data, originalDoc, req.query);
167
+ return data; // Return data to either create or update a document with
168
+ };
132
169
  */
133
170
 
134
171
  //# sourceMappingURL=page.service.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/api/page.service.ts"],"sourcesContent":["import { ICategorized } from '@websolutespa/bom-core';\r\nimport { ResponseError, ResponseSuccess } from '@websolutespa/payload-utils/server';\r\nimport { CollectionAfterChangeHook, CollectionAfterDeleteHook, CollectionAfterOperationHook, CollectionAfterReadHook, CollectionConfig, Endpoint, PayloadRequest } from 'payload';\r\nimport { decorateCategory_, decorateComponents_, decorateHref_, decorateNav_, decorateSchema_ } from '../decorators';\r\nimport { findByIDHandler } from '../utils/findByIDHandler';\r\nimport { findHandler } from '../utils/findHandler';\r\nimport { getCollectionItems } from './collection.service';\r\nimport { collectPageRedirects } from './redirect.service';\r\nimport { MixerContext } from './types';\r\nimport { isMixerRequest } from './utils';\r\n\r\n/**\r\n * Rest api page collection get handler.\r\n */\r\nexport const pageIndexGet: ((slug: string) => Endpoint) = (slug: string) => ({\r\n path: '/',\r\n method: 'get',\r\n handler: async (req: PayloadRequest) => {\r\n try {\r\n const { query } = req;\r\n // console.log('pageIndexGet.query', ...Object.entries(query || {}));\r\n if (!query) {\r\n return findHandler(req);\r\n }\r\n const { locale, market, pagination } = query;\r\n if (typeof market === 'string' && typeof locale === 'string') {\r\n // const context = await setMixerContext(req, market, locale);\r\n // console.log('pageIndexGet.context', context.market, context.locale, context.routes.length, context.categories.length);\r\n if (pagination === 'true') {\r\n return findHandler(req);\r\n } else {\r\n const items = await getCollectionItems(req, slug);\r\n return ResponseSuccess(items);\r\n }\r\n } else if (pagination === 'false') {\r\n const items = await getCollectionItems(req, slug);\r\n return ResponseSuccess(items);\r\n }\r\n return findHandler(req);\r\n } catch (error: any) {\r\n console.error(`PageService.pageIndexGet.${slug}.error`, error);\r\n return ResponseError(error);\r\n }\r\n },\r\n});\r\n\r\n/**\r\n * Rest api page collection detail get handler.\r\n */\r\nexport const pageDetailGet: ((slug: string) => Endpoint) = (slug: string) => ({\r\n path: '/:id',\r\n method: 'get',\r\n handler: async (req: PayloadRequest) => {\r\n try {\r\n const { query } = req;\r\n // console.log('pageDetailGet.query', ...Object.entries(query || {}));\r\n if (!query) {\r\n return findByIDHandler(req);\r\n }\r\n const { market, locale } = query;\r\n // console.log('pageDetailGet', 'market', market, 'locale', locale);\r\n if (!(typeof market === 'string' && typeof locale === 'string')) {\r\n return findByIDHandler(req);\r\n }\r\n req.query.depth = req.query.depth || '3';\r\n // const context = await setMixerContext(req, market, locale);\r\n // console.log('pageDetailGet.context', context.market, context.locale, context.routes.length, context.categories.length);\r\n return findByIDHandler(req);\r\n } catch (error: any) {\r\n console.error(`PageService.pageDetailGet.${slug}.error`, error);\r\n return ResponseError(error);\r\n }\r\n },\r\n});\r\n\r\n/**\r\n * eg. PAYLOAD_PAGE_FIND = 'components'\r\n */\r\nconst afterPageOperationFind: string[] = (\r\n process.env.PAYLOAD_FILTER_FIND ?\r\n process.env.PAYLOAD_FILTER_FIND.split(',').map(x => x.trim()) :\r\n []\r\n);\r\n\r\n/**\r\n * Modify record for Mixer when queried by market and locale.\r\n */\r\nexport const afterPageOperationHook: (collectionConfig: CollectionConfig) => CollectionAfterOperationHook = (collectionConfig: CollectionConfig) => async ({\r\n args,\r\n collection,\r\n req,\r\n operation,\r\n result,\r\n}) => {\r\n if (\r\n afterPageOperationFind.length > 0 &&\r\n isMixerRequest(req) &&\r\n operation === 'find' &&\r\n req.pathname !== '/store' &&\r\n req.query.optimize !== 'false'\r\n ) {\r\n // console.log('withPage.afterPageOperationHook', operation, collection.slug, req.pathname);\r\n result.docs = result.docs.map(x => Object.fromEntries(\r\n Object.entries(x).filter(\r\n ([k, v]) => !afterPageOperationFind.includes(k)\r\n )\r\n )) as typeof result.docs;\r\n // console.log('withPage.afterPageOperationHook.done');\r\n }\r\n return result;\r\n};\r\n\r\n/**\r\n * Decorate record for Mixer when queried by market and locale.\r\n */\r\nexport const afterPageReadHook: (collectionConfig: CollectionConfig) => CollectionAfterReadHook = (collectionConfig: CollectionConfig) => async ({\r\n doc,\r\n req,\r\n context,\r\n findMany,\r\n}) => {\r\n const { market, locale, routes, categories } = context as MixerContext;\r\n // console.log('afterPageReadHook', doc.title, query, market, locale);\r\n if (!market || !locale || !routes || !categories) {\r\n return doc;\r\n }\r\n const withSchema = await decorateSchema_(doc, collectionConfig.slug);\r\n const withComponents = await decorateComponents_(withSchema, collectionConfig.slug, context as Required<MixerContext>);\r\n const withCategory = await decorateCategory_(withComponents, collectionConfig.slug, context as Required<MixerContext>);\r\n const withHref = await decorateHref_(withCategory, collectionConfig.slug, context as Required<MixerContext>);\r\n const withNav = await decorateNav_(withHref, collectionConfig.slug, context as Required<MixerContext>);\r\n return withNav;\r\n /*\r\n const withRichText = await decorateRichText_(withNav, collectionConfig.fields, context as Required<MixerContext>, req.payload.config);\r\n return withRichText;\r\n */\r\n};\r\n\r\n/**\r\n * Create a record of the pages collection related to the created document.\r\n */\r\nexport const afterPageChangeHook: CollectionAfterChangeHook<ICategorized> = async ({\r\n doc, // full document data\r\n req, // full express request\r\n previousDoc, // document data before updating the collection\r\n operation, // name of the operation ie. 'create', 'update'\r\n}) => {\r\n if (operation === 'update') {\r\n const { query = {} } = req;\r\n const { draft } = query;\r\n // console.log('afterPageChange', operation, draft, doc.isDefault, previousDoc.slug, doc.slug);\r\n if (!draft && doc.isDefault !== true && previousDoc.slug && doc.slug) {\r\n const redirects = await collectPageRedirects(req, previousDoc, doc);\r\n // console.log('redirects', redirects);\r\n }\r\n }\r\n return doc;\r\n};\r\n\r\n/**\r\n * Delete records of the pages collection related to the deleted document.\r\n */\r\nexport const afterPageDeleteHook: CollectionAfterDeleteHook = async ({\r\n req, // full express request\r\n id, // id of document to delete\r\n doc, // deleted document\r\n}) => {\r\n const { query = {} } = req;\r\n const { draft } = query;\r\n if (!draft && doc.isDefault !== true && doc.slug) {\r\n console.log('RedirectService.deletePage !!!');\r\n // !!! todo find and redirect to parentCategory connected to a page\r\n }\r\n};\r\n\r\n/*\r\nexport const beforeValidateHook: CollectionBeforeValidateHook = async ({\r\n data, // incoming data to update or create with\r\n req, // full express request\r\n operation, // name of the operation ie. 'create', 'update'\r\n originalDoc, // original document\r\n}) => {\r\n console.log(data, originalDoc, req.query);\r\n return data; // Return data to either create or update a document with\r\n};\r\n*/\r\n"],"names":["ResponseError","ResponseSuccess","decorateCategory_","decorateComponents_","decorateHref_","decorateNav_","decorateSchema_","findByIDHandler","findHandler","getCollectionItems","collectPageRedirects","isMixerRequest","pageIndexGet","slug","path","method","handler","req","query","locale","market","pagination","items","error","console","pageDetailGet","depth","afterPageOperationFind","process","env","PAYLOAD_FILTER_FIND","split","map","x","trim","afterPageOperationHook","collectionConfig","args","collection","operation","result","length","pathname","optimize","docs","Object","fromEntries","entries","filter","k","v","includes","afterPageReadHook","doc","context","findMany","routes","categories","withSchema","withComponents","withCategory","withHref","withNav","afterPageChangeHook","previousDoc","draft","isDefault","redirects","afterPageDeleteHook","id","log"],"mappings":"AACA,SAASA,aAAa,EAAEC,eAAe,QAAQ,qCAAqC;AAEpF,SAASC,iBAAiB,EAAEC,mBAAmB,EAAEC,aAAa,EAAEC,YAAY,EAAEC,eAAe,QAAQ,gBAAgB;AACrH,SAASC,eAAe,QAAQ,2BAA2B;AAC3D,SAASC,WAAW,QAAQ,uBAAuB;AACnD,SAASC,kBAAkB,QAAQ,uBAAuB;AAC1D,SAASC,oBAAoB,QAAQ,qBAAqB;AAE1D,SAASC,cAAc,QAAQ,UAAU;AAEzC;;CAEC,GACD,OAAO,MAAMC,eAA6C,CAACC,OAAkB,CAAA;QAC3EC,MAAM;QACNC,QAAQ;QACRC,SAAS,OAAOC;YACd,IAAI;gBACF,MAAM,EAAEC,KAAK,EAAE,GAAGD;gBAClB,qEAAqE;gBACrE,IAAI,CAACC,OAAO;oBACV,OAAOV,YAAYS;gBACrB;gBACA,MAAM,EAAEE,MAAM,EAAEC,MAAM,EAAEC,UAAU,EAAE,GAAGH;gBACvC,IAAI,OAAOE,WAAW,YAAY,OAAOD,WAAW,UAAU;oBAC5D,8DAA8D;oBAC9D,yHAAyH;oBACzH,IAAIE,eAAe,QAAQ;wBACzB,OAAOb,YAAYS;oBACrB,OAAO;wBACL,MAAMK,QAAQ,MAAMb,mBAAmBQ,KAAKJ;wBAC5C,OAAOZ,gBAAgBqB;oBACzB;gBACF,OAAO,IAAID,eAAe,SAAS;oBACjC,MAAMC,QAAQ,MAAMb,mBAAmBQ,KAAKJ;oBAC5C,OAAOZ,gBAAgBqB;gBACzB;gBACA,OAAOd,YAAYS;YACrB,EAAE,OAAOM,OAAY;gBACnBC,QAAQD,KAAK,CAAC,CAAC,yBAAyB,EAAEV,KAAK,MAAM,CAAC,EAAEU;gBACxD,OAAOvB,cAAcuB;YACvB;QACF;IACF,CAAA,EAAG;AAEH;;CAEC,GACD,OAAO,MAAME,gBAA8C,CAACZ,OAAkB,CAAA;QAC5EC,MAAM;QACNC,QAAQ;QACRC,SAAS,OAAOC;YACd,IAAI;gBACF,MAAM,EAAEC,KAAK,EAAE,GAAGD;gBAClB,sEAAsE;gBACtE,IAAI,CAACC,OAAO;oBACV,OAAOX,gBAAgBU;gBACzB;gBACA,MAAM,EAAEG,MAAM,EAAED,MAAM,EAAE,GAAGD;gBAC3B,oEAAoE;gBACpE,IAAI,CAAE,CAAA,OAAOE,WAAW,YAAY,OAAOD,WAAW,QAAO,GAAI;oBAC/D,OAAOZ,gBAAgBU;gBACzB;gBACAA,IAAIC,KAAK,CAACQ,KAAK,GAAGT,IAAIC,KAAK,CAACQ,KAAK,IAAI;gBACrC,8DAA8D;gBAC9D,0HAA0H;gBAC1H,OAAOnB,gBAAgBU;YACzB,EAAE,OAAOM,OAAY;gBACnBC,QAAQD,KAAK,CAAC,CAAC,0BAA0B,EAAEV,KAAK,MAAM,CAAC,EAAEU;gBACzD,OAAOvB,cAAcuB;YACvB;QACF;IACF,CAAA,EAAG;AAEH;;CAEC,GACD,MAAMI,yBACJC,QAAQC,GAAG,CAACC,mBAAmB,GAC7BF,QAAQC,GAAG,CAACC,mBAAmB,CAACC,KAAK,CAAC,KAAKC,GAAG,CAACC,CAAAA,IAAKA,EAAEC,IAAI,MAC1D,EAAE;AAGN;;CAEC,GACD,OAAO,MAAMC,yBAA+F,CAACC,mBAAuC,OAAO,EACzJC,IAAI,EACJC,UAAU,EACVrB,GAAG,EACHsB,SAAS,EACTC,MAAM,EACP;QACC,IACEb,uBAAuBc,MAAM,GAAG,KAChC9B,eAAeM,QACfsB,cAAc,UACdtB,IAAIyB,QAAQ,KAAK,YACjBzB,IAAIC,KAAK,CAACyB,QAAQ,KAAK,SACvB;YACA,4FAA4F;YAC5FH,OAAOI,IAAI,GAAGJ,OAAOI,IAAI,CAACZ,GAAG,CAACC,CAAAA,IAAKY,OAAOC,WAAW,CACnDD,OAAOE,OAAO,CAACd,GAAGe,MAAM,CACtB,CAAC,CAACC,GAAGC,EAAE,GAAK,CAACvB,uBAAuBwB,QAAQ,CAACF;QAGjD,uDAAuD;QACzD;QACA,OAAOT;IACT,EAAE;AAEF;;CAEC,GACD,OAAO,MAAMY,oBAAqF,CAAChB,mBAAuC,OAAO,EAC/IiB,GAAG,EACHpC,GAAG,EACHqC,OAAO,EACPC,QAAQ,EACT;QACC,MAAM,EAAEnC,MAAM,EAAED,MAAM,EAAEqC,MAAM,EAAEC,UAAU,EAAE,GAAGH;QAC/C,sEAAsE;QACtE,IAAI,CAAClC,UAAU,CAACD,UAAU,CAACqC,UAAU,CAACC,YAAY;YAChD,OAAOJ;QACT;QACA,MAAMK,aAAa,MAAMpD,gBAAgB+C,KAAKjB,iBAAiBvB,IAAI;QACnE,MAAM8C,iBAAiB,MAAMxD,oBAAoBuD,YAAYtB,iBAAiBvB,IAAI,EAAEyC;QACpF,MAAMM,eAAe,MAAM1D,kBAAkByD,gBAAgBvB,iBAAiBvB,IAAI,EAAEyC;QACpF,MAAMO,WAAW,MAAMzD,cAAcwD,cAAcxB,iBAAiBvB,IAAI,EAAEyC;QAC1E,MAAMQ,UAAU,MAAMzD,aAAawD,UAAUzB,iBAAiBvB,IAAI,EAAEyC;QACpE,OAAOQ;IACP;;;EAGA,GACF,EAAE;AAEF;;CAEC,GACD,OAAO,MAAMC,sBAA+D,OAAO,EACjFV,GAAG,EACHpC,GAAG,EACH+C,WAAW,EACXzB,SAAS,EACV;IACC,IAAIA,cAAc,UAAU;QAC1B,MAAM,EAAErB,QAAQ,CAAC,CAAC,EAAE,GAAGD;QACvB,MAAM,EAAEgD,KAAK,EAAE,GAAG/C;QAClB,+FAA+F;QAC/F,IAAI,CAAC+C,SAASZ,IAAIa,SAAS,KAAK,QAAQF,YAAYnD,IAAI,IAAIwC,IAAIxC,IAAI,EAAE;YACpE,MAAMsD,YAAY,MAAMzD,qBAAqBO,KAAK+C,aAAaX;QAC/D,uCAAuC;QACzC;IACF;IACA,OAAOA;AACT,EAAE;AAEF;;CAEC,GACD,OAAO,MAAMe,sBAAiD,OAAO,EACnEnD,GAAG,EACHoD,EAAE,EACFhB,GAAG,EACJ;IACC,MAAM,EAAEnC,QAAQ,CAAC,CAAC,EAAE,GAAGD;IACvB,MAAM,EAAEgD,KAAK,EAAE,GAAG/C;IAClB,IAAI,CAAC+C,SAASZ,IAAIa,SAAS,KAAK,QAAQb,IAAIxC,IAAI,EAAE;QAChDW,QAAQ8C,GAAG,CAAC;IACZ,mEAAmE;IACrE;AACF,EAAE,CAEF;;;;;;;;;;AAUA"}
1
+ {"version":3,"sources":["../../../src/core/api/page.service.ts"],"sourcesContent":["import { ICategorized } from '@websolutespa/bom-core';\nimport { ResponseError, ResponseSuccess } from '@websolutespa/payload-utils/server';\nimport { CollectionAfterChangeHook, CollectionAfterDeleteHook, CollectionAfterOperationHook, CollectionAfterReadHook, CollectionConfig, Endpoint, PayloadRequest } from 'payload';\nimport { decorateCategory_, decorateComponents_, decorateHref_, decorateNav_, decorateSchema_ } from '../decorators';\nimport { findByIDHandler } from '../utils/findByIDHandler';\nimport { findHandler } from '../utils/findHandler';\nimport { getCollectionItems } from './collection.service';\nimport { collectPageRedirects } from './redirect.service';\nimport { MixerContext } from './types';\nimport { isMixerRequest } from './utils';\n\n/**\n * Rest api page collection get handler.\n */\nexport const pageIndexGet: ((slug: string) => Endpoint) = (slug: string) => ({\n path: '/',\n method: 'get',\n handler: async (req: PayloadRequest) => {\n try {\n const { query } = req;\n // console.log('pageIndexGet.query', ...Object.entries(query || {}));\n if (!query) {\n return findHandler(req);\n }\n const { locale, market, pagination } = query;\n if (typeof market === 'string' && typeof locale === 'string') {\n // const context = await setMixerContext(req, market, locale);\n // console.log('pageIndexGet.context', context.market, context.locale, context.routes.length, context.categories.length);\n if (pagination === 'true') {\n return findHandler(req);\n } else {\n const items = await getCollectionItems(req, slug);\n return ResponseSuccess(items);\n }\n } else if (pagination === 'false') {\n const items = await getCollectionItems(req, slug);\n return ResponseSuccess(items);\n }\n return findHandler(req);\n } catch (error: any) {\n console.error(`PageService.pageIndexGet.${slug}.error`, error);\n return ResponseError(error);\n }\n },\n});\n\n/**\n * Rest api page collection detail get handler.\n */\nexport const pageDetailGet: ((slug: string) => Endpoint) = (slug: string) => ({\n path: '/:id',\n method: 'get',\n handler: async (req: PayloadRequest) => {\n try {\n const { query } = req;\n // console.log('pageDetailGet.query', ...Object.entries(query || {}));\n if (!query) {\n return findByIDHandler(req);\n }\n const { market, locale } = query;\n // console.log('pageDetailGet', 'market', market, 'locale', locale);\n if (!(typeof market === 'string' && typeof locale === 'string')) {\n return findByIDHandler(req);\n }\n req.query.depth = req.query.depth || '3';\n // const context = await setMixerContext(req, market, locale);\n // console.log('pageDetailGet.context', context.market, context.locale, context.routes.length, context.categories.length);\n return findByIDHandler(req);\n } catch (error: any) {\n console.error(`PageService.pageDetailGet.${slug}.error`, error);\n return ResponseError(error);\n }\n },\n});\n\n/**\n * eg. PAYLOAD_PAGE_FIND = 'components'\n */\nconst afterPageOperationFind: string[] = (\n process.env.PAYLOAD_FILTER_FIND ?\n process.env.PAYLOAD_FILTER_FIND.split(',').map(x => x.trim()) :\n []\n);\n\n/**\n * Modify record for Mixer when queried by market and locale.\n */\nexport const afterPageOperationHook: (collectionConfig: CollectionConfig) => CollectionAfterOperationHook = (collectionConfig: CollectionConfig) => async ({\n args,\n collection,\n req,\n operation,\n result,\n}) => {\n if (\n afterPageOperationFind.length > 0 &&\n isMixerRequest(req) &&\n operation === 'find' &&\n req.pathname !== '/store' &&\n req.query.optimize !== 'false'\n ) {\n // console.log('withPage.afterPageOperationHook', operation, collection.slug, req.pathname);\n result.docs = result.docs.map(x => Object.fromEntries(\n Object.entries(x).filter(\n ([k, v]) => !afterPageOperationFind.includes(k)\n )\n )) as typeof result.docs;\n // console.log('withPage.afterPageOperationHook.done');\n }\n return result;\n};\n\n/**\n * Decorate record for Mixer when queried by market and locale.\n */\nexport const afterPageReadHook: (collectionConfig: CollectionConfig) => CollectionAfterReadHook = (collectionConfig: CollectionConfig) => async ({\n doc,\n req,\n context,\n findMany,\n}) => {\n const { market, locale, routes, categories } = context as MixerContext;\n // console.log('afterPageReadHook', doc.title, query, market, locale);\n if (!market || !locale || !routes || !categories) {\n return doc;\n }\n const withSchema = await decorateSchema_(doc, collectionConfig.slug);\n const withComponents = await decorateComponents_(withSchema, collectionConfig.slug, context as Required<MixerContext>);\n const withCategory = await decorateCategory_(withComponents, collectionConfig.slug, context as Required<MixerContext>);\n const withHref = await decorateHref_(withCategory, collectionConfig.slug, context as Required<MixerContext>);\n const withNav = await decorateNav_(withHref, collectionConfig.slug, context as Required<MixerContext>);\n return withNav;\n /*\n const withRichText = await decorateRichText_(withNav, collectionConfig.fields, context as Required<MixerContext>, req.payload.config);\n return withRichText;\n */\n};\n\n/**\n * Trigger revalidation in the Next.js Mixer app for a given page document.\n */\nasync function triggerPageRevalidation(schema?: string, pageId?: string | number) {\n if (!schema || !pageId) return;\n // todo: dedicated envVar for mixerUrl\n const mixerUrl = process.env.PAYLOAD_PUBLIC_PREVIEW_URL;\n const mixerSecret = process.env.MIXER_SECRET;\n\n if (!mixerUrl || !mixerSecret) {\n console.warn(`[revalidation] Skipping revalidation for ${schema}:${pageId}: MIXER_SECRET or PAYLOAD_PUBLIC_PREVIEW_URL is missing.`);\n return;\n }\n\n try {\n // console.log(`[revalidation] Triggering revalidation for ${schema}:${pageId}`);\n const response = await fetch(`${mixerUrl}/api/__revalidate`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${mixerSecret}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ schema, page: String(pageId) }),\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n console.warn(`[revalidation] Failed to revalidate ${schema}:${pageId}`, response.status, text);\n } else {\n // console.log(`[revalidation] Successfully revalidated ${schema}:${pageId}`);\n }\n } catch (error) {\n console.error(`[revalidation] Error triggering revalidation for ${schema}:${pageId}`, error);\n }\n}\n\n/**\n * Create a record of the pages collection related to the created document.\n */\nexport const afterPageChangeHook: CollectionAfterChangeHook<ICategorized> = async ({\n doc, // full document data\n req, // full express request\n previousDoc, // document data before updating the collection\n operation, // name of the operation ie. 'create', 'update'\n collection,\n}) => {\n if (operation === 'update') {\n const { query = {} } = req;\n const { draft } = query;\n // console.log('afterPageChange', operation, draft, doc.isDefault, previousDoc.slug, doc.slug);\n if (!draft && doc.isDefault !== true && previousDoc.slug && doc.slug) {\n const redirects = await collectPageRedirects(req, previousDoc, doc);\n // console.log('redirects', redirects);\n }\n }\n\n if (doc._status === 'published') {\n triggerPageRevalidation(collection?.slug, doc.id);\n }\n\n return doc;\n};\n\n/**\n * Delete records of the pages collection related to the deleted document.\n */\nexport const afterPageDeleteHook: CollectionAfterDeleteHook = async ({\n req, // full express request\n id, // id of document to delete\n doc, // deleted document\n}) => {\n const { query = {} } = req;\n const { draft } = query;\n if (!draft && doc.isDefault !== true && doc.slug) {\n console.log('RedirectService.deletePage !!!');\n // !!! todo find and redirect to parentCategory connected to a page\n }\n};\n\n/*\nexport const beforeValidateHook: CollectionBeforeValidateHook = async ({\n data, // incoming data to update or create with\n req, // full express request\n operation, // name of the operation ie. 'create', 'update'\n originalDoc, // original document\n}) => {\n console.log(data, originalDoc, req.query);\n return data; // Return data to either create or update a document with\n};\n*/\n"],"names":["ResponseError","ResponseSuccess","decorateCategory_","decorateComponents_","decorateHref_","decorateNav_","decorateSchema_","findByIDHandler","findHandler","getCollectionItems","collectPageRedirects","isMixerRequest","pageIndexGet","slug","path","method","handler","req","query","locale","market","pagination","items","error","console","pageDetailGet","depth","afterPageOperationFind","process","env","PAYLOAD_FILTER_FIND","split","map","x","trim","afterPageOperationHook","collectionConfig","args","collection","operation","result","length","pathname","optimize","docs","Object","fromEntries","entries","filter","k","v","includes","afterPageReadHook","doc","context","findMany","routes","categories","withSchema","withComponents","withCategory","withHref","withNav","triggerPageRevalidation","schema","pageId","mixerUrl","PAYLOAD_PUBLIC_PREVIEW_URL","mixerSecret","MIXER_SECRET","warn","response","fetch","headers","body","JSON","stringify","page","String","ok","text","catch","status","afterPageChangeHook","previousDoc","draft","isDefault","redirects","_status","id","afterPageDeleteHook","log"],"mappings":"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"}
@@ -1,33 +1,55 @@
1
1
  // !!! todo use json service from bom-core
2
+ function clauseValue(value) {
3
+ if (value == null) {
4
+ return;
5
+ }
6
+ if (Array.isArray(value)) {
7
+ return value.map((x)=>clauseValue(x));
8
+ }
9
+ if (typeof value === 'string') {
10
+ if (String(parseInt(value)) === value) {
11
+ return Number(value);
12
+ } else if (value === 'true') {
13
+ return true;
14
+ } else if (value === 'false') {
15
+ return false;
16
+ }
17
+ }
18
+ return value;
19
+ }
2
20
  function existsClause(value, exists) {
3
- // console.log('existsClause', value, exists);
4
- if (typeof exists === 'boolean') {
5
- return value != null === exists;
21
+ // console.log('existsClause', value, typeof value, exists, typeof exists);
22
+ const clause = clauseValue(exists);
23
+ if (typeof clause === 'boolean') {
24
+ return Boolean(value) === clause;
6
25
  }
7
26
  return true;
8
27
  }
9
28
  function equalsClause(value, equals) {
10
- // console.log('equalsClause', value, equals);
11
- if (typeof equals !== 'undefined') {
12
- return String(value) === String(equals);
29
+ // console.log('equalsClause', value, typeof value, equals, typeof equals);
30
+ const clause = clauseValue(equals);
31
+ if (typeof clause !== 'undefined') {
32
+ return value === clause;
13
33
  }
14
34
  return true;
15
35
  }
16
36
  function notEqualsClause(value, not_equals) {
17
- // console.log('notEqualsClause', value, not_equals);
18
- if (typeof not_equals !== 'undefined') {
19
- return String(value) != String(not_equals);
37
+ // console.log('notEqualsClause', value, typeof value, not_equals, typeof not_equals);
38
+ const clause = clauseValue(not_equals);
39
+ if (typeof clause !== 'undefined') {
40
+ return value !== not_equals;
20
41
  }
21
42
  return true;
22
43
  }
23
44
  function containsClause(value, contains) {
24
45
  // console.log('containsClause', value, contains);
25
- if (typeof contains !== 'undefined') {
26
- contains = String(contains).toLowerCase();
46
+ const clause = clauseValue(contains);
47
+ if (typeof clause !== 'undefined') {
48
+ const query = String(clause).toLowerCase();
27
49
  if (Array.isArray(value)) {
28
- return value.reduce((p, c)=>p || String(c).toLowerCase() === contains, false);
50
+ return value.reduce((p, c)=>p || String(c).toLowerCase() === query, false);
29
51
  } else if (typeof value === 'string') {
30
- return value.toLowerCase().includes(contains);
52
+ return value.toLowerCase().includes(query);
31
53
  } else {
32
54
  return false;
33
55
  }
@@ -36,63 +58,72 @@ function containsClause(value, contains) {
36
58
  }
37
59
  function inClause(value, values) {
38
60
  // console.log('inClause', value, values);
39
- if (Array.isArray(values)) {
40
- return values.map((x)=>String(x)).indexOf(String(value)) !== -1;
61
+ const clause = clauseValue(values);
62
+ if (Array.isArray(clause)) {
63
+ return clause.indexOf(value) !== -1;
41
64
  }
42
65
  return true;
43
66
  }
44
67
  function notInClause(value, values) {
45
68
  // console.log('notInClause', value, values);
46
- if (Array.isArray(values)) {
47
- return values.map((x)=>String(x)).indexOf(String(value)) === -1;
69
+ const clause = clauseValue(values);
70
+ if (Array.isArray(clause)) {
71
+ return clause.indexOf(value) === -1;
48
72
  }
49
73
  return true;
50
74
  }
51
75
  function greaterThanClause(value, greater_than) {
52
76
  // console.log('greaterThanClause', value, greater_than);
53
- if (typeof greater_than === 'number') {
54
- return typeof value === 'number' && value > Number(greater_than);
77
+ const clause = clauseValue(greater_than);
78
+ if (typeof clause === 'number') {
79
+ return typeof value === 'number' && value > clause;
55
80
  }
56
81
  return true;
57
82
  }
58
83
  function greaterThanEqualClause(value, greater_than_equal) {
59
84
  // console.log('greaterThanEqualClause', value, greater_than_equal);
60
- if (typeof greater_than_equal === 'number') {
61
- return typeof value === 'number' && value >= Number(greater_than_equal);
85
+ const clause = clauseValue(greater_than_equal);
86
+ if (typeof clause === 'number') {
87
+ return typeof value === 'number' && value >= clause;
62
88
  }
63
89
  return true;
64
90
  }
65
91
  function lessThanClause(value, less_than) {
66
92
  // console.log('lessThanClause', value, less_than);
67
- if (typeof less_than === 'number') {
68
- return typeof value === 'number' && value < Number(less_than);
93
+ const clause = clauseValue(less_than);
94
+ if (typeof clause === 'number') {
95
+ return typeof value === 'number' && value < clause;
69
96
  }
70
97
  return true;
71
98
  }
72
99
  function lessThanEqualClause(value, less_than_equal) {
73
100
  // console.log('lessThanEqualClause', value, less_than_equal);
74
- if (typeof less_than_equal === 'number') {
75
- return typeof value === 'number' && value <= Number(less_than_equal);
101
+ const clause = clauseValue(less_than_equal);
102
+ if (typeof clause === 'number') {
103
+ return typeof value === 'number' && value <= clause;
76
104
  }
77
105
  return true;
78
106
  }
79
107
  function likeClause(value, query) {
80
108
  // console.log('likeClause', value, query);
81
- if (typeof query === 'string') {
109
+ const clause = clauseValue(query);
110
+ if (typeof clause === 'string' && clause.length > 0) {
82
111
  return String(value).toLowerCase().indexOf(query.toLowerCase()) !== -1;
83
112
  }
84
113
  return true;
85
114
  }
86
115
  function allClause(value, values) {
87
116
  // console.log('allClause', value, values);
88
- if (Array.isArray(values) && values.length > 0) {
89
- return Array.isArray(value) ? values.reduce((p, c)=>p && value.includes(c), true) : false;
117
+ const clause = clauseValue(values);
118
+ if (Array.isArray(clause) && clause.length > 0) {
119
+ return Array.isArray(value) ? clause.reduce((p, c)=>p && value.includes(c), true) : false;
90
120
  }
91
121
  return true;
92
122
  }
93
123
  function nearClause(value, near) {
94
124
  // console.log('nearClause', value, near);
95
- if (Array.isArray(near) && near.reduce((p, c)=>p && typeof c === 'number', true)) {
125
+ const clause = clauseValue(near);
126
+ if (Array.isArray(clause) && clause.reduce((p, c)=>p && typeof c === 'number', true)) {
96
127
  if (!Array.isArray(value)) {
97
128
  return false;
98
129
  }
@@ -104,7 +135,7 @@ function nearClause(value, near) {
104
135
  if (typeof itemLatitude !== 'number') {
105
136
  return false;
106
137
  }
107
- const [longitude, latitude, maxDistance, minDistance] = near;
138
+ const [longitude, latitude, maxDistance, minDistance] = clause;
108
139
  const distance = longitude && latitude ? calculateDistanceInMeters_(itemLongitude, itemLatitude, longitude, latitude) : 0;
109
140
  if (typeof maxDistance === 'number' && typeof minDistance === 'number') {
110
141
  return distance <= maxDistance && distance >= minDistance;
@@ -180,16 +211,7 @@ export async function sortCollection(items, sort) {
180
211
  const aStringValue = String(aValue);
181
212
  const bStringValue = String(bValue);
182
213
  return aStringValue.localeCompare(bStringValue) * reverse;
183
- /*
184
- const aValue = String(a[key]);
185
- const bValue = String(b[key]);
186
- if (aValue.localeCompare(bValue) < 0) {
187
- return -1 * reverse;
188
- } else if (aValue.localeCompare(bValue) > 0) {
189
- return 1 * reverse;
190
- }
191
- return 0;
192
- */ });
214
+ });
193
215
  }
194
216
  return items;
195
217
  }