{"version":3,"file":"metadata.mjs","sources":["../../src/metadata/metadata.ts"],"sourcesContent":["import { cloneDeep, snakeCase } from 'lodash/fp';\nimport { identifiers } from '../utils/identifiers';\nimport * as types from '../utils/types';\nimport { createRelation } from './relations';\nimport type { Attribute, Model } from '../types';\nimport type { ForeignKey, Index } from '../schema/types';\nimport type { Action, SubscriberFn } from '../lifecycles';\n\nexport interface Meta extends Model {\n  columnToAttribute: Record<string, string>;\n  indexes: Index[];\n  foreignKeys: ForeignKey[];\n  lifecycles: Partial<Record<Action, SubscriberFn>>;\n}\n\nexport class Metadata extends Map<string, Meta> {\n  // TODO: we expose the global identifiers in this way so that in the future we can instantiate our own\n  // However, it should NOT be done until all the methods used by metadata can be part of this metadata object\n  // and access this one; currently they all access the global identifiers directly.\n  get identifiers() {\n    return identifiers;\n  }\n\n  get(key: string): Meta {\n    if (!super.has(key)) {\n      throw new Error(`Metadata for \"${key}\" not found`);\n    }\n\n    return super.get(key) as Meta;\n  }\n\n  add(meta: Meta) {\n    return this.set(meta.uid, meta);\n  }\n\n  /**\n   * Validate the DB metadata, throwing an error if a duplicate DB table name is detected\n   */\n  validate() {\n    const seenTables = new Map();\n    for (const meta of this.values()) {\n      if (seenTables.get(meta.tableName)) {\n        throw new Error(\n          `DB table \"${meta.tableName}\" already exists. Change the collectionName of the related content type.`\n        );\n      }\n      seenTables.set(meta.tableName, true);\n    }\n  }\n\n  loadModels(models: Model[]) {\n    // init pass\n    for (const model of cloneDeep(models ?? [])) {\n      const tableName = identifiers.getTableName(model.tableName);\n      this.add({\n        ...model,\n        tableName,\n        attributes: {\n          ...model.attributes,\n        },\n        lifecycles: model.lifecycles ?? {},\n        indexes: model.indexes ?? [],\n        foreignKeys: model.foreignKeys ?? [],\n        columnToAttribute: {},\n      });\n    }\n\n    // build compos / relations\n    for (const meta of this.values()) {\n      for (const [attributeName, attribute] of Object.entries(meta.attributes)) {\n        try {\n          if (attribute.unstable_virtual) {\n            continue;\n          }\n\n          if (types.isRelationalAttribute(attribute)) {\n            createRelation(attributeName, attribute, meta, this);\n            continue;\n          }\n\n          createAttribute(attributeName, attribute);\n        } catch (error) {\n          if (error instanceof Error) {\n            throw new Error(\n              `Error on attribute ${attributeName} in model ${meta.singularName}(${meta.uid}): ${error.message}`\n            );\n          }\n        }\n      }\n    }\n\n    for (const meta of this.values()) {\n      const columnToAttribute = Object.keys(meta.attributes).reduce((acc, key) => {\n        const attribute = meta.attributes[key];\n        if ('columnName' in attribute) {\n          return Object.assign(acc, { [attribute.columnName || key]: key });\n        }\n\n        return Object.assign(acc, { [key]: key });\n      }, {});\n\n      meta.columnToAttribute = columnToAttribute;\n    }\n\n    this.validate();\n  }\n}\n\nconst createAttribute = (attributeName: string, attribute: Attribute) => {\n  // if the attribute has already set its own column name, use that\n  // this will prevent us from shortening a name twice\n  if ('columnName' in attribute && attribute.columnName) {\n    return;\n  }\n\n  const columnName = identifiers.getColumnName(snakeCase(attributeName));\n\n  Object.assign(attribute, { columnName });\n};\n"],"names":["Metadata","Map","identifiers","get","key","has","Error","add","meta","set","uid","validate","seenTables","values","tableName","loadModels","models","model","cloneDeep","getTableName","attributes","lifecycles","indexes","foreignKeys","columnToAttribute","attributeName","attribute","Object","entries","unstable_virtual","types","createRelation","createAttribute","error","singularName","message","keys","reduce","acc","assign","columnName","getColumnName","snakeCase"],"mappings":"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"}