@lucidcms/core
Version:
The core of the Lucid CMS. It's responsible for spinning up the API and serving the CMS.
1 lines • 8.11 kB
Source Map (JSON)
{"version":3,"file":"insert-brick-tables.mjs","names":[],"sources":["../../../src/services/documents-bricks/insert-brick-tables.ts"],"sourcesContent":["import type { ColumnDataType } from \"kysely\";\nimport type CollectionBuilder from \"../../libs/collection/builders/collection-builder/index.js\";\nimport {\n\tgetFieldDatabaseConfig,\n\tisStorageMode,\n} from \"../../libs/collection/custom-fields/storage/index.js\";\nimport { getBricksTableSchema } from \"../../libs/collection/schema/runtime/runtime-schema-selectors.js\";\nimport { DocumentBricksRepository } from \"../../libs/repositories/index.js\";\nimport type { LucidBricksTable } from \"../../types.js\";\nimport type { ServiceFn } from \"../../utils/services/types.js\";\nimport type { InsertBrickTables } from \"./helpers/construct-brick-table.js\";\n\n/**\n * Inserts aggregated brick tables in dependency order while resolving temporary\n * parent and root references between batches.\n */\nconst insertBrickTables: ServiceFn<\n\t[\n\t\t{\n\t\t\ttables: InsertBrickTables[];\n\t\t\tcollection: CollectionBuilder;\n\t\t},\n\t],\n\tundefined\n> = async (context, data) => {\n\tconst Bricks = new DocumentBricksRepository(\n\t\tcontext.db.client,\n\t\tcontext.config.db,\n\t);\n\n\tconst idMapping: Record<number, number> = {};\n\n\tconst bricksTableSchemaRes = await getBricksTableSchema(\n\t\tcontext,\n\t\tdata.collection.key,\n\t);\n\tif (bricksTableSchemaRes.error) return bricksTableSchemaRes;\n\n\tfor (const table of data.tables) {\n\t\tif (table.data.length === 0) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// update parent and brick IDs using the mappings before inserting\n\t\tfor (const row of table.data) {\n\t\t\t// check for parent_id_ref that needs updating\n\t\t\tif (\n\t\t\t\t\"parent_id_ref\" in row &&\n\t\t\t\ttypeof row.parent_id_ref === \"number\" &&\n\t\t\t\trow.parent_id_ref < 0\n\t\t\t) {\n\t\t\t\t// try primary mapping first\n\t\t\t\tconst mappedId = idMapping[row.parent_id_ref];\n\t\t\t\tif (mappedId) row.parent_id = mappedId;\n\t\t\t\t// fall back to parent_id mapping if available\n\t\t\t\telse if (\n\t\t\t\t\t\"parent_id\" in row &&\n\t\t\t\t\ttypeof row.parent_id === \"number\" &&\n\t\t\t\t\trow.parent_id < 0 &&\n\t\t\t\t\tidMapping[row.parent_id]\n\t\t\t\t) {\n\t\t\t\t\trow.parent_id = idMapping[row.parent_id];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// relation tables use parent_id directly as their transient parent ref.\n\t\t\tif (\n\t\t\t\t\"parent_id\" in row &&\n\t\t\t\ttypeof row.parent_id === \"number\" &&\n\t\t\t\trow.parent_id < 0\n\t\t\t) {\n\t\t\t\tconst mappedId = idMapping[row.parent_id];\n\t\t\t\tif (mappedId) row.parent_id = mappedId;\n\t\t\t}\n\n\t\t\t// check for brick_id that needs updating\n\t\t\tif (\n\t\t\t\t\"brick_id\" in row &&\n\t\t\t\ttypeof row.brick_id === \"number\" &&\n\t\t\t\trow.brick_id < 0\n\t\t\t) {\n\t\t\t\t// Look up the actual brick ID from the mapping\n\t\t\t\tconst mappedBrickId = idMapping[row.brick_id];\n\t\t\t\tif (mappedBrickId) row.brick_id = mappedBrickId;\n\t\t\t}\n\t\t}\n\n\t\t// determine which columns to return\n\t\tconst hasParentIdRef = table.data.some((row) => \"parent_id_ref\" in row);\n\t\tconst hasBrickIdRef = table.data.some((row) => \"brick_id_ref\" in row);\n\t\tconst returningColumns: Array<keyof LucidBricksTable> = [];\n\t\t// always return ID\n\t\treturningColumns.push(\"id\");\n\t\t// return additional columns as needed for mapping\n\t\tif (hasParentIdRef) returningColumns.push(\"parent_id_ref\");\n\t\tif (hasBrickIdRef) returningColumns.push(\"brick_id_ref\");\n\n\t\tconst schema = bricksTableSchemaRes.data.find(\n\t\t\t(s) => s.name === table.table,\n\t\t);\n\t\tconst fieldDatabaseConfig = schema\n\t\t\t? getFieldDatabaseConfig(schema.type)\n\t\t\t: null;\n\t\tconst isTreeTableInsert =\n\t\t\tfieldDatabaseConfig !== null &&\n\t\t\tisStorageMode(fieldDatabaseConfig, \"tree-table\");\n\n\t\t// insert rows for this table\n\t\tconst response = await Bricks.createMultiple(\n\t\t\t{\n\t\t\t\tdata: table.data,\n\t\t\t\treturning: returningColumns,\n\t\t\t},\n\t\t\t{\n\t\t\t\ttableName: table.table,\n\t\t\t\tcolumns:\n\t\t\t\t\tschema?.columns.reduce<Record<string, ColumnDataType>>(\n\t\t\t\t\t\t(record, column) => {\n\t\t\t\t\t\t\trecord[column.name] = column.type;\n\t\t\t\t\t\t\treturn record;\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{},\n\t\t\t\t\t) || {},\n\t\t\t},\n\t\t);\n\t\tif (response.error) return response;\n\n\t\t// create mappings for the next tables.\n\t\t// Prefer returned ref values when available; fall back to original row\n\t\t// refs for adapters that do not return custom columns in insert results.\n\t\tif (response.data?.length) {\n\t\t\tfor (let i = 0; i < response.data.length; i++) {\n\t\t\t\tconst insertedRow = response.data[i];\n\t\t\t\tconst originalRow = table.data[i];\n\t\t\t\tif (!insertedRow) continue;\n\t\t\t\tif (typeof insertedRow.id !== \"number\") continue;\n\n\t\t\t\tlet mappedFromInsertedRefs = false;\n\n\t\t\t\tif (\n\t\t\t\t\t\"parent_id_ref\" in insertedRow &&\n\t\t\t\t\ttypeof insertedRow.parent_id_ref === \"number\" &&\n\t\t\t\t\tinsertedRow.parent_id_ref < 0 &&\n\t\t\t\t\tisTreeTableInsert\n\t\t\t\t) {\n\t\t\t\t\tidMapping[insertedRow.parent_id_ref] = insertedRow.id;\n\t\t\t\t\tmappedFromInsertedRefs = true;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\t\"brick_id_ref\" in insertedRow &&\n\t\t\t\t\ttypeof insertedRow.brick_id_ref === \"number\" &&\n\t\t\t\t\tinsertedRow.brick_id_ref < 0\n\t\t\t\t) {\n\t\t\t\t\tidMapping[insertedRow.brick_id_ref] = insertedRow.id;\n\t\t\t\t\tmappedFromInsertedRefs = true;\n\t\t\t\t}\n\n\t\t\t\tif (mappedFromInsertedRefs || !originalRow) continue;\n\n\t\t\t\tif (\n\t\t\t\t\t\"parent_id_ref\" in originalRow &&\n\t\t\t\t\ttypeof originalRow.parent_id_ref === \"number\" &&\n\t\t\t\t\toriginalRow.parent_id_ref < 0 &&\n\t\t\t\t\tisTreeTableInsert\n\t\t\t\t) {\n\t\t\t\t\tidMapping[originalRow.parent_id_ref] = insertedRow.id;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\t\"brick_id_ref\" in originalRow &&\n\t\t\t\t\ttypeof originalRow.brick_id_ref === \"number\" &&\n\t\t\t\t\toriginalRow.brick_id_ref < 0\n\t\t\t\t) {\n\t\t\t\t\tidMapping[originalRow.brick_id_ref] = insertedRow.id;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\terror: undefined,\n\t\tdata: undefined,\n\t};\n};\n\nexport default insertBrickTables;\n"],"mappings":"sRAgBA,MAAM,EAQF,MAAO,EAAS,IAAS,CAC5B,IAAM,EAAS,IAAI,EAClB,EAAQ,GAAG,OACX,EAAQ,OAAO,EAChB,EAEM,EAAoC,CAAC,EAErC,EAAuB,MAAM,EAClC,EACA,EAAK,WAAW,GACjB,EACA,GAAI,EAAqB,MAAO,OAAO,EAEvC,IAAK,IAAM,KAAS,EAAK,OAAQ,CAChC,GAAI,EAAM,KAAK,SAAW,EACzB,SAID,IAAK,IAAM,KAAO,EAAM,KAAM,CAE7B,GACC,kBAAmB,GACnB,OAAO,EAAI,eAAkB,UAC7B,EAAI,cAAgB,EACnB,CAED,IAAM,EAAW,EAAU,EAAI,eAC3B,EAAU,EAAI,UAAY,EAG7B,cAAe,GACf,OAAO,EAAI,WAAc,UACzB,EAAI,UAAY,GAChB,EAAU,EAAI,aAEd,EAAI,UAAY,EAAU,EAAI,WAEhC,CAGA,GACC,cAAe,GACf,OAAO,EAAI,WAAc,UACzB,EAAI,UAAY,EACf,CACD,IAAM,EAAW,EAAU,EAAI,WAC3B,IAAU,EAAI,UAAY,EAC/B,CAGA,GACC,aAAc,GACd,OAAO,EAAI,UAAa,UACxB,EAAI,SAAW,EACd,CAED,IAAM,EAAgB,EAAU,EAAI,UAChC,IAAe,EAAI,SAAW,EACnC,CACD,CAGA,IAAM,EAAiB,EAAM,KAAK,KAAM,GAAQ,kBAAmB,CAAG,EAChE,EAAgB,EAAM,KAAK,KAAM,GAAQ,iBAAkB,CAAG,EAC9D,EAAkD,CAAC,EAEzD,EAAiB,KAAK,IAAI,EAEtB,GAAgB,EAAiB,KAAK,eAAe,EACrD,GAAe,EAAiB,KAAK,cAAc,EAEvD,IAAM,EAAS,EAAqB,KAAK,KACvC,GAAM,EAAE,OAAS,EAAM,KACzB,EACM,EAAsB,EACzB,EAAuB,EAAO,IAAI,EAClC,KACG,EACL,IAAwB,MACxB,EAAc,EAAqB,YAAY,EAG1C,EAAW,MAAM,EAAO,eAC7B,CACC,KAAM,EAAM,KACZ,UAAW,CACZ,EACA,CACC,UAAW,EAAM,MACjB,QACC,GAAQ,QAAQ,QACd,EAAQ,KACR,EAAO,EAAO,MAAQ,EAAO,KACtB,GAER,CAAC,CACF,GAAK,CAAC,CACR,CACD,EACA,GAAI,EAAS,MAAO,OAAO,EAK3B,GAAI,EAAS,MAAM,OAClB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAS,KAAK,OAAQ,IAAK,CAC9C,IAAM,EAAc,EAAS,KAAK,GAC5B,EAAc,EAAM,KAAK,GAE/B,GADI,CAAC,GACD,OAAO,EAAY,IAAO,SAAU,SAExC,IAAI,EAAyB,GAG5B,kBAAmB,GACnB,OAAO,EAAY,eAAkB,UACrC,EAAY,cAAgB,GAC5B,IAEA,EAAU,EAAY,eAAiB,EAAY,GACnD,EAAyB,IAIzB,iBAAkB,GAClB,OAAO,EAAY,cAAiB,UACpC,EAAY,aAAe,IAE3B,EAAU,EAAY,cAAgB,EAAY,GAClD,EAAyB,IAGtB,KAA0B,CAAC,KAG9B,kBAAmB,GACnB,OAAO,EAAY,eAAkB,UACrC,EAAY,cAAgB,GAC5B,IAEA,EAAU,EAAY,eAAiB,EAAY,IAInD,iBAAkB,GAClB,OAAO,EAAY,cAAiB,UACpC,EAAY,aAAe,IAE3B,EAAU,EAAY,cAAgB,EAAY,IAEpD,CAEF,CAEA,MAAO,CACN,MAAO,IAAA,GACP,KAAM,IAAA,EACP,CACD"}