@autofleet/sadot 1.5.1 → 1.5.2-beta-2cd7f45c.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/models/index.cjs +1 -1
- package/dist/models/index.cjs.map +1 -1
- package/dist/models/index.js +1 -1
- package/dist/models/index.js.map +1 -1
- package/dist/scopes/helpers/filter.helpers.cjs +3 -5
- package/dist/scopes/helpers/filter.helpers.cjs.map +1 -1
- package/dist/scopes/helpers/filter.helpers.js +3 -5
- package/dist/scopes/helpers/filter.helpers.js.map +1 -1
- package/package.json +3 -3
package/dist/models/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require(`../_virtual/rolldown_runtime.cjs`),t=require(`../utils/logger/index.cjs`),n=require(`./CustomFieldValue.cjs`),r=require(`./CustomFieldDefinition.cjs`),i=require(`./tests/AssociatedTestModel.cjs`),a=require(`./tests/TestModel.cjs`),o=require(`./tests/contextAwareModels/ContextTestModel.cjs`),s=require(`./tests/contextAwareModels/ContextAwareTestModel.cjs`),c=require(`./CustomFieldEntries.cjs`),l=require(`./CustomValidator.cjs`),u=require(`./CustomFieldModelTypeMap.cjs`);let d=require(`sequelize`);const f=[a.default,i.default,s.default,o.default],p=`sadot-migration`,m=`5f8e4a7c-9b2d-4e1f-8c3a-b6d9e2f7a4c1`,h=async(e,i,{schemaPrefix:a=`sadot-migration`,schemaVersion:o=`5f8e4a7c-9b2d-4e1f-8c3a-b6d9e2f7a4c1`,useCustomFieldsEntries:s=!1,useModelTypeMapping:f=!1,isMatPathEnabled:p}={})=>{let m=`${a}_${o}${s?`_withEntries`:``}${f?`_withTypeMapping`:``}`;if(t.default.info(`custom-fields: initialize custom-fields tables`),!e.addModels)throw Error(`sequelize instance must have addModels function`);let h=[r.default,n.default,l.default,...s?[c.default]:[],...f?[u.default]:[]];e.addModels(h),f&&(r.default.hasMany(u.default,{foreignKey:`customFieldDefinitionId`,as:`modelTypeMappings`}),u.default.belongsTo(r.default,{foreignKey:`customFieldDefinitionId`,as:`customFieldDefinition`})),r.default.addScope(`userScope`,()=>{if(p?.())return{};let e=i();return e?.permissions?{where:{entityId:[...Object.keys(e.permissions.fleets),...Object.keys(e.permissions.businessModels),...Object.keys(e.permissions.demandSources)]}}:{}}),l.default.addScope(`userScope`,()=>{if(p?.())return{};let e=i();return e?.permissions?{where:{entityId:[...Object.keys(e.permissions.fleets),...Object.keys(e.permissions.businessModels),...Object.keys(e.permissions.demandSources)]}}:{}}),t.default.info(`custom-fields: models added`);let g=e.define(`SequelizeMeta`,{name:{type:d.DataTypes.STRING,allowNull:!1,unique:!0,primaryKey:!0,autoIncrement:!1}},{tableName:`SequelizeMeta`,timestamps:!1,schema:`public`});t.default.info(`custom-fields: starting migrations`);let
|
|
1
|
+
const e=require(`../_virtual/rolldown_runtime.cjs`),t=require(`../utils/logger/index.cjs`),n=require(`./CustomFieldValue.cjs`),r=require(`./CustomFieldDefinition.cjs`),i=require(`./tests/AssociatedTestModel.cjs`),a=require(`./tests/TestModel.cjs`),o=require(`./tests/contextAwareModels/ContextTestModel.cjs`),s=require(`./tests/contextAwareModels/ContextAwareTestModel.cjs`),c=require(`./CustomFieldEntries.cjs`),l=require(`./CustomValidator.cjs`),u=require(`./CustomFieldModelTypeMap.cjs`);let d=require(`sequelize`);const f=[a.default,i.default,s.default,o.default],p=`sadot-migration`,m=`5f8e4a7c-9b2d-4e1f-8c3a-b6d9e2f7a4c1`,h=5948077501984310073n,g=async(e,i,{schemaPrefix:a=`sadot-migration`,schemaVersion:o=`5f8e4a7c-9b2d-4e1f-8c3a-b6d9e2f7a4c1`,useCustomFieldsEntries:s=!1,useModelTypeMapping:f=!1,isMatPathEnabled:p}={})=>{let m=`${a}_${o}${s?`_withEntries`:``}${f?`_withTypeMapping`:``}`;if(t.default.info(`custom-fields: initialize custom-fields tables`),!e.addModels)throw Error(`sequelize instance must have addModels function`);let h=[r.default,n.default,l.default,...s?[c.default]:[],...f?[u.default]:[]];e.addModels(h),f&&(r.default.hasMany(u.default,{foreignKey:`customFieldDefinitionId`,as:`modelTypeMappings`}),u.default.belongsTo(r.default,{foreignKey:`customFieldDefinitionId`,as:`customFieldDefinition`})),r.default.addScope(`userScope`,()=>{if(p?.())return{};let e=i();return e?.permissions?{where:{entityId:[...Object.keys(e.permissions.fleets),...Object.keys(e.permissions.businessModels),...Object.keys(e.permissions.demandSources)]}}:{}}),l.default.addScope(`userScope`,()=>{if(p?.())return{};let e=i();return e?.permissions?{where:{entityId:[...Object.keys(e.permissions.fleets),...Object.keys(e.permissions.businessModels),...Object.keys(e.permissions.demandSources)]}}:{}}),t.default.info(`custom-fields: models added`);let g=e.define(`SequelizeMeta`,{name:{type:d.DataTypes.STRING,allowNull:!1,unique:!0,primaryKey:!0,autoIncrement:!1}},{tableName:`SequelizeMeta`,timestamps:!1,schema:`public`});t.default.info(`custom-fields: starting migrations`),await e.transaction(async i=>{await e.query(`SELECT pg_advisory_xact_lock(5948077501984310073)`,{transaction:i});let o=await g.findAll({where:{name:{[d.Op.like]:`${a}%`}},raw:!0,transaction:i}),p=o.at(-1),h=o.findIndex(e=>e.name===m);if(t.default.info(`custom-fields: migrations`,{currentMigrations:o,currentSadotSchemaVersion:p,newSadotSchemaVersion:m,expectedSchemaVersionIndex:h}),!p||p.name!==m){t.default.info(`custom-fields: syncing models`);let e={alter:!0,transaction:i};try{if(await r.default.sync(e),t.default.info(`custom-fields: CustomFieldDefinition synced successfully`),await n.default.sync(e),t.default.info(`custom-fields: CustomFieldValue synced successfully`),await l.default.sync(e),t.default.info(`custom-fields: CustomValidator synced successfully`),s&&(await c.default.sync(e),t.default.info(`custom-fields: CustomFieldEntries synced successfully`)),f&&(await u.default.sync(e),t.default.info(`custom-fields: CustomFieldModelTypeMap synced successfully`)),h===-1&&(await g.create({name:m},{transaction:i}),t.default.info(`custom-fields: SequelizeMeta entry created successfully`)),t.default.info(`custom-fields: models synced`),o.length&&h!==-1&&h<o.length-1){let e=o.slice(h+1);t.default.info(`custom-fields: deleting newer migrations during down migration`,{count:e.length}),await g.destroy({where:{name:{[d.Op.in]:e.map(e=>e.name)}},transaction:i}),t.default.info(`custom-fields: newer migrations deleted successfully`)}}catch(e){throw t.default.error(`custom-fields: failed to sync models`,{error:e}),e}}})},_=async e=>{if(t.default.info(`custom-fields: initialize custom-fields test models`),!e.addModels)throw Error(`sequelize instance must have addModels function`);e.addModels(f),await e.dropSchema(`custom-fields`,{logging:!1}),await e.createSchema(`custom-fields`,{logging:!1}),t.default.info(`custom-fields: test models added`),await a.default.sync({alter:!0}),await i.default.sync({alter:!0}),await o.default.sync({alter:!0}),await s.default.sync({alter:!0}),t.default.info(`custom-fields: test models synced`)};exports.initTables=g,exports.initTestModels=_;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["TestModel","AssociatedTestModel","ContextAwareTestModel","ContextTestModel","sequelize","productionModels: ProductionModel[]","CustomFieldDefinition","CustomFieldValue","CustomValidator","CustomFieldEntries","CustomFieldModelTypeMap","DataTypes","Op"],"sources":["../../src/models/index.ts"],"sourcesContent":["import { DataTypes, Op } from 'sequelize';\nimport type { Sequelize } from 'sequelize-typescript';\nimport logger from '../utils/logger';\nimport CustomFieldDefinition from './CustomFieldDefinition';\nimport CustomFieldValue from './CustomFieldValue';\nimport TestModel from './tests/TestModel';\nimport ContextAwareTestModel from './tests/contextAwareModels/ContextAwareTestModel';\nimport ContextTestModel from './tests/contextAwareModels/ContextTestModel';\nimport AssociatedTestModel from './tests/AssociatedTestModel';\nimport type { CustomFieldOptions } from '../types';\nimport CustomFieldEntries from './CustomFieldEntries';\nimport CustomValidator from './CustomValidator';\nimport CustomFieldModelTypeMap from './CustomFieldModelTypeMap';\n\ntype ProductionModel = typeof CustomFieldDefinition | typeof CustomFieldValue | typeof CustomFieldEntries | typeof CustomValidator | typeof CustomFieldModelTypeMap;\ninterface InitTablesOptions {\n schemaPrefix?: string;\n schemaVersion?: string;\n useCustomFieldsEntries?: boolean;\n useModelTypeMapping?: boolean;\n isMatPathEnabled?: CustomFieldOptions['isMatPathEnabled'];\n}\n\nconst testModels = [TestModel, AssociatedTestModel, ContextAwareTestModel, ContextTestModel];\n\nconst SADOT_MIGRATION_PREFIX = 'sadot-migration';\nconst SCHEMA_VERSION = '5f8e4a7c-9b2d-4e1f-8c3a-b6d9e2f7a4c1';\n\nconst initTables = async (\n sequelize: Sequelize,\n getUser: CustomFieldOptions['getUser'],\n {\n schemaPrefix = SADOT_MIGRATION_PREFIX,\n schemaVersion = SCHEMA_VERSION,\n useCustomFieldsEntries = false,\n useModelTypeMapping = false,\n isMatPathEnabled,\n }: InitTablesOptions = {},\n): Promise<void> => {\n const CUSTOM_FIELDS_SCHEMA_VERSION = `${schemaPrefix}_${schemaVersion}${useCustomFieldsEntries ? '_withEntries' : ''}${useModelTypeMapping ? '_withTypeMapping' : ''}`;\n logger.info('custom-fields: initialize custom-fields tables');\n // Detect models and import them to the orm\n if (!sequelize.addModels) {\n throw new Error('sequelize instance must have addModels function');\n }\n const productionModels: ProductionModel[] = [\n CustomFieldDefinition,\n CustomFieldValue,\n CustomValidator,\n ...(useCustomFieldsEntries ? [CustomFieldEntries] : []),\n ...(useModelTypeMapping ? [CustomFieldModelTypeMap] : []),\n ];\n\n sequelize.addModels(productionModels);\n\n // Add the association only when useModelTypeMapping is enabled\n if (useModelTypeMapping) {\n CustomFieldDefinition.hasMany(CustomFieldModelTypeMap, {\n foreignKey: 'customFieldDefinitionId',\n as: 'modelTypeMappings',\n });\n CustomFieldModelTypeMap.belongsTo(CustomFieldDefinition, {\n foreignKey: 'customFieldDefinitionId',\n as: 'customFieldDefinition',\n });\n }\n\n CustomFieldDefinition.addScope('userScope', () => {\n // When mat-path is active, the consumer is responsible for restricting entityIds\n // (typically by expanding the request's entityIds to include ancestor paths the\n // caller can see). Bypass the legacy permission filter so partner/ancestor\n // entityIds are not dropped.\n if (isMatPathEnabled?.()) return {};\n const user = getUser();\n if (!user?.permissions) {\n return {};\n }\n return {\n where: {\n entityId: [\n ...Object.keys(user.permissions.fleets),\n ...Object.keys(user.permissions.businessModels),\n ...Object.keys(user.permissions.demandSources),\n ],\n },\n };\n });\n\n CustomValidator.addScope('userScope', () => {\n if (isMatPathEnabled?.()) return {};\n const user = getUser();\n if (!user?.permissions) {\n return {};\n }\n return {\n where: {\n entityId: [\n ...Object.keys(user.permissions.fleets),\n ...Object.keys(user.permissions.businessModels),\n ...Object.keys(user.permissions.demandSources),\n ],\n },\n };\n });\n\n logger.info('custom-fields: models added');\n\n const SequelizeMeta = sequelize.define(\n 'SequelizeMeta',\n {\n name: {\n type: DataTypes.STRING,\n allowNull: false,\n unique: true,\n primaryKey: true,\n autoIncrement: false,\n },\n },\n {\n tableName: 'SequelizeMeta',\n timestamps: false,\n schema: 'public',\n },\n );\n\n logger.info('custom-fields: starting migrations');\n const migrations = await SequelizeMeta.findAll({ where: { name: { [Op.like]: `${schemaPrefix}%` } }, raw: true });\n const currentSadotSchemaVersion = migrations.at(-1);\n const expectedSchemaVersionIndex = migrations.findIndex(m => (m as any).name === CUSTOM_FIELDS_SCHEMA_VERSION);\n\n logger.info('custom-fields: migrations', {\n currentMigrations: migrations,\n currentSadotSchemaVersion,\n newSadotSchemaVersion: CUSTOM_FIELDS_SCHEMA_VERSION,\n expectedSchemaVersionIndex,\n });\n if (!currentSadotSchemaVersion || (currentSadotSchemaVersion as any).name !== CUSTOM_FIELDS_SCHEMA_VERSION) {\n logger.info('custom-fields: syncing models');\n try {\n await CustomFieldDefinition.sync({ alter: true });\n logger.info('custom-fields: CustomFieldDefinition synced successfully');\n\n await CustomFieldValue.sync({ alter: true });\n logger.info('custom-fields: CustomFieldValue synced successfully');\n\n await CustomValidator.sync({ alter: true });\n logger.info('custom-fields: CustomValidator synced successfully');\n\n // T.Y TODO: Remove the if statement once we're ready to add the new entries table for all MS\n if (useCustomFieldsEntries) {\n await CustomFieldEntries.sync({ alter: true });\n logger.info('custom-fields: CustomFieldEntries synced successfully');\n }\n\n if (useModelTypeMapping) {\n await CustomFieldModelTypeMap.sync({ alter: true });\n logger.info('custom-fields: CustomFieldModelTypeMap synced successfully');\n }\n\n if (expectedSchemaVersionIndex === -1) {\n await SequelizeMeta.create({ name: CUSTOM_FIELDS_SCHEMA_VERSION });\n logger.info('custom-fields: SequelizeMeta entry created successfully');\n }\n\n logger.info('custom-fields: models synced');\n if (migrations.length && expectedSchemaVersionIndex !== -1 && expectedSchemaVersionIndex < migrations.length - 1) {\n // We have existing migrations, and we are calling `sync`.\n // This means we are in a `down` migration, and hence we should delete newer migrations to ensure we can reapply them.\n const migrationsToDelete = migrations.slice(expectedSchemaVersionIndex + 1);\n logger.info('custom-fields: deleting newer migrations during down migration', { count: migrationsToDelete.length });\n await SequelizeMeta.destroy({ where: { name: { [Op.in]: migrationsToDelete.map(m => (m as any).name) } } });\n logger.info('custom-fields: newer migrations deleted successfully');\n }\n } catch (error) {\n logger.error('custom-fields: failed to sync models', { error });\n throw error;\n }\n }\n};\n\nconst initTestModels = async (sequelize: Sequelize): Promise<void> => {\n logger.info('custom-fields: initialize custom-fields test models');\n // Detect models and import them to the orm\n if (!sequelize.addModels) {\n throw new Error('sequelize instance must have addModels function');\n }\n\n sequelize.addModels(testModels);\n await sequelize.dropSchema('custom-fields', { logging: false });\n await sequelize.createSchema('custom-fields', { logging: false });\n\n logger.info('custom-fields: test models added');\n await TestModel.sync({ alter: true });\n await AssociatedTestModel.sync({ alter: true });\n await ContextTestModel.sync({ alter: true });\n await ContextAwareTestModel.sync({ alter: true });\n logger.info('custom-fields: test models synced');\n};\n\nexport {\n CustomFieldValue,\n CustomFieldDefinition,\n CustomFieldEntries,\n CustomValidator,\n CustomFieldModelTypeMap,\n TestModel,\n AssociatedTestModel,\n ContextAwareTestModel,\n ContextTestModel,\n initTables,\n initTestModels,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["TestModel","AssociatedTestModel","ContextAwareTestModel","ContextTestModel","sequelize","productionModels: ProductionModel[]","CustomFieldDefinition","CustomFieldValue","CustomValidator","CustomFieldEntries","CustomFieldModelTypeMap","DataTypes","Op"],"sources":["../../src/models/index.ts"],"sourcesContent":["import { DataTypes, Op } from 'sequelize';\nimport type { Sequelize } from 'sequelize-typescript';\nimport logger from '../utils/logger';\nimport CustomFieldDefinition from './CustomFieldDefinition';\nimport CustomFieldValue from './CustomFieldValue';\nimport TestModel from './tests/TestModel';\nimport ContextAwareTestModel from './tests/contextAwareModels/ContextAwareTestModel';\nimport ContextTestModel from './tests/contextAwareModels/ContextTestModel';\nimport AssociatedTestModel from './tests/AssociatedTestModel';\nimport type { CustomFieldOptions } from '../types';\nimport CustomFieldEntries from './CustomFieldEntries';\nimport CustomValidator from './CustomValidator';\nimport CustomFieldModelTypeMap from './CustomFieldModelTypeMap';\n\ntype ProductionModel = typeof CustomFieldDefinition | typeof CustomFieldValue | typeof CustomFieldEntries | typeof CustomValidator | typeof CustomFieldModelTypeMap;\ninterface InitTablesOptions {\n schemaPrefix?: string;\n schemaVersion?: string;\n useCustomFieldsEntries?: boolean;\n useModelTypeMapping?: boolean;\n isMatPathEnabled?: CustomFieldOptions['isMatPathEnabled'];\n}\n\nconst testModels = [TestModel, AssociatedTestModel, ContextAwareTestModel, ContextTestModel];\n\nconst SADOT_MIGRATION_PREFIX = 'sadot-migration';\nconst SCHEMA_VERSION = '5f8e4a7c-9b2d-4e1f-8c3a-b6d9e2f7a4c1';\n// Arbitrary stable bigint used as a Postgres advisory-lock key for sadot init.\n// Picked once and never changes; uniqueness only matters within the sadot codebase.\nconst SADOT_INIT_ADVISORY_LOCK_KEY = 5_948_077_501_984_310_073n;\n\nconst initTables = async (\n sequelize: Sequelize,\n getUser: CustomFieldOptions['getUser'],\n {\n schemaPrefix = SADOT_MIGRATION_PREFIX,\n schemaVersion = SCHEMA_VERSION,\n useCustomFieldsEntries = false,\n useModelTypeMapping = false,\n isMatPathEnabled,\n }: InitTablesOptions = {},\n): Promise<void> => {\n const CUSTOM_FIELDS_SCHEMA_VERSION = `${schemaPrefix}_${schemaVersion}${useCustomFieldsEntries ? '_withEntries' : ''}${useModelTypeMapping ? '_withTypeMapping' : ''}`;\n logger.info('custom-fields: initialize custom-fields tables');\n // Detect models and import them to the orm\n if (!sequelize.addModels) {\n throw new Error('sequelize instance must have addModels function');\n }\n const productionModels: ProductionModel[] = [\n CustomFieldDefinition,\n CustomFieldValue,\n CustomValidator,\n ...(useCustomFieldsEntries ? [CustomFieldEntries] : []),\n ...(useModelTypeMapping ? [CustomFieldModelTypeMap] : []),\n ];\n\n sequelize.addModels(productionModels);\n\n // Add the association only when useModelTypeMapping is enabled\n if (useModelTypeMapping) {\n CustomFieldDefinition.hasMany(CustomFieldModelTypeMap, {\n foreignKey: 'customFieldDefinitionId',\n as: 'modelTypeMappings',\n });\n CustomFieldModelTypeMap.belongsTo(CustomFieldDefinition, {\n foreignKey: 'customFieldDefinitionId',\n as: 'customFieldDefinition',\n });\n }\n\n CustomFieldDefinition.addScope('userScope', () => {\n // When mat-path is active, the consumer is responsible for restricting entityIds\n // (typically by expanding the request's entityIds to include ancestor paths the\n // caller can see). Bypass the legacy permission filter so partner/ancestor\n // entityIds are not dropped.\n if (isMatPathEnabled?.()) return {};\n const user = getUser();\n if (!user?.permissions) {\n return {};\n }\n return {\n where: {\n entityId: [\n ...Object.keys(user.permissions.fleets),\n ...Object.keys(user.permissions.businessModels),\n ...Object.keys(user.permissions.demandSources),\n ],\n },\n };\n });\n\n CustomValidator.addScope('userScope', () => {\n if (isMatPathEnabled?.()) return {};\n const user = getUser();\n if (!user?.permissions) {\n return {};\n }\n return {\n where: {\n entityId: [\n ...Object.keys(user.permissions.fleets),\n ...Object.keys(user.permissions.businessModels),\n ...Object.keys(user.permissions.demandSources),\n ],\n },\n };\n });\n\n logger.info('custom-fields: models added');\n\n const SequelizeMeta = sequelize.define(\n 'SequelizeMeta',\n {\n name: {\n type: DataTypes.STRING,\n allowNull: false,\n unique: true,\n primaryKey: true,\n autoIncrement: false,\n },\n },\n {\n tableName: 'SequelizeMeta',\n timestamps: false,\n schema: 'public',\n },\n );\n\n logger.info('custom-fields: starting migrations');\n // Serialize init across concurrent pods: multiple `sync({ alter: true })` calls\n // racing each other can deadlock against read traffic that needs AccessShareLock\n // on the same tables (Postgres error 40P01). One pod runs sync, the rest wait.\n // Use a transaction-scoped advisory lock so it auto-releases on commit/rollback\n // and is guaranteed to share a connection with the work below.\n await sequelize.transaction(async (transaction) => {\n await sequelize.query(`SELECT pg_advisory_xact_lock(${SADOT_INIT_ADVISORY_LOCK_KEY})`, { transaction });\n\n const migrations = await SequelizeMeta.findAll({ where: { name: { [Op.like]: `${schemaPrefix}%` } }, raw: true, transaction });\n const currentSadotSchemaVersion = migrations.at(-1);\n const expectedSchemaVersionIndex = migrations.findIndex(m => (m as any).name === CUSTOM_FIELDS_SCHEMA_VERSION);\n\n logger.info('custom-fields: migrations', {\n currentMigrations: migrations,\n currentSadotSchemaVersion,\n newSadotSchemaVersion: CUSTOM_FIELDS_SCHEMA_VERSION,\n expectedSchemaVersionIndex,\n });\n if (!currentSadotSchemaVersion || (currentSadotSchemaVersion as any).name !== CUSTOM_FIELDS_SCHEMA_VERSION) {\n logger.info('custom-fields: syncing models');\n // sequelize's SyncOptions type omits `transaction`, but the runtime accepts and uses it\n // to bind the DDL to our advisory-lock transaction.\n const syncOptions = { alter: true, transaction } as Parameters<typeof CustomFieldDefinition.sync>[0];\n try {\n await CustomFieldDefinition.sync(syncOptions);\n logger.info('custom-fields: CustomFieldDefinition synced successfully');\n\n await CustomFieldValue.sync(syncOptions);\n logger.info('custom-fields: CustomFieldValue synced successfully');\n\n await CustomValidator.sync(syncOptions);\n logger.info('custom-fields: CustomValidator synced successfully');\n\n // T.Y TODO: Remove the if statement once we're ready to add the new entries table for all MS\n if (useCustomFieldsEntries) {\n await CustomFieldEntries.sync(syncOptions);\n logger.info('custom-fields: CustomFieldEntries synced successfully');\n }\n\n if (useModelTypeMapping) {\n await CustomFieldModelTypeMap.sync(syncOptions);\n logger.info('custom-fields: CustomFieldModelTypeMap synced successfully');\n }\n\n if (expectedSchemaVersionIndex === -1) {\n await SequelizeMeta.create({ name: CUSTOM_FIELDS_SCHEMA_VERSION }, { transaction });\n logger.info('custom-fields: SequelizeMeta entry created successfully');\n }\n\n logger.info('custom-fields: models synced');\n if (migrations.length && expectedSchemaVersionIndex !== -1 && expectedSchemaVersionIndex < migrations.length - 1) {\n // We have existing migrations, and we are calling `sync`.\n // This means we are in a `down` migration, and hence we should delete newer migrations to ensure we can reapply them.\n const migrationsToDelete = migrations.slice(expectedSchemaVersionIndex + 1);\n logger.info('custom-fields: deleting newer migrations during down migration', { count: migrationsToDelete.length });\n await SequelizeMeta.destroy({ where: { name: { [Op.in]: migrationsToDelete.map(m => (m as any).name) } }, transaction });\n logger.info('custom-fields: newer migrations deleted successfully');\n }\n } catch (error) {\n logger.error('custom-fields: failed to sync models', { error });\n throw error;\n }\n }\n });\n};\n\nconst initTestModels = async (sequelize: Sequelize): Promise<void> => {\n logger.info('custom-fields: initialize custom-fields test models');\n // Detect models and import them to the orm\n if (!sequelize.addModels) {\n throw new Error('sequelize instance must have addModels function');\n }\n\n sequelize.addModels(testModels);\n await sequelize.dropSchema('custom-fields', { logging: false });\n await sequelize.createSchema('custom-fields', { logging: false });\n\n logger.info('custom-fields: test models added');\n await TestModel.sync({ alter: true });\n await AssociatedTestModel.sync({ alter: true });\n await ContextTestModel.sync({ alter: true });\n await ContextAwareTestModel.sync({ alter: true });\n logger.info('custom-fields: test models synced');\n};\n\nexport {\n CustomFieldValue,\n CustomFieldDefinition,\n CustomFieldEntries,\n CustomValidator,\n CustomFieldModelTypeMap,\n TestModel,\n AssociatedTestModel,\n ContextAwareTestModel,\n ContextTestModel,\n initTables,\n initTestModels,\n};\n"],"mappings":"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"}
|
package/dist/models/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e from"../utils/logger/index.js";import t from"./CustomFieldValue.js";import n from"./CustomFieldDefinition.js";import r from"./tests/AssociatedTestModel.js";import i from"./tests/TestModel.js";import a from"./tests/contextAwareModels/ContextTestModel.js";import o from"./tests/contextAwareModels/ContextAwareTestModel.js";import s from"./CustomFieldEntries.js";import c from"./CustomValidator.js";import l from"./CustomFieldModelTypeMap.js";import{DataTypes as u,Op as d}from"sequelize";const f=[i,r,o,a],p=async(r,i,{schemaPrefix:a=`sadot-migration`,schemaVersion:o=`5f8e4a7c-9b2d-4e1f-8c3a-b6d9e2f7a4c1`,useCustomFieldsEntries:f=!1,useModelTypeMapping:p=!1,isMatPathEnabled:m}={})=>{let h=`${a}_${o}${f?`_withEntries`:``}${p?`_withTypeMapping`:``}`;if(e.info(`custom-fields: initialize custom-fields tables`),!r.addModels)throw Error(`sequelize instance must have addModels function`);let g=[n,t,c,...f?[s]:[],...p?[l]:[]];r.addModels(g),p&&(n.hasMany(l,{foreignKey:`customFieldDefinitionId`,as:`modelTypeMappings`}),l.belongsTo(n,{foreignKey:`customFieldDefinitionId`,as:`customFieldDefinition`})),n.addScope(`userScope`,()=>{if(m?.())return{};let e=i();return e?.permissions?{where:{entityId:[...Object.keys(e.permissions.fleets),...Object.keys(e.permissions.businessModels),...Object.keys(e.permissions.demandSources)]}}:{}}),c.addScope(`userScope`,()=>{if(m?.())return{};let e=i();return e?.permissions?{where:{entityId:[...Object.keys(e.permissions.fleets),...Object.keys(e.permissions.businessModels),...Object.keys(e.permissions.demandSources)]}}:{}}),e.info(`custom-fields: models added`);let _=r.define(`SequelizeMeta`,{name:{type:u.STRING,allowNull:!1,unique:!0,primaryKey:!0,autoIncrement:!1}},{tableName:`SequelizeMeta`,timestamps:!1,schema:`public`});e.info(`custom-fields: starting migrations`);let
|
|
1
|
+
import e from"../utils/logger/index.js";import t from"./CustomFieldValue.js";import n from"./CustomFieldDefinition.js";import r from"./tests/AssociatedTestModel.js";import i from"./tests/TestModel.js";import a from"./tests/contextAwareModels/ContextTestModel.js";import o from"./tests/contextAwareModels/ContextAwareTestModel.js";import s from"./CustomFieldEntries.js";import c from"./CustomValidator.js";import l from"./CustomFieldModelTypeMap.js";import{DataTypes as u,Op as d}from"sequelize";const f=[i,r,o,a],p=async(r,i,{schemaPrefix:a=`sadot-migration`,schemaVersion:o=`5f8e4a7c-9b2d-4e1f-8c3a-b6d9e2f7a4c1`,useCustomFieldsEntries:f=!1,useModelTypeMapping:p=!1,isMatPathEnabled:m}={})=>{let h=`${a}_${o}${f?`_withEntries`:``}${p?`_withTypeMapping`:``}`;if(e.info(`custom-fields: initialize custom-fields tables`),!r.addModels)throw Error(`sequelize instance must have addModels function`);let g=[n,t,c,...f?[s]:[],...p?[l]:[]];r.addModels(g),p&&(n.hasMany(l,{foreignKey:`customFieldDefinitionId`,as:`modelTypeMappings`}),l.belongsTo(n,{foreignKey:`customFieldDefinitionId`,as:`customFieldDefinition`})),n.addScope(`userScope`,()=>{if(m?.())return{};let e=i();return e?.permissions?{where:{entityId:[...Object.keys(e.permissions.fleets),...Object.keys(e.permissions.businessModels),...Object.keys(e.permissions.demandSources)]}}:{}}),c.addScope(`userScope`,()=>{if(m?.())return{};let e=i();return e?.permissions?{where:{entityId:[...Object.keys(e.permissions.fleets),...Object.keys(e.permissions.businessModels),...Object.keys(e.permissions.demandSources)]}}:{}}),e.info(`custom-fields: models added`);let _=r.define(`SequelizeMeta`,{name:{type:u.STRING,allowNull:!1,unique:!0,primaryKey:!0,autoIncrement:!1}},{tableName:`SequelizeMeta`,timestamps:!1,schema:`public`});e.info(`custom-fields: starting migrations`),await r.transaction(async i=>{await r.query(`SELECT pg_advisory_xact_lock(5948077501984310073)`,{transaction:i});let o=await _.findAll({where:{name:{[d.like]:`${a}%`}},raw:!0,transaction:i}),u=o.at(-1),m=o.findIndex(e=>e.name===h);if(e.info(`custom-fields: migrations`,{currentMigrations:o,currentSadotSchemaVersion:u,newSadotSchemaVersion:h,expectedSchemaVersionIndex:m}),!u||u.name!==h){e.info(`custom-fields: syncing models`);let r={alter:!0,transaction:i};try{if(await n.sync(r),e.info(`custom-fields: CustomFieldDefinition synced successfully`),await t.sync(r),e.info(`custom-fields: CustomFieldValue synced successfully`),await c.sync(r),e.info(`custom-fields: CustomValidator synced successfully`),f&&(await s.sync(r),e.info(`custom-fields: CustomFieldEntries synced successfully`)),p&&(await l.sync(r),e.info(`custom-fields: CustomFieldModelTypeMap synced successfully`)),m===-1&&(await _.create({name:h},{transaction:i}),e.info(`custom-fields: SequelizeMeta entry created successfully`)),e.info(`custom-fields: models synced`),o.length&&m!==-1&&m<o.length-1){let t=o.slice(m+1);e.info(`custom-fields: deleting newer migrations during down migration`,{count:t.length}),await _.destroy({where:{name:{[d.in]:t.map(e=>e.name)}},transaction:i}),e.info(`custom-fields: newer migrations deleted successfully`)}}catch(t){throw e.error(`custom-fields: failed to sync models`,{error:t}),t}}})},m=async t=>{if(e.info(`custom-fields: initialize custom-fields test models`),!t.addModels)throw Error(`sequelize instance must have addModels function`);t.addModels(f),await t.dropSchema(`custom-fields`,{logging:!1}),await t.createSchema(`custom-fields`,{logging:!1}),e.info(`custom-fields: test models added`),await i.sync({alter:!0}),await r.sync({alter:!0}),await a.sync({alter:!0}),await o.sync({alter:!0}),e.info(`custom-fields: test models synced`)};export{p as initTables,m as initTestModels};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/models/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["TestModel","AssociatedTestModel","ContextAwareTestModel","ContextTestModel","productionModels: ProductionModel[]","CustomFieldDefinition","CustomFieldValue","CustomValidator","CustomFieldEntries","CustomFieldModelTypeMap"],"sources":["../../src/models/index.ts"],"sourcesContent":["import { DataTypes, Op } from 'sequelize';\nimport type { Sequelize } from 'sequelize-typescript';\nimport logger from '../utils/logger';\nimport CustomFieldDefinition from './CustomFieldDefinition';\nimport CustomFieldValue from './CustomFieldValue';\nimport TestModel from './tests/TestModel';\nimport ContextAwareTestModel from './tests/contextAwareModels/ContextAwareTestModel';\nimport ContextTestModel from './tests/contextAwareModels/ContextTestModel';\nimport AssociatedTestModel from './tests/AssociatedTestModel';\nimport type { CustomFieldOptions } from '../types';\nimport CustomFieldEntries from './CustomFieldEntries';\nimport CustomValidator from './CustomValidator';\nimport CustomFieldModelTypeMap from './CustomFieldModelTypeMap';\n\ntype ProductionModel = typeof CustomFieldDefinition | typeof CustomFieldValue | typeof CustomFieldEntries | typeof CustomValidator | typeof CustomFieldModelTypeMap;\ninterface InitTablesOptions {\n schemaPrefix?: string;\n schemaVersion?: string;\n useCustomFieldsEntries?: boolean;\n useModelTypeMapping?: boolean;\n isMatPathEnabled?: CustomFieldOptions['isMatPathEnabled'];\n}\n\nconst testModels = [TestModel, AssociatedTestModel, ContextAwareTestModel, ContextTestModel];\n\nconst SADOT_MIGRATION_PREFIX = 'sadot-migration';\nconst SCHEMA_VERSION = '5f8e4a7c-9b2d-4e1f-8c3a-b6d9e2f7a4c1';\n\nconst initTables = async (\n sequelize: Sequelize,\n getUser: CustomFieldOptions['getUser'],\n {\n schemaPrefix = SADOT_MIGRATION_PREFIX,\n schemaVersion = SCHEMA_VERSION,\n useCustomFieldsEntries = false,\n useModelTypeMapping = false,\n isMatPathEnabled,\n }: InitTablesOptions = {},\n): Promise<void> => {\n const CUSTOM_FIELDS_SCHEMA_VERSION = `${schemaPrefix}_${schemaVersion}${useCustomFieldsEntries ? '_withEntries' : ''}${useModelTypeMapping ? '_withTypeMapping' : ''}`;\n logger.info('custom-fields: initialize custom-fields tables');\n // Detect models and import them to the orm\n if (!sequelize.addModels) {\n throw new Error('sequelize instance must have addModels function');\n }\n const productionModels: ProductionModel[] = [\n CustomFieldDefinition,\n CustomFieldValue,\n CustomValidator,\n ...(useCustomFieldsEntries ? [CustomFieldEntries] : []),\n ...(useModelTypeMapping ? [CustomFieldModelTypeMap] : []),\n ];\n\n sequelize.addModels(productionModels);\n\n // Add the association only when useModelTypeMapping is enabled\n if (useModelTypeMapping) {\n CustomFieldDefinition.hasMany(CustomFieldModelTypeMap, {\n foreignKey: 'customFieldDefinitionId',\n as: 'modelTypeMappings',\n });\n CustomFieldModelTypeMap.belongsTo(CustomFieldDefinition, {\n foreignKey: 'customFieldDefinitionId',\n as: 'customFieldDefinition',\n });\n }\n\n CustomFieldDefinition.addScope('userScope', () => {\n // When mat-path is active, the consumer is responsible for restricting entityIds\n // (typically by expanding the request's entityIds to include ancestor paths the\n // caller can see). Bypass the legacy permission filter so partner/ancestor\n // entityIds are not dropped.\n if (isMatPathEnabled?.()) return {};\n const user = getUser();\n if (!user?.permissions) {\n return {};\n }\n return {\n where: {\n entityId: [\n ...Object.keys(user.permissions.fleets),\n ...Object.keys(user.permissions.businessModels),\n ...Object.keys(user.permissions.demandSources),\n ],\n },\n };\n });\n\n CustomValidator.addScope('userScope', () => {\n if (isMatPathEnabled?.()) return {};\n const user = getUser();\n if (!user?.permissions) {\n return {};\n }\n return {\n where: {\n entityId: [\n ...Object.keys(user.permissions.fleets),\n ...Object.keys(user.permissions.businessModels),\n ...Object.keys(user.permissions.demandSources),\n ],\n },\n };\n });\n\n logger.info('custom-fields: models added');\n\n const SequelizeMeta = sequelize.define(\n 'SequelizeMeta',\n {\n name: {\n type: DataTypes.STRING,\n allowNull: false,\n unique: true,\n primaryKey: true,\n autoIncrement: false,\n },\n },\n {\n tableName: 'SequelizeMeta',\n timestamps: false,\n schema: 'public',\n },\n );\n\n logger.info('custom-fields: starting migrations');\n const migrations = await SequelizeMeta.findAll({ where: { name: { [Op.like]: `${schemaPrefix}%` } }, raw: true });\n const currentSadotSchemaVersion = migrations.at(-1);\n const expectedSchemaVersionIndex = migrations.findIndex(m => (m as any).name === CUSTOM_FIELDS_SCHEMA_VERSION);\n\n logger.info('custom-fields: migrations', {\n currentMigrations: migrations,\n currentSadotSchemaVersion,\n newSadotSchemaVersion: CUSTOM_FIELDS_SCHEMA_VERSION,\n expectedSchemaVersionIndex,\n });\n if (!currentSadotSchemaVersion || (currentSadotSchemaVersion as any).name !== CUSTOM_FIELDS_SCHEMA_VERSION) {\n logger.info('custom-fields: syncing models');\n try {\n await CustomFieldDefinition.sync({ alter: true });\n logger.info('custom-fields: CustomFieldDefinition synced successfully');\n\n await CustomFieldValue.sync({ alter: true });\n logger.info('custom-fields: CustomFieldValue synced successfully');\n\n await CustomValidator.sync({ alter: true });\n logger.info('custom-fields: CustomValidator synced successfully');\n\n // T.Y TODO: Remove the if statement once we're ready to add the new entries table for all MS\n if (useCustomFieldsEntries) {\n await CustomFieldEntries.sync({ alter: true });\n logger.info('custom-fields: CustomFieldEntries synced successfully');\n }\n\n if (useModelTypeMapping) {\n await CustomFieldModelTypeMap.sync({ alter: true });\n logger.info('custom-fields: CustomFieldModelTypeMap synced successfully');\n }\n\n if (expectedSchemaVersionIndex === -1) {\n await SequelizeMeta.create({ name: CUSTOM_FIELDS_SCHEMA_VERSION });\n logger.info('custom-fields: SequelizeMeta entry created successfully');\n }\n\n logger.info('custom-fields: models synced');\n if (migrations.length && expectedSchemaVersionIndex !== -1 && expectedSchemaVersionIndex < migrations.length - 1) {\n // We have existing migrations, and we are calling `sync`.\n // This means we are in a `down` migration, and hence we should delete newer migrations to ensure we can reapply them.\n const migrationsToDelete = migrations.slice(expectedSchemaVersionIndex + 1);\n logger.info('custom-fields: deleting newer migrations during down migration', { count: migrationsToDelete.length });\n await SequelizeMeta.destroy({ where: { name: { [Op.in]: migrationsToDelete.map(m => (m as any).name) } } });\n logger.info('custom-fields: newer migrations deleted successfully');\n }\n } catch (error) {\n logger.error('custom-fields: failed to sync models', { error });\n throw error;\n }\n }\n};\n\nconst initTestModels = async (sequelize: Sequelize): Promise<void> => {\n logger.info('custom-fields: initialize custom-fields test models');\n // Detect models and import them to the orm\n if (!sequelize.addModels) {\n throw new Error('sequelize instance must have addModels function');\n }\n\n sequelize.addModels(testModels);\n await sequelize.dropSchema('custom-fields', { logging: false });\n await sequelize.createSchema('custom-fields', { logging: false });\n\n logger.info('custom-fields: test models added');\n await TestModel.sync({ alter: true });\n await AssociatedTestModel.sync({ alter: true });\n await ContextTestModel.sync({ alter: true });\n await ContextAwareTestModel.sync({ alter: true });\n logger.info('custom-fields: test models synced');\n};\n\nexport {\n CustomFieldValue,\n CustomFieldDefinition,\n CustomFieldEntries,\n CustomValidator,\n CustomFieldModelTypeMap,\n TestModel,\n AssociatedTestModel,\n ContextAwareTestModel,\n ContextTestModel,\n initTables,\n initTestModels,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["TestModel","AssociatedTestModel","ContextAwareTestModel","ContextTestModel","productionModels: ProductionModel[]","CustomFieldDefinition","CustomFieldValue","CustomValidator","CustomFieldEntries","CustomFieldModelTypeMap"],"sources":["../../src/models/index.ts"],"sourcesContent":["import { DataTypes, Op } from 'sequelize';\nimport type { Sequelize } from 'sequelize-typescript';\nimport logger from '../utils/logger';\nimport CustomFieldDefinition from './CustomFieldDefinition';\nimport CustomFieldValue from './CustomFieldValue';\nimport TestModel from './tests/TestModel';\nimport ContextAwareTestModel from './tests/contextAwareModels/ContextAwareTestModel';\nimport ContextTestModel from './tests/contextAwareModels/ContextTestModel';\nimport AssociatedTestModel from './tests/AssociatedTestModel';\nimport type { CustomFieldOptions } from '../types';\nimport CustomFieldEntries from './CustomFieldEntries';\nimport CustomValidator from './CustomValidator';\nimport CustomFieldModelTypeMap from './CustomFieldModelTypeMap';\n\ntype ProductionModel = typeof CustomFieldDefinition | typeof CustomFieldValue | typeof CustomFieldEntries | typeof CustomValidator | typeof CustomFieldModelTypeMap;\ninterface InitTablesOptions {\n schemaPrefix?: string;\n schemaVersion?: string;\n useCustomFieldsEntries?: boolean;\n useModelTypeMapping?: boolean;\n isMatPathEnabled?: CustomFieldOptions['isMatPathEnabled'];\n}\n\nconst testModels = [TestModel, AssociatedTestModel, ContextAwareTestModel, ContextTestModel];\n\nconst SADOT_MIGRATION_PREFIX = 'sadot-migration';\nconst SCHEMA_VERSION = '5f8e4a7c-9b2d-4e1f-8c3a-b6d9e2f7a4c1';\n// Arbitrary stable bigint used as a Postgres advisory-lock key for sadot init.\n// Picked once and never changes; uniqueness only matters within the sadot codebase.\nconst SADOT_INIT_ADVISORY_LOCK_KEY = 5_948_077_501_984_310_073n;\n\nconst initTables = async (\n sequelize: Sequelize,\n getUser: CustomFieldOptions['getUser'],\n {\n schemaPrefix = SADOT_MIGRATION_PREFIX,\n schemaVersion = SCHEMA_VERSION,\n useCustomFieldsEntries = false,\n useModelTypeMapping = false,\n isMatPathEnabled,\n }: InitTablesOptions = {},\n): Promise<void> => {\n const CUSTOM_FIELDS_SCHEMA_VERSION = `${schemaPrefix}_${schemaVersion}${useCustomFieldsEntries ? '_withEntries' : ''}${useModelTypeMapping ? '_withTypeMapping' : ''}`;\n logger.info('custom-fields: initialize custom-fields tables');\n // Detect models and import them to the orm\n if (!sequelize.addModels) {\n throw new Error('sequelize instance must have addModels function');\n }\n const productionModels: ProductionModel[] = [\n CustomFieldDefinition,\n CustomFieldValue,\n CustomValidator,\n ...(useCustomFieldsEntries ? [CustomFieldEntries] : []),\n ...(useModelTypeMapping ? [CustomFieldModelTypeMap] : []),\n ];\n\n sequelize.addModels(productionModels);\n\n // Add the association only when useModelTypeMapping is enabled\n if (useModelTypeMapping) {\n CustomFieldDefinition.hasMany(CustomFieldModelTypeMap, {\n foreignKey: 'customFieldDefinitionId',\n as: 'modelTypeMappings',\n });\n CustomFieldModelTypeMap.belongsTo(CustomFieldDefinition, {\n foreignKey: 'customFieldDefinitionId',\n as: 'customFieldDefinition',\n });\n }\n\n CustomFieldDefinition.addScope('userScope', () => {\n // When mat-path is active, the consumer is responsible for restricting entityIds\n // (typically by expanding the request's entityIds to include ancestor paths the\n // caller can see). Bypass the legacy permission filter so partner/ancestor\n // entityIds are not dropped.\n if (isMatPathEnabled?.()) return {};\n const user = getUser();\n if (!user?.permissions) {\n return {};\n }\n return {\n where: {\n entityId: [\n ...Object.keys(user.permissions.fleets),\n ...Object.keys(user.permissions.businessModels),\n ...Object.keys(user.permissions.demandSources),\n ],\n },\n };\n });\n\n CustomValidator.addScope('userScope', () => {\n if (isMatPathEnabled?.()) return {};\n const user = getUser();\n if (!user?.permissions) {\n return {};\n }\n return {\n where: {\n entityId: [\n ...Object.keys(user.permissions.fleets),\n ...Object.keys(user.permissions.businessModels),\n ...Object.keys(user.permissions.demandSources),\n ],\n },\n };\n });\n\n logger.info('custom-fields: models added');\n\n const SequelizeMeta = sequelize.define(\n 'SequelizeMeta',\n {\n name: {\n type: DataTypes.STRING,\n allowNull: false,\n unique: true,\n primaryKey: true,\n autoIncrement: false,\n },\n },\n {\n tableName: 'SequelizeMeta',\n timestamps: false,\n schema: 'public',\n },\n );\n\n logger.info('custom-fields: starting migrations');\n // Serialize init across concurrent pods: multiple `sync({ alter: true })` calls\n // racing each other can deadlock against read traffic that needs AccessShareLock\n // on the same tables (Postgres error 40P01). One pod runs sync, the rest wait.\n // Use a transaction-scoped advisory lock so it auto-releases on commit/rollback\n // and is guaranteed to share a connection with the work below.\n await sequelize.transaction(async (transaction) => {\n await sequelize.query(`SELECT pg_advisory_xact_lock(${SADOT_INIT_ADVISORY_LOCK_KEY})`, { transaction });\n\n const migrations = await SequelizeMeta.findAll({ where: { name: { [Op.like]: `${schemaPrefix}%` } }, raw: true, transaction });\n const currentSadotSchemaVersion = migrations.at(-1);\n const expectedSchemaVersionIndex = migrations.findIndex(m => (m as any).name === CUSTOM_FIELDS_SCHEMA_VERSION);\n\n logger.info('custom-fields: migrations', {\n currentMigrations: migrations,\n currentSadotSchemaVersion,\n newSadotSchemaVersion: CUSTOM_FIELDS_SCHEMA_VERSION,\n expectedSchemaVersionIndex,\n });\n if (!currentSadotSchemaVersion || (currentSadotSchemaVersion as any).name !== CUSTOM_FIELDS_SCHEMA_VERSION) {\n logger.info('custom-fields: syncing models');\n // sequelize's SyncOptions type omits `transaction`, but the runtime accepts and uses it\n // to bind the DDL to our advisory-lock transaction.\n const syncOptions = { alter: true, transaction } as Parameters<typeof CustomFieldDefinition.sync>[0];\n try {\n await CustomFieldDefinition.sync(syncOptions);\n logger.info('custom-fields: CustomFieldDefinition synced successfully');\n\n await CustomFieldValue.sync(syncOptions);\n logger.info('custom-fields: CustomFieldValue synced successfully');\n\n await CustomValidator.sync(syncOptions);\n logger.info('custom-fields: CustomValidator synced successfully');\n\n // T.Y TODO: Remove the if statement once we're ready to add the new entries table for all MS\n if (useCustomFieldsEntries) {\n await CustomFieldEntries.sync(syncOptions);\n logger.info('custom-fields: CustomFieldEntries synced successfully');\n }\n\n if (useModelTypeMapping) {\n await CustomFieldModelTypeMap.sync(syncOptions);\n logger.info('custom-fields: CustomFieldModelTypeMap synced successfully');\n }\n\n if (expectedSchemaVersionIndex === -1) {\n await SequelizeMeta.create({ name: CUSTOM_FIELDS_SCHEMA_VERSION }, { transaction });\n logger.info('custom-fields: SequelizeMeta entry created successfully');\n }\n\n logger.info('custom-fields: models synced');\n if (migrations.length && expectedSchemaVersionIndex !== -1 && expectedSchemaVersionIndex < migrations.length - 1) {\n // We have existing migrations, and we are calling `sync`.\n // This means we are in a `down` migration, and hence we should delete newer migrations to ensure we can reapply them.\n const migrationsToDelete = migrations.slice(expectedSchemaVersionIndex + 1);\n logger.info('custom-fields: deleting newer migrations during down migration', { count: migrationsToDelete.length });\n await SequelizeMeta.destroy({ where: { name: { [Op.in]: migrationsToDelete.map(m => (m as any).name) } }, transaction });\n logger.info('custom-fields: newer migrations deleted successfully');\n }\n } catch (error) {\n logger.error('custom-fields: failed to sync models', { error });\n throw error;\n }\n }\n });\n};\n\nconst initTestModels = async (sequelize: Sequelize): Promise<void> => {\n logger.info('custom-fields: initialize custom-fields test models');\n // Detect models and import them to the orm\n if (!sequelize.addModels) {\n throw new Error('sequelize instance must have addModels function');\n }\n\n sequelize.addModels(testModels);\n await sequelize.dropSchema('custom-fields', { logging: false });\n await sequelize.createSchema('custom-fields', { logging: false });\n\n logger.info('custom-fields: test models added');\n await TestModel.sync({ alter: true });\n await AssociatedTestModel.sync({ alter: true });\n await ContextTestModel.sync({ alter: true });\n await ContextAwareTestModel.sync({ alter: true });\n logger.info('custom-fields: test models synced');\n};\n\nexport {\n CustomFieldValue,\n CustomFieldDefinition,\n CustomFieldEntries,\n CustomValidator,\n CustomFieldModelTypeMap,\n TestModel,\n AssociatedTestModel,\n ContextAwareTestModel,\n ContextTestModel,\n initTables,\n initTestModels,\n};\n"],"mappings":"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"}
|
|
@@ -3,16 +3,14 @@ let e=function(e){return e.VALUES=`values`,e.ENTRIES=`entries`,e}({});const t=e=
|
|
|
3
3
|
${a?`${a} OR`:``}
|
|
4
4
|
ce.custom_fields @> '${i}'
|
|
5
5
|
)
|
|
6
|
-
`},y=(t,n,r)=>{switch(t){case e.VALUES:return
|
|
6
|
+
`},y=(t,n,r)=>{switch(t){case e.VALUES:return r.map(e=>`
|
|
7
7
|
SELECT cv.model_id
|
|
8
8
|
FROM custom_field_values AS cv
|
|
9
9
|
INNER JOIN custom_field_definitions AS cd ON cv.custom_field_definition_id = cd.id
|
|
10
10
|
${l}cd.model_type = '${n}'
|
|
11
|
-
WHERE ${
|
|
11
|
+
WHERE ${e}
|
|
12
12
|
${l}cv.deleted_at IS NULL${l}cd.deleted_at IS NULL
|
|
13
|
-
|
|
14
|
-
HAVING COUNT(DISTINCT cv.custom_field_definition_id) = ${r.length}
|
|
15
|
-
`.replace(/\n/g,``);case e.ENTRIES:return`
|
|
13
|
+
`).join(` INTERSECT `).replace(/\n/g,``);case e.ENTRIES:return`
|
|
16
14
|
SELECT ce.model_id
|
|
17
15
|
FROM custom_field_entries ce
|
|
18
16
|
JOIN custom_field_definitions cfd
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.helpers.cjs","names":["CD_NAME_COLUMN: `${typeof CD_TABLE_ALIAS}.name`","CV_VALUE_COLUMN: `${typeof CV_TABLE_ALIAS}.value`","formattedValue: string | number | boolean"],"sources":["../../../src/scopes/helpers/filter.helpers.ts"],"sourcesContent":["import type { WhereOptions } from 'sequelize';\n\n/**\n * Type representing possible condition values.\n * Currently supporting strings and arrays of strings.\n * More types to be added (TBA).\n */\nexport interface ConditionWithOperator {\n operator: string;\n value: string;\n}\nexport type ConditionValue = ConditionWithOperator | ConditionWithOperator[] | string | string[];\n\nexport interface CustomFieldSort {\n field: string;\n direction: 'ASC' | 'DESC';\n}\n\nexport interface CustomFieldFilterOptions {\n where?: WhereOptions;\n replacements?: Record<string, string>;\n}\n\nexport enum SubQueryType {\n VALUES = 'values',\n ENTRIES = 'entries',\n}\n\nexport const isConditionStringArray = (input: any): input is string[] => Array.isArray(input) && typeof input[0] === 'string';\nexport const isBooleanString = (input: string): boolean => ['true', 'false'].includes(input.toString());\nexport const isDate = (input: any): input is Date => input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n\nexport const castValueToJsonb = (value: string, type: string) => `to_jsonb(${value}::${type})`;\nexport const castValueToJsonbText = (value: string): string => castValueToJsonb(value, 'text');\nexport const castValueToJsonbBoolean = (value: string): string => castValueToJsonb(value, 'boolean');\nexport const castValueToJsonbNumeric = (value: string): string => castValueToJsonb(value, 'numeric');\nexport const castIfNeeded = (columnName: string, conditionValue: string): string => {\n if (isDate(conditionValue)) {\n return castValueToJsonb(columnName, 'timestamp');\n }\n return columnName;\n};\n\nexport const AND_DELIMITER = ' AND ';\nexport const OR_DELIMITER = ' OR ';\nexport const CD_TABLE_ALIAS = 'cd';\nexport const CD_NAME_COLUMN: `${typeof CD_TABLE_ALIAS}.name` = `${CD_TABLE_ALIAS}.name`;\nexport const CV_TABLE_ALIAS = 'cv';\nexport const CV_VALUE_COLUMN: `${typeof CV_TABLE_ALIAS}.value` = `${CV_TABLE_ALIAS}.value`;\nexport const CE_TABLE_ALIAS = 'ce';\n\nconst getSingleConditionWithOperator = (value: any, operator: string, replacementKey: string, reverseReplacementsMap: Map<string, string>) => {\n let type = 'text';\n if (isDate(value)) {\n type = 'date';\n } else if (!Number.isNaN(Number(value))) {\n type = 'numeric';\n } else if (isBooleanString(value)) {\n type = 'boolean';\n }\n const replacedValue = reverseReplacementsMap.get(value);\n\n return `(jsonb_extract_path_text(${CE_TABLE_ALIAS}.custom_fields, :${replacementKey})::${type}) ${operator} :${replacedValue}`;\n};\n\nconst getFormattedValue = (value: string) => {\n let formattedValue: string | number | boolean = value;\n if (isBooleanString(value)) {\n formattedValue = value === 'true';\n } else if (!Number.isNaN(Number(value))) {\n formattedValue = Number(value);\n }\n\n return formattedValue;\n};\n\nconst getJSONSubQuery = (value: string, key: string) => {\n const formattedValue = getFormattedValue(value);\n const jsonQuery = JSON.stringify({ [key]: formattedValue });\n let jsonQueryWithStringBoolean;\n if (isBooleanString(value)) {\n jsonQueryWithStringBoolean = `${CE_TABLE_ALIAS}.custom_fields @> '${JSON.stringify({ [key]: value })}'`;\n }\n return `\n (\n ${jsonQueryWithStringBoolean ? `${jsonQueryWithStringBoolean} OR` : ''}\n ${CE_TABLE_ALIAS}.custom_fields @> '${jsonQuery}'\n )\n `;\n};\n\nexport const getFilterCustomFieldsSubQuery = (queryType: SubQueryType, modelType: string, conditionsStrings: (string | boolean)[]): string => {\n switch (queryType) {\n case SubQueryType.VALUES:\n return `\n SELECT ${CV_TABLE_ALIAS}.model_id\n FROM custom_field_values AS ${CV_TABLE_ALIAS}\n INNER JOIN custom_field_definitions AS ${CD_TABLE_ALIAS} ON ${CV_TABLE_ALIAS}.custom_field_definition_id = ${CD_TABLE_ALIAS}.id\n ${AND_DELIMITER}${CD_TABLE_ALIAS}.model_type = '${modelType}'\n WHERE ${conditionsStrings.join(OR_DELIMITER)}\n ${AND_DELIMITER}${CV_TABLE_ALIAS}.deleted_at IS NULL${AND_DELIMITER}${CD_TABLE_ALIAS}.deleted_at IS NULL\n GROUP BY ${CV_TABLE_ALIAS}.model_id\n HAVING COUNT(DISTINCT ${CV_TABLE_ALIAS}.custom_field_definition_id) = ${conditionsStrings.length}\n `.replace(/\\n/g, '');\n case SubQueryType.ENTRIES:\n return `\n SELECT ce.model_id\n FROM custom_field_entries ce\n JOIN custom_field_definitions cfd\n ON ce.model_type = cfd.model_type\n AND ce.entity_id = cfd.entity_id\n WHERE\n cfd.deleted_at IS NULL AND\n ${conditionsStrings.join(AND_DELIMITER)}\n `;\n default:\n throw new Error('Invalid query type');\n }\n};\n\nexport const getSortCustomFieldsSubQuery = (queryType: SubQueryType, modelType: string, replacementKey: string): string => {\n switch (queryType) {\n case SubQueryType.VALUES:\n return `(\n SELECT value\n FROM (SELECT cv.model_id, cv.value\n FROM custom_field_values AS cv INNER JOIN custom_field_definitions AS cd\n ON cv.custom_field_definition_id = cd.id\n ${AND_DELIMITER}cd.model_type = '${modelType}'\n WHERE cv.model_id = \"${modelType}\".\"id\"\n ${AND_DELIMITER}cd.name = :${replacementKey}\n ) AS CustomFieldAggregation\n )\n `;\n case SubQueryType.ENTRIES:\n return `(\n SELECT\n customFields.value\n FROM\n custom_field_entries AS ${CE_TABLE_ALIAS},\n jsonb_each_text(custom_fields) AS customFields\n WHERE\n customFields.key = :${replacementKey}${AND_DELIMITER}\n ${CE_TABLE_ALIAS}.model_type = '${modelType}'${AND_DELIMITER}\n ${CE_TABLE_ALIAS}.model_id = \"${modelType}\".\"id\"\n )\n `;\n default:\n throw new Error('Invalid query type');\n }\n};\n\nexport const formatConditionsForValues = (key: string, condition: ConditionValue, reverseReplacementsMap: Map<string, string>): false | string => {\n const replacementKey = reverseReplacementsMap.get(key);\n if (!replacementKey) {\n return false;\n }\n\n const columnCondition = `(${CD_NAME_COLUMN} = :${replacementKey})`;\n if (Array.isArray(condition)) {\n if (condition.length === 0) {\n // if empty array, the condition is ignored\n return false;\n }\n\n if (isConditionStringArray(condition)) {\n const values = condition.flatMap((v) => {\n const valRandom = reverseReplacementsMap.get(v);\n if (isBooleanString(v)) {\n return [castValueToJsonbText(`:${valRandom}`), castValueToJsonbBoolean(`:${valRandom}`)];\n }\n if (!Number.isNaN(Number(v))) {\n return castValueToJsonbNumeric(`:${valRandom}`);\n }\n return castValueToJsonbText(`:${valRandom}`);\n }).join(',');\n return `(${columnCondition}${AND_DELIMITER}${CV_VALUE_COLUMN} IN (${values}))`;\n }\n return condition.map((c) => {\n const valRep = reverseReplacementsMap.get(c.value);\n const valueAsJsonb = castValueToJsonbText(`:${valRep}`);\n\n return `(${columnCondition}${AND_DELIMITER}${castIfNeeded(CV_VALUE_COLUMN, c.value)} ${c.operator} ${valueAsJsonb})`;\n }).join(AND_DELIMITER);\n }\n if (typeof condition === 'string' || typeof condition === 'number') {\n const conditionRep = reverseReplacementsMap.get(condition);\n const valueAsJsonb = !Number.isNaN(Number(condition)) ? castValueToJsonbNumeric(`:${conditionRep}`) : castValueToJsonbText(`:${conditionRep}`);\n const valueAsJsonbBoolean = isBooleanString(condition) ? `${OR_DELIMITER}${CV_VALUE_COLUMN} = ${castValueToJsonbBoolean(`:${conditionRep}`)}` : '';\n return `(${columnCondition}${AND_DELIMITER}(${castIfNeeded(CV_VALUE_COLUMN, condition)} = ${valueAsJsonb}${valueAsJsonbBoolean}))`;\n }\n if (condition?.operator) {\n const valueRep = reverseReplacementsMap.get(condition.value);\n const valueAsJsonb = castValueToJsonbText(`:${valueRep}`);\n return `( ${columnCondition}${AND_DELIMITER}${castIfNeeded(CV_VALUE_COLUMN, condition.value)} ${condition.operator} ${valueAsJsonb})`;\n }\n return false;\n};\n\nexport const formatConditionsForEntries = (key: string, condition: ConditionValue, reverseReplacementsMap: Map<string, string>): false | string => {\n const replacementKey = reverseReplacementsMap.get(key);\n if (!replacementKey) {\n return false;\n }\n\n if (Array.isArray(condition)) {\n if (condition.length === 0) {\n // if empty array, the condition is ignored\n return false;\n }\n\n if (isConditionStringArray(condition)) {\n const values = condition.map(value => getJSONSubQuery(value, key)).join(`${OR_DELIMITER}\\n`);\n return `( ${values})`;\n }\n return condition.map(c => getSingleConditionWithOperator(c.value, c.operator, replacementKey, reverseReplacementsMap)).join(AND_DELIMITER);\n }\n\n if (typeof condition === 'string' || typeof condition === 'number') {\n return getJSONSubQuery(condition, key);\n }\n\n if (condition?.operator) {\n return getSingleConditionWithOperator(condition.value, condition.operator, replacementKey, reverseReplacementsMap);\n }\n return false;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"filter.helpers.cjs","names":["CD_NAME_COLUMN: `${typeof CD_TABLE_ALIAS}.name`","CV_VALUE_COLUMN: `${typeof CV_TABLE_ALIAS}.value`","formattedValue: string | number | boolean"],"sources":["../../../src/scopes/helpers/filter.helpers.ts"],"sourcesContent":["import type { WhereOptions } from 'sequelize';\n\n/**\n * Type representing possible condition values.\n * Currently supporting strings and arrays of strings.\n * More types to be added (TBA).\n */\nexport interface ConditionWithOperator {\n operator: string;\n value: string;\n}\nexport type ConditionValue = ConditionWithOperator | ConditionWithOperator[] | string | string[];\n\nexport interface CustomFieldSort {\n field: string;\n direction: 'ASC' | 'DESC';\n}\n\nexport interface CustomFieldFilterOptions {\n where?: WhereOptions;\n replacements?: Record<string, string>;\n}\n\nexport enum SubQueryType {\n VALUES = 'values',\n ENTRIES = 'entries',\n}\n\nexport const isConditionStringArray = (input: any): input is string[] => Array.isArray(input) && typeof input[0] === 'string';\nexport const isBooleanString = (input: string): boolean => ['true', 'false'].includes(input.toString());\nexport const isDate = (input: any): input is Date => input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n\nexport const castValueToJsonb = (value: string, type: string) => `to_jsonb(${value}::${type})`;\nexport const castValueToJsonbText = (value: string): string => castValueToJsonb(value, 'text');\nexport const castValueToJsonbBoolean = (value: string): string => castValueToJsonb(value, 'boolean');\nexport const castValueToJsonbNumeric = (value: string): string => castValueToJsonb(value, 'numeric');\nexport const castIfNeeded = (columnName: string, conditionValue: string): string => {\n if (isDate(conditionValue)) {\n return castValueToJsonb(columnName, 'timestamp');\n }\n return columnName;\n};\n\nexport const AND_DELIMITER = ' AND ';\nexport const OR_DELIMITER = ' OR ';\nexport const CD_TABLE_ALIAS = 'cd';\nexport const CD_NAME_COLUMN: `${typeof CD_TABLE_ALIAS}.name` = `${CD_TABLE_ALIAS}.name`;\nexport const CV_TABLE_ALIAS = 'cv';\nexport const CV_VALUE_COLUMN: `${typeof CV_TABLE_ALIAS}.value` = `${CV_TABLE_ALIAS}.value`;\nexport const CE_TABLE_ALIAS = 'ce';\n\nconst getSingleConditionWithOperator = (value: any, operator: string, replacementKey: string, reverseReplacementsMap: Map<string, string>) => {\n let type = 'text';\n if (isDate(value)) {\n type = 'date';\n } else if (!Number.isNaN(Number(value))) {\n type = 'numeric';\n } else if (isBooleanString(value)) {\n type = 'boolean';\n }\n const replacedValue = reverseReplacementsMap.get(value);\n\n return `(jsonb_extract_path_text(${CE_TABLE_ALIAS}.custom_fields, :${replacementKey})::${type}) ${operator} :${replacedValue}`;\n};\n\nconst getFormattedValue = (value: string) => {\n let formattedValue: string | number | boolean = value;\n if (isBooleanString(value)) {\n formattedValue = value === 'true';\n } else if (!Number.isNaN(Number(value))) {\n formattedValue = Number(value);\n }\n\n return formattedValue;\n};\n\nconst getJSONSubQuery = (value: string, key: string) => {\n const formattedValue = getFormattedValue(value);\n const jsonQuery = JSON.stringify({ [key]: formattedValue });\n let jsonQueryWithStringBoolean;\n if (isBooleanString(value)) {\n jsonQueryWithStringBoolean = `${CE_TABLE_ALIAS}.custom_fields @> '${JSON.stringify({ [key]: value })}'`;\n }\n return `\n (\n ${jsonQueryWithStringBoolean ? `${jsonQueryWithStringBoolean} OR` : ''}\n ${CE_TABLE_ALIAS}.custom_fields @> '${jsonQuery}'\n )\n `;\n};\n\nexport const getFilterCustomFieldsSubQuery = (queryType: SubQueryType, modelType: string, conditionsStrings: (string | boolean)[]): string => {\n switch (queryType) {\n case SubQueryType.VALUES: {\n // INTERSECT of one SELECT per condition gives the same semantics as\n // `WHERE c1 OR c2 ... GROUP BY model_id HAVING COUNT(DISTINCT def_id) = N`\n // but lets the planner pick an index-driven plan per branch instead of\n // a single sequential scan of custom_field_values.\n const branches = conditionsStrings.map((condition) => `\n SELECT ${CV_TABLE_ALIAS}.model_id\n FROM custom_field_values AS ${CV_TABLE_ALIAS}\n INNER JOIN custom_field_definitions AS ${CD_TABLE_ALIAS} ON ${CV_TABLE_ALIAS}.custom_field_definition_id = ${CD_TABLE_ALIAS}.id\n ${AND_DELIMITER}${CD_TABLE_ALIAS}.model_type = '${modelType}'\n WHERE ${condition}\n ${AND_DELIMITER}${CV_TABLE_ALIAS}.deleted_at IS NULL${AND_DELIMITER}${CD_TABLE_ALIAS}.deleted_at IS NULL\n `);\n return branches.join(' INTERSECT ').replace(/\\n/g, '');\n }\n case SubQueryType.ENTRIES:\n return `\n SELECT ce.model_id\n FROM custom_field_entries ce\n JOIN custom_field_definitions cfd\n ON ce.model_type = cfd.model_type\n AND ce.entity_id = cfd.entity_id\n WHERE\n cfd.deleted_at IS NULL AND\n ${conditionsStrings.join(AND_DELIMITER)}\n `;\n default:\n throw new Error('Invalid query type');\n }\n};\n\nexport const getSortCustomFieldsSubQuery = (queryType: SubQueryType, modelType: string, replacementKey: string): string => {\n switch (queryType) {\n case SubQueryType.VALUES:\n return `(\n SELECT value\n FROM (SELECT cv.model_id, cv.value\n FROM custom_field_values AS cv INNER JOIN custom_field_definitions AS cd\n ON cv.custom_field_definition_id = cd.id\n ${AND_DELIMITER}cd.model_type = '${modelType}'\n WHERE cv.model_id = \"${modelType}\".\"id\"\n ${AND_DELIMITER}cd.name = :${replacementKey}\n ) AS CustomFieldAggregation\n )\n `;\n case SubQueryType.ENTRIES:\n return `(\n SELECT\n customFields.value\n FROM\n custom_field_entries AS ${CE_TABLE_ALIAS},\n jsonb_each_text(custom_fields) AS customFields\n WHERE\n customFields.key = :${replacementKey}${AND_DELIMITER}\n ${CE_TABLE_ALIAS}.model_type = '${modelType}'${AND_DELIMITER}\n ${CE_TABLE_ALIAS}.model_id = \"${modelType}\".\"id\"\n )\n `;\n default:\n throw new Error('Invalid query type');\n }\n};\n\nexport const formatConditionsForValues = (key: string, condition: ConditionValue, reverseReplacementsMap: Map<string, string>): false | string => {\n const replacementKey = reverseReplacementsMap.get(key);\n if (!replacementKey) {\n return false;\n }\n\n const columnCondition = `(${CD_NAME_COLUMN} = :${replacementKey})`;\n if (Array.isArray(condition)) {\n if (condition.length === 0) {\n // if empty array, the condition is ignored\n return false;\n }\n\n if (isConditionStringArray(condition)) {\n const values = condition.flatMap((v) => {\n const valRandom = reverseReplacementsMap.get(v);\n if (isBooleanString(v)) {\n return [castValueToJsonbText(`:${valRandom}`), castValueToJsonbBoolean(`:${valRandom}`)];\n }\n if (!Number.isNaN(Number(v))) {\n return castValueToJsonbNumeric(`:${valRandom}`);\n }\n return castValueToJsonbText(`:${valRandom}`);\n }).join(',');\n return `(${columnCondition}${AND_DELIMITER}${CV_VALUE_COLUMN} IN (${values}))`;\n }\n return condition.map((c) => {\n const valRep = reverseReplacementsMap.get(c.value);\n const valueAsJsonb = castValueToJsonbText(`:${valRep}`);\n\n return `(${columnCondition}${AND_DELIMITER}${castIfNeeded(CV_VALUE_COLUMN, c.value)} ${c.operator} ${valueAsJsonb})`;\n }).join(AND_DELIMITER);\n }\n if (typeof condition === 'string' || typeof condition === 'number') {\n const conditionRep = reverseReplacementsMap.get(condition);\n const valueAsJsonb = !Number.isNaN(Number(condition)) ? castValueToJsonbNumeric(`:${conditionRep}`) : castValueToJsonbText(`:${conditionRep}`);\n const valueAsJsonbBoolean = isBooleanString(condition) ? `${OR_DELIMITER}${CV_VALUE_COLUMN} = ${castValueToJsonbBoolean(`:${conditionRep}`)}` : '';\n return `(${columnCondition}${AND_DELIMITER}(${castIfNeeded(CV_VALUE_COLUMN, condition)} = ${valueAsJsonb}${valueAsJsonbBoolean}))`;\n }\n if (condition?.operator) {\n const valueRep = reverseReplacementsMap.get(condition.value);\n const valueAsJsonb = castValueToJsonbText(`:${valueRep}`);\n return `( ${columnCondition}${AND_DELIMITER}${castIfNeeded(CV_VALUE_COLUMN, condition.value)} ${condition.operator} ${valueAsJsonb})`;\n }\n return false;\n};\n\nexport const formatConditionsForEntries = (key: string, condition: ConditionValue, reverseReplacementsMap: Map<string, string>): false | string => {\n const replacementKey = reverseReplacementsMap.get(key);\n if (!replacementKey) {\n return false;\n }\n\n if (Array.isArray(condition)) {\n if (condition.length === 0) {\n // if empty array, the condition is ignored\n return false;\n }\n\n if (isConditionStringArray(condition)) {\n const values = condition.map(value => getJSONSubQuery(value, key)).join(`${OR_DELIMITER}\\n`);\n return `( ${values})`;\n }\n return condition.map(c => getSingleConditionWithOperator(c.value, c.operator, replacementKey, reverseReplacementsMap)).join(AND_DELIMITER);\n }\n\n if (typeof condition === 'string' || typeof condition === 'number') {\n return getJSONSubQuery(condition, key);\n }\n\n if (condition?.operator) {\n return getSingleConditionWithOperator(condition.value, condition.operator, replacementKey, reverseReplacementsMap);\n }\n return false;\n};\n"],"mappings":"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"}
|
|
@@ -3,16 +3,14 @@ let e=function(e){return e.VALUES=`values`,e.ENTRIES=`entries`,e}({});const t=e=
|
|
|
3
3
|
${a?`${a} OR`:``}
|
|
4
4
|
ce.custom_fields @> '${i}'
|
|
5
5
|
)
|
|
6
|
-
`},h=(t,n,r)=>{switch(t){case e.VALUES:return
|
|
6
|
+
`},h=(t,n,r)=>{switch(t){case e.VALUES:return r.map(e=>`
|
|
7
7
|
SELECT cv.model_id
|
|
8
8
|
FROM custom_field_values AS cv
|
|
9
9
|
INNER JOIN custom_field_definitions AS cd ON cv.custom_field_definition_id = cd.id
|
|
10
10
|
${l}cd.model_type = '${n}'
|
|
11
|
-
WHERE ${
|
|
11
|
+
WHERE ${e}
|
|
12
12
|
${l}cv.deleted_at IS NULL${l}cd.deleted_at IS NULL
|
|
13
|
-
|
|
14
|
-
HAVING COUNT(DISTINCT cv.custom_field_definition_id) = ${r.length}
|
|
15
|
-
`.replace(/\n/g,``);case e.ENTRIES:return`
|
|
13
|
+
`).join(` INTERSECT `).replace(/\n/g,``);case e.ENTRIES:return`
|
|
16
14
|
SELECT ce.model_id
|
|
17
15
|
FROM custom_field_entries ce
|
|
18
16
|
JOIN custom_field_definitions cfd
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.helpers.js","names":["CD_NAME_COLUMN: `${typeof CD_TABLE_ALIAS}.name`","CV_VALUE_COLUMN: `${typeof CV_TABLE_ALIAS}.value`","formattedValue: string | number | boolean"],"sources":["../../../src/scopes/helpers/filter.helpers.ts"],"sourcesContent":["import type { WhereOptions } from 'sequelize';\n\n/**\n * Type representing possible condition values.\n * Currently supporting strings and arrays of strings.\n * More types to be added (TBA).\n */\nexport interface ConditionWithOperator {\n operator: string;\n value: string;\n}\nexport type ConditionValue = ConditionWithOperator | ConditionWithOperator[] | string | string[];\n\nexport interface CustomFieldSort {\n field: string;\n direction: 'ASC' | 'DESC';\n}\n\nexport interface CustomFieldFilterOptions {\n where?: WhereOptions;\n replacements?: Record<string, string>;\n}\n\nexport enum SubQueryType {\n VALUES = 'values',\n ENTRIES = 'entries',\n}\n\nexport const isConditionStringArray = (input: any): input is string[] => Array.isArray(input) && typeof input[0] === 'string';\nexport const isBooleanString = (input: string): boolean => ['true', 'false'].includes(input.toString());\nexport const isDate = (input: any): input is Date => input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n\nexport const castValueToJsonb = (value: string, type: string) => `to_jsonb(${value}::${type})`;\nexport const castValueToJsonbText = (value: string): string => castValueToJsonb(value, 'text');\nexport const castValueToJsonbBoolean = (value: string): string => castValueToJsonb(value, 'boolean');\nexport const castValueToJsonbNumeric = (value: string): string => castValueToJsonb(value, 'numeric');\nexport const castIfNeeded = (columnName: string, conditionValue: string): string => {\n if (isDate(conditionValue)) {\n return castValueToJsonb(columnName, 'timestamp');\n }\n return columnName;\n};\n\nexport const AND_DELIMITER = ' AND ';\nexport const OR_DELIMITER = ' OR ';\nexport const CD_TABLE_ALIAS = 'cd';\nexport const CD_NAME_COLUMN: `${typeof CD_TABLE_ALIAS}.name` = `${CD_TABLE_ALIAS}.name`;\nexport const CV_TABLE_ALIAS = 'cv';\nexport const CV_VALUE_COLUMN: `${typeof CV_TABLE_ALIAS}.value` = `${CV_TABLE_ALIAS}.value`;\nexport const CE_TABLE_ALIAS = 'ce';\n\nconst getSingleConditionWithOperator = (value: any, operator: string, replacementKey: string, reverseReplacementsMap: Map<string, string>) => {\n let type = 'text';\n if (isDate(value)) {\n type = 'date';\n } else if (!Number.isNaN(Number(value))) {\n type = 'numeric';\n } else if (isBooleanString(value)) {\n type = 'boolean';\n }\n const replacedValue = reverseReplacementsMap.get(value);\n\n return `(jsonb_extract_path_text(${CE_TABLE_ALIAS}.custom_fields, :${replacementKey})::${type}) ${operator} :${replacedValue}`;\n};\n\nconst getFormattedValue = (value: string) => {\n let formattedValue: string | number | boolean = value;\n if (isBooleanString(value)) {\n formattedValue = value === 'true';\n } else if (!Number.isNaN(Number(value))) {\n formattedValue = Number(value);\n }\n\n return formattedValue;\n};\n\nconst getJSONSubQuery = (value: string, key: string) => {\n const formattedValue = getFormattedValue(value);\n const jsonQuery = JSON.stringify({ [key]: formattedValue });\n let jsonQueryWithStringBoolean;\n if (isBooleanString(value)) {\n jsonQueryWithStringBoolean = `${CE_TABLE_ALIAS}.custom_fields @> '${JSON.stringify({ [key]: value })}'`;\n }\n return `\n (\n ${jsonQueryWithStringBoolean ? `${jsonQueryWithStringBoolean} OR` : ''}\n ${CE_TABLE_ALIAS}.custom_fields @> '${jsonQuery}'\n )\n `;\n};\n\nexport const getFilterCustomFieldsSubQuery = (queryType: SubQueryType, modelType: string, conditionsStrings: (string | boolean)[]): string => {\n switch (queryType) {\n case SubQueryType.VALUES:\n return `\n SELECT ${CV_TABLE_ALIAS}.model_id\n FROM custom_field_values AS ${CV_TABLE_ALIAS}\n INNER JOIN custom_field_definitions AS ${CD_TABLE_ALIAS} ON ${CV_TABLE_ALIAS}.custom_field_definition_id = ${CD_TABLE_ALIAS}.id\n ${AND_DELIMITER}${CD_TABLE_ALIAS}.model_type = '${modelType}'\n WHERE ${conditionsStrings.join(OR_DELIMITER)}\n ${AND_DELIMITER}${CV_TABLE_ALIAS}.deleted_at IS NULL${AND_DELIMITER}${CD_TABLE_ALIAS}.deleted_at IS NULL\n GROUP BY ${CV_TABLE_ALIAS}.model_id\n HAVING COUNT(DISTINCT ${CV_TABLE_ALIAS}.custom_field_definition_id) = ${conditionsStrings.length}\n `.replace(/\\n/g, '');\n case SubQueryType.ENTRIES:\n return `\n SELECT ce.model_id\n FROM custom_field_entries ce\n JOIN custom_field_definitions cfd\n ON ce.model_type = cfd.model_type\n AND ce.entity_id = cfd.entity_id\n WHERE\n cfd.deleted_at IS NULL AND\n ${conditionsStrings.join(AND_DELIMITER)}\n `;\n default:\n throw new Error('Invalid query type');\n }\n};\n\nexport const getSortCustomFieldsSubQuery = (queryType: SubQueryType, modelType: string, replacementKey: string): string => {\n switch (queryType) {\n case SubQueryType.VALUES:\n return `(\n SELECT value\n FROM (SELECT cv.model_id, cv.value\n FROM custom_field_values AS cv INNER JOIN custom_field_definitions AS cd\n ON cv.custom_field_definition_id = cd.id\n ${AND_DELIMITER}cd.model_type = '${modelType}'\n WHERE cv.model_id = \"${modelType}\".\"id\"\n ${AND_DELIMITER}cd.name = :${replacementKey}\n ) AS CustomFieldAggregation\n )\n `;\n case SubQueryType.ENTRIES:\n return `(\n SELECT\n customFields.value\n FROM\n custom_field_entries AS ${CE_TABLE_ALIAS},\n jsonb_each_text(custom_fields) AS customFields\n WHERE\n customFields.key = :${replacementKey}${AND_DELIMITER}\n ${CE_TABLE_ALIAS}.model_type = '${modelType}'${AND_DELIMITER}\n ${CE_TABLE_ALIAS}.model_id = \"${modelType}\".\"id\"\n )\n `;\n default:\n throw new Error('Invalid query type');\n }\n};\n\nexport const formatConditionsForValues = (key: string, condition: ConditionValue, reverseReplacementsMap: Map<string, string>): false | string => {\n const replacementKey = reverseReplacementsMap.get(key);\n if (!replacementKey) {\n return false;\n }\n\n const columnCondition = `(${CD_NAME_COLUMN} = :${replacementKey})`;\n if (Array.isArray(condition)) {\n if (condition.length === 0) {\n // if empty array, the condition is ignored\n return false;\n }\n\n if (isConditionStringArray(condition)) {\n const values = condition.flatMap((v) => {\n const valRandom = reverseReplacementsMap.get(v);\n if (isBooleanString(v)) {\n return [castValueToJsonbText(`:${valRandom}`), castValueToJsonbBoolean(`:${valRandom}`)];\n }\n if (!Number.isNaN(Number(v))) {\n return castValueToJsonbNumeric(`:${valRandom}`);\n }\n return castValueToJsonbText(`:${valRandom}`);\n }).join(',');\n return `(${columnCondition}${AND_DELIMITER}${CV_VALUE_COLUMN} IN (${values}))`;\n }\n return condition.map((c) => {\n const valRep = reverseReplacementsMap.get(c.value);\n const valueAsJsonb = castValueToJsonbText(`:${valRep}`);\n\n return `(${columnCondition}${AND_DELIMITER}${castIfNeeded(CV_VALUE_COLUMN, c.value)} ${c.operator} ${valueAsJsonb})`;\n }).join(AND_DELIMITER);\n }\n if (typeof condition === 'string' || typeof condition === 'number') {\n const conditionRep = reverseReplacementsMap.get(condition);\n const valueAsJsonb = !Number.isNaN(Number(condition)) ? castValueToJsonbNumeric(`:${conditionRep}`) : castValueToJsonbText(`:${conditionRep}`);\n const valueAsJsonbBoolean = isBooleanString(condition) ? `${OR_DELIMITER}${CV_VALUE_COLUMN} = ${castValueToJsonbBoolean(`:${conditionRep}`)}` : '';\n return `(${columnCondition}${AND_DELIMITER}(${castIfNeeded(CV_VALUE_COLUMN, condition)} = ${valueAsJsonb}${valueAsJsonbBoolean}))`;\n }\n if (condition?.operator) {\n const valueRep = reverseReplacementsMap.get(condition.value);\n const valueAsJsonb = castValueToJsonbText(`:${valueRep}`);\n return `( ${columnCondition}${AND_DELIMITER}${castIfNeeded(CV_VALUE_COLUMN, condition.value)} ${condition.operator} ${valueAsJsonb})`;\n }\n return false;\n};\n\nexport const formatConditionsForEntries = (key: string, condition: ConditionValue, reverseReplacementsMap: Map<string, string>): false | string => {\n const replacementKey = reverseReplacementsMap.get(key);\n if (!replacementKey) {\n return false;\n }\n\n if (Array.isArray(condition)) {\n if (condition.length === 0) {\n // if empty array, the condition is ignored\n return false;\n }\n\n if (isConditionStringArray(condition)) {\n const values = condition.map(value => getJSONSubQuery(value, key)).join(`${OR_DELIMITER}\\n`);\n return `( ${values})`;\n }\n return condition.map(c => getSingleConditionWithOperator(c.value, c.operator, replacementKey, reverseReplacementsMap)).join(AND_DELIMITER);\n }\n\n if (typeof condition === 'string' || typeof condition === 'number') {\n return getJSONSubQuery(condition, key);\n }\n\n if (condition?.operator) {\n return getSingleConditionWithOperator(condition.value, condition.operator, replacementKey, reverseReplacementsMap);\n }\n return false;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"filter.helpers.js","names":["CD_NAME_COLUMN: `${typeof CD_TABLE_ALIAS}.name`","CV_VALUE_COLUMN: `${typeof CV_TABLE_ALIAS}.value`","formattedValue: string | number | boolean"],"sources":["../../../src/scopes/helpers/filter.helpers.ts"],"sourcesContent":["import type { WhereOptions } from 'sequelize';\n\n/**\n * Type representing possible condition values.\n * Currently supporting strings and arrays of strings.\n * More types to be added (TBA).\n */\nexport interface ConditionWithOperator {\n operator: string;\n value: string;\n}\nexport type ConditionValue = ConditionWithOperator | ConditionWithOperator[] | string | string[];\n\nexport interface CustomFieldSort {\n field: string;\n direction: 'ASC' | 'DESC';\n}\n\nexport interface CustomFieldFilterOptions {\n where?: WhereOptions;\n replacements?: Record<string, string>;\n}\n\nexport enum SubQueryType {\n VALUES = 'values',\n ENTRIES = 'entries',\n}\n\nexport const isConditionStringArray = (input: any): input is string[] => Array.isArray(input) && typeof input[0] === 'string';\nexport const isBooleanString = (input: string): boolean => ['true', 'false'].includes(input.toString());\nexport const isDate = (input: any): input is Date => input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n\nexport const castValueToJsonb = (value: string, type: string) => `to_jsonb(${value}::${type})`;\nexport const castValueToJsonbText = (value: string): string => castValueToJsonb(value, 'text');\nexport const castValueToJsonbBoolean = (value: string): string => castValueToJsonb(value, 'boolean');\nexport const castValueToJsonbNumeric = (value: string): string => castValueToJsonb(value, 'numeric');\nexport const castIfNeeded = (columnName: string, conditionValue: string): string => {\n if (isDate(conditionValue)) {\n return castValueToJsonb(columnName, 'timestamp');\n }\n return columnName;\n};\n\nexport const AND_DELIMITER = ' AND ';\nexport const OR_DELIMITER = ' OR ';\nexport const CD_TABLE_ALIAS = 'cd';\nexport const CD_NAME_COLUMN: `${typeof CD_TABLE_ALIAS}.name` = `${CD_TABLE_ALIAS}.name`;\nexport const CV_TABLE_ALIAS = 'cv';\nexport const CV_VALUE_COLUMN: `${typeof CV_TABLE_ALIAS}.value` = `${CV_TABLE_ALIAS}.value`;\nexport const CE_TABLE_ALIAS = 'ce';\n\nconst getSingleConditionWithOperator = (value: any, operator: string, replacementKey: string, reverseReplacementsMap: Map<string, string>) => {\n let type = 'text';\n if (isDate(value)) {\n type = 'date';\n } else if (!Number.isNaN(Number(value))) {\n type = 'numeric';\n } else if (isBooleanString(value)) {\n type = 'boolean';\n }\n const replacedValue = reverseReplacementsMap.get(value);\n\n return `(jsonb_extract_path_text(${CE_TABLE_ALIAS}.custom_fields, :${replacementKey})::${type}) ${operator} :${replacedValue}`;\n};\n\nconst getFormattedValue = (value: string) => {\n let formattedValue: string | number | boolean = value;\n if (isBooleanString(value)) {\n formattedValue = value === 'true';\n } else if (!Number.isNaN(Number(value))) {\n formattedValue = Number(value);\n }\n\n return formattedValue;\n};\n\nconst getJSONSubQuery = (value: string, key: string) => {\n const formattedValue = getFormattedValue(value);\n const jsonQuery = JSON.stringify({ [key]: formattedValue });\n let jsonQueryWithStringBoolean;\n if (isBooleanString(value)) {\n jsonQueryWithStringBoolean = `${CE_TABLE_ALIAS}.custom_fields @> '${JSON.stringify({ [key]: value })}'`;\n }\n return `\n (\n ${jsonQueryWithStringBoolean ? `${jsonQueryWithStringBoolean} OR` : ''}\n ${CE_TABLE_ALIAS}.custom_fields @> '${jsonQuery}'\n )\n `;\n};\n\nexport const getFilterCustomFieldsSubQuery = (queryType: SubQueryType, modelType: string, conditionsStrings: (string | boolean)[]): string => {\n switch (queryType) {\n case SubQueryType.VALUES: {\n // INTERSECT of one SELECT per condition gives the same semantics as\n // `WHERE c1 OR c2 ... GROUP BY model_id HAVING COUNT(DISTINCT def_id) = N`\n // but lets the planner pick an index-driven plan per branch instead of\n // a single sequential scan of custom_field_values.\n const branches = conditionsStrings.map((condition) => `\n SELECT ${CV_TABLE_ALIAS}.model_id\n FROM custom_field_values AS ${CV_TABLE_ALIAS}\n INNER JOIN custom_field_definitions AS ${CD_TABLE_ALIAS} ON ${CV_TABLE_ALIAS}.custom_field_definition_id = ${CD_TABLE_ALIAS}.id\n ${AND_DELIMITER}${CD_TABLE_ALIAS}.model_type = '${modelType}'\n WHERE ${condition}\n ${AND_DELIMITER}${CV_TABLE_ALIAS}.deleted_at IS NULL${AND_DELIMITER}${CD_TABLE_ALIAS}.deleted_at IS NULL\n `);\n return branches.join(' INTERSECT ').replace(/\\n/g, '');\n }\n case SubQueryType.ENTRIES:\n return `\n SELECT ce.model_id\n FROM custom_field_entries ce\n JOIN custom_field_definitions cfd\n ON ce.model_type = cfd.model_type\n AND ce.entity_id = cfd.entity_id\n WHERE\n cfd.deleted_at IS NULL AND\n ${conditionsStrings.join(AND_DELIMITER)}\n `;\n default:\n throw new Error('Invalid query type');\n }\n};\n\nexport const getSortCustomFieldsSubQuery = (queryType: SubQueryType, modelType: string, replacementKey: string): string => {\n switch (queryType) {\n case SubQueryType.VALUES:\n return `(\n SELECT value\n FROM (SELECT cv.model_id, cv.value\n FROM custom_field_values AS cv INNER JOIN custom_field_definitions AS cd\n ON cv.custom_field_definition_id = cd.id\n ${AND_DELIMITER}cd.model_type = '${modelType}'\n WHERE cv.model_id = \"${modelType}\".\"id\"\n ${AND_DELIMITER}cd.name = :${replacementKey}\n ) AS CustomFieldAggregation\n )\n `;\n case SubQueryType.ENTRIES:\n return `(\n SELECT\n customFields.value\n FROM\n custom_field_entries AS ${CE_TABLE_ALIAS},\n jsonb_each_text(custom_fields) AS customFields\n WHERE\n customFields.key = :${replacementKey}${AND_DELIMITER}\n ${CE_TABLE_ALIAS}.model_type = '${modelType}'${AND_DELIMITER}\n ${CE_TABLE_ALIAS}.model_id = \"${modelType}\".\"id\"\n )\n `;\n default:\n throw new Error('Invalid query type');\n }\n};\n\nexport const formatConditionsForValues = (key: string, condition: ConditionValue, reverseReplacementsMap: Map<string, string>): false | string => {\n const replacementKey = reverseReplacementsMap.get(key);\n if (!replacementKey) {\n return false;\n }\n\n const columnCondition = `(${CD_NAME_COLUMN} = :${replacementKey})`;\n if (Array.isArray(condition)) {\n if (condition.length === 0) {\n // if empty array, the condition is ignored\n return false;\n }\n\n if (isConditionStringArray(condition)) {\n const values = condition.flatMap((v) => {\n const valRandom = reverseReplacementsMap.get(v);\n if (isBooleanString(v)) {\n return [castValueToJsonbText(`:${valRandom}`), castValueToJsonbBoolean(`:${valRandom}`)];\n }\n if (!Number.isNaN(Number(v))) {\n return castValueToJsonbNumeric(`:${valRandom}`);\n }\n return castValueToJsonbText(`:${valRandom}`);\n }).join(',');\n return `(${columnCondition}${AND_DELIMITER}${CV_VALUE_COLUMN} IN (${values}))`;\n }\n return condition.map((c) => {\n const valRep = reverseReplacementsMap.get(c.value);\n const valueAsJsonb = castValueToJsonbText(`:${valRep}`);\n\n return `(${columnCondition}${AND_DELIMITER}${castIfNeeded(CV_VALUE_COLUMN, c.value)} ${c.operator} ${valueAsJsonb})`;\n }).join(AND_DELIMITER);\n }\n if (typeof condition === 'string' || typeof condition === 'number') {\n const conditionRep = reverseReplacementsMap.get(condition);\n const valueAsJsonb = !Number.isNaN(Number(condition)) ? castValueToJsonbNumeric(`:${conditionRep}`) : castValueToJsonbText(`:${conditionRep}`);\n const valueAsJsonbBoolean = isBooleanString(condition) ? `${OR_DELIMITER}${CV_VALUE_COLUMN} = ${castValueToJsonbBoolean(`:${conditionRep}`)}` : '';\n return `(${columnCondition}${AND_DELIMITER}(${castIfNeeded(CV_VALUE_COLUMN, condition)} = ${valueAsJsonb}${valueAsJsonbBoolean}))`;\n }\n if (condition?.operator) {\n const valueRep = reverseReplacementsMap.get(condition.value);\n const valueAsJsonb = castValueToJsonbText(`:${valueRep}`);\n return `( ${columnCondition}${AND_DELIMITER}${castIfNeeded(CV_VALUE_COLUMN, condition.value)} ${condition.operator} ${valueAsJsonb})`;\n }\n return false;\n};\n\nexport const formatConditionsForEntries = (key: string, condition: ConditionValue, reverseReplacementsMap: Map<string, string>): false | string => {\n const replacementKey = reverseReplacementsMap.get(key);\n if (!replacementKey) {\n return false;\n }\n\n if (Array.isArray(condition)) {\n if (condition.length === 0) {\n // if empty array, the condition is ignored\n return false;\n }\n\n if (isConditionStringArray(condition)) {\n const values = condition.map(value => getJSONSubQuery(value, key)).join(`${OR_DELIMITER}\\n`);\n return `( ${values})`;\n }\n return condition.map(c => getSingleConditionWithOperator(c.value, c.operator, replacementKey, reverseReplacementsMap)).join(AND_DELIMITER);\n }\n\n if (typeof condition === 'string' || typeof condition === 'number') {\n return getJSONSubQuery(condition, key);\n }\n\n if (condition?.operator) {\n return getSingleConditionWithOperator(condition.value, condition.operator, replacementKey, reverseReplacementsMap);\n }\n return false;\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autofleet/sadot",
|
|
3
|
-
"version": "1.5.1",
|
|
3
|
+
"version": "1.5.2-beta-2cd7f45c.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
"express": "^4.21.2",
|
|
53
53
|
"npm-watch": "^0.11.0",
|
|
54
54
|
"supertest": "^7.0.0",
|
|
55
|
-
"@autofleet/errors": "^3.1.53",
|
|
56
|
-
"@autofleet/logger": "^4.5.1",
|
|
57
55
|
"@autofleet/node-common": "^4.3.13",
|
|
56
|
+
"@autofleet/logger": "^4.5.1",
|
|
57
|
+
"@autofleet/errors": "^3.1.53",
|
|
58
58
|
"@autofleet/zehut": "^4.12.8"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|