@esheet/adapters 0.0.4-1 → 0.0.4-2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"fhir-adapter.d.ts","sourceRoot":"","sources":["../../src/fhir/fhir-adapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EAOf,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EACV,iBAAiB,EAEjB,yBAAyB,EAMzB,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EAKtB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAc5B,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,CAAC;AAM5D;;GAEG;AACH,wBAAgB,cAAc,CAC5B,aAAa,EAAE,iBAAiB,EAChC,OAAO,CAAC,EAAE,iBAAiB,GAC1B,cAAc,CA0BhB;AAiSD;;GAEG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,cAAc,EACpB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,iBAAiB,CAmCnB;AAsID;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,yBAAyB,EACnC,OAAO,CAAC,EAAE,qBAAqB,GAC9B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB;AAuDD;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,EAAE,qBAAqB,GAC7B,yBAAyB,CAa3B"}
1
+ {"version":3,"file":"fhir-adapter.d.ts","sourceRoot":"","sources":["../../src/fhir/fhir-adapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EASf,MAAM,cAAc,CAAC;AAItB,OAAO,KAAK,EACV,iBAAiB,EAEjB,yBAAyB,EAMzB,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EAMtB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAc5B,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,CAAC;AAM5D;;GAEG;AACH,wBAAgB,cAAc,CAC5B,aAAa,EAAE,iBAAiB,EAChC,OAAO,CAAC,EAAE,iBAAiB,GAC1B,cAAc,CA0BhB;AAyXD;;GAEG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,cAAc,EACpB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,iBAAiB,CAmCnB;AAsJD;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,yBAAyB,EACnC,OAAO,CAAC,EAAE,qBAAqB,GAC9B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB;AA6DD;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,EAAE,qBAAqB,GAC7B,yBAAyB,CAa3B"}
@@ -1,6 +1,7 @@
1
1
  // ---------------------------------------------------------------------------
2
2
  // FHIR R4 Adapter - Bidirectional conversion
3
3
  // ---------------------------------------------------------------------------
4
+ import { normalizeExpression } from '@esheet/core';
4
5
  import { isFhirQuestionnaire, isFhirQuestionnaireResponse, mapFhirTypeToEsheet, mapEsheetTypeToFhir, convertAnswerOptionToFieldOption, convertOptionToFhirAnswerOption, mapFhirOperatorToEsheet, mapEsheetOperatorToFhir, mapEnableBehaviorToLogic, extractEnableWhenAnswer, getExtensionValue, createItemControlExtension, createSignatureRequiredExtension, generateUUID, FHIR_EXT, } from './utils.js';
5
6
  // Re-export type guards
6
7
  export { isFhirQuestionnaire, isFhirQuestionnaireResponse };
@@ -66,18 +67,35 @@ function convertItemToField(item, path, warnings, options) {
66
67
  question: item.text,
67
68
  required: item.required,
68
69
  };
70
+ // Extract eSheet layout extensions — first-class field properties, not metadata
71
+ const width = getExtensionValue(item.extension, FHIR_EXT.FIELD_WIDTH);
72
+ const optionLayout = getExtensionValue(item.extension, FHIR_EXT.OPTION_LAYOUT);
73
+ const widthSpread = width ? { width } : {};
74
+ const optionLayoutSpread = optionLayout ? { optionLayout } : {};
69
75
  // Build _sourceData for round-trip
70
76
  const fieldMeta = buildFieldMeta(item, typeResult, options);
71
77
  const hasFieldMeta = Object.keys(fieldMeta).length > 0;
72
78
  // Convert enableWhen to rules
73
79
  const rules = convertEnableWhenToRules(item.enableWhen, item.enableBehavior);
80
+ // Convert calculatedExpression / initialExpression to a setValue rule.
81
+ const exprMeta = fieldMeta.calculatedExpression ?? fieldMeta.initialExpression;
82
+ if (exprMeta?.expression) {
83
+ const expression = exprMeta.language === 'text/fhirpath'
84
+ ? normalizeExpression(exprMeta.expression)
85
+ : exprMeta.expression;
86
+ rules.push({
87
+ effect: 'setValue',
88
+ logic: 'AND',
89
+ conditions: [{ conditionType: 'expression', expression }],
90
+ });
91
+ }
74
92
  const rulesSpread = rules.length > 0 ? { rules } : {};
75
93
  // Handle warnings for lossy conversions
76
94
  addConversionWarnings(item, path, typeResult, warnings);
77
95
  // Build field based on type
78
96
  switch (typeResult.fieldType) {
79
97
  case 'section':
80
- return buildSectionField(base, item, path, warnings, options, hasFieldMeta ? fieldMeta : undefined);
98
+ return buildSectionField(base, item, path, warnings, options, hasFieldMeta ? fieldMeta : undefined, widthSpread);
81
99
  case 'radio':
82
100
  case 'check':
83
101
  case 'dropdown':
@@ -86,15 +104,29 @@ function convertItemToField(item, path, warnings, options) {
86
104
  ...base,
87
105
  ...(hasFieldMeta ? { _sourceData: fieldMeta } : {}),
88
106
  ...rulesSpread,
107
+ ...widthSpread,
108
+ ...optionLayoutSpread,
89
109
  fieldType: typeResult.fieldType,
90
110
  options: convertAnswerOptions(item.answerOption, existingIds),
91
111
  };
112
+ case 'openchoice':
113
+ return {
114
+ ...base,
115
+ ...(hasFieldMeta ? { _sourceData: fieldMeta } : {}),
116
+ ...rulesSpread,
117
+ ...widthSpread,
118
+ ...optionLayoutSpread,
119
+ fieldType: 'openchoice',
120
+ options: convertAnswerOptions(item.answerOption, existingIds),
121
+ };
92
122
  case 'rating':
93
123
  case 'slider':
94
124
  return {
95
125
  ...base,
96
126
  ...(hasFieldMeta ? { _sourceData: fieldMeta } : {}),
97
127
  ...rulesSpread,
128
+ ...widthSpread,
129
+ ...optionLayoutSpread,
98
130
  fieldType: typeResult.fieldType,
99
131
  options: convertAnswerOptions(item.answerOption, existingIds),
100
132
  };
@@ -104,6 +136,7 @@ function convertItemToField(item, path, warnings, options) {
104
136
  ...base,
105
137
  ...(hasFieldMeta ? { _sourceData: fieldMeta } : {}),
106
138
  ...rulesSpread,
139
+ ...widthSpread,
107
140
  fieldType: typeResult.fieldType,
108
141
  ...(typeResult.inputType ? { inputType: typeResult.inputType } : {}),
109
142
  };
@@ -119,10 +152,12 @@ function convertItemToField(item, path, warnings, options) {
119
152
  case 'boolean':
120
153
  case 'signature':
121
154
  case 'diagram':
155
+ case 'file':
122
156
  return {
123
157
  ...base,
124
158
  ...(hasFieldMeta ? { _sourceData: fieldMeta } : {}),
125
159
  ...rulesSpread,
160
+ ...widthSpread,
126
161
  fieldType: typeResult.fieldType,
127
162
  };
128
163
  default:
@@ -130,17 +165,19 @@ function convertItemToField(item, path, warnings, options) {
130
165
  ...base,
131
166
  ...(hasFieldMeta ? { _sourceData: fieldMeta } : {}),
132
167
  ...rulesSpread,
168
+ ...widthSpread,
133
169
  fieldType: 'text',
134
170
  };
135
171
  }
136
172
  }
137
- function buildSectionField(base, item, path, warnings, options, fieldMeta) {
173
+ function buildSectionField(base, item, path, warnings, options, fieldMeta, widthSpread) {
138
174
  const nestedFields = item.item
139
175
  ? item.item.map((child, i) => convertItemToField(child, `${path}.item[${i}]`, warnings, options))
140
176
  : [];
141
177
  return {
142
178
  ...base,
143
179
  ...(fieldMeta ? { _sourceData: fieldMeta } : {}),
180
+ ...widthSpread,
144
181
  fieldType: 'section',
145
182
  title: item.text,
146
183
  fields: nestedFields,
@@ -159,6 +196,15 @@ function buildFieldMeta(item, typeResult, options) {
159
196
  meta.readOnly = item.readOnly;
160
197
  if (item.repeats)
161
198
  meta.repeats = item.repeats;
199
+ // Extract SDC expression extensions for round-trip and setValue conversion
200
+ const calcExpr = getExtensionValue(item.extension, FHIR_EXT.CALCULATED_EXPRESSION);
201
+ if (calcExpr)
202
+ meta.calculatedExpression =
203
+ calcExpr;
204
+ const initExpr = getExtensionValue(item.extension, FHIR_EXT.INITIAL_EXPRESSION);
205
+ if (initExpr)
206
+ meta.initialExpression =
207
+ initExpr;
162
208
  // Store original FHIR type for export
163
209
  meta.fhirItemType = item.type;
164
210
  // Extract validation extensions
@@ -232,6 +278,19 @@ function addConversionWarnings(item, path, typeResult, warnings) {
232
278
  message: `FHIR quantity type converted to number field. Unit choices lost.`,
233
279
  });
234
280
  }
281
+ // Expression warning — calculatedExpression / initialExpression are imported
282
+ // as setValue rules but the expression string (CQL/FHIRPath) must be manually
283
+ // adapted to eSheet {fieldId} syntax before it will evaluate correctly.
284
+ const hasCalcExpr = !!getExtensionValue(item.extension, FHIR_EXT.CALCULATED_EXPRESSION);
285
+ const hasInitExpr = !!getExtensionValue(item.extension, FHIR_EXT.INITIAL_EXPRESSION);
286
+ if (hasCalcExpr || hasInitExpr) {
287
+ warnings.push({
288
+ path,
289
+ code: 'UNSUPPORTED_TYPE',
290
+ severity: 'info',
291
+ message: `${hasCalcExpr ? 'calculatedExpression' : 'initialExpression'} imported as a setValue rule. Expression syntax must be adapted to eSheet {fieldId} notation.`,
292
+ });
293
+ }
235
294
  // ValueSet reference (informational)
236
295
  if (item.answerValueSet) {
237
296
  warnings.push({
@@ -305,10 +364,26 @@ function convertFieldToItem(field) {
305
364
  if (field.fieldType === 'signature') {
306
365
  extensions.push(createSignatureRequiredExtension());
307
366
  }
308
- // Add preserved extensions
367
+ // Add eSheet layout extensions
368
+ const fieldDef = field;
369
+ if (fieldDef.width && fieldDef.width !== 'full') {
370
+ extensions.push({ url: FHIR_EXT.FIELD_WIDTH, valueCode: fieldDef.width });
371
+ }
372
+ if (fieldDef.optionLayout && fieldDef.optionLayout !== 'stack') {
373
+ extensions.push({
374
+ url: FHIR_EXT.OPTION_LAYOUT,
375
+ valueCode: fieldDef.optionLayout,
376
+ });
377
+ }
378
+ // Add preserved extensions (exclude any we regenerate to avoid duplicates)
309
379
  if (fieldMeta?.fhirExtensions) {
310
- // Filter out extensions we're generating ourselves
311
- const preserved = fieldMeta.fhirExtensions.filter((e) => e.url !== FHIR_EXT.ITEM_CONTROL && e.url !== FHIR_EXT.SIGNATURE_REQUIRED);
380
+ const generated = new Set([
381
+ FHIR_EXT.ITEM_CONTROL,
382
+ FHIR_EXT.SIGNATURE_REQUIRED,
383
+ FHIR_EXT.FIELD_WIDTH,
384
+ FHIR_EXT.OPTION_LAYOUT,
385
+ ]);
386
+ const preserved = fieldMeta.fhirExtensions.filter((e) => !generated.has(e.url));
312
387
  extensions.push(...preserved);
313
388
  }
314
389
  if (extensions.length > 0) {
@@ -445,7 +520,12 @@ function extractSingleAnswerValue(answer) {
445
520
  if (answer.valueQuantity)
446
521
  return answer.valueQuantity.value;
447
522
  if (answer.valueAttachment)
448
- return answer.valueAttachment.data;
523
+ return {
524
+ data: answer.valueAttachment.data,
525
+ contentType: answer.valueAttachment.contentType,
526
+ title: answer.valueAttachment.title,
527
+ url: answer.valueAttachment.url,
528
+ };
449
529
  if (answer.valueReference)
450
530
  return answer.valueReference.reference;
451
531
  return undefined;
@@ -532,6 +612,41 @@ function convertValueToAnswers(field, value) {
532
612
  },
533
613
  },
534
614
  ];
615
+ case 'file': {
616
+ // value may be a string (base64) or an object with data/dataUrl/contentType/title
617
+ if (typeof value === 'string') {
618
+ return [
619
+ {
620
+ valueAttachment: {
621
+ contentType: 'application/octet-stream',
622
+ data: value,
623
+ },
624
+ },
625
+ ];
626
+ }
627
+ const v = value;
628
+ let dataBase64 = undefined;
629
+ let contentType = v.contentType ?? 'application/octet-stream';
630
+ if (v.data)
631
+ dataBase64 = v.data;
632
+ else if (v.dataUrl) {
633
+ const comma = v.dataUrl.indexOf(',');
634
+ dataBase64 = comma >= 0 ? v.dataUrl.slice(comma + 1) : v.dataUrl;
635
+ const prefix = v.dataUrl.slice(0, comma);
636
+ const m = prefix.match(/data:([^;]+)/);
637
+ if (m && m[1])
638
+ contentType = m[1];
639
+ }
640
+ return [
641
+ {
642
+ valueAttachment: {
643
+ contentType,
644
+ data: dataBase64,
645
+ title: v.title,
646
+ },
647
+ },
648
+ ];
649
+ }
535
650
  default:
536
651
  return [{ valueString: String(value) }];
537
652
  }
@@ -552,13 +667,22 @@ function convertTextAnswer(value, inputType) {
552
667
  return { valueString: String(value) };
553
668
  }
554
669
  }
555
- function createCodingAnswer(field, selectedId) {
670
+ function createCodingAnswer(field, selectedIdOrObj) {
556
671
  const options = 'options' in field ? field.options : undefined;
672
+ const selectedId = typeof selectedIdOrObj === 'string'
673
+ ? selectedIdOrObj
674
+ : selectedIdOrObj.id ?? String(selectedIdOrObj.value ?? '');
557
675
  const option = options?.find((o) => o.id === selectedId);
558
676
  return {
559
677
  valueCoding: {
560
- code: option?.value ?? selectedId,
561
- display: option?.text,
678
+ code: option?.value ??
679
+ (typeof selectedIdOrObj === 'string'
680
+ ? selectedIdOrObj
681
+ : selectedIdOrObj.value ?? selectedId),
682
+ display: option?.text ??
683
+ (typeof selectedIdOrObj === 'object'
684
+ ? selectedIdOrObj.value
685
+ : undefined),
562
686
  },
563
687
  };
564
688
  }
@@ -15,6 +15,10 @@ export declare const FHIR_EXT: {
15
15
  readonly CALCULATED_EXPRESSION: "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression";
16
16
  readonly ENABLE_WHEN_EXPRESSION: "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression";
17
17
  readonly VARIABLE: "http://hl7.org/fhir/StructureDefinition/variable";
18
+ /** valueCode: 'full' | 'half' | 'third' */
19
+ readonly FIELD_WIDTH: "https://esheet.os.mieweb.org/docs/adapters/fhir/extensions#field-width";
20
+ /** valueCode: 'stack' | 'wrap' */
21
+ readonly OPTION_LAYOUT: "https://esheet.os.mieweb.org/docs/adapters/fhir/extensions#option-layout";
18
22
  };
19
23
  export declare const ITEM_CONTROL_SYSTEM = "http://hl7.org/fhir/questionnaire-item-control";
20
24
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/fhir/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/fhir/utils.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,WAAW,EACX,iBAAiB,EACjB,aAAa,EACd,MAAM,cAAc,CAAC;AAGtB,OAAO,KAAK,EACV,iBAAiB,EACjB,yBAAyB,EACzB,yBAAyB,EACzB,qBAAqB,EACrB,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,aAAa,EAEd,MAAM,YAAY,CAAC;AAMpB,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;IAqCnB,2CAA2C;;IAG3C,kCAAkC;;CAG1B,CAAC;AAEX,eAAO,MAAM,mBAAmB,mDACkB,CAAC;AAMnD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,iBAAiB,CAI5B;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,yBAAyB,CAIpC;AAMD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,yBAAyB,EACnC,IAAI,EAAE,qBAAqB,GAC1B,qBAAqB,CA2DvB;AAkCD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,yBAAyB,CAAC;IACzC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,aAAa,EACzB,OAAO,CAAC,EAAE,MAAM,GACf,mBAAmB,CA0DrB;AAuBD;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,aAAa,EAAE,MAAM,GACpB,WAAW,CAUb;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,gBAAgB,EACxB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,KAAK,EAAE,MAAM,GACZ,WAAW,CA0Cb;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,WAAW,GAClB,gBAAgB,CAwBlB;AAMD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,sBAAsB,EAChC,aAAa,CAAC,EAAE,OAAO,GACtB,iBAAiB,GAAG,IAAI,CAmB1B;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,iBAAiB,GAC1B;IAAE,QAAQ,EAAE,sBAAsB,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAyBtE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,kBAAkB,GAAG,SAAS,GACvC,KAAK,GAAG,IAAI,CAEd;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,cAAc,GACzB,MAAM,GAAG,SAAS,CA0BpB;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAC3C,UAAU,EAAE,SAAS,aAAa,EAAE,GAAG,SAAS,EAChD,GAAG,EAAE,MAAM,GACV,CAAC,GAAG,SAAS,CAaf;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,SAAS,aAAa,EAAE,GAAG,SAAS,GAC/C,MAAM,GAAG,SAAS,CASpB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,SAAS,aAAa,EAAE,GAAG,SAAS,GAC/C,OAAO,CAKT;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CAY7E;AAED;;GAEG;AACH,wBAAgB,gCAAgC,IAAI,aAAa,CAKhE;AAMD;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAOrC"}
@@ -27,6 +27,12 @@ export const FHIR_EXT = {
27
27
  CALCULATED_EXPRESSION: 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression',
28
28
  ENABLE_WHEN_EXPRESSION: 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression',
29
29
  VARIABLE: 'http://hl7.org/fhir/StructureDefinition/variable',
30
+ // eSheet layout extensions (custom)
31
+ // Definitions are documented at the URLs used as extension identifiers.
32
+ /** valueCode: 'full' | 'half' | 'third' */
33
+ FIELD_WIDTH: 'https://esheet.os.mieweb.org/docs/adapters/fhir/extensions#field-width',
34
+ /** valueCode: 'stack' | 'wrap' */
35
+ OPTION_LAYOUT: 'https://esheet.os.mieweb.org/docs/adapters/fhir/extensions#option-layout',
30
36
  };
31
37
  export const ITEM_CONTROL_SYSTEM = 'http://hl7.org/fhir/questionnaire-item-control';
32
38
  // ---------------------------------------------------------------------------
@@ -88,7 +94,7 @@ export function mapFhirTypeToEsheet(fhirType, item) {
88
94
  if (hasSignatureRequired(item.extension)) {
89
95
  return { fieldType: 'signature' };
90
96
  }
91
- return { fieldType: 'diagram' };
97
+ return { fieldType: 'file' };
92
98
  case 'reference':
93
99
  return { fieldType: 'text', subType: 'reference' };
94
100
  case 'quantity':
@@ -104,6 +110,9 @@ function mapChoiceType(item, itemControl) {
104
110
  ? { fieldType: 'multiselectdropdown' }
105
111
  : { fieldType: 'dropdown' };
106
112
  }
113
+ if (itemControl === 'open-choice') {
114
+ return { fieldType: 'openchoice' };
115
+ }
107
116
  if (itemControl === 'check-box') {
108
117
  return { fieldType: 'check' };
109
118
  }
@@ -144,6 +153,10 @@ export function mapEsheetTypeToFhir(esheetType, inputType, subType) {
144
153
  return { type: 'attachment' };
145
154
  case 'diagram':
146
155
  return { type: 'attachment' };
156
+ case 'file':
157
+ return { type: 'attachment' };
158
+ case 'openchoice':
159
+ return { type: 'choice', itemControl: 'open-choice' };
147
160
  case 'singlematrix':
148
161
  case 'multimatrix':
149
162
  return { type: 'group' };
package/dist/lib/mcp.d.ts CHANGED
@@ -125,6 +125,8 @@ export declare function importFromMcp(schema: McpElicitationSchema, options?: {
125
125
  * - `check` / `multiselectdropdown` → `array` enum (with or without titles)
126
126
  * - `rating` → `integer` (min=1, max=option count)
127
127
  * - `slider` → `number`
128
+ * - `openchoice` → `string` enum with openchoice metadata
129
+ * - `file` → `string` with file metadata (outside MCP spec)
128
130
  */
129
131
  export declare function exportToMcp(definition: FormDefinition): McpElicitationRequest;
130
132
  //# sourceMappingURL=mcp.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/lib/mcp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/lib/mcp.ts"],"names":[],"mappings":"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"}
package/dist/lib/mcp.js CHANGED
@@ -211,6 +211,8 @@ function mcpFormatToInputType(format) {
211
211
  * - `check` / `multiselectdropdown` → `array` enum (with or without titles)
212
212
  * - `rating` → `integer` (min=1, max=option count)
213
213
  * - `slider` → `number`
214
+ * - `openchoice` → `string` enum with openchoice metadata
215
+ * - `file` → `string` with file metadata (outside MCP spec)
214
216
  */
215
217
  export function exportToMcp(definition) {
216
218
  const properties = {};
@@ -396,6 +398,80 @@ function fieldToMcpProp(field) {
396
398
  : {}),
397
399
  };
398
400
  }
401
+ case 'openchoice': {
402
+ // OpenChoice maps to radio with metadata preserved for round-trip.
403
+ const options = field.options ?? [];
404
+ const fieldDef = field;
405
+ const ocMeta = {
406
+ ...meta,
407
+ };
408
+ if (fieldDef.maxCustomOptions !== undefined) {
409
+ ocMeta.maxCustomOptions = fieldDef.maxCustomOptions;
410
+ }
411
+ if (fieldDef.otherLabel !== undefined) {
412
+ ocMeta.otherLabel = fieldDef.otherLabel;
413
+ }
414
+ const hasText = options.some((o) => o.text !== undefined);
415
+ if (hasText) {
416
+ return {
417
+ type: 'string',
418
+ ...(title !== undefined ? { title } : {}),
419
+ ...(description !== undefined ? { description } : {}),
420
+ oneOf: options.map((o) => ({
421
+ const: o.value,
422
+ title: o.text ?? o.value,
423
+ })),
424
+ ...(Object.keys(ocMeta).length > 0
425
+ ? {
426
+ _sourceData: {
427
+ fieldType: 'openchoice',
428
+ ...ocMeta,
429
+ },
430
+ }
431
+ : {}),
432
+ };
433
+ }
434
+ return {
435
+ type: 'string',
436
+ ...(title !== undefined ? { title } : {}),
437
+ ...(description !== undefined ? { description } : {}),
438
+ enum: options.map((o) => o.value),
439
+ ...(Object.keys(ocMeta).length > 0
440
+ ? {
441
+ _sourceData: {
442
+ fieldType: 'openchoice',
443
+ ...ocMeta,
444
+ },
445
+ }
446
+ : {}),
447
+ };
448
+ }
449
+ case 'file': {
450
+ // File upload is outside MCP flat-form spec. Preserve as object definition
451
+ // so export restores field type and constraints verbatim.
452
+ const fieldDef = field;
453
+ const fMeta = {
454
+ ...meta,
455
+ };
456
+ if (fieldDef.accept !== undefined) {
457
+ fMeta.accept = fieldDef.accept;
458
+ }
459
+ if (fieldDef.maxFileSize !== undefined) {
460
+ fMeta.maxFileSize = fieldDef.maxFileSize;
461
+ }
462
+ if (fieldDef.maxFiles !== undefined) {
463
+ fMeta.maxFiles = fieldDef.maxFiles;
464
+ }
465
+ return {
466
+ type: 'string',
467
+ ...(title !== undefined ? { title } : {}),
468
+ ...(description !== undefined ? { description } : {}),
469
+ _sourceData: {
470
+ fieldType: 'file',
471
+ ...fMeta,
472
+ },
473
+ };
474
+ }
399
475
  default:
400
476
  // ranking, multitext, singlematrix, multimatrix, image, html,
401
477
  // signature, diagram, display → no MCP equivalent
@@ -29,6 +29,7 @@ interface SurveyJSElement {
29
29
  title?: string;
30
30
  description?: string;
31
31
  isRequired?: boolean;
32
+ readOnly?: boolean;
32
33
  inputType?: string;
33
34
  choices?: (string | SurveyJSChoice)[];
34
35
  rows?: (string | SurveyJSMatrixItem)[];
@@ -1 +1 @@
1
- {"version":3,"file":"surveyjs-converter.d.ts","sourceRoot":"","sources":["../../src/lib/surveyjs-converter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"surveyjs-converter.d.ts","sourceRoot":"","sources":["../../src/lib/surveyjs-converter.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,7 @@ const TYPE_MAP = {
15
15
  checkbox: 'check',
16
16
  dropdown: 'dropdown',
17
17
  tagbox: 'multiselectdropdown',
18
+ select: 'openchoice',
18
19
  boolean: 'boolean',
19
20
  rating: 'rating',
20
21
  ranking: 'ranking',
@@ -26,7 +27,7 @@ const TYPE_MAP = {
26
27
  html: 'html',
27
28
  expression: 'html',
28
29
  imagepicker: 'radio',
29
- file: 'text',
30
+ file: 'file',
30
31
  panel: 'section',
31
32
  paneldynamic: 'section',
32
33
  multipletext: 'multitext',
@@ -339,6 +340,32 @@ function convertElement(element, ancestorIds = new Set()) {
339
340
  ...base,
340
341
  fieldType: 'signature',
341
342
  };
343
+ case 'file': {
344
+ const fileField = {
345
+ ...base,
346
+ fieldType: 'file',
347
+ };
348
+ // Preserve file-specific metadata
349
+ if (element.acceptedTypes !== undefined) {
350
+ fileField.accept =
351
+ element.acceptedTypes;
352
+ }
353
+ if (element.allowMultiple !== undefined) {
354
+ fileField.maxFiles =
355
+ element.allowMultiple ? undefined : 1;
356
+ }
357
+ return fileField;
358
+ }
359
+ case 'openchoice': {
360
+ return {
361
+ ...base,
362
+ fieldType: 'openchoice',
363
+ options: (element.choices ?? []).map(convertChoice),
364
+ ...(element.otherText
365
+ ? { otherLabel: element.otherText }
366
+ : { otherLabel: 'Other, please specify' }),
367
+ };
368
+ }
342
369
  case 'image':
343
370
  return {
344
371
  ...base,
@@ -520,10 +547,14 @@ function fieldToSurveyElement(field) {
520
547
  // Restore original SurveyJS type if available; otherwise use reverse map
521
548
  const type = meta?.surveyType ?? FIELD_TYPE_TO_SURVEY[field.fieldType] ?? 'text';
522
549
  const el = { type, name };
523
- if (field.question !== undefined)
524
- el.title = field.question;
550
+ const q = field.question;
551
+ if (q !== undefined)
552
+ el.title = q;
525
553
  if (field.required)
526
554
  el.isRequired = true;
555
+ if (field.readOnly) {
556
+ el.readOnly = true;
557
+ }
527
558
  // Restore conditional expressions verbatim from _sourceData for lossless round-trip.
528
559
  // Fall back to re-constructing from parsed rules.
529
560
  const visibleRule = field.rules?.find((r) => r.effect === 'visible');
@@ -600,6 +631,7 @@ function fieldToSurveyElement(field) {
600
631
  case 'multiselectdropdown':
601
632
  case 'ranking':
602
633
  case 'rating':
634
+ case 'openchoice':
603
635
  el.choices = (field.options ?? []).map((o) => o.text !== undefined
604
636
  ? {
605
637
  value: o.value,
@@ -608,6 +640,14 @@ function fieldToSurveyElement(field) {
608
640
  }
609
641
  : o.value);
610
642
  break;
643
+ case 'file': {
644
+ const fileField = field;
645
+ if (fileField.accept)
646
+ el.acceptedTypes = fileField.accept;
647
+ if (fileField.maxFiles)
648
+ el.allowMultiple = fileField.maxFiles > 1;
649
+ break;
650
+ }
611
651
  case 'singlematrix':
612
652
  case 'multimatrix':
613
653
  el.rows = (field.rows ?? []).map((r) => ({ value: r.id, text: r.value }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@esheet/adapters",
3
- "version": "0.0.4-1",
3
+ "version": "0.0.4-2",
4
4
  "description": "Convert external form schemas (SurveyJS, etc.) to eSheet FormDefinition",
5
5
  "repository": {
6
6
  "type": "git",
@@ -32,7 +32,7 @@
32
32
  ]
33
33
  },
34
34
  "dependencies": {
35
- "@esheet/core": "0.0.4-1",
35
+ "@esheet/core": "0.0.4-2",
36
36
  "tslib": "^2.3.0"
37
37
  },
38
38
  "devDependencies": {}