@okf/ootils 1.31.5 → 1.32.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/node.d.mts CHANGED
@@ -1425,6 +1425,15 @@ declare const UI_CONTENT: {
1425
1425
  */
1426
1426
  declare const genCleanCamelCaseId: (id: string) => string;
1427
1427
 
1428
+ /**
1429
+ * Convert a plain text string into the standard Lexical value shape
1430
+ * used across the platform: { allText, isLexical, editorState }.
1431
+ *
1432
+ * If the value is already Lexical (has `isLexical: true`), returns it as-is.
1433
+ * Each line in the text becomes its own paragraph node.
1434
+ */
1435
+ declare const plainTextToLexical: (value: string | number | any) => any;
1436
+
1428
1437
  /**
1429
1438
  * BlockDef — single source of truth for a tplBlock's cross-cutting configuration.
1430
1439
  *
@@ -1436,6 +1445,18 @@ interface BlockDef {
1436
1445
  compName: string;
1437
1446
  category: 'text' | 'selection' | 'tags' | 'date' | 'number' | 'media' | 'structural' | 'special';
1438
1447
  qualQuant: 'qual' | 'quant' | null;
1448
+ /**
1449
+ * Optional gate that downgrades a block instance from its declared qualQuant unless
1450
+ * ALL conditions match. Used for blocks whose qual-ness depends on a per-instance prop
1451
+ * (e.g. AudioInput is only qual when `props.transcription.enable === true`).
1452
+ *
1453
+ * Each condition is a dotted path into `block.props` with a required value.
1454
+ * No conditions / undefined → block's qualQuant applies unconditionally.
1455
+ */
1456
+ qualConditions?: Array<{
1457
+ propPath: string;
1458
+ equals: any;
1459
+ }>;
1439
1460
  /** Mongoose schema type — the actual value returned to compToTypeMap (e.g. { type: Object }) */
1440
1461
  mongoSchemaType: Record<string, any>;
1441
1462
  /** Elasticsearch mapping shape — used directly by generateMappingsFromTpl */
@@ -1447,8 +1468,6 @@ interface BlockDef {
1447
1468
  plainTextString?: string | null;
1448
1469
  /** Path appended to valuePath for ES/listing search (e.g. 'allText'). null = valuePath used directly. */
1449
1470
  searchField?: string | null;
1450
- /** Path to get display value for table/card rendering (e.g. 'allText'). null = value itself. */
1451
- displayValue?: string | null;
1452
1471
  };
1453
1472
  validation: {
1454
1473
  /** Name of the "is populated" validator fn (resolved by consumer) */
@@ -1566,6 +1585,9 @@ declare const MONGO_SCHEMA_PRESETS: {
1566
1585
  readonly string: {
1567
1586
  readonly type: StringConstructor;
1568
1587
  };
1588
+ readonly array: {
1589
+ readonly type: ArrayConstructor;
1590
+ };
1569
1591
  };
1570
1592
  declare const ELASTIC_MAPPING_PRESETS: {
1571
1593
  readonly largeText: {
@@ -1576,6 +1598,26 @@ declare const ELASTIC_MAPPING_PRESETS: {
1576
1598
  };
1577
1599
  };
1578
1600
  };
1601
+ readonly audioTranscription: {
1602
+ readonly properties: {
1603
+ readonly transcription: {
1604
+ readonly properties: {
1605
+ readonly result: {
1606
+ readonly properties: {
1607
+ readonly finalText: {
1608
+ readonly properties: {
1609
+ readonly allText: {
1610
+ readonly type: "text";
1611
+ readonly analyzer: "LargeTextAnalyzer";
1612
+ };
1613
+ };
1614
+ };
1615
+ };
1616
+ };
1617
+ };
1618
+ };
1619
+ };
1620
+ };
1579
1621
  };
1580
1622
  declare const CHUNKING_PRESETS: {
1581
1623
  readonly lexicalSemantic: {
@@ -1616,8 +1658,24 @@ declare class BlockRegistry {
1616
1658
  getQualBlocks(): string[];
1617
1659
  /** Get compType strings for all quant blocks. */
1618
1660
  getQuantBlocks(): string[];
1661
+ /**
1662
+ * Returns true if a specific block instance should be treated as qualitative.
1663
+ * Combines the static `qualQuant` flag with any per-instance `qualConditions`
1664
+ * — e.g. AudioInput is only qual when `props.transcription.enable === true`.
1665
+ */
1666
+ isQualBlock(block: {
1667
+ comp: string;
1668
+ props?: any;
1669
+ }): boolean;
1619
1670
  /** Check if a specific block has a specific capability. */
1620
1671
  hasCapability(compType: string, capability: keyof BlockCapabilities): boolean;
1672
+ /**
1673
+ * Returns true if the block stores its value as an array (Mongo schema type is Array).
1674
+ * Useful for callers that need to know whether to query `valuePath.0` for existence
1675
+ * vs just `valuePath` — empty arrays still pass `$exists: true` on the field itself.
1676
+ * Returns false for unregistered blocks.
1677
+ */
1678
+ isArrayShaped(compType: string): boolean;
1621
1679
  /** Get all registered block descriptors. */
1622
1680
  getAll(): BlockDef[];
1623
1681
  /**
@@ -2398,4 +2456,4 @@ declare function GET_GLOBAL_BULLMQ_CONFIG({ env, redisCredentials }: {
2398
2456
  };
2399
2457
  }): Object;
2400
2458
 
2401
- export { AIChatSchema, AnnosElasticSyncProducer, AnnotationSchema, BASE_BULLMQ_CONFIG, BaseProducer, BaseWorker, type BlockCapabilities, type BlockDef, BlockRegistry, CHUNKING_PRESETS, ChunksElasticSyncProducer, ELASTIC_MAPPING_PRESETS, ElasticSearchConnector, FILTER_IDS, GET_GLOBAL_BULLMQ_CONFIG, GeneratedEntitiesSchema, GeneratedTopicsSchema, MONGO_SCHEMA_PRESETS, MongoConnector, PlatformConfigsSchema, ProducerManager, RedisCacheConnector, SecretManagerConnector, TEMP_removeDuplicateFilters, TplSchema, UI_CONTENT, WorkerManager, _self_managed_buildAnnoHierarchyConfig, _self_managed_buildDocHierarchyConfig, _self_managed_getFixedAnnoRollupBlocks, _self_managed_getFixedAnnoTagBlock, autoGenFilterConfigsFromTpl, blockRegistry, buildFilterConfigurations, compareAndGroupBlocks, deleteVal, extractAllBlocksFromTpl, extractAndOrganizeBlocks, genCleanCamelCaseId, genTagId, generateFilterKey, getAIChatModelByTenant, getAnnotationsModelByTenant, getDbByTenant, getFilterKeyForBlock, getGeneratedEntitiesModelByTenant, getGeneratedTopicsModelByTenant, getModelByTenant, getPlatformConfigsModelByTenant, getPlatformContextContent, getRollupPossibilities, getRoutePathToContentTypeLanding, getRoutePathToEditContent, getRoutePathToModerateContent, getRoutePathToMyContent, getRoutePathToPublishedContent, getRoutePathToReviewDashboard, getRoutePathToTCI, getRoutePathToTagCategoryLanding, getTplModelByTenant, getVal, isTplAnnotationEnabled, mergeAnnoDataIntoAnnotationsTags, parseSpecialConfigSyntax, processAuthorAndCommonFilters, _recursExtractBlocks as recursivelyExtractBlocks, segrigateDocs, setVal, toArray };
2459
+ export { AIChatSchema, AnnosElasticSyncProducer, AnnotationSchema, BASE_BULLMQ_CONFIG, BaseProducer, BaseWorker, type BlockCapabilities, type BlockDef, BlockRegistry, CHUNKING_PRESETS, ChunksElasticSyncProducer, ELASTIC_MAPPING_PRESETS, ElasticSearchConnector, FILTER_IDS, GET_GLOBAL_BULLMQ_CONFIG, GeneratedEntitiesSchema, GeneratedTopicsSchema, MONGO_SCHEMA_PRESETS, MongoConnector, PlatformConfigsSchema, ProducerManager, RedisCacheConnector, SecretManagerConnector, TEMP_removeDuplicateFilters, TplSchema, UI_CONTENT, WorkerManager, _self_managed_buildAnnoHierarchyConfig, _self_managed_buildDocHierarchyConfig, _self_managed_getFixedAnnoRollupBlocks, _self_managed_getFixedAnnoTagBlock, autoGenFilterConfigsFromTpl, blockRegistry, buildFilterConfigurations, compareAndGroupBlocks, deleteVal, extractAllBlocksFromTpl, extractAndOrganizeBlocks, genCleanCamelCaseId, genTagId, generateFilterKey, getAIChatModelByTenant, getAnnotationsModelByTenant, getDbByTenant, getFilterKeyForBlock, getGeneratedEntitiesModelByTenant, getGeneratedTopicsModelByTenant, getModelByTenant, getPlatformConfigsModelByTenant, getPlatformContextContent, getRollupPossibilities, getRoutePathToContentTypeLanding, getRoutePathToEditContent, getRoutePathToModerateContent, getRoutePathToMyContent, getRoutePathToPublishedContent, getRoutePathToReviewDashboard, getRoutePathToTCI, getRoutePathToTagCategoryLanding, getTplModelByTenant, getVal, isTplAnnotationEnabled, mergeAnnoDataIntoAnnotationsTags, parseSpecialConfigSyntax, plainTextToLexical, processAuthorAndCommonFilters, _recursExtractBlocks as recursivelyExtractBlocks, segrigateDocs, setVal, toArray };
package/dist/node.d.ts CHANGED
@@ -1425,6 +1425,15 @@ declare const UI_CONTENT: {
1425
1425
  */
1426
1426
  declare const genCleanCamelCaseId: (id: string) => string;
1427
1427
 
1428
+ /**
1429
+ * Convert a plain text string into the standard Lexical value shape
1430
+ * used across the platform: { allText, isLexical, editorState }.
1431
+ *
1432
+ * If the value is already Lexical (has `isLexical: true`), returns it as-is.
1433
+ * Each line in the text becomes its own paragraph node.
1434
+ */
1435
+ declare const plainTextToLexical: (value: string | number | any) => any;
1436
+
1428
1437
  /**
1429
1438
  * BlockDef — single source of truth for a tplBlock's cross-cutting configuration.
1430
1439
  *
@@ -1436,6 +1445,18 @@ interface BlockDef {
1436
1445
  compName: string;
1437
1446
  category: 'text' | 'selection' | 'tags' | 'date' | 'number' | 'media' | 'structural' | 'special';
1438
1447
  qualQuant: 'qual' | 'quant' | null;
1448
+ /**
1449
+ * Optional gate that downgrades a block instance from its declared qualQuant unless
1450
+ * ALL conditions match. Used for blocks whose qual-ness depends on a per-instance prop
1451
+ * (e.g. AudioInput is only qual when `props.transcription.enable === true`).
1452
+ *
1453
+ * Each condition is a dotted path into `block.props` with a required value.
1454
+ * No conditions / undefined → block's qualQuant applies unconditionally.
1455
+ */
1456
+ qualConditions?: Array<{
1457
+ propPath: string;
1458
+ equals: any;
1459
+ }>;
1439
1460
  /** Mongoose schema type — the actual value returned to compToTypeMap (e.g. { type: Object }) */
1440
1461
  mongoSchemaType: Record<string, any>;
1441
1462
  /** Elasticsearch mapping shape — used directly by generateMappingsFromTpl */
@@ -1447,8 +1468,6 @@ interface BlockDef {
1447
1468
  plainTextString?: string | null;
1448
1469
  /** Path appended to valuePath for ES/listing search (e.g. 'allText'). null = valuePath used directly. */
1449
1470
  searchField?: string | null;
1450
- /** Path to get display value for table/card rendering (e.g. 'allText'). null = value itself. */
1451
- displayValue?: string | null;
1452
1471
  };
1453
1472
  validation: {
1454
1473
  /** Name of the "is populated" validator fn (resolved by consumer) */
@@ -1566,6 +1585,9 @@ declare const MONGO_SCHEMA_PRESETS: {
1566
1585
  readonly string: {
1567
1586
  readonly type: StringConstructor;
1568
1587
  };
1588
+ readonly array: {
1589
+ readonly type: ArrayConstructor;
1590
+ };
1569
1591
  };
1570
1592
  declare const ELASTIC_MAPPING_PRESETS: {
1571
1593
  readonly largeText: {
@@ -1576,6 +1598,26 @@ declare const ELASTIC_MAPPING_PRESETS: {
1576
1598
  };
1577
1599
  };
1578
1600
  };
1601
+ readonly audioTranscription: {
1602
+ readonly properties: {
1603
+ readonly transcription: {
1604
+ readonly properties: {
1605
+ readonly result: {
1606
+ readonly properties: {
1607
+ readonly finalText: {
1608
+ readonly properties: {
1609
+ readonly allText: {
1610
+ readonly type: "text";
1611
+ readonly analyzer: "LargeTextAnalyzer";
1612
+ };
1613
+ };
1614
+ };
1615
+ };
1616
+ };
1617
+ };
1618
+ };
1619
+ };
1620
+ };
1579
1621
  };
1580
1622
  declare const CHUNKING_PRESETS: {
1581
1623
  readonly lexicalSemantic: {
@@ -1616,8 +1658,24 @@ declare class BlockRegistry {
1616
1658
  getQualBlocks(): string[];
1617
1659
  /** Get compType strings for all quant blocks. */
1618
1660
  getQuantBlocks(): string[];
1661
+ /**
1662
+ * Returns true if a specific block instance should be treated as qualitative.
1663
+ * Combines the static `qualQuant` flag with any per-instance `qualConditions`
1664
+ * — e.g. AudioInput is only qual when `props.transcription.enable === true`.
1665
+ */
1666
+ isQualBlock(block: {
1667
+ comp: string;
1668
+ props?: any;
1669
+ }): boolean;
1619
1670
  /** Check if a specific block has a specific capability. */
1620
1671
  hasCapability(compType: string, capability: keyof BlockCapabilities): boolean;
1672
+ /**
1673
+ * Returns true if the block stores its value as an array (Mongo schema type is Array).
1674
+ * Useful for callers that need to know whether to query `valuePath.0` for existence
1675
+ * vs just `valuePath` — empty arrays still pass `$exists: true` on the field itself.
1676
+ * Returns false for unregistered blocks.
1677
+ */
1678
+ isArrayShaped(compType: string): boolean;
1621
1679
  /** Get all registered block descriptors. */
1622
1680
  getAll(): BlockDef[];
1623
1681
  /**
@@ -2398,4 +2456,4 @@ declare function GET_GLOBAL_BULLMQ_CONFIG({ env, redisCredentials }: {
2398
2456
  };
2399
2457
  }): Object;
2400
2458
 
2401
- export { AIChatSchema, AnnosElasticSyncProducer, AnnotationSchema, BASE_BULLMQ_CONFIG, BaseProducer, BaseWorker, type BlockCapabilities, type BlockDef, BlockRegistry, CHUNKING_PRESETS, ChunksElasticSyncProducer, ELASTIC_MAPPING_PRESETS, ElasticSearchConnector, FILTER_IDS, GET_GLOBAL_BULLMQ_CONFIG, GeneratedEntitiesSchema, GeneratedTopicsSchema, MONGO_SCHEMA_PRESETS, MongoConnector, PlatformConfigsSchema, ProducerManager, RedisCacheConnector, SecretManagerConnector, TEMP_removeDuplicateFilters, TplSchema, UI_CONTENT, WorkerManager, _self_managed_buildAnnoHierarchyConfig, _self_managed_buildDocHierarchyConfig, _self_managed_getFixedAnnoRollupBlocks, _self_managed_getFixedAnnoTagBlock, autoGenFilterConfigsFromTpl, blockRegistry, buildFilterConfigurations, compareAndGroupBlocks, deleteVal, extractAllBlocksFromTpl, extractAndOrganizeBlocks, genCleanCamelCaseId, genTagId, generateFilterKey, getAIChatModelByTenant, getAnnotationsModelByTenant, getDbByTenant, getFilterKeyForBlock, getGeneratedEntitiesModelByTenant, getGeneratedTopicsModelByTenant, getModelByTenant, getPlatformConfigsModelByTenant, getPlatformContextContent, getRollupPossibilities, getRoutePathToContentTypeLanding, getRoutePathToEditContent, getRoutePathToModerateContent, getRoutePathToMyContent, getRoutePathToPublishedContent, getRoutePathToReviewDashboard, getRoutePathToTCI, getRoutePathToTagCategoryLanding, getTplModelByTenant, getVal, isTplAnnotationEnabled, mergeAnnoDataIntoAnnotationsTags, parseSpecialConfigSyntax, processAuthorAndCommonFilters, _recursExtractBlocks as recursivelyExtractBlocks, segrigateDocs, setVal, toArray };
2459
+ export { AIChatSchema, AnnosElasticSyncProducer, AnnotationSchema, BASE_BULLMQ_CONFIG, BaseProducer, BaseWorker, type BlockCapabilities, type BlockDef, BlockRegistry, CHUNKING_PRESETS, ChunksElasticSyncProducer, ELASTIC_MAPPING_PRESETS, ElasticSearchConnector, FILTER_IDS, GET_GLOBAL_BULLMQ_CONFIG, GeneratedEntitiesSchema, GeneratedTopicsSchema, MONGO_SCHEMA_PRESETS, MongoConnector, PlatformConfigsSchema, ProducerManager, RedisCacheConnector, SecretManagerConnector, TEMP_removeDuplicateFilters, TplSchema, UI_CONTENT, WorkerManager, _self_managed_buildAnnoHierarchyConfig, _self_managed_buildDocHierarchyConfig, _self_managed_getFixedAnnoRollupBlocks, _self_managed_getFixedAnnoTagBlock, autoGenFilterConfigsFromTpl, blockRegistry, buildFilterConfigurations, compareAndGroupBlocks, deleteVal, extractAllBlocksFromTpl, extractAndOrganizeBlocks, genCleanCamelCaseId, genTagId, generateFilterKey, getAIChatModelByTenant, getAnnotationsModelByTenant, getDbByTenant, getFilterKeyForBlock, getGeneratedEntitiesModelByTenant, getGeneratedTopicsModelByTenant, getModelByTenant, getPlatformConfigsModelByTenant, getPlatformContextContent, getRollupPossibilities, getRoutePathToContentTypeLanding, getRoutePathToEditContent, getRoutePathToModerateContent, getRoutePathToMyContent, getRoutePathToPublishedContent, getRoutePathToReviewDashboard, getRoutePathToTCI, getRoutePathToTagCategoryLanding, getTplModelByTenant, getVal, isTplAnnotationEnabled, mergeAnnoDataIntoAnnotationsTags, parseSpecialConfigSyntax, plainTextToLexical, processAuthorAndCommonFilters, _recursExtractBlocks as recursivelyExtractBlocks, segrigateDocs, setVal, toArray };
package/dist/node.js CHANGED
@@ -2035,6 +2035,7 @@ __export(node_exports, {
2035
2035
  isTplAnnotationEnabled: () => isTplAnnotationEnabled,
2036
2036
  mergeAnnoDataIntoAnnotationsTags: () => mergeAnnoDataIntoAnnotationsTags,
2037
2037
  parseSpecialConfigSyntax: () => parseSpecialConfigSyntax,
2038
+ plainTextToLexical: () => plainTextToLexical,
2038
2039
  processAuthorAndCommonFilters: () => processAuthorAndCommonFilters,
2039
2040
  recursivelyExtractBlocks: () => _recursExtractBlocks,
2040
2041
  segrigateDocs: () => segrigateDocs,
@@ -2357,7 +2358,8 @@ var _extractBlocksFromSomeBuilders = ({
2357
2358
  // src/blockRegistry/schemaPresets.ts
2358
2359
  var MONGO_SCHEMA_PRESETS = {
2359
2360
  object: { type: Object },
2360
- string: { type: String }
2361
+ string: { type: String },
2362
+ array: { type: Array }
2361
2363
  };
2362
2364
  var ELASTIC_MAPPING_PRESETS = {
2363
2365
  largeText: {
@@ -2367,6 +2369,29 @@ var ELASTIC_MAPPING_PRESETS = {
2367
2369
  analyzer: "LargeTextAnalyzer"
2368
2370
  }
2369
2371
  }
2372
+ },
2373
+ // Audio file value (array of one object) — only the transcription.result.finalText.allText
2374
+ // is indexed as searchable text. finalText is stored in Lexical shape; allText is the
2375
+ // plain text within it. Everything else on the audio object is ignored by ES.
2376
+ audioTranscription: {
2377
+ properties: {
2378
+ transcription: {
2379
+ properties: {
2380
+ result: {
2381
+ properties: {
2382
+ finalText: {
2383
+ properties: {
2384
+ allText: {
2385
+ type: "text",
2386
+ analyzer: "LargeTextAnalyzer"
2387
+ }
2388
+ }
2389
+ }
2390
+ }
2391
+ }
2392
+ }
2393
+ }
2394
+ }
2370
2395
  }
2371
2396
  };
2372
2397
  var CHUNKING_PRESETS = {
@@ -2408,8 +2433,7 @@ var LexicalTextEditor = {
2408
2433
  // Field paths
2409
2434
  fieldPaths: {
2410
2435
  plainTextString: "allText",
2411
- searchField: "allText",
2412
- displayValue: "allText"
2436
+ searchField: "allText"
2413
2437
  },
2414
2438
  // Validation
2415
2439
  validation: {
@@ -2447,11 +2471,72 @@ var LexicalTextEditor = {
2447
2471
  chunkingConfig: CHUNKING_PRESETS.lexicalSemantic
2448
2472
  };
2449
2473
 
2474
+ // src/blockRegistry/blocks/AudioInput.ts
2475
+ var AudioInput = {
2476
+ compName: "AudioInput",
2477
+ // Identity
2478
+ category: "media",
2479
+ qualQuant: "qual",
2480
+ // Only qualitative when the tpl block has transcription turned on.
2481
+ // A non-transcribed audio input has no text to analyze, so downstream
2482
+ // qual widgets / search tools should skip it.
2483
+ qualConditions: [
2484
+ { propPath: "transcription.enable", equals: true }
2485
+ ],
2486
+ // Schema
2487
+ mongoSchemaType: MONGO_SCHEMA_PRESETS.array,
2488
+ esMapping: ELASTIC_MAPPING_PRESETS.audioTranscription,
2489
+ // Capabilities
2490
+ capabilities: {
2491
+ // Text lives at transcription.result.finalText on the first (and only) audio item,
2492
+ // derived by the Sarvam adapter into a single canonical field.
2493
+ hasPlainText: true,
2494
+ annotation: true,
2495
+ aiAnnotation: true,
2496
+ aiEnrichment: true,
2497
+ searchable: true,
2498
+ directDataImport: false,
2499
+ csvExport: true,
2500
+ // Translation already happens at the Sarvam level via translateToEnglish flag,
2501
+ // so the autoTranslate pipeline doesn't need to touch this block.
2502
+ translatable: false,
2503
+ documentSummarizer: true,
2504
+ // Transcription payloads can be large — strip from chunk/anno main snapshots
2505
+ // and listing projections.
2506
+ stripFromMainOnAnnoChunkSync: true,
2507
+ excludeFromListingProjection: true
2508
+ },
2509
+ // Field paths
2510
+ // `plainTextString` is the Mongo path consumed by getVal (supports the leading
2511
+ // array index). `searchField` is the ES path — ES flattens arrays of objects
2512
+ // so no index is needed there.
2513
+ fieldPaths: {
2514
+ plainTextString: "0.transcription.result.finalText.allText",
2515
+ searchField: "transcription.result.finalText.allText"
2516
+ },
2517
+ // Validation
2518
+ validation: {
2519
+ populatedCheckFn: "valueArrayIsNotEmpty"
2520
+ },
2521
+ // CSV export — existing transformStructureComp switch routes AudioInput to
2522
+ // formatMediaLinks (outputs audio URLs).
2523
+ csvExport: {
2524
+ transformFn: "formatMediaLinks"
2525
+ },
2526
+ // Chunking — finalText is long free-form speech, so semantic chunking applies.
2527
+ chunkingConfig: CHUNKING_PRESETS.lexicalSemantic,
2528
+ // Content block option — matches the current static entry exactly
2529
+ contentBlockOption: {
2530
+ display: "Audio Input"
2531
+ }
2532
+ };
2533
+
2450
2534
  // src/blockRegistry/registry.ts
2451
2535
  var BlockRegistry = class {
2452
2536
  constructor() {
2453
2537
  this.blocks = /* @__PURE__ */ new Map();
2454
2538
  this.register(LexicalTextEditor);
2539
+ this.register(AudioInput);
2455
2540
  }
2456
2541
  /** Register a block descriptor. */
2457
2542
  register(descriptor) {
@@ -2498,12 +2583,36 @@ var BlockRegistry = class {
2498
2583
  getQuantBlocks() {
2499
2584
  return Array.from(this.blocks.values()).filter((b) => b.qualQuant === "quant").map((b) => b.compName);
2500
2585
  }
2586
+ /**
2587
+ * Returns true if a specific block instance should be treated as qualitative.
2588
+ * Combines the static `qualQuant` flag with any per-instance `qualConditions`
2589
+ * — e.g. AudioInput is only qual when `props.transcription.enable === true`.
2590
+ */
2591
+ isQualBlock(block) {
2592
+ const def = this.blocks.get(block.comp);
2593
+ if (!def || def.qualQuant !== "qual") return false;
2594
+ if (!def.qualConditions?.length) return true;
2595
+ return def.qualConditions.every((cond) => {
2596
+ const value = cond.propPath.split(".").reduce((obj, key) => obj?.[key], block.props);
2597
+ return value === cond.equals;
2598
+ });
2599
+ }
2501
2600
  /** Check if a specific block has a specific capability. */
2502
2601
  hasCapability(compType, capability) {
2503
2602
  const block = this.blocks.get(compType);
2504
2603
  if (!block) return false;
2505
2604
  return !!block.capabilities[capability];
2506
2605
  }
2606
+ /**
2607
+ * Returns true if the block stores its value as an array (Mongo schema type is Array).
2608
+ * Useful for callers that need to know whether to query `valuePath.0` for existence
2609
+ * vs just `valuePath` — empty arrays still pass `$exists: true` on the field itself.
2610
+ * Returns false for unregistered blocks.
2611
+ */
2612
+ isArrayShaped(compType) {
2613
+ const def = this.blocks.get(compType);
2614
+ return def?.mongoSchemaType?.type === Array;
2615
+ }
2507
2616
  /** Get all registered block descriptors. */
2508
2617
  getAll() {
2509
2618
  return Array.from(this.blocks.values());
@@ -4065,6 +4174,38 @@ var genCleanCamelCaseId = (id) => {
4065
4174
  return result.slice(0, MAX_LENGTH);
4066
4175
  };
4067
4176
 
4177
+ // src/utils/plainTextToLexical.ts
4178
+ var plainTextToLexical = (value) => {
4179
+ if (!value && value !== 0) return void 0;
4180
+ if (value?.isLexical === true) return value;
4181
+ if (typeof value !== "string" && typeof value !== "number") return void 0;
4182
+ const text = String(value);
4183
+ const lines = text.split(/\r?\n/);
4184
+ const paragraphNodes = lines.map((line) => ({
4185
+ type: "paragraph",
4186
+ children: [
4187
+ {
4188
+ type: "text",
4189
+ text: line
4190
+ }
4191
+ ]
4192
+ }));
4193
+ return {
4194
+ allText: text,
4195
+ isLexical: true,
4196
+ editorState: {
4197
+ root: {
4198
+ children: paragraphNodes,
4199
+ direction: "ltr",
4200
+ format: "",
4201
+ indent: 0,
4202
+ type: "root",
4203
+ version: 1
4204
+ }
4205
+ }
4206
+ };
4207
+ };
4208
+
4068
4209
  // src/node.ts
4069
4210
  var import_MongoConnector3 = __toESM(require_MongoConnector());
4070
4211
  var import_ElasticSearchConnector = __toESM(require_ElasticSearchConnector());
@@ -4512,6 +4653,7 @@ var import_GET_GLOBAL_BULLMQ_CONFIG = __toESM(require_GET_GLOBAL_BULLMQ_CONFIG()
4512
4653
  isTplAnnotationEnabled,
4513
4654
  mergeAnnoDataIntoAnnotationsTags,
4514
4655
  parseSpecialConfigSyntax,
4656
+ plainTextToLexical,
4515
4657
  processAuthorAndCommonFilters,
4516
4658
  recursivelyExtractBlocks,
4517
4659
  segrigateDocs,
package/dist/node.mjs CHANGED
@@ -2289,7 +2289,8 @@ var _extractBlocksFromSomeBuilders = ({
2289
2289
  // src/blockRegistry/schemaPresets.ts
2290
2290
  var MONGO_SCHEMA_PRESETS = {
2291
2291
  object: { type: Object },
2292
- string: { type: String }
2292
+ string: { type: String },
2293
+ array: { type: Array }
2293
2294
  };
2294
2295
  var ELASTIC_MAPPING_PRESETS = {
2295
2296
  largeText: {
@@ -2299,6 +2300,29 @@ var ELASTIC_MAPPING_PRESETS = {
2299
2300
  analyzer: "LargeTextAnalyzer"
2300
2301
  }
2301
2302
  }
2303
+ },
2304
+ // Audio file value (array of one object) — only the transcription.result.finalText.allText
2305
+ // is indexed as searchable text. finalText is stored in Lexical shape; allText is the
2306
+ // plain text within it. Everything else on the audio object is ignored by ES.
2307
+ audioTranscription: {
2308
+ properties: {
2309
+ transcription: {
2310
+ properties: {
2311
+ result: {
2312
+ properties: {
2313
+ finalText: {
2314
+ properties: {
2315
+ allText: {
2316
+ type: "text",
2317
+ analyzer: "LargeTextAnalyzer"
2318
+ }
2319
+ }
2320
+ }
2321
+ }
2322
+ }
2323
+ }
2324
+ }
2325
+ }
2302
2326
  }
2303
2327
  };
2304
2328
  var CHUNKING_PRESETS = {
@@ -2340,8 +2364,7 @@ var LexicalTextEditor = {
2340
2364
  // Field paths
2341
2365
  fieldPaths: {
2342
2366
  plainTextString: "allText",
2343
- searchField: "allText",
2344
- displayValue: "allText"
2367
+ searchField: "allText"
2345
2368
  },
2346
2369
  // Validation
2347
2370
  validation: {
@@ -2379,11 +2402,72 @@ var LexicalTextEditor = {
2379
2402
  chunkingConfig: CHUNKING_PRESETS.lexicalSemantic
2380
2403
  };
2381
2404
 
2405
+ // src/blockRegistry/blocks/AudioInput.ts
2406
+ var AudioInput = {
2407
+ compName: "AudioInput",
2408
+ // Identity
2409
+ category: "media",
2410
+ qualQuant: "qual",
2411
+ // Only qualitative when the tpl block has transcription turned on.
2412
+ // A non-transcribed audio input has no text to analyze, so downstream
2413
+ // qual widgets / search tools should skip it.
2414
+ qualConditions: [
2415
+ { propPath: "transcription.enable", equals: true }
2416
+ ],
2417
+ // Schema
2418
+ mongoSchemaType: MONGO_SCHEMA_PRESETS.array,
2419
+ esMapping: ELASTIC_MAPPING_PRESETS.audioTranscription,
2420
+ // Capabilities
2421
+ capabilities: {
2422
+ // Text lives at transcription.result.finalText on the first (and only) audio item,
2423
+ // derived by the Sarvam adapter into a single canonical field.
2424
+ hasPlainText: true,
2425
+ annotation: true,
2426
+ aiAnnotation: true,
2427
+ aiEnrichment: true,
2428
+ searchable: true,
2429
+ directDataImport: false,
2430
+ csvExport: true,
2431
+ // Translation already happens at the Sarvam level via translateToEnglish flag,
2432
+ // so the autoTranslate pipeline doesn't need to touch this block.
2433
+ translatable: false,
2434
+ documentSummarizer: true,
2435
+ // Transcription payloads can be large — strip from chunk/anno main snapshots
2436
+ // and listing projections.
2437
+ stripFromMainOnAnnoChunkSync: true,
2438
+ excludeFromListingProjection: true
2439
+ },
2440
+ // Field paths
2441
+ // `plainTextString` is the Mongo path consumed by getVal (supports the leading
2442
+ // array index). `searchField` is the ES path — ES flattens arrays of objects
2443
+ // so no index is needed there.
2444
+ fieldPaths: {
2445
+ plainTextString: "0.transcription.result.finalText.allText",
2446
+ searchField: "transcription.result.finalText.allText"
2447
+ },
2448
+ // Validation
2449
+ validation: {
2450
+ populatedCheckFn: "valueArrayIsNotEmpty"
2451
+ },
2452
+ // CSV export — existing transformStructureComp switch routes AudioInput to
2453
+ // formatMediaLinks (outputs audio URLs).
2454
+ csvExport: {
2455
+ transformFn: "formatMediaLinks"
2456
+ },
2457
+ // Chunking — finalText is long free-form speech, so semantic chunking applies.
2458
+ chunkingConfig: CHUNKING_PRESETS.lexicalSemantic,
2459
+ // Content block option — matches the current static entry exactly
2460
+ contentBlockOption: {
2461
+ display: "Audio Input"
2462
+ }
2463
+ };
2464
+
2382
2465
  // src/blockRegistry/registry.ts
2383
2466
  var BlockRegistry = class {
2384
2467
  constructor() {
2385
2468
  this.blocks = /* @__PURE__ */ new Map();
2386
2469
  this.register(LexicalTextEditor);
2470
+ this.register(AudioInput);
2387
2471
  }
2388
2472
  /** Register a block descriptor. */
2389
2473
  register(descriptor) {
@@ -2430,12 +2514,36 @@ var BlockRegistry = class {
2430
2514
  getQuantBlocks() {
2431
2515
  return Array.from(this.blocks.values()).filter((b) => b.qualQuant === "quant").map((b) => b.compName);
2432
2516
  }
2517
+ /**
2518
+ * Returns true if a specific block instance should be treated as qualitative.
2519
+ * Combines the static `qualQuant` flag with any per-instance `qualConditions`
2520
+ * — e.g. AudioInput is only qual when `props.transcription.enable === true`.
2521
+ */
2522
+ isQualBlock(block) {
2523
+ const def = this.blocks.get(block.comp);
2524
+ if (!def || def.qualQuant !== "qual") return false;
2525
+ if (!def.qualConditions?.length) return true;
2526
+ return def.qualConditions.every((cond) => {
2527
+ const value = cond.propPath.split(".").reduce((obj, key) => obj?.[key], block.props);
2528
+ return value === cond.equals;
2529
+ });
2530
+ }
2433
2531
  /** Check if a specific block has a specific capability. */
2434
2532
  hasCapability(compType, capability) {
2435
2533
  const block = this.blocks.get(compType);
2436
2534
  if (!block) return false;
2437
2535
  return !!block.capabilities[capability];
2438
2536
  }
2537
+ /**
2538
+ * Returns true if the block stores its value as an array (Mongo schema type is Array).
2539
+ * Useful for callers that need to know whether to query `valuePath.0` for existence
2540
+ * vs just `valuePath` — empty arrays still pass `$exists: true` on the field itself.
2541
+ * Returns false for unregistered blocks.
2542
+ */
2543
+ isArrayShaped(compType) {
2544
+ const def = this.blocks.get(compType);
2545
+ return def?.mongoSchemaType?.type === Array;
2546
+ }
2439
2547
  /** Get all registered block descriptors. */
2440
2548
  getAll() {
2441
2549
  return Array.from(this.blocks.values());
@@ -3997,6 +4105,38 @@ var genCleanCamelCaseId = (id) => {
3997
4105
  return result.slice(0, MAX_LENGTH);
3998
4106
  };
3999
4107
 
4108
+ // src/utils/plainTextToLexical.ts
4109
+ var plainTextToLexical = (value) => {
4110
+ if (!value && value !== 0) return void 0;
4111
+ if (value?.isLexical === true) return value;
4112
+ if (typeof value !== "string" && typeof value !== "number") return void 0;
4113
+ const text = String(value);
4114
+ const lines = text.split(/\r?\n/);
4115
+ const paragraphNodes = lines.map((line) => ({
4116
+ type: "paragraph",
4117
+ children: [
4118
+ {
4119
+ type: "text",
4120
+ text: line
4121
+ }
4122
+ ]
4123
+ }));
4124
+ return {
4125
+ allText: text,
4126
+ isLexical: true,
4127
+ editorState: {
4128
+ root: {
4129
+ children: paragraphNodes,
4130
+ direction: "ltr",
4131
+ format: "",
4132
+ indent: 0,
4133
+ type: "root",
4134
+ version: 1
4135
+ }
4136
+ }
4137
+ };
4138
+ };
4139
+
4000
4140
  // src/node.ts
4001
4141
  var import_MongoConnector3 = __toESM(require_MongoConnector());
4002
4142
  var import_ElasticSearchConnector = __toESM(require_ElasticSearchConnector());
@@ -4459,6 +4599,7 @@ export {
4459
4599
  isTplAnnotationEnabled,
4460
4600
  mergeAnnoDataIntoAnnotationsTags,
4461
4601
  parseSpecialConfigSyntax,
4602
+ plainTextToLexical,
4462
4603
  processAuthorAndCommonFilters,
4463
4604
  _recursExtractBlocks as recursivelyExtractBlocks,
4464
4605
  segrigateDocs,