UNPKG

@lucidcms/plugin-pages

Version:

The official Pages plugin for Lucid CMS

1 lines 366 kB
{"version":3,"file":"index.mjs","names":["#props","trim","#props","#props","#queryId","#promise","#reject","#resolve","#plugins","#transformResult","#node","#expr","#alias","#props","#join","#queryBuilder","#alias","#props","#aggregateFunctionBuilder","#alias","#props","#node","#createBuilderWithPathLeg","#jsonPath","#alias","#props","#toOperationNode","#getExecutor","#compile","#rawBuilder","#alias","constants","constants","copy","copy","constants","buildFullSlug","constants","copy","constants","copy","constants","constants","copy","constants","copy","constants","copy","copy","constants","copy","copy","constants","copy","copy","constants","constants","copy","copy","constants","constants"],"sources":["../src/constants.ts","../src/utils/get-parent-page-id.ts","../src/utils/normalize-path-value.ts","../src/utils/format-fullslug.ts","../src/utils/build-fullslug-from-fullslug.ts","../src/utils/resolve-collection-prefix.ts","../src/services/construct-parent-fullslug.ts","../../../node_modules/kysely/dist/util/object-utils.js","../../../node_modules/kysely/dist/operation-node/identifier-node.js","../../../node_modules/kysely/dist/operation-node/schemable-identifier-node.js","../../../node_modules/kysely/dist/operation-node/alias-node.js","../../../node_modules/kysely/dist/operation-node/table-node.js","../../../node_modules/kysely/dist/operation-node/operation-node-source.js","../../../node_modules/kysely/dist/expression/expression.js","../../../node_modules/kysely/dist/operation-node/select-modifier-node.js","../../../node_modules/kysely/dist/operation-node/and-node.js","../../../node_modules/kysely/dist/operation-node/or-node.js","../../../node_modules/kysely/dist/operation-node/on-node.js","../../../node_modules/kysely/dist/operation-node/join-node.js","../../../node_modules/kysely/dist/operation-node/binary-operation-node.js","../../../node_modules/kysely/dist/operation-node/operator-node.js","../../../node_modules/kysely/dist/operation-node/column-node.js","../../../node_modules/kysely/dist/operation-node/select-all-node.js","../../../node_modules/kysely/dist/operation-node/reference-node.js","../../../node_modules/kysely/dist/dynamic/dynamic-reference-builder.js","../../../node_modules/kysely/dist/operation-node/order-by-item-node.js","../../../node_modules/kysely/dist/operation-node/raw-node.js","../../../node_modules/kysely/dist/operation-node/collate-node.js","../../../node_modules/kysely/dist/query-builder/order-by-item-builder.js","../../../node_modules/kysely/dist/util/log-once.js","../../../node_modules/kysely/dist/parser/order-by-parser.js","../../../node_modules/kysely/dist/operation-node/json-reference-node.js","../../../node_modules/kysely/dist/operation-node/json-operator-chain-node.js","../../../node_modules/kysely/dist/operation-node/json-path-node.js","../../../node_modules/kysely/dist/parser/reference-parser.js","../../../node_modules/kysely/dist/operation-node/primitive-value-list-node.js","../../../node_modules/kysely/dist/operation-node/value-list-node.js","../../../node_modules/kysely/dist/operation-node/value-node.js","../../../node_modules/kysely/dist/parser/value-parser.js","../../../node_modules/kysely/dist/operation-node/parens-node.js","../../../node_modules/kysely/dist/parser/binary-operation-parser.js","../../../node_modules/kysely/dist/operation-node/order-by-node.js","../../../node_modules/kysely/dist/operation-node/partition-by-node.js","../../../node_modules/kysely/dist/operation-node/over-node.js","../../../node_modules/kysely/dist/operation-node/from-node.js","../../../node_modules/kysely/dist/operation-node/group-by-node.js","../../../node_modules/kysely/dist/operation-node/having-node.js","../../../node_modules/kysely/dist/operation-node/insert-query-node.js","../../../node_modules/kysely/dist/operation-node/list-node.js","../../../node_modules/kysely/dist/operation-node/update-query-node.js","../../../node_modules/kysely/dist/operation-node/using-node.js","../../../node_modules/kysely/dist/operation-node/delete-query-node.js","../../../node_modules/kysely/dist/operation-node/where-node.js","../../../node_modules/kysely/dist/operation-node/returning-node.js","../../../node_modules/kysely/dist/operation-node/explain-node.js","../../../node_modules/kysely/dist/operation-node/when-node.js","../../../node_modules/kysely/dist/operation-node/merge-query-node.js","../../../node_modules/kysely/dist/operation-node/output-node.js","../../../node_modules/kysely/dist/operation-node/query-node.js","../../../node_modules/kysely/dist/operation-node/select-query-node.js","../../../node_modules/kysely/dist/query-builder/join-builder.js","../../../node_modules/kysely/dist/operation-node/partition-by-item-node.js","../../../node_modules/kysely/dist/parser/partition-by-parser.js","../../../node_modules/kysely/dist/query-builder/over-builder.js","../../../node_modules/kysely/dist/operation-node/selection-node.js","../../../node_modules/kysely/dist/parser/select-parser.js","../../../node_modules/kysely/dist/query-builder/no-result-error.js","../../../node_modules/kysely/dist/operation-node/top-node.js","../../../node_modules/kysely/dist/parser/top-parser.js","../../../node_modules/kysely/dist/operation-node/limit-node.js","../../../node_modules/kysely/dist/util/random-string.js","../../../node_modules/kysely/dist/util/query-id.js","../../../node_modules/kysely/dist/util/deferred.js","../../../node_modules/kysely/dist/util/provide-controlled-connection.js","../../../node_modules/kysely/dist/util/abort.js","../../../node_modules/kysely/dist/query-executor/query-executor-base.js","../../../node_modules/kysely/dist/query-executor/noop-query-executor.js","../../../node_modules/kysely/dist/parser/parse-utils.js","../../../node_modules/kysely/dist/parser/join-parser.js","../../../node_modules/kysely/dist/operation-node/offset-node.js","../../../node_modules/kysely/dist/operation-node/group-by-item-node.js","../../../node_modules/kysely/dist/parser/group-by-parser.js","../../../node_modules/kysely/dist/operation-node/set-operation-node.js","../../../node_modules/kysely/dist/parser/set-operation-parser.js","../../../node_modules/kysely/dist/expression/expression-wrapper.js","../../../node_modules/kysely/dist/operation-node/fetch-node.js","../../../node_modules/kysely/dist/parser/fetch-parser.js","../../../node_modules/kysely/dist/query-builder/select-query-builder.js","../../../node_modules/kysely/dist/operation-node/aggregate-function-node.js","../../../node_modules/kysely/dist/operation-node/function-node.js","../../../node_modules/kysely/dist/query-builder/aggregate-function-builder.js","../../../node_modules/kysely/dist/query-builder/function-module.js","../../../node_modules/kysely/dist/operation-node/unary-operation-node.js","../../../node_modules/kysely/dist/parser/unary-operation-parser.js","../../../node_modules/kysely/dist/operation-node/case-node.js","../../../node_modules/kysely/dist/query-builder/case-builder.js","../../../node_modules/kysely/dist/operation-node/json-path-leg-node.js","../../../node_modules/kysely/dist/query-builder/json-path-builder.js","../../../node_modules/kysely/dist/operation-node/tuple-node.js","../../../node_modules/kysely/dist/operation-node/data-type-node.js","../../../node_modules/kysely/dist/parser/data-type-parser.js","../../../node_modules/kysely/dist/operation-node/cast-node.js","../../../node_modules/kysely/dist/expression/expression-builder.js","../../../node_modules/kysely/dist/parser/expression-parser.js","../../../node_modules/kysely/dist/dynamic/dynamic-table-builder.js","../../../node_modules/kysely/dist/parser/table-parser.js","../../../node_modules/kysely/dist/raw-builder/raw-builder.js","../../../node_modules/kysely/dist/raw-builder/sql.js","../src/utils/apply-tenant-scope.ts","../src/utils/get-parent-page-relation-table.ts","../src/services/get-parent-fields.ts","../src/services/get-target-collection.ts","../src/services/hooks/after-fetch-handler.ts","../src/utils/build-fullslug-from-slugs.ts","../src/services/construct-child-fullslugs.ts","../src/services/get-descendant-fields.ts","../src/services/get-document-version-fields.ts","../src/services/plugin-options.ts","../src/services/register-fields.ts","../src/services/set-full-slug.ts","../src/services/update-fullslug-fields.ts","../src/services/update-slug-fields.ts","../src/services/hooks/after-upsert-handler.ts","../src/services/checks/check-fields-exist.ts","../src/services/checks/circular-parents.ts","../src/utils/duplicate-route-message.ts","../src/utils/route-uniqueness.ts","../src/services/checks/fullslug-unique-fields.ts","../src/services/checks/fullslug-uniqueness.ts","../src/services/checks/page-is-parent-of-self.ts","../src/services/checks/root-slug-withparent.ts","../src/services/hooks/before-delete-handler.ts","../src/services/hooks/before-upsert-handler.ts","../src/utils/field-res-to-schema.ts","../src/services/hooks/version-promote.ts","../src/plugin.ts","../src/index.ts"],"sourcesContent":["export const PLUGIN_KEY = \"plugin-pages\";\nexport const LUCID_VERSION = \"0.x.x\";\n\nexport default {\n\tfields: {\n\t\tparentPage: {\n\t\t\tkey: \"parentPage\",\n\t\t},\n\t\tslug: {\n\t\t\tkey: \"slug\",\n\t\t},\n\t\tfullSlug: {\n\t\t\tkey: \"fullSlug\",\n\t\t},\n\t},\n};\n","import type { FieldInputSchema } from \"@lucidcms/core/types\";\n\n/**\n * Returns the single parent page ID used by the pages plugin.\n */\nconst getParentPageId = (field: FieldInputSchema): number | null => {\n\tif (!Array.isArray(field.value)) return null;\n\n\tconst parentPageValue = field.value[0];\n\tif (typeof parentPageValue !== \"object\" || parentPageValue === null) {\n\t\treturn null;\n\t}\n\tif (!(\"id\" in parentPageValue)) return null;\n\n\treturn typeof parentPageValue.id === \"number\" ? parentPageValue.id : null;\n};\n\nexport default getParentPageId;\n","const normalizePathValue = (\n\tvalue: string | null | undefined,\n): string | null | undefined => {\n\tif (value === null || value === undefined) return value;\n\tif (value === \"/\") return \"/\";\n\n\treturn value.toLowerCase();\n};\n\nexport default normalizePathValue;\n","import normalizePathValue from \"./normalize-path-value.js\";\n\nconst formatFullSlug = (\n\t...parts: Array<string | null | undefined>\n): string | null => {\n\tconst hasRoot = parts.some((part) => part === \"/\");\n\tconst normalizedParts = parts\n\t\t.map((part) => normalizePathValue(part))\n\t\t.filter((part): part is string => part !== null && part !== undefined)\n\t\t.map((part) => {\n\t\t\tif (part === \"/\") return \"\";\n\t\t\treturn part.replace(/^\\/+|\\/+$/g, \"\");\n\t\t})\n\t\t.filter(Boolean);\n\n\tif (normalizedParts.length === 0) {\n\t\treturn hasRoot ? \"/\" : null;\n\t}\n\n\treturn `/${normalizedParts.join(\"/\")}`.replace(/\\/+/g, \"/\");\n};\n\nexport default formatFullSlug;\n","import type { ParentPageQueryResponse } from \"../services/get-parent-fields.js\";\nimport formatFullSlug from \"./format-fullslug.js\";\n\nconst buildFullSlug = (data: {\n\tparentFields: Array<ParentPageQueryResponse>;\n\ttargetLocale: string;\n\tslug: string | null | undefined;\n\tprefix?: string;\n}): string | null => {\n\tif (\n\t\tdata.slug === null ||\n\t\tdata.slug === undefined ||\n\t\tdata.slug.trim() === \"\"\n\t) {\n\t\treturn null;\n\t}\n\n\tconst targetParentFullSlugField = data.parentFields.find((field) => {\n\t\treturn field.locale === data.targetLocale;\n\t});\n\n\tif (targetParentFullSlugField?._fullSlug) {\n\t\treturn formatFullSlug(targetParentFullSlugField._fullSlug, data.slug);\n\t}\n\n\treturn formatFullSlug(data.prefix, data.slug);\n};\n\nexport default buildFullSlug;\n","import type { CollectionConfig } from \"../types/types.js\";\nimport normalizePathValue from \"./normalize-path-value.js\";\n\nconst normalizePrefix = (\n\tprefix: string | null | undefined,\n): string | undefined => {\n\tconst normalizedPrefix = normalizePathValue(prefix);\n\tif (!normalizedPrefix) return undefined;\n\n\tconst trimmed = normalizedPrefix.replace(/^\\/+|\\/+$/g, \"\");\n\treturn trimmed.length > 0 ? trimmed : undefined;\n};\n\nconst resolveCollectionPrefix = (data: {\n\tcollection: CollectionConfig;\n\tlocaleCode: string;\n}): string | undefined => {\n\tif (!data.collection.prefix) return undefined;\n\n\tif (typeof data.collection.prefix === \"string\") {\n\t\treturn normalizePrefix(data.collection.prefix);\n\t}\n\n\treturn normalizePrefix(data.collection.prefix[data.localeCode]);\n};\n\nexport default resolveCollectionPrefix;\n","import type {\n\tConfig,\n\tFieldInputSchema,\n\tServiceResponse,\n} from \"@lucidcms/core/types\";\nimport type { CollectionConfig } from \"../types/types.js\";\nimport buildFullSlug from \"../utils/build-fullslug-from-fullslug.js\";\nimport resolveCollectionPrefix from \"../utils/resolve-collection-prefix.js\";\nimport type { ParentPageQueryResponse } from \"./get-parent-fields.js\";\n\n/**\n * Constructs the fullSlug from the slug and parentPage fields\n */\nconst constructParentFullSlug = (data: {\n\tcollection: CollectionConfig;\n\tparentFields: Array<ParentPageQueryResponse>;\n\tlocalization: Config[\"localization\"];\n\tfields: {\n\t\tslug: FieldInputSchema;\n\t};\n}): Awaited<ServiceResponse<Record<string, string | null>>> => {\n\t// initialise fullSlug with null values for each locale\n\tconst fullSlug: Record<string, string | null> =\n\t\tdata.localization.locales.reduce<Record<string, string | null>>(\n\t\t\t(acc, locale) => {\n\t\t\t\tacc[locale.code] = null;\n\t\t\t\treturn acc;\n\t\t\t},\n\t\t\t{},\n\t\t);\n\n\t// if translations are enabled/set\n\tif (data.collection.localized && data.fields.slug.translations) {\n\t\tfor (let i = 0; i < data.localization.locales.length; i++) {\n\t\t\tconst locale = data.localization.locales[i];\n\t\t\tif (!locale) continue;\n\n\t\t\tfullSlug[locale.code] = buildFullSlug({\n\t\t\t\tparentFields: data.parentFields || [],\n\t\t\t\ttargetLocale: locale.code,\n\t\t\t\tslug: data.fields.slug.translations[locale.code],\n\t\t\t\tprefix: resolveCollectionPrefix({\n\t\t\t\t\tcollection: data.collection,\n\t\t\t\t\tlocaleCode: locale.code,\n\t\t\t\t}),\n\t\t\t});\n\t\t}\n\t} else {\n\t\tfullSlug[data.localization.defaultLocale] = buildFullSlug({\n\t\t\tparentFields: data.parentFields || [],\n\t\t\ttargetLocale: data.localization.defaultLocale,\n\t\t\tslug: data.fields.slug.value,\n\t\t\tprefix: resolveCollectionPrefix({\n\t\t\t\tcollection: data.collection,\n\t\t\t\tlocaleCode: data.localization.defaultLocale,\n\t\t\t}),\n\t\t});\n\t}\n\n\treturn {\n\t\terror: undefined,\n\t\tdata: fullSlug,\n\t};\n};\n\nexport default constructParentFullSlug;\n","/// <reference types=\"./object-utils.d.ts\" />\nexport function isEmpty(obj) {\n if (Array.isArray(obj) || isString(obj) || isBuffer(obj)) {\n return obj.length === 0;\n }\n else if (obj) {\n return Object.keys(obj).length === 0;\n }\n return false;\n}\nexport function isUndefined(obj) {\n return typeof obj === 'undefined' || obj === undefined;\n}\nexport function isString(obj) {\n return typeof obj === 'string';\n}\nexport function isNumber(obj) {\n return typeof obj === 'number';\n}\nexport function isBoolean(obj) {\n return typeof obj === 'boolean';\n}\nexport function isNull(obj) {\n return obj === null;\n}\nexport function isDate(obj) {\n return obj instanceof Date;\n}\nexport function isBigInt(obj) {\n return typeof obj === 'bigint';\n}\n// Don't change the returnd type to `obj is Buffer` to not create a\n// hard dependency to node.\nexport function isBuffer(obj) {\n return typeof Buffer !== 'undefined' && Buffer.isBuffer(obj);\n}\nexport function isFunction(obj) {\n return typeof obj === 'function';\n}\nexport function isObject(obj) {\n return typeof obj === 'object' && obj !== null;\n}\nexport function isArrayBufferOrView(obj) {\n return obj instanceof ArrayBuffer || ArrayBuffer.isView(obj);\n}\nexport function isPlainObject(obj) {\n if (!isObject(obj) || getTag(obj) !== '[object Object]') {\n return false;\n }\n if (Object.getPrototypeOf(obj) === null) {\n return true;\n }\n let proto = obj;\n while (Object.getPrototypeOf(proto) !== null) {\n proto = Object.getPrototypeOf(proto);\n }\n return Object.getPrototypeOf(obj) === proto;\n}\nexport function getLast(arr) {\n return arr[arr.length - 1];\n}\nexport function freeze(obj) {\n return Object.freeze(obj);\n}\nexport function asArray(arg) {\n if (isReadonlyArray(arg)) {\n return arg;\n }\n else {\n return [arg];\n }\n}\nexport function asReadonlyArray(arg) {\n if (isReadonlyArray(arg)) {\n return arg;\n }\n else {\n return freeze([arg]);\n }\n}\nexport function isReadonlyArray(arg) {\n return Array.isArray(arg);\n}\nexport function noop(obj) {\n return obj;\n}\nexport function compare(obj1, obj2) {\n if (isReadonlyArray(obj1) && isReadonlyArray(obj2)) {\n return compareArrays(obj1, obj2);\n }\n else if (isObject(obj1) && isObject(obj2)) {\n return compareObjects(obj1, obj2);\n }\n return obj1 === obj2;\n}\nexport function getMessage(error) {\n return error instanceof Error ? error.message : String(error);\n}\nfunction compareArrays(arr1, arr2) {\n if (arr1.length !== arr2.length) {\n return false;\n }\n for (let i = 0; i < arr1.length; ++i) {\n if (!compare(arr1[i], arr2[i])) {\n return false;\n }\n }\n return true;\n}\nfunction compareObjects(obj1, obj2) {\n if (isBuffer(obj1) && isBuffer(obj2)) {\n return compareBuffers(obj1, obj2);\n }\n else if (isDate(obj1) && isDate(obj2)) {\n return compareDates(obj1, obj2);\n }\n return compareGenericObjects(obj1, obj2);\n}\nfunction compareBuffers(buf1, buf2) {\n return Buffer.compare(buf1, buf2) === 0;\n}\nfunction compareDates(date1, date2) {\n return date1.getTime() === date2.getTime();\n}\nfunction compareGenericObjects(obj1, obj2) {\n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n if (keys1.length !== keys2.length) {\n return false;\n }\n for (const key of keys1) {\n if (!compare(obj1[key], obj2[key])) {\n return false;\n }\n }\n return true;\n}\nconst toString = Object.prototype.toString;\nfunction getTag(value) {\n if (value == null) {\n return value === undefined ? '[object Undefined]' : '[object Null]';\n }\n return toString.call(value);\n}\n","/// <reference types=\"./identifier-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const IdentifierNode = freeze({\n is(node) {\n return node.kind === 'IdentifierNode';\n },\n create(name) {\n return freeze({\n kind: 'IdentifierNode',\n name,\n });\n },\n});\n","/// <reference types=\"./schemable-identifier-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\nimport { IdentifierNode } from './identifier-node.js';\n/**\n * @internal\n */\nexport const SchemableIdentifierNode = freeze({\n is(node) {\n return node.kind === 'SchemableIdentifierNode';\n },\n create(identifier) {\n return freeze({\n kind: 'SchemableIdentifierNode',\n identifier: IdentifierNode.create(identifier),\n });\n },\n createWithSchema(schema, identifier) {\n return freeze({\n kind: 'SchemableIdentifierNode',\n schema: IdentifierNode.create(schema),\n identifier: IdentifierNode.create(identifier),\n });\n },\n});\n","/// <reference types=\"./alias-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const AliasNode = freeze({\n is(node) {\n return node.kind === 'AliasNode';\n },\n create(node, alias) {\n return freeze({\n kind: 'AliasNode',\n node,\n alias,\n });\n },\n});\n","/// <reference types=\"./table-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\nimport { SchemableIdentifierNode } from './schemable-identifier-node.js';\n/**\n * @internal\n */\nexport const TableNode = freeze({\n is(node) {\n return node.kind === 'TableNode';\n },\n create(table) {\n return freeze({\n kind: 'TableNode',\n table: SchemableIdentifierNode.create(table),\n });\n },\n createWithSchema(schema, table) {\n return freeze({\n kind: 'TableNode',\n table: SchemableIdentifierNode.createWithSchema(schema, table),\n });\n },\n});\n","/// <reference types=\"./operation-node-source.d.ts\" />\nimport { isFunction, isObject } from '../util/object-utils.js';\nexport function isOperationNodeSource(obj) {\n return isObject(obj) && isFunction(obj.toOperationNode);\n}\n","/// <reference types=\"./expression.d.ts\" />\nimport { isOperationNodeSource, } from '../operation-node/operation-node-source.js';\nimport { isObject, isString } from '../util/object-utils.js';\nexport function isExpression(obj) {\n return isObject(obj) && 'expressionType' in obj && isOperationNodeSource(obj);\n}\nexport function isAliasedExpression(obj) {\n return (isObject(obj) &&\n 'expression' in obj &&\n isString(obj.alias) &&\n isOperationNodeSource(obj));\n}\n","/// <reference types=\"./select-modifier-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const SelectModifierNode = freeze({\n is(node) {\n return node.kind === 'SelectModifierNode';\n },\n create(modifier, of) {\n return freeze({\n kind: 'SelectModifierNode',\n modifier,\n of,\n });\n },\n createWithExpression(modifier) {\n return freeze({\n kind: 'SelectModifierNode',\n rawModifier: modifier,\n });\n },\n});\n","/// <reference types=\"./and-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const AndNode = freeze({\n is(node) {\n return node.kind === 'AndNode';\n },\n create(left, right) {\n return freeze({\n kind: 'AndNode',\n left,\n right,\n });\n },\n});\n","/// <reference types=\"./or-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const OrNode = freeze({\n is(node) {\n return node.kind === 'OrNode';\n },\n create(left, right) {\n return freeze({\n kind: 'OrNode',\n left,\n right,\n });\n },\n});\n","/// <reference types=\"./on-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\nimport { AndNode } from './and-node.js';\nimport { OrNode } from './or-node.js';\n/**\n * @internal\n */\nexport const OnNode = freeze({\n is(node) {\n return node.kind === 'OnNode';\n },\n create(filter) {\n return freeze({\n kind: 'OnNode',\n on: filter,\n });\n },\n cloneWithOperation(onNode, operator, operation) {\n return freeze({\n ...onNode,\n on: operator === 'And'\n ? AndNode.create(onNode.on, operation)\n : OrNode.create(onNode.on, operation),\n });\n },\n});\n","/// <reference types=\"./join-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\nimport { OnNode } from './on-node.js';\n/**\n * @internal\n */\nexport const JoinNode = freeze({\n is(node) {\n return node.kind === 'JoinNode';\n },\n create(joinType, table) {\n return freeze({\n kind: 'JoinNode',\n joinType,\n table,\n on: undefined,\n });\n },\n createWithOn(joinType, table, on) {\n return freeze({\n kind: 'JoinNode',\n joinType,\n table,\n on: OnNode.create(on),\n });\n },\n cloneWithOn(joinNode, operation) {\n return freeze({\n ...joinNode,\n on: joinNode.on\n ? OnNode.cloneWithOperation(joinNode.on, 'And', operation)\n : OnNode.create(operation),\n });\n },\n});\n","/// <reference types=\"./binary-operation-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const BinaryOperationNode = freeze({\n is(node) {\n return node.kind === 'BinaryOperationNode';\n },\n create(leftOperand, operator, rightOperand) {\n return freeze({\n kind: 'BinaryOperationNode',\n leftOperand,\n operator,\n rightOperand,\n });\n },\n});\n","/// <reference types=\"./operator-node.d.ts\" />\nimport { freeze, isString } from '../util/object-utils.js';\nconst COMPARISON_OPERATORS_DICTIONARY = freeze({\n '=': true,\n '==': true,\n '!=': true,\n '<>': true,\n '>': true,\n '>=': true,\n '<': true,\n '<=': true,\n in: true,\n 'not in': true,\n is: true,\n 'is not': true,\n like: true,\n 'not like': true,\n match: true,\n ilike: true,\n 'not ilike': true,\n '@>': true,\n '<@': true,\n '^@': true,\n '&&': true,\n '?': true,\n '?&': true,\n '?|': true,\n '!<': true,\n '!>': true,\n '<=>': true,\n '!~': true,\n '~': true,\n '~*': true,\n '!~*': true,\n '@@': true,\n '@@@': true,\n '!!': true,\n '<->': true,\n regexp: true,\n 'is distinct from': true,\n 'is not distinct from': true,\n});\n/**\n * @deprecated will be removed in version 0.30.x\n */\nexport const COMPARISON_OPERATORS = Object.keys(COMPARISON_OPERATORS_DICTIONARY);\nconst ARITHMETIC_OPERATORS_DICTIONARY = freeze({\n '+': true,\n '-': true,\n '*': true,\n '/': true,\n '%': true,\n '^': true,\n '&': true,\n '|': true,\n '#': true,\n '<<': true,\n '>>': true,\n});\n/**\n * @deprecated will be removed in version 0.30.x\n */\nexport const ARITHMETIC_OPERATORS = Object.keys(ARITHMETIC_OPERATORS_DICTIONARY);\nconst JSON_OPERATORS_DICTIONARY = freeze({\n '->': true,\n '->>': true,\n});\n/**\n * @deprecated will be removed in version 0.30.x\n */\nexport const JSON_OPERATORS = Object.keys(JSON_OPERATORS_DICTIONARY);\nconst BINARY_OPERATORS_DICTIONARY = freeze({\n ...COMPARISON_OPERATORS_DICTIONARY,\n ...ARITHMETIC_OPERATORS_DICTIONARY,\n '||': true,\n});\n/**\n * @deprecated will be removed in version 0.30.x\n */\nexport const BINARY_OPERATORS = Object.keys(BINARY_OPERATORS_DICTIONARY);\nconst UNARY_FILTER_OPERATORS_DICTIONARY = freeze({\n exists: true,\n 'not exists': true,\n});\n/**\n * @deprecated will be removed in version 0.30.x\n */\nexport const UNARY_FILTER_OPERATORS = Object.keys(UNARY_FILTER_OPERATORS_DICTIONARY);\nconst UNARY_OPERATORS_DICTIONARY = freeze({\n ...UNARY_FILTER_OPERATORS_DICTIONARY,\n '-': true,\n not: true,\n});\n/**\n * @deprecated will be removed in version 0.30.x\n */\nexport const UNARY_OPERATORS = Object.keys(UNARY_OPERATORS_DICTIONARY);\n/**\n * @deprecated will be removed in version 0.30.x\n */\nexport const OPERATORS = [\n ...BINARY_OPERATORS,\n ...JSON_OPERATORS,\n ...UNARY_OPERATORS,\n 'between',\n 'between symmetric',\n];\n/**\n * @internal\n */\nexport const OperatorNode = freeze({\n is(node) {\n return node.kind === 'OperatorNode';\n },\n create(operator) {\n return freeze({\n kind: 'OperatorNode',\n operator,\n });\n },\n});\n/**\n * @deprecated will be removed in version 0.30.x\n */\nexport function isOperator(op) {\n return isString(op) && OPERATORS.includes(op);\n}\nexport function isBinaryOperator(op) {\n return isString(op) && BINARY_OPERATORS_DICTIONARY[op];\n}\n/**\n * @deprecated will be removed in version 0.30.x\n */\nexport function isComparisonOperator(op) {\n return isString(op) && COMPARISON_OPERATORS.includes(op);\n}\n/**\n * @deprecated will be removed in version 0.30.x\n */\nexport function isArithmeticOperator(op) {\n return isString(op) && ARITHMETIC_OPERATORS.includes(op);\n}\nexport function isJSONOperator(op) {\n return isString(op) && JSON_OPERATORS_DICTIONARY[op];\n}\nexport function isUnaryOperator(op) {\n return isString(op) && UNARY_OPERATORS_DICTIONARY[op];\n}\n","/// <reference types=\"./column-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\nimport { IdentifierNode } from './identifier-node.js';\n/**\n * @internal\n */\nexport const ColumnNode = freeze({\n is(node) {\n return node.kind === 'ColumnNode';\n },\n create(column) {\n return freeze({\n kind: 'ColumnNode',\n column: IdentifierNode.create(column),\n });\n },\n});\n","/// <reference types=\"./select-all-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const SelectAllNode = freeze({\n is(node) {\n return node.kind === 'SelectAllNode';\n },\n create() {\n return freeze({\n kind: 'SelectAllNode',\n });\n },\n});\n","/// <reference types=\"./reference-node.d.ts\" />\nimport { SelectAllNode } from './select-all-node.js';\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const ReferenceNode = freeze({\n is(node) {\n return node.kind === 'ReferenceNode';\n },\n create(column, table) {\n return freeze({\n kind: 'ReferenceNode',\n table,\n column,\n });\n },\n createSelectAll(table) {\n return freeze({\n kind: 'ReferenceNode',\n table,\n column: SelectAllNode.create(),\n });\n },\n});\n","/// <reference types=\"./dynamic-reference-builder.d.ts\" />\nimport { isOperationNodeSource, } from '../operation-node/operation-node-source.js';\nimport { parseSimpleReferenceExpression } from '../parser/reference-parser.js';\nimport { isObject, isString } from '../util/object-utils.js';\nexport class DynamicReferenceBuilder {\n #dynamicReference;\n get dynamicReference() {\n return this.#dynamicReference;\n }\n /**\n * @private\n *\n * This needs to be here just so that the typings work. Without this\n * the generated .d.ts file contains no reference to the type param R\n * which causes this type to be equal to DynamicReferenceBuilder with\n * any R.\n */\n get refType() {\n return undefined;\n }\n constructor(reference) {\n this.#dynamicReference = reference;\n }\n toOperationNode() {\n return parseSimpleReferenceExpression(this.#dynamicReference);\n }\n}\nexport function isDynamicReferenceBuilder(obj) {\n return (isObject(obj) &&\n isOperationNodeSource(obj) &&\n isString(obj.dynamicReference));\n}\n","/// <reference types=\"./order-by-item-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const OrderByItemNode = freeze({\n is(node) {\n return node.kind === 'OrderByItemNode';\n },\n create(orderBy, direction) {\n return freeze({\n kind: 'OrderByItemNode',\n orderBy,\n direction,\n });\n },\n cloneWith(node, props) {\n return freeze({\n ...node,\n ...props,\n });\n },\n});\n","/// <reference types=\"./raw-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const RawNode = freeze({\n is(node) {\n return node.kind === 'RawNode';\n },\n create(sqlFragments, parameters) {\n return freeze({\n kind: 'RawNode',\n sqlFragments: freeze(sqlFragments),\n parameters: freeze(parameters),\n });\n },\n createWithSql(sql) {\n return RawNode.create([sql], []);\n },\n createWithChild(child) {\n return RawNode.create(['', ''], [child]);\n },\n createWithChildren(children) {\n return RawNode.create(new Array(children.length + 1).fill(''), children);\n },\n});\n","/// <reference types=\"./collate-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\nimport { IdentifierNode } from './identifier-node.js';\n/**\n * @internal\n */\nexport const CollateNode = freeze({\n is(node) {\n return node.kind === 'CollateNode';\n },\n create(collation) {\n return freeze({\n kind: 'CollateNode',\n collation: IdentifierNode.create(collation),\n });\n },\n});\n","/// <reference types=\"./order-by-item-builder.d.ts\" />\nimport { CollateNode } from '../operation-node/collate-node.js';\nimport { OrderByItemNode } from '../operation-node/order-by-item-node.js';\nimport { RawNode } from '../operation-node/raw-node.js';\nimport { freeze } from '../util/object-utils.js';\nexport class OrderByItemBuilder {\n #props;\n constructor(props) {\n this.#props = freeze(props);\n }\n /**\n * Adds `desc` to the `order by` item.\n *\n * See {@link asc} for the opposite.\n */\n desc() {\n return new OrderByItemBuilder({\n node: OrderByItemNode.cloneWith(this.#props.node, {\n direction: RawNode.createWithSql('desc'),\n }),\n });\n }\n /**\n * Adds `asc` to the `order by` item.\n *\n * See {@link desc} for the opposite.\n */\n asc() {\n return new OrderByItemBuilder({\n node: OrderByItemNode.cloneWith(this.#props.node, {\n direction: RawNode.createWithSql('asc'),\n }),\n });\n }\n /**\n * Adds `nulls last` to the `order by` item.\n *\n * This is only supported by some dialects like PostgreSQL and SQLite.\n *\n * See {@link nullsFirst} for the opposite.\n */\n nullsLast() {\n return new OrderByItemBuilder({\n node: OrderByItemNode.cloneWith(this.#props.node, { nulls: 'last' }),\n });\n }\n /**\n * Adds `nulls first` to the `order by` item.\n *\n * This is only supported by some dialects like PostgreSQL and SQLite.\n *\n * See {@link nullsLast} for the opposite.\n */\n nullsFirst() {\n return new OrderByItemBuilder({\n node: OrderByItemNode.cloneWith(this.#props.node, { nulls: 'first' }),\n });\n }\n /**\n * Adds `collate <collationName>` to the `order by` item.\n */\n collate(collation) {\n return new OrderByItemBuilder({\n node: OrderByItemNode.cloneWith(this.#props.node, {\n collation: CollateNode.create(collation),\n }),\n });\n }\n toOperationNode() {\n return this.#props.node;\n }\n}\n","/// <reference types=\"./log-once.d.ts\" />\nconst LOGGED_MESSAGES = new Set();\n/**\n * Use for system-level logging, such as deprecation messages.\n * Logs a message and ensures it won't be logged again.\n */\nexport function logOnce(message) {\n if (LOGGED_MESSAGES.has(message)) {\n return;\n }\n LOGGED_MESSAGES.add(message);\n console.log(message);\n}\n","/// <reference types=\"./order-by-parser.d.ts\" />\nimport { isDynamicReferenceBuilder, } from '../dynamic/dynamic-reference-builder.js';\nimport { isExpression } from '../expression/expression.js';\nimport { OrderByItemNode } from '../operation-node/order-by-item-node.js';\nimport { RawNode } from '../operation-node/raw-node.js';\nimport { OrderByItemBuilder } from '../query-builder/order-by-item-builder.js';\nimport { logOnce } from '../util/log-once.js';\nimport { isExpressionOrFactory, parseExpression, } from './expression-parser.js';\nimport { parseStringReference, } from './reference-parser.js';\nexport function isOrderByDirection(thing) {\n return thing === 'asc' || thing === 'desc';\n}\nexport function parseOrderBy(args) {\n if (args.length === 2) {\n return [parseOrderByItem(args[0], args[1])];\n }\n if (args.length === 1) {\n const [orderBy] = args;\n if (Array.isArray(orderBy)) {\n logOnce('orderBy(array) is deprecated, use multiple orderBy calls instead.');\n return orderBy.map((item) => parseOrderByItem(item));\n }\n return [parseOrderByItem(orderBy)];\n }\n throw new Error(`Invalid number of arguments at order by! expected 1-2, received ${args.length}`);\n}\nexport function parseOrderByItem(expr, modifiers) {\n const parsedRef = parseOrderByExpression(expr);\n if (OrderByItemNode.is(parsedRef)) {\n if (modifiers) {\n throw new Error('Cannot specify direction twice!');\n }\n return parsedRef;\n }\n return parseOrderByWithModifiers(parsedRef, modifiers);\n}\nfunction parseOrderByExpression(expr) {\n if (isExpressionOrFactory(expr)) {\n return parseExpression(expr);\n }\n if (isDynamicReferenceBuilder(expr)) {\n return expr.toOperationNode();\n }\n const [ref, direction] = expr.split(' ');\n if (direction) {\n logOnce(\"`orderBy('column asc')` is deprecated. Use `orderBy('column', 'asc')` instead.\");\n return parseOrderByWithModifiers(parseStringReference(ref), direction);\n }\n return parseStringReference(expr);\n}\nfunction parseOrderByWithModifiers(expr, modifiers) {\n if (typeof modifiers === 'string') {\n if (!isOrderByDirection(modifiers)) {\n throw new Error(`Invalid order by direction: ${modifiers}`);\n }\n return OrderByItemNode.create(expr, RawNode.createWithSql(modifiers));\n }\n if (isExpression(modifiers)) {\n logOnce(\"`orderBy(..., expr)` is deprecated. Use `orderBy(..., 'asc')` or `orderBy(..., (ob) => ...)` instead.\");\n return OrderByItemNode.create(expr, modifiers.toOperationNode());\n }\n const node = OrderByItemNode.create(expr);\n if (!modifiers) {\n return node;\n }\n return modifiers(new OrderByItemBuilder({ node })).toOperationNode();\n}\n","/// <reference types=\"./json-reference-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const JSONReferenceNode = freeze({\n is(node) {\n return node.kind === 'JSONReferenceNode';\n },\n create(reference, traversal) {\n return freeze({\n kind: 'JSONReferenceNode',\n reference,\n traversal,\n });\n },\n cloneWithTraversal(node, traversal) {\n return freeze({\n ...node,\n traversal,\n });\n },\n});\n","/// <reference types=\"./json-operator-chain-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const JSONOperatorChainNode = freeze({\n is(node) {\n return node.kind === 'JSONOperatorChainNode';\n },\n create(operator) {\n return freeze({\n kind: 'JSONOperatorChainNode',\n operator,\n values: freeze([]),\n });\n },\n cloneWithValue(node, value) {\n return freeze({\n ...node,\n values: freeze([...node.values, value]),\n });\n },\n});\n","/// <reference types=\"./json-path-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const JSONPathNode = freeze({\n is(node) {\n return node.kind === 'JSONPathNode';\n },\n create(inOperator) {\n return freeze({\n kind: 'JSONPathNode',\n inOperator,\n pathLegs: freeze([]),\n });\n },\n cloneWithLeg(jsonPathNode, pathLeg) {\n return freeze({\n ...jsonPathNode,\n pathLegs: freeze([...jsonPathNode.pathLegs, pathLeg]),\n });\n },\n});\n","/// <reference types=\"./reference-parser.d.ts\" />\nimport { AliasNode } from '../operation-node/alias-node.js';\nimport { ColumnNode } from '../operation-node/column-node.js';\nimport { ReferenceNode } from '../operation-node/reference-node.js';\nimport { TableNode } from '../operation-node/table-node.js';\nimport { isReadonlyArray, isString } from '../util/object-utils.js';\nimport { parseExpression, isExpressionOrFactory, } from './expression-parser.js';\nimport { IdentifierNode } from '../operation-node/identifier-node.js';\nimport { isOrderByDirection, parseOrderBy, } from './order-by-parser.js';\nimport { OperatorNode, isJSONOperator, } from '../operation-node/operator-node.js';\nimport { JSONReferenceNode } from '../operation-node/json-reference-node.js';\nimport { JSONOperatorChainNode } from '../operation-node/json-operator-chain-node.js';\nimport { JSONPathNode } from '../operation-node/json-path-node.js';\nexport function parseSimpleReferenceExpression(exp) {\n if (isString(exp)) {\n return parseStringReference(exp);\n }\n return exp.toOperationNode();\n}\nexport function parseReferenceExpressionOrList(arg) {\n if (isReadonlyArray(arg)) {\n return arg.map((it) => parseReferenceExpression(it));\n }\n else {\n return [parseReferenceExpression(arg)];\n }\n}\nexport function parseReferenceExpression(exp) {\n if (isExpressionOrFactory(exp)) {\n return parseExpression(exp);\n }\n return parseSimpleReferenceExpression(exp);\n}\nexport function parseJSONReference(ref, op) {\n if (isJSONOperator(op)) {\n return JSONReferenceNode.create(parseStringReference(ref), JSONOperatorChainNode.create(OperatorNode.create(op)));\n }\n if (op === '->$' || op === '->>$') {\n return JSONReferenceNode.create(parseStringReference(ref), JSONPathNode.create(OperatorNode.create(op.slice(0, -1))));\n }\n throw new Error(`Invalid JSON operator: ${op}`);\n}\nexport function parseStringReference(ref) {\n const COLUMN_SEPARATOR = '.';\n if (!ref.includes(COLUMN_SEPARATOR)) {\n return ReferenceNode.create(ColumnNode.create(ref));\n }\n const parts = ref.split(COLUMN_SEPARATOR).map(trim);\n if (parts.length === 3) {\n return parseStringReferenceWithTableAndSchema(parts);\n }\n if (parts.length === 2) {\n return parseStringReferenceWithTable(parts);\n }\n throw new Error(`invalid column reference ${ref}`);\n}\nexport function parseAliasedStringReference(ref) {\n const ALIAS_SEPARATOR = ' as ';\n if (ref.includes(ALIAS_SEPARATOR)) {\n const [columnRef, alias] = ref.split(ALIAS_SEPARATOR).map(trim);\n return AliasNode.create(parseStringReference(columnRef), IdentifierNode.create(alias));\n }\n else {\n return parseStringReference(ref);\n }\n}\nexport function parseColumnName(column) {\n return ColumnNode.create(column);\n}\nexport function parseOrderedColumnName(column) {\n const ORDER_SEPARATOR = ' ';\n if (column.includes(ORDER_SEPARATOR)) {\n const [columnName, order] = column.split(ORDER_SEPARATOR).map(trim);\n if (!isOrderByDirection(order)) {\n throw new Error(`invalid order direction \"${order}\" next to \"${columnName}\"`);\n }\n return parseOrderBy([columnName, order])[0];\n }\n else {\n return parseColumnName(column);\n }\n}\nfunction parseStringReferenceWithTableAndSchema(parts) {\n const [schema, table, column] = parts;\n return ReferenceNode.create(ColumnNode.create(column), TableNode.createWithSchema(schema, table));\n}\nfunction parseStringReferenceWithTable(parts) {\n const [table, column] = parts;\n return ReferenceNode.create(ColumnNode.create(column), TableNode.create(table));\n}\nfunction trim(str) {\n return str.trim();\n}\n","/// <reference types=\"./primitive-value-list-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const PrimitiveValueListNode = freeze({\n is(node) {\n return node.kind === 'PrimitiveValueListNode';\n },\n create(values) {\n return freeze({\n kind: 'PrimitiveValueListNode',\n values: freeze([...values]),\n });\n },\n});\n","/// <reference types=\"./value-list-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const ValueListNode = freeze({\n is(node) {\n return node.kind === 'ValueListNode';\n },\n create(values) {\n return freeze({\n kind: 'ValueListNode',\n values: freeze(values),\n });\n },\n});\n","/// <reference types=\"./value-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const ValueNode = freeze({\n is(node) {\n return node.kind === 'ValueNode';\n },\n create(value) {\n return freeze({\n kind: 'ValueNode',\n value,\n });\n },\n createImmediate(value) {\n return freeze({\n kind: 'ValueNode',\n value,\n immediate: true,\n });\n },\n});\n","/// <reference types=\"./value-parser.d.ts\" />\nimport { PrimitiveValueListNode } from '../operation-node/primitive-value-list-node.js';\nimport { ValueListNode } from '../operation-node/value-list-node.js';\nimport { ValueNode } from '../operation-node/value-node.js';\nimport { isBoolean, isNull, isNumber, isReadonlyArray, } from '../util/object-utils.js';\nimport { parseExpression, isExpressionOrFactory, } from './expression-parser.js';\nexport function parseValueExpressionOrList(arg) {\n if (isReadonlyArray(arg)) {\n return parseValueExpressionList(arg);\n }\n return parseValueExpression(arg);\n}\nexport function parseValueExpression(exp) {\n if (isExpressionOrFactory(exp)) {\n return parseExpression(exp);\n }\n return ValueNode.create(exp);\n}\nexport function isSafeImmediateValue(value) {\n return isNumber(value) || isBoolean(value) || isNull(value);\n}\nexport function parseSafeImmediateValue(value) {\n if (!isSafeImmediateValue(value)) {\n throw new Error(`unsafe immediate value ${JSON.stringify(value)}`);\n }\n return ValueNode.createImmediate(value);\n}\nfunction parseValueExpressionList(arg) {\n if (arg.some(isExpressionOrFactory)) {\n return ValueListNode.create(arg.map((it) => parseValueExpression(it)));\n }\n return PrimitiveValueListNode.create(arg);\n}\n","/// <reference types=\"./parens-node.d.ts\" />\nimport { freeze } from '../util/object-utils.js';\n/**\n * @internal\n */\nexport const ParensNode = freeze({\n is(node) {\n return node.kind === 'ParensNode';\n },\n create(node) {\n return freeze({\n kind: 'ParensNode',\n node,\n });\n },\n});\n","/// <reference types=\"./binary-operation-parser.d.ts\" />\nimport { BinaryOperationNode } from '../operation-node/binary-operation-node.js';\nimport { isBoolean, isNull, isUndefined } from '../util/object-utils.js';\nimport { isOperationNodeSource, } from '../operation-node/operation-node-source.js';\nimport { OperatorNode, isBinaryOperator, } from '../operation-node/operator-node.js';\nimport { parseReferenceExpression, } from './reference-parser.js';\nimport { parseValueExpression, parseValueExpressionOrList, } from './value-parser.js';\nimport { ValueNode } from '../operation-node/value-node.js';\nimport { AndNode } from '../operation-node/and-node.js';\nimport { ParensNode } from '../operation-node/parens-node.js';\nimport { OrNode } from '../operation-node/or-node.js';\nexport function parseValueBinaryOperationOrExpression(args) {\n if (args.length === 3) {\n return parseValueBinaryOperation(args[0], args[1], args[2]);\n }\n else if (args.length === 1) {\n return parseValueExpression(args[0]);\n }\n throw new Error(`invalid arguments: ${JSON.stringify(args)}`);\n}\nexport function parseValueBinaryOperation(left, operator, right) {\n if (isIsOperator(operator) && needsIsOperator(right)) {\n return BinaryOperationNode.create(parseReferenceExpression(left), parseBinaryOperator(operator), ValueNode.createImmediate(right));\n }\n return BinaryOperationNode.create(parseReferenceExpression(left), parseBinaryOperator(operator), parseValueExpressionOrList(right));\n}\nexport function parseReferentialBinaryOperation(left, operator, right) {\n return BinaryOperationNode.create(parseReferenceExpression(left), parseBinaryOperator(operator), parseReferenceExpression(right));\n}\nexport function parseFilterObject(obj, combinator) {\n return parseFilterList(Object.entries(obj)\n .filter(([, v]) => !isUndefined(v))\n .map(([k, v]) => parseValueBinaryOperation(k, needsIsOperator(v) ? 'is' : '=', v)), combinator);\n}\nexport function parseFilterList(list, combinator, withParens = true) {\n const combine = combinator === 'and' ? AndNode.create : OrNode.create;\n if (list.length === 0) {\n return BinaryOperationNode.create(ValueNode.createImmediate(1), OperatorNode.create('='), ValueNode.createImmediate(combinator === 'and' ? 1 : 0));\n }\n let node = toOperationNode(list[0]);\n for (let i = 1; i < list.length; ++i) {\n node = combine(node, toOperationNode(list[i]));\n }\n if (list.length > 1 && withParens) {\n return ParensNode.create(node);\n }\n return node;\n}\nfunction isIsOperator(operator) {\n return operator === 'is' || operator === 'is not';\n}\nfunction needsIsOperator(value) {\n return isNull(value) || isBoolean(value);\n}\nfunction parseBinaryOperator(operator) {\n if (isBinaryOperator(operator)) {\n return OperatorNode.create(operator);\n }\n if (isOperationNodeSource(operator)) {\n return operator.toOperationNode();\n }\n throw new Error(`invalid operator ${JSON.stringify(operator)}`);\n}\nfunction toOperationNode(nodeOrSource) {\n return isOperationNodeSource(nodeO