@okf/ootils 1.41.2 → 1.43.0

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/node.js CHANGED
@@ -935,7 +935,7 @@ var init_Tpl = __esm({
935
935
  var require_MongoConnector = __commonJS({
936
936
  "src/db/MongoConnector.js"(exports2, module2) {
937
937
  "use strict";
938
- var mongoose5 = require("mongoose");
938
+ var mongoose10 = require("mongoose");
939
939
  var { ServerApiVersion } = require("mongodb");
940
940
  var AnnotationsSchema = (init_Annotations(), __toCommonJS(Annotations_exports));
941
941
  var PlatformConfigsSchema2 = (init_PlatformConfigs(), __toCommonJS(PlatformConfigs_exports));
@@ -999,7 +999,7 @@ var require_MongoConnector = __commonJS({
999
999
  `Missing CLUSTER_NAME or CLUSTER_URI in cluster conf: ${JSON.stringify(clusterConf)}`
1000
1000
  );
1001
1001
  }
1002
- this.clusterConnections[CLUSTER_NAME] = mongoose5.createConnection(
1002
+ this.clusterConnections[CLUSTER_NAME] = mongoose10.createConnection(
1003
1003
  CLUSTER_URI,
1004
1004
  this.mongoOptions
1005
1005
  );
@@ -1026,7 +1026,7 @@ var require_MongoConnector = __commonJS({
1026
1026
  this.skippedClusters.add(CLUSTER_NAME);
1027
1027
  return;
1028
1028
  }
1029
- const connection = mongoose5.createConnection(CLUSTER_URI, this.mongoOptions);
1029
+ const connection = mongoose10.createConnection(CLUSTER_URI, this.mongoOptions);
1030
1030
  this.clusterConnections[CLUSTER_NAME] = connection;
1031
1031
  this.initiateConnectionEventListeners(CLUSTER_NAME);
1032
1032
  await new Promise((resolve, reject) => {
@@ -1491,7 +1491,7 @@ var require_getModelByTenant = __commonJS({
1491
1491
  "use strict";
1492
1492
  var { getDbByTenant: getDbByTenant2 } = (init_getDbByTenant(), __toCommonJS(getDbByTenant_exports));
1493
1493
  var { AIChatSchema: AIChatSchema2, AnnotationSchema: AnnotationSchema2, PlatformConfigsSchema: PlatformConfigsSchema2, TplSchema: TplSchema2, GeneratedTopicsSchema: GeneratedTopicsSchema2, GeneratedEntitiesSchema: GeneratedEntitiesSchema2 } = (init_models(), __toCommonJS(models_exports));
1494
- var getModelByTenant3 = ({ tenant, modelName, schema, env }) => {
1494
+ var getModelByTenant4 = ({ tenant, modelName, schema, env }) => {
1495
1495
  if (!tenant) {
1496
1496
  throw new Error("tenant id has not been provided");
1497
1497
  }
@@ -1501,48 +1501,48 @@ var require_getModelByTenant = __commonJS({
1501
1501
  }
1502
1502
  return db.model(modelName);
1503
1503
  };
1504
- var getAnnotationsModelByTenant2 = ({ tenant, env, mongodb, modelName }) => getModelByTenant3({
1504
+ var getAnnotationsModelByTenant2 = ({ tenant, env, mongodb, modelName }) => getModelByTenant4({
1505
1505
  tenant,
1506
1506
  modelName: modelName || "annotations",
1507
1507
  schema: AnnotationSchema2,
1508
1508
  env
1509
1509
  });
1510
- var getPlatformConfigsModelByTenant2 = ({ tenant, env, mongodb }) => getModelByTenant3({
1510
+ var getPlatformConfigsModelByTenant2 = ({ tenant, env, mongodb }) => getModelByTenant4({
1511
1511
  tenant,
1512
1512
  modelName: "platformConfigs",
1513
1513
  schema: PlatformConfigsSchema2,
1514
1514
  env
1515
1515
  });
1516
- var getTplModelByTenant2 = ({ tenant, env, mongodb }) => getModelByTenant3({
1516
+ var getTplModelByTenant3 = ({ tenant, env, mongodb }) => getModelByTenant4({
1517
1517
  tenant,
1518
1518
  modelName: "tpl",
1519
1519
  schema: TplSchema2,
1520
1520
  env
1521
1521
  });
1522
- var getAIChatModelByTenant2 = ({ tenant, env, mongodb }) => getModelByTenant3({
1522
+ var getAIChatModelByTenant2 = ({ tenant, env, mongodb }) => getModelByTenant4({
1523
1523
  tenant,
1524
1524
  modelName: "aiChat",
1525
1525
  schema: AIChatSchema2,
1526
1526
  env
1527
1527
  });
1528
- var getGeneratedTopicsModelByTenant2 = ({ tenant, env }) => getModelByTenant3({
1528
+ var getGeneratedTopicsModelByTenant2 = ({ tenant, env }) => getModelByTenant4({
1529
1529
  tenant,
1530
1530
  modelName: "generatedTopics",
1531
1531
  schema: GeneratedTopicsSchema2,
1532
1532
  env
1533
1533
  });
1534
- var getGeneratedEntitiesModelByTenant2 = ({ tenant, env }) => getModelByTenant3({
1534
+ var getGeneratedEntitiesModelByTenant2 = ({ tenant, env }) => getModelByTenant4({
1535
1535
  tenant,
1536
1536
  modelName: "generatedEntities",
1537
1537
  schema: GeneratedEntitiesSchema2,
1538
1538
  env
1539
1539
  });
1540
1540
  module2.exports = {
1541
- getModelByTenant: getModelByTenant3,
1541
+ getModelByTenant: getModelByTenant4,
1542
1542
  getAIChatModelByTenant: getAIChatModelByTenant2,
1543
1543
  getAnnotationsModelByTenant: getAnnotationsModelByTenant2,
1544
1544
  getPlatformConfigsModelByTenant: getPlatformConfigsModelByTenant2,
1545
- getTplModelByTenant: getTplModelByTenant2,
1545
+ getTplModelByTenant: getTplModelByTenant3,
1546
1546
  getGeneratedTopicsModelByTenant: getGeneratedTopicsModelByTenant2,
1547
1547
  getGeneratedEntitiesModelByTenant: getGeneratedEntitiesModelByTenant2
1548
1548
  };
@@ -2280,6 +2280,91 @@ var require_AnnosElasticSyncProducer = __commonJS({
2280
2280
  }
2281
2281
  });
2282
2282
 
2283
+ // src/bullmq/ContentElasticSyncProducer.js
2284
+ var require_ContentElasticSyncProducer = __commonJS({
2285
+ "src/bullmq/ContentElasticSyncProducer.js"(exports2, module2) {
2286
+ "use strict";
2287
+ var { BaseProducer: BaseProducer2 } = require_BaseProducer();
2288
+ var { GET_GLOBAL_BULLMQ_CONFIG: GET_GLOBAL_BULLMQ_CONFIG2 } = require_GET_GLOBAL_BULLMQ_CONFIG();
2289
+ var { SecretManagerConnector: SecretManagerConnector2 } = (init_SecretManagerConnector(), __toCommonJS(SecretManagerConnector_exports));
2290
+ var ContentElasticSyncProducer2 = class _ContentElasticSyncProducer extends BaseProducer2 {
2291
+ // Preserve class name through minification for ProducerManager lookup
2292
+ static get name() {
2293
+ return "ContentElasticSyncProducer";
2294
+ }
2295
+ // env is OPTIONAL — cross-env routing: jobs land in the target env's Redis
2296
+ // so that env's deployed workers pick them up (see okf-be
2297
+ // CreateChunksProducer for the rationale and the localhost `_local_<user>`
2298
+ // queue-id quirk).
2299
+ constructor(options = {}) {
2300
+ const env = options.env || process.env.ENV;
2301
+ const c = SecretManagerConnector2.getEnvSpecificConfigs(env);
2302
+ const redisCredentials = options.redisCredentials || {
2303
+ REDIS_HOST: c.REDIS_HOST,
2304
+ REDIS_PORT: c.REDIS_PORT,
2305
+ REDIS_PASSWORD: c.REDIS_PASSWORD
2306
+ };
2307
+ const GLOBAL_BULLMQ_CONFIG = GET_GLOBAL_BULLMQ_CONFIG2({
2308
+ env,
2309
+ redisCredentials
2310
+ });
2311
+ super(GLOBAL_BULLMQ_CONFIG.CONTENT_ELASTIC_SYNC_QUEUE);
2312
+ this.env = env;
2313
+ }
2314
+ async addJobs({ documents, tenant, contentType, operationType, sourceMetadata }) {
2315
+ if (!documents || documents.length === 0 || contentType === "staticPages") {
2316
+ return { jobCount: 0, jobIds: [] };
2317
+ }
2318
+ const batchSize = 200;
2319
+ let jobs = [];
2320
+ for (let i = 0; i < documents.length; i += batchSize) {
2321
+ const batch = documents.slice(i, i + batchSize);
2322
+ jobs.push({
2323
+ name: "processContentElasticSync",
2324
+ data: {
2325
+ docIds: batch.map((doc) => doc._id),
2326
+ tenant,
2327
+ env: this.env,
2328
+ contentType,
2329
+ operationType,
2330
+ sourceMetadata: {
2331
+ ...sourceMetadata,
2332
+ contentId: batch.map((d) => d._id)
2333
+ }
2334
+ }
2335
+ });
2336
+ }
2337
+ const addedJobs = await this.addBulkJobs(jobs);
2338
+ const jobIds = addedJobs.map((job) => job.id);
2339
+ console.log(`\u{1F4E6} Added ${addedJobs.length} jobs for ${contentType} contents sync atomically`);
2340
+ return {
2341
+ jobCount: addedJobs.length,
2342
+ jobIds
2343
+ };
2344
+ }
2345
+ static async addJobsAndClose(params) {
2346
+ const producer = new _ContentElasticSyncProducer({ env: params?.env });
2347
+ try {
2348
+ return await producer.addJobs(params);
2349
+ } finally {
2350
+ await producer.stop();
2351
+ }
2352
+ }
2353
+ static async removeJobsAndClose(jobIds, env) {
2354
+ const producer = new _ContentElasticSyncProducer({ env });
2355
+ try {
2356
+ return await producer.removeJobs(jobIds);
2357
+ } finally {
2358
+ await producer.stop();
2359
+ }
2360
+ }
2361
+ };
2362
+ module2.exports = {
2363
+ ContentElasticSyncProducer: ContentElasticSyncProducer2
2364
+ };
2365
+ }
2366
+ });
2367
+
2283
2368
  // src/node.ts
2284
2369
  var node_exports = {};
2285
2370
  __export(node_exports, {
@@ -2293,6 +2378,7 @@ __export(node_exports, {
2293
2378
  BlockRegistry: () => BlockRegistry,
2294
2379
  CHUNKING_PRESETS: () => CHUNKING_PRESETS,
2295
2380
  ChunksElasticSyncProducer: () => import_ChunksElasticSyncProducer.ChunksElasticSyncProducer,
2381
+ ContentElasticSyncProducer: () => import_ContentElasticSyncProducer.ContentElasticSyncProducer,
2296
2382
  ELASTIC_MAPPING_PRESETS: () => ELASTIC_MAPPING_PRESETS,
2297
2383
  ElasticSearchConnector: () => import_ElasticSearchConnector.ElasticSearchConnector,
2298
2384
  FILTER_IDS: () => FILTER_IDS,
@@ -2306,9 +2392,13 @@ __export(node_exports, {
2306
2392
  RedisCacheConnector: () => RedisCacheConnector,
2307
2393
  SecretManagerConnector: () => SecretManagerConnector,
2308
2394
  TEMP_removeDuplicateFilters: () => TEMP_removeDuplicateFilters,
2395
+ TenantRegistry: () => TenantRegistry,
2309
2396
  TplSchema: () => Tpl_default,
2310
2397
  UI_CONTENT: () => UI_CONTENT,
2311
2398
  WorkerManager: () => import_WorkerManager.WorkerManager,
2399
+ _backOfficeFields__contr: () => _backOfficeFields__contr,
2400
+ _constantMeta__contr: () => _constantMeta__contr,
2401
+ _fixedMainFields__contr: () => _fixedMainFields__contr,
2312
2402
  _self_managed_buildAnnoHierarchyConfig: () => _self_managed_buildAnnoHierarchyConfig,
2313
2403
  _self_managed_buildDocHierarchyConfig: () => _self_managed_buildDocHierarchyConfig,
2314
2404
  _self_managed_getFixedAnnoRollupBlocks: () => _self_managed_getFixedAnnoRollupBlocks,
@@ -2320,19 +2410,23 @@ __export(node_exports, {
2320
2410
  compareAndGroupBlocks: () => compareAndGroupBlocks,
2321
2411
  deleteVal: () => deleteVal,
2322
2412
  extractAllBlocksFromTpl: () => extractAllBlocksFromTpl,
2413
+ extractAllUniqueAnnoTagTypesFromTpl: () => extractAllUniqueAnnoTagTypesFromTpl,
2323
2414
  extractAndOrganizeBlocks: () => extractAndOrganizeBlocks,
2415
+ extractNumberFromValue: () => extractNumberFromValue,
2324
2416
  genCleanCamelCaseId: () => genCleanCamelCaseId,
2417
+ genContentTypeSchema: () => genContentTypeSchema,
2325
2418
  genTagId: () => genTagId,
2326
2419
  generateFilterKey: () => generateFilterKey,
2327
- getAIChatModelByTenant: () => import_getModelByTenant2.getAIChatModelByTenant,
2420
+ getAIChatModelByTenant: () => import_getModelByTenant4.getAIChatModelByTenant,
2328
2421
  getAnnoFilterBucketKey: () => getAnnoFilterBucketKey,
2329
- getAnnotationsModelByTenant: () => import_getModelByTenant2.getAnnotationsModelByTenant,
2422
+ getAnnotationsModelByTenant: () => import_getModelByTenant4.getAnnotationsModelByTenant,
2423
+ getContrModelByTenant: () => getContrModelByTenant,
2330
2424
  getDbByTenant: () => getDbByTenant,
2331
2425
  getFilterKeyForBlock: () => getFilterKeyForBlock,
2332
- getGeneratedEntitiesModelByTenant: () => import_getModelByTenant2.getGeneratedEntitiesModelByTenant,
2333
- getGeneratedTopicsModelByTenant: () => import_getModelByTenant2.getGeneratedTopicsModelByTenant,
2334
- getModelByTenant: () => import_getModelByTenant2.getModelByTenant,
2335
- getPlatformConfigsModelByTenant: () => import_getModelByTenant2.getPlatformConfigsModelByTenant,
2426
+ getGeneratedEntitiesModelByTenant: () => import_getModelByTenant4.getGeneratedEntitiesModelByTenant,
2427
+ getGeneratedTopicsModelByTenant: () => import_getModelByTenant4.getGeneratedTopicsModelByTenant,
2428
+ getModelByTenant: () => import_getModelByTenant4.getModelByTenant,
2429
+ getPlatformConfigsModelByTenant: () => import_getModelByTenant4.getPlatformConfigsModelByTenant,
2336
2430
  getPlatformContextContent: () => getPlatformContextContent,
2337
2431
  getRollupPossibilities: () => getRollupPossibilities,
2338
2432
  getRoutePathToContentTypeLanding: () => getRoutePathToContentTypeLanding,
@@ -2343,7 +2437,9 @@ __export(node_exports, {
2343
2437
  getRoutePathToReviewDashboard: () => getRoutePathToReviewDashboard,
2344
2438
  getRoutePathToTCI: () => getRoutePathToTCI,
2345
2439
  getRoutePathToTagCategoryLanding: () => getRoutePathToTagCategoryLanding,
2346
- getTplModelByTenant: () => import_getModelByTenant2.getTplModelByTenant,
2440
+ getTpl: () => getTpl,
2441
+ getTplModelByTenant: () => import_getModelByTenant4.getTplModelByTenant,
2442
+ getTypesForSchemaFromTpl: () => getTypesForSchemaFromTpl,
2347
2443
  getVal: () => getVal,
2348
2444
  isTplAnnotationEnabled: () => isTplAnnotationEnabled,
2349
2445
  mergeAnnoDataIntoAnnotationsTags: () => mergeAnnoDataIntoAnnotationsTags,
@@ -5006,7 +5102,751 @@ RedisCacheConnector.instance = null;
5006
5102
  // src/node.ts
5007
5103
  init_SecretManagerConnector();
5008
5104
  init_getDbByTenant();
5105
+ var import_getModelByTenant4 = __toESM(require_getModelByTenant());
5106
+
5107
+ // src/contentSchema/genContentTypeSchema.js
5108
+ var import_mongoose12 = __toESM(require("mongoose"));
5109
+
5110
+ // src/contentSchema/components/_backOfficeFields__contr.js
5111
+ var import_mongoose8 = __toESM(require("mongoose"));
5112
+ var _backOfficeFields__contr = (thisContentModelRef) => ({
5113
+ //----- (USUSED AT THE MOMENT) version 2 properties for better tracking & interlinking of document clones ---- //
5114
+ isPrimaryDoc: Boolean,
5115
+ cloneStack: [import_mongoose8.default.Schema.Types.ObjectId],
5116
+ // the last item in the array being the last clone
5117
+ ogStack: [import_mongoose8.default.Schema.Types.ObjectId],
5118
+ // the last item in the array being the og-est og ( the primaryDoc )
5119
+ //----- END version 2 properties ---- //
5120
+ tagId: String,
5121
+ kp_published_status: {
5122
+ type: String,
5123
+ // options : draft | published | editPublished | awaitingModeration | underModeration
5124
+ default: "draft",
5125
+ required: true
5126
+ },
5127
+ warnings: [Object],
5128
+ kp_og_published_doc: {
5129
+ type: import_mongoose8.default.Schema.Types.ObjectId,
5130
+ ref: thisContentModelRef
5131
+ },
5132
+ // ----- mod rel --- //
5133
+ kp_pre_mod_doc: {
5134
+ type: import_mongoose8.default.Schema.Types.ObjectId
5135
+ },
5136
+ kp_is_pbl_taken_into_mod: Boolean,
5137
+ kp_is_mod_clone: Boolean,
5138
+ kp_moderator: {
5139
+ type: import_mongoose8.default.Schema.Types.ObjectId,
5140
+ ref: "user"
5141
+ },
5142
+ kp_date_mod_begin: Date,
5143
+ kp_date_mod_end: Date,
5144
+ kp_date_submitted: Date,
5145
+ // ----- END mod rel --- //
5146
+ kp_date_created: Date,
5147
+ kp_date_last_saved: Date,
5148
+ kp_date_published: {
5149
+ type: Date
5150
+ },
5151
+ editPublishedDocId: {
5152
+ //only comes on og docs that have an editPbl clone
5153
+ type: import_mongoose8.default.Schema.Types.ObjectId,
5154
+ ref: thisContentModelRef
5155
+ },
5156
+ currentEditor: {
5157
+ type: import_mongoose8.default.Schema.Types.ObjectId,
5158
+ //relevant for segments : staticPages & collection, where author dont matter.
5159
+ ref: "user"
5160
+ },
5161
+ lastActivity: {
5162
+ date: {
5163
+ type: Date
5164
+ }
5165
+ }
5166
+ });
5167
+
5168
+ // src/contentSchema/components/_comments__contr.js
5169
+ var import_mongoose9 = __toESM(require("mongoose"));
5170
+ var baseCommentsObj = {
5171
+ user: {
5172
+ userId: { type: import_mongoose9.default.Schema.Types.ObjectId, ref: "user" },
5173
+ profileType: String,
5174
+ name: String,
5175
+ avatar: Object
5176
+ },
5177
+ text: Object,
5178
+ dateCreated: Date,
5179
+ dateModified: [Date]
5180
+ //the start of tracking mod dates on things..experiment...
5181
+ };
5182
+ var _comments__contr = {
5183
+ comments: [
5184
+ {
5185
+ ...baseCommentsObj,
5186
+ responses: [baseCommentsObj]
5187
+ }
5188
+ ]
5189
+ };
5190
+
5191
+ // src/contentSchema/components/_reaction_contr.js
5192
+ var import_mongoose10 = __toESM(require("mongoose"));
5193
+ var baseSchema = {
5194
+ type: {
5195
+ type: String,
5196
+ enum: ["like", "celebrate", "inspiring", "learnings"]
5197
+ },
5198
+ dateCreated: Date,
5199
+ userId: { type: import_mongoose10.default.Schema.Types.ObjectId, ref: "user" }
5200
+ };
5201
+ var _reaction_contr = {
5202
+ reactions: [
5203
+ {
5204
+ ...baseSchema
5205
+ }
5206
+ ]
5207
+ };
5208
+
5209
+ // src/contentSchema/components/_constantMeta__contr.js
5210
+ var import_mongoose11 = __toESM(require("mongoose"));
5211
+ var _constantMeta__contr = {
5212
+ kp_contributed_by: {
5213
+ type: import_mongoose11.default.Schema.Types.ObjectId,
5214
+ ref: "user",
5215
+ required: true
5216
+ },
5217
+ kp_content_type: {
5218
+ type: String,
5219
+ required: true
5220
+ },
5221
+ // "thematic" or "attribute" — distinguishes thematic sub-themes/tags from
5222
+ // attribute classification categories (speech act, emotion, etc.).
5223
+ taxonomyRole: {
5224
+ type: String
5225
+ },
5226
+ // Only meaningful on sub-theme docs. When false, new tags cannot be created under
5227
+ // this sub-theme (by humans via API or by the inductive AI annotator).
5228
+ // Absent/true = allowed (default).
5229
+ allowNewTags: {
5230
+ type: Boolean
5231
+ },
5232
+ // Only meaningful on attribute-role sub-themes. "single" = pick one tag,
5233
+ // "multi" = pick one or more. Default "multi".
5234
+ selectMode: {
5235
+ type: String
5236
+ },
5237
+ // "autoAI" | "humanInTheLoop" — absent means human editor (default).
5238
+ createdVia: {
5239
+ type: String
5240
+ }
5241
+ };
5242
+
5243
+ // src/contentSchema/components/_fixedMainFields__contr.js
5244
+ var _fixedMainFields__contr = {
5245
+ /**
5246
+ * hard coding title & subtitle is required because,
5247
+ * in tpl categories like 'researchNotes' the title comp is never defined in the template.
5248
+ * instead, it is hardcoded in the code, and it expects a 'main.title' value path.
5249
+ * Hence the hardcode below. Besides its not a problem, since, if in the template a
5250
+ * main.title component is indeed defined, then these hardcodes would be overwritten by
5251
+ * mainExtract. Which is what we want.
5252
+ */
5253
+ title: {
5254
+ type: String,
5255
+ cast: (v) => typeof v === "string" ? String(v) : Object(v)
5256
+ },
5257
+ subtitle: {
5258
+ type: String,
5259
+ cast: (v) => typeof v === "string" ? String(v) : Object(v)
5260
+ },
5261
+ titleInfo: String
5262
+ // this is used to show the meta text ("This story is supported by AI-assisted bot") on the published page
5263
+ };
5264
+
5265
+ // src/contentSchema/extractAllUniqueAnnoTagTypesFromTpl.js
5266
+ var extractAllUniqueAnnoTagTypesFromTpl = (extractedBlocks, { smTagTypesConfig } = {}) => {
5267
+ return Array.from(
5268
+ new Set(
5269
+ blockRegistry.getAnnotationEnabledBlocks(extractedBlocks).flatMap((bl) => [
5270
+ ...blockRegistry.getTagTypesConfig(bl, smTagTypesConfig).map((tt) => tt.tagType),
5271
+ ...bl.props?.annotation?.toggleTagTypesConfig?.map((tt) => tt.tagType) || []
5272
+ ])
5273
+ )
5274
+ );
5275
+ };
5276
+
5277
+ // src/contentSchema/getTypesForSchemaFromTpl/compToTypeMap/getConditionalDataType.js
5278
+ var getConditionalDataType = ({ block }) => {
5279
+ if (block.props?.saveValueAsString)
5280
+ return {
5281
+ type: Number,
5282
+ cast: (v) => {
5283
+ if (typeof v === "number" && !isNaN(v)) {
5284
+ return Number(v);
5285
+ } else if (typeof v === "string") {
5286
+ return String(v);
5287
+ } else {
5288
+ return Boolean(v);
5289
+ }
5290
+ }
5291
+ };
5292
+ else {
5293
+ const returnValue = ["DropdownMulti", "CheckboxList"].includes(block.comp) ? { type: Array } : { type: Object };
5294
+ return returnValue;
5295
+ }
5296
+ };
5297
+
5298
+ // src/contentSchema/utils/extractNumberFromValue.js
5299
+ var extractNumberFromValue = (value) => {
5300
+ if (value === null || value === void 0) return void 0;
5301
+ if (typeof value === "number") return isNaN(value) ? void 0 : value;
5302
+ const str = String(value).trim();
5303
+ if (str === "") return void 0;
5304
+ const directParse = Number(str);
5305
+ if (!isNaN(directParse)) return directParse;
5306
+ const commaNumberMatch = str.match(/-?\d[\d,]*\d(?:\.\d+)?/);
5307
+ if (commaNumberMatch && commaNumberMatch[0].includes(",")) {
5308
+ const num = Number(commaNumberMatch[0].replace(/,/g, ""));
5309
+ if (!isNaN(num)) return num;
5310
+ }
5311
+ const numberMatch = str.match(/-?\d+(?:\.\d+)?/);
5312
+ if (numberMatch) {
5313
+ const num = Number(numberMatch[0]);
5314
+ return isNaN(num) ? void 0 : num;
5315
+ }
5316
+ return void 0;
5317
+ };
5318
+
5319
+ // src/contentSchema/getTypesForSchemaFromTpl/compToTypeMap/index.js
5320
+ var compToTypeMap = ({ block }) => {
5321
+ const comp = block.comp;
5322
+ const blockDef = blockRegistry.getBlock(comp);
5323
+ if (blockDef) return blockDef.mongoSchemaType;
5324
+ switch (comp) {
5325
+ case "SummaryInput":
5326
+ case "KPRichInput":
5327
+ //deprecated
5328
+ case "RichTextEditor":
5329
+ //deprecated
5330
+ case "StaticRichText":
5331
+ case "CardRadioInput":
5332
+ case "NumberRangeInput":
5333
+ case "KPLikeContactChannelsBlock":
5334
+ case "TitleInput":
5335
+ case "SubtitleInput":
5336
+ case "PluginSentinel":
5337
+ case "DynamicRefetchDropdown":
5338
+ case "VideoInput":
5339
+ // data type for videoinput should actually be array, but since the old version of the comp used a string data type, we are currently setting it to object to avoid error
5340
+ case "SimpleTable":
5341
+ case "GroupQuestionsInputSingle":
5342
+ return { type: Object };
5343
+ case "ProfileImageInput":
5344
+ case "ResourceInput":
5345
+ case "ImageInput":
5346
+ case "VideoInput":
5347
+ case "Repeater":
5348
+ case "RepeaterTabs":
5349
+ case "PDFInput":
5350
+ case "TextInputToArray":
5351
+ return { type: Array };
5352
+ case "RichTextAsPlainText":
5353
+ case "PasswordInput":
5354
+ case "EmailInput":
5355
+ case "TextInput":
5356
+ case "URLInput":
5357
+ case "PhoneInput":
5358
+ case "KPMetaPrimary":
5359
+ case "IFrameInput":
5360
+ case "JSONInput":
5361
+ return { type: String };
5362
+ case "NumberInput":
5363
+ return {
5364
+ type: Number,
5365
+ // Smart extraction of numbers from messy values (e.g. "18+", "18 years old", "$100")
5366
+ // Uses extractNumberFromValue utility for consistent behavior with direct import
5367
+ set: extractNumberFromValue
5368
+ };
5369
+ case "DropdownSingleLanguage":
5370
+ case "ComboboxSingleLanguage":
5371
+ return {
5372
+ type: [
5373
+ {
5374
+ display: String,
5375
+ value: String
5376
+ }
5377
+ ]
5378
+ };
5379
+ case "DatePicker":
5380
+ return { type: Date };
5381
+ case "DateTimePicker":
5382
+ return { type: Date };
5383
+ case "TimePicker":
5384
+ return {
5385
+ type: String,
5386
+ // Validates time is in 24-hour format (00:00-23:59) with hours 00-23, a colon, and minutes 00-59
5387
+ validate: {
5388
+ validator: function(v) {
5389
+ return /^([01]\d|2[0-3]):([0-5]\d)$/.test(v);
5390
+ },
5391
+ message: (props) => `${props.value} is not a valid time format!`
5392
+ }
5393
+ };
5394
+ case "CheckboxButton":
5395
+ return { type: Boolean };
5396
+ case "TagsInputMulti":
5397
+ case "FragmentsSet":
5398
+ case "FragmentsDict":
5399
+ case "TagsInputSingle":
5400
+ return {
5401
+ type: {
5402
+ collectionId: String,
5403
+ data: [
5404
+ {
5405
+ _id: {
5406
+ type: String,
5407
+ index: block.index === true
5408
+ },
5409
+ display: String,
5410
+ tagId: String
5411
+ }
5412
+ ]
5413
+ }
5414
+ };
5415
+ case "SPECIAL_AnnotationTagsField":
5416
+ return {
5417
+ /**
5418
+ * very important that we wrap the whole thing in type,
5419
+ * because, if the tag name itself is type (like in the case of noora),
5420
+ * then it completely confuses mongoose, since type is a reserved word,
5421
+ * and causes all sorts of bugs.
5422
+ */
5423
+ type: {
5424
+ collectionId: String,
5425
+ data: Array
5426
+ //leaving this weakly typed for now cuz annotations have several other properties in here which i am not aware of..
5427
+ }
5428
+ };
5429
+ case "LinkEmbedWithInput":
5430
+ return {
5431
+ type: {
5432
+ url: String,
5433
+ metadata: Object
5434
+ }
5435
+ };
5436
+ case "CheckboxList":
5437
+ //new
5438
+ case "RadioList":
5439
+ //new
5440
+ case "DropdownSingle":
5441
+ //new
5442
+ case "DropdownMulti":
5443
+ //new
5444
+ case "SwitchDouble":
5445
+ case "SwitchSingle":
5446
+ return getConditionalDataType({ block });
5447
+ case "DateTimeRangePicker":
5448
+ return {
5449
+ type: {
5450
+ date: Date,
5451
+ timeRange: Array
5452
+ }
5453
+ };
5454
+ case "DateRangePicker":
5455
+ return { type: Array };
5456
+ }
5457
+ };
5458
+
5459
+ // src/contentSchema/getTypesForSchemaFromTpl/index.js
5460
+ var getTypesForSchemaFromTpl = (options = {}) => {
5461
+ const { tpl, smTagTypesConfig } = options;
5462
+ const defaultSchemaFieldsByTplLayout = {
5463
+ researchNotes2: {
5464
+ tags: {
5465
+ quotes: {
5466
+ collectionId: String,
5467
+ data: Array
5468
+ },
5469
+ vocabs: {
5470
+ collectionId: String,
5471
+ data: Array
5472
+ }
5473
+ }
5474
+ }
5475
+ };
5476
+ let mainExtract = {};
5477
+ let metaExtract = {};
5478
+ let tagsExtract = {};
5479
+ let rootExtract = {};
5480
+ let annoExtract = {
5481
+ ...defaultSchemaFieldsByTplLayout[tpl?.category] || {}
5482
+ };
5483
+ const extractedBlocks = extractAllBlocksFromTpl({ tpl });
5484
+ const annotationTagTypes = extractAllUniqueAnnoTagTypesFromTpl(extractedBlocks, {
5485
+ smTagTypesConfig
5486
+ });
5487
+ annotationTagTypes.forEach((annoTagType) => {
5488
+ const annotationFieldDef = compToTypeMap({
5489
+ block: { comp: "SPECIAL_AnnotationTagsField" }
5490
+ });
5491
+ annoExtract = setVal(annoExtract, `tags.${annoTagType}`, annotationFieldDef);
5492
+ });
5493
+ extractedBlocks.forEach((block) => {
5494
+ const { valuePath } = block;
5495
+ if (!valuePath) return;
5496
+ const pathSegments = valuePath.split(".");
5497
+ const [prefix, ...remainingPath] = pathSegments;
5498
+ const nestedPath = remainingPath.join(".");
5499
+ const fieldDefinition = compToTypeMap({ block });
5500
+ switch (prefix) {
5501
+ case "meta":
5502
+ metaExtract = setVal(
5503
+ metaExtract,
5504
+ nestedPath,
5505
+ // "author.name" (without "meta" prefix)
5506
+ fieldDefinition
5507
+ );
5508
+ break;
5509
+ case "main":
5510
+ mainExtract = setVal(
5511
+ mainExtract,
5512
+ nestedPath,
5513
+ // "content.title" (without "main" prefix)
5514
+ fieldDefinition
5515
+ );
5516
+ break;
5517
+ case "tags":
5518
+ tagsExtract = setVal(
5519
+ tagsExtract,
5520
+ nestedPath,
5521
+ // "categories.primary" (without "tags" prefix)
5522
+ fieldDefinition
5523
+ );
5524
+ break;
5525
+ default:
5526
+ if (block.comp && block.comp !== "TplMetaBlock" && valuePath !== ".") {
5527
+ rootExtract = setVal(
5528
+ rootExtract,
5529
+ valuePath,
5530
+ // Use full path since it's not prefixed
5531
+ fieldDefinition
5532
+ );
5533
+ }
5534
+ break;
5535
+ }
5536
+ });
5537
+ return {
5538
+ metaExtract,
5539
+ mainExtract,
5540
+ tagsExtract,
5541
+ rootExtract,
5542
+ annoExtract
5543
+ };
5544
+ };
5545
+
5546
+ // src/contentSchema/genContentTypeSchema.js
5547
+ var genContentTypeSchema = ({ contentType, segment, contentTypeConfig, smTagTypesConfig }) => {
5548
+ let SchemaToReturn;
5549
+ let {
5550
+ mainExtract = {},
5551
+ metaExtract = {},
5552
+ tagsExtract = {},
5553
+ rootExtract = {},
5554
+ annoExtract = {}
5555
+ } = getTypesForSchemaFromTpl({ tpl: contentTypeConfig, smTagTypesConfig });
5556
+ const schemaDef = {
5557
+ /**
5558
+ * this metadata is v.important from an optimization point of view.
5559
+ * it helps with getAllContrModelsByTenant, without having to
5560
+ * query the database for content type configurations.
5561
+ */
5562
+ metadata: {
5563
+ isContentType: { type: String, default: true },
5564
+ contentType: { type: String, default: contentType },
5565
+ segment: { type: String, default: segment }
5566
+ },
5567
+ ..._backOfficeFields__contr(contentType),
5568
+ ...rootExtract,
5569
+ tags: {
5570
+ ...tagsExtract
5571
+ },
5572
+ annotations: {
5573
+ ...annoExtract
5574
+ },
5575
+ meta: {
5576
+ ..._constantMeta__contr,
5577
+ ...metaExtract
5578
+ },
5579
+ main: {
5580
+ ..._fixedMainFields__contr,
5581
+ ...mainExtract
5582
+ },
5583
+ archive: Object,
5584
+ //burial ground for past fields that have eventually been removed from the tpl (and therefore the schema)
5585
+ translations: Object,
5586
+ reviewerNotes: Object,
5587
+ ..._reaction_contr,
5588
+ ..._comments__contr,
5589
+ ...segment === "publishing" && {
5590
+ shares: {
5591
+ count: {
5592
+ type: Number,
5593
+ default: 0
5594
+ }
5595
+ },
5596
+ views: {
5597
+ count: {
5598
+ type: Number,
5599
+ default: 0
5600
+ }
5601
+ }
5602
+ },
5603
+ updates: Object
5604
+ // DEPRECATED. DONT USE IT. DONT DELETE EITHER. ELSE WE WILL HAVE TO MAKE DATA UPDATES
5605
+ };
5606
+ SchemaToReturn = new import_mongoose12.default.Schema(schemaDef, {
5607
+ collection: contentType,
5608
+ toJSON: { virtuals: true },
5609
+ // So `res.json()` and other `JSON.stringify()` functions include virtuals
5610
+ toObject: { virtuals: true },
5611
+ // So `toObject()` output includes virtuals
5612
+ strict: "throw"
5613
+ //will throw an error if we try to add properties that arent on this schema
5614
+ });
5615
+ SchemaToReturn.index(
5616
+ { tagId: 1 },
5617
+ ...segment === "collections" ? [
5618
+ {
5619
+ unique: true,
5620
+ partialFilterExpression: {
5621
+ kp_published_status: { $eq: "published" }
5622
+ }
5623
+ }
5624
+ ] : []
5625
+ );
5626
+ SchemaToReturn.index({
5627
+ kp_published_status: 1,
5628
+ kp_date_published: -1,
5629
+ _id: -1
5630
+ });
5631
+ SchemaToReturn.index(
5632
+ { kp_published_status: 1, "main.title": 1, _id: 1 },
5633
+ { collation: { locale: "en", numericOrdering: true } }
5634
+ );
5635
+ SchemaToReturn.index({ kp_published_status: 1, kp_is_mod_clone: 1 });
5636
+ return SchemaToReturn;
5637
+ };
5638
+
5639
+ // src/TenantRegistry.js
5640
+ var import_storage = require("@google-cloud/storage");
5641
+ var BUCKET_NAME = "dots-system-configs";
5642
+ var FILE_NAME = "tenantRegistry.json";
5643
+ var TenantRegistry = class {
5644
+ // ─── Initialization ─────────────────────────────────
5645
+ /**
5646
+ * Must be awaited at startup before any sync getter is called.
5647
+ * Uses Application Default Credentials (ADC) for GCS auth.
5648
+ */
5649
+ static async init() {
5650
+ this._data = await this._load();
5651
+ this._rebuildCaches();
5652
+ this._lastRefreshAt = Date.now();
5653
+ }
5654
+ /**
5655
+ * Reload from GCS when this instance sees an unknown tenant/origin — likely one
5656
+ * provisioned on another instance after startup. Rate-limited; on failure keeps
5657
+ * the existing cache (never throws). Returns true if a reload actually ran.
5658
+ */
5659
+ static async refreshIfStale() {
5660
+ const now = Date.now();
5661
+ if (now - this._lastRefreshAt < this.REFRESH_COOLDOWN_MS) return false;
5662
+ this._lastRefreshAt = now;
5663
+ try {
5664
+ this._data = await this._load();
5665
+ this._rebuildCaches();
5666
+ return true;
5667
+ } catch (err) {
5668
+ console.error(`[TenantRegistry] refresh failed (keeping cache): ${err.message}`);
5669
+ return false;
5670
+ }
5671
+ }
5672
+ // ─── Storage layer (swap only these to change backend) ───
5673
+ static async _load() {
5674
+ const storage = new import_storage.Storage();
5675
+ const file = storage.bucket(BUCKET_NAME).file(FILE_NAME);
5676
+ const [buffer] = await file.download();
5677
+ const { data } = JSON.parse(buffer.toString("utf-8"));
5678
+ console.log(`[TenantRegistry] Loaded ${data.length} tenants from GCS`);
5679
+ return data;
5680
+ }
5681
+ static async _save() {
5682
+ const storage = new import_storage.Storage();
5683
+ const file = storage.bucket(BUCKET_NAME).file(FILE_NAME);
5684
+ await file.save(JSON.stringify({ data: this._data }, null, 2), {
5685
+ contentType: "application/json"
5686
+ });
5687
+ }
5688
+ // ─── End storage layer ──────────────────────────────
5689
+ static _rebuildCaches() {
5690
+ this._byEnv = {};
5691
+ this._selfManagedSet = /* @__PURE__ */ new Set();
5692
+ for (const entry of this._data) {
5693
+ const { tenantId, urls, isSelfManaged } = entry;
5694
+ if (isSelfManaged) this._selfManagedSet.add(tenantId);
5695
+ for (const env of ["dev", "staging", "prod"]) {
5696
+ if (!urls[env]) continue;
5697
+ if (!this._byEnv[env]) this._byEnv[env] = {};
5698
+ this._byEnv[env][tenantId] = urls[env];
5699
+ }
5700
+ }
5701
+ }
5702
+ // ─── Sync getters ───────────────────────────────────
5703
+ /** { tenantId: url } for the given env */
5704
+ static getMappingsForEnv(env) {
5705
+ return this._byEnv[env] || {};
5706
+ }
5707
+ /** [url, url, ...] for the given env */
5708
+ static getUrlsForEnv(env) {
5709
+ return Object.values(this._byEnv[env] || {});
5710
+ }
5711
+ /** [tenantId, tenantId, ...] for the given env */
5712
+ static getTenantIdsForEnv(env) {
5713
+ return Object.keys(this._byEnv[env] || {});
5714
+ }
5715
+ /** Single URL for a tenant+env, or undefined */
5716
+ static getUrl(tenant, env) {
5717
+ return (this._byEnv[env] || {})[tenant];
5718
+ }
5719
+ static isSelfManaged(tenant) {
5720
+ return this._selfManagedSet.has(tenant);
5721
+ }
5722
+ static getSelfManagedTenantIds() {
5723
+ return [...this._selfManagedSet];
5724
+ }
5725
+ /** Full registry data array (read-only snapshot) */
5726
+ static getData() {
5727
+ return this._data;
5728
+ }
5729
+ // ─── Mutator ────────────────────────────────────────
5730
+ /**
5731
+ * Idempotent: removes existing entry for tenantId (if any), then adds.
5732
+ * Persists to GCS and updates in-memory caches.
5733
+ */
5734
+ static async addTenant({ tenantId, urls, isSelfManaged = false }) {
5735
+ this._data = this._data.filter((e) => e.tenantId !== tenantId);
5736
+ this._data.push({ tenantId, urls, isSelfManaged });
5737
+ await this._save();
5738
+ this._rebuildCaches();
5739
+ }
5740
+ /**
5741
+ * Idempotent inverse of addTenant: drops the tenant's entry from the registry,
5742
+ * persists to GCS, and rebuilds in-memory caches (so the tenant stops resolving
5743
+ * on THIS instance immediately). Returns true if an entry was actually removed.
5744
+ * Other running instances pick up the removal via refreshIfStale() on their next
5745
+ * unknown-origin miss.
5746
+ */
5747
+ static async removeTenant(tenantId) {
5748
+ const before = this._data.length;
5749
+ this._data = this._data.filter((e) => e.tenantId !== tenantId);
5750
+ const removed = this._data.length < before;
5751
+ if (removed) {
5752
+ await this._save();
5753
+ this._rebuildCaches();
5754
+ }
5755
+ return removed;
5756
+ }
5757
+ };
5758
+ // ─── In-memory state ────────────────────────────────
5759
+ __publicField(TenantRegistry, "_data", null);
5760
+ // [{ tenantId, urls: { dev, staging, prod }, isSelfManaged }]
5761
+ __publicField(TenantRegistry, "_byEnv", {});
5762
+ // { dev: { tenantId: url }, staging: {...}, prod: {...} }
5763
+ __publicField(TenantRegistry, "_selfManagedSet", /* @__PURE__ */ new Set());
5764
+ // On-miss refresh rate-limit (see refreshIfStale).
5765
+ __publicField(TenantRegistry, "_lastRefreshAt", 0);
5766
+ __publicField(TenantRegistry, "REFRESH_COOLDOWN_MS", 3e4);
5767
+
5768
+ // src/contentSchema/selfManagedAnnotationTagTypesConfig.js
5769
+ var SM_ANNOTATION_TAG_TYPES_CONFIG = [{ tagType: "tags" }];
5770
+ var getSmTagTypesConfigForTenant = async (tenant) => {
5771
+ return TenantRegistry.isSelfManaged(tenant) ? SM_ANNOTATION_TAG_TYPES_CONFIG : null;
5772
+ };
5773
+
5774
+ // src/db/getContrModelByTenant.js
5775
+ var import_getModelByTenant3 = __toESM(require_getModelByTenant());
5776
+ init_getDbByTenant();
5777
+
5778
+ // src/db/getTpl.js
5009
5779
  var import_getModelByTenant2 = __toESM(require_getModelByTenant());
5780
+ var getTpl = async ({ tenant, contentType, env, source = "db" }) => {
5781
+ if (source === "cache") {
5782
+ return RedisCacheConnector.findOneConfigInCache({
5783
+ tenant,
5784
+ modelName: "tpl",
5785
+ type: contentType,
5786
+ env
5787
+ });
5788
+ }
5789
+ return (0, import_getModelByTenant2.getTplModelByTenant)({ tenant, env }).findOne({ kp_content_type: contentType }).lean();
5790
+ };
5791
+
5792
+ // src/db/getContrModelByTenant.js
5793
+ var getContrModelByTenant = async ({
5794
+ tenant,
5795
+ contentType,
5796
+ env = process.env.ENV,
5797
+ // v.imp, else the reuse check below always fails when env isn't passed (env is meant to be optional)
5798
+ tpl,
5799
+ //optional : if passed uses it instead of fetching the tpl for this contenttype from db. important in the case of _createTpl, where, within a transaction we create a tpl and then use this tpl to create some content against it. since this is within a transaction, this newly created tpl wont be available in the db just yet.
5800
+ tplSource = "db",
5801
+ // "db" (okf-be default, original semantics) | "cache" (okf-sub — tpl cache is kept in sync on every tpl write)
5802
+ /**
5803
+ * When true, the registered-model reuse is SKIPPED — the schema is rebuilt
5804
+ * from the current tpl on every call (~5-10ms CPU + the tpl read).
5805
+ *
5806
+ * okf-sub passes this on every collab call: unlike okf-be — which
5807
+ * invalidates registered models on tpl change via
5808
+ * reRegisterModelInLocalCache + the '${env}-tpl-model-recache' Pub/Sub —
5809
+ * okf-sub subscribes to nothing, so a reused model could carry a stale
5810
+ * schema after a tpl edit, and strict:"throw" would reject collab flushes
5811
+ * for newly added fields. Rebuilding every time is correct by
5812
+ * construction: no freshness bookkeeping for tpl write paths (or raw
5813
+ * mongodbscripts that mutate tpls + recache) to ever get wrong.
5814
+ */
5815
+ rebuild = false
5816
+ }) => {
5817
+ try {
5818
+ const db = getDbByTenant({ tenant });
5819
+ if (!rebuild && db.models[contentType] && env === process.env.ENV && !tpl) {
5820
+ const modelToReturn = db.model(contentType);
5821
+ if (modelToReturn.schema.obj.metadata && modelToReturn.schema.obj.metadata.isContentType && modelToReturn.schema.obj.metadata.isContentType.default === true) {
5822
+ return modelToReturn;
5823
+ }
5824
+ return void 0;
5825
+ }
5826
+ const contentTypeConfig = tpl || await getTpl({ tenant, contentType, env, source: tplSource });
5827
+ if (!contentTypeConfig) return void 0;
5828
+ const smTagTypesConfig = await getSmTagTypesConfigForTenant(tenant);
5829
+ const thisSchema = genContentTypeSchema({
5830
+ contentType,
5831
+ segment: contentTypeConfig.general?.segment,
5832
+ contentTypeConfig,
5833
+ smTagTypesConfig
5834
+ });
5835
+ if (rebuild && db.models[contentType]) {
5836
+ db.deleteModel(contentType);
5837
+ }
5838
+ return (0, import_getModelByTenant3.getModelByTenant)({
5839
+ tenant,
5840
+ modelName: contentType,
5841
+ schema: thisSchema,
5842
+ env
5843
+ });
5844
+ } catch (err) {
5845
+ throw err;
5846
+ }
5847
+ };
5848
+
5849
+ // src/node.ts
5010
5850
  init_models();
5011
5851
  var import_WorkerManager = __toESM(require_WorkerManager());
5012
5852
  var import_ProducerManager = __toESM(require_ProducerManager());
@@ -5015,6 +5855,7 @@ var import_BaseFlowProducer = __toESM(require_BaseFlowProducer());
5015
5855
  var import_BaseWorker = __toESM(require_BaseWorker());
5016
5856
  var import_ChunksElasticSyncProducer = __toESM(require_ChunksElasticSyncProducer());
5017
5857
  var import_AnnosElasticSyncProducer = __toESM(require_AnnosElasticSyncProducer());
5858
+ var import_ContentElasticSyncProducer = __toESM(require_ContentElasticSyncProducer());
5018
5859
  var import_GET_GLOBAL_BULLMQ_CONFIG = __toESM(require_GET_GLOBAL_BULLMQ_CONFIG());
5019
5860
  // Annotate the CommonJS export names for ESM import in node:
5020
5861
  0 && (module.exports = {
@@ -5028,6 +5869,7 @@ var import_GET_GLOBAL_BULLMQ_CONFIG = __toESM(require_GET_GLOBAL_BULLMQ_CONFIG()
5028
5869
  BlockRegistry,
5029
5870
  CHUNKING_PRESETS,
5030
5871
  ChunksElasticSyncProducer,
5872
+ ContentElasticSyncProducer,
5031
5873
  ELASTIC_MAPPING_PRESETS,
5032
5874
  ElasticSearchConnector,
5033
5875
  FILTER_IDS,
@@ -5041,9 +5883,13 @@ var import_GET_GLOBAL_BULLMQ_CONFIG = __toESM(require_GET_GLOBAL_BULLMQ_CONFIG()
5041
5883
  RedisCacheConnector,
5042
5884
  SecretManagerConnector,
5043
5885
  TEMP_removeDuplicateFilters,
5886
+ TenantRegistry,
5044
5887
  TplSchema,
5045
5888
  UI_CONTENT,
5046
5889
  WorkerManager,
5890
+ _backOfficeFields__contr,
5891
+ _constantMeta__contr,
5892
+ _fixedMainFields__contr,
5047
5893
  _self_managed_buildAnnoHierarchyConfig,
5048
5894
  _self_managed_buildDocHierarchyConfig,
5049
5895
  _self_managed_getFixedAnnoRollupBlocks,
@@ -5055,13 +5901,17 @@ var import_GET_GLOBAL_BULLMQ_CONFIG = __toESM(require_GET_GLOBAL_BULLMQ_CONFIG()
5055
5901
  compareAndGroupBlocks,
5056
5902
  deleteVal,
5057
5903
  extractAllBlocksFromTpl,
5904
+ extractAllUniqueAnnoTagTypesFromTpl,
5058
5905
  extractAndOrganizeBlocks,
5906
+ extractNumberFromValue,
5059
5907
  genCleanCamelCaseId,
5908
+ genContentTypeSchema,
5060
5909
  genTagId,
5061
5910
  generateFilterKey,
5062
5911
  getAIChatModelByTenant,
5063
5912
  getAnnoFilterBucketKey,
5064
5913
  getAnnotationsModelByTenant,
5914
+ getContrModelByTenant,
5065
5915
  getDbByTenant,
5066
5916
  getFilterKeyForBlock,
5067
5917
  getGeneratedEntitiesModelByTenant,
@@ -5078,7 +5928,9 @@ var import_GET_GLOBAL_BULLMQ_CONFIG = __toESM(require_GET_GLOBAL_BULLMQ_CONFIG()
5078
5928
  getRoutePathToReviewDashboard,
5079
5929
  getRoutePathToTCI,
5080
5930
  getRoutePathToTagCategoryLanding,
5931
+ getTpl,
5081
5932
  getTplModelByTenant,
5933
+ getTypesForSchemaFromTpl,
5082
5934
  getVal,
5083
5935
  isTplAnnotationEnabled,
5084
5936
  mergeAnnoDataIntoAnnotationsTags,