@esheet/adapters 0.0.3 → 0.0.4-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.
@@ -0,0 +1,440 @@
1
+ // ---------------------------------------------------------------------------
2
+ // FHIR Adapter Utilities
3
+ // ---------------------------------------------------------------------------
4
+ import { generateOptionId } from '@esheet/core';
5
+ // ---------------------------------------------------------------------------
6
+ // Extension URLs (Constants)
7
+ // ---------------------------------------------------------------------------
8
+ export const FHIR_EXT = {
9
+ // Questionnaire item control
10
+ ITEM_CONTROL: 'http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl',
11
+ // Validation
12
+ MIN_VALUE: 'http://hl7.org/fhir/StructureDefinition/minValue',
13
+ MAX_VALUE: 'http://hl7.org/fhir/StructureDefinition/maxValue',
14
+ MIN_LENGTH: 'http://hl7.org/fhir/StructureDefinition/minLength',
15
+ REGEX: 'http://hl7.org/fhir/StructureDefinition/regex',
16
+ // Option scoring
17
+ ORDINAL_VALUE: 'http://hl7.org/fhir/StructureDefinition/ordinalValue',
18
+ // Display
19
+ HIDDEN: 'http://hl7.org/fhir/StructureDefinition/questionnaire-hidden',
20
+ ITEM_MEDIA: 'http://hl7.org/fhir/StructureDefinition/questionnaire-itemMedia',
21
+ // Slider
22
+ SLIDER_STEP: 'http://hl7.org/fhir/StructureDefinition/questionnaire-sliderStepValue',
23
+ // Signature
24
+ SIGNATURE_REQUIRED: 'http://hl7.org/fhir/StructureDefinition/questionnaire-signatureRequired',
25
+ // SDC / DTR
26
+ INITIAL_EXPRESSION: 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression',
27
+ CALCULATED_EXPRESSION: 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression',
28
+ ENABLE_WHEN_EXPRESSION: 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression',
29
+ VARIABLE: 'http://hl7.org/fhir/StructureDefinition/variable',
30
+ };
31
+ export const ITEM_CONTROL_SYSTEM = 'http://hl7.org/fhir/questionnaire-item-control';
32
+ // ---------------------------------------------------------------------------
33
+ // Type Guards
34
+ // ---------------------------------------------------------------------------
35
+ /**
36
+ * Type guard to check if a value is a FHIR Questionnaire resource.
37
+ */
38
+ export function isFhirQuestionnaire(value) {
39
+ if (typeof value !== 'object' || value === null)
40
+ return false;
41
+ const v = value;
42
+ return v['resourceType'] === 'Questionnaire';
43
+ }
44
+ /**
45
+ * Type guard to check if a value is a FHIR QuestionnaireResponse resource.
46
+ */
47
+ export function isFhirQuestionnaireResponse(value) {
48
+ if (typeof value !== 'object' || value === null)
49
+ return false;
50
+ const v = value;
51
+ return v['resourceType'] === 'QuestionnaireResponse';
52
+ }
53
+ /**
54
+ * Map a FHIR item type to eSheet field type.
55
+ */
56
+ export function mapFhirTypeToEsheet(fhirType, item) {
57
+ const itemControl = getItemControlCode(item.extension);
58
+ switch (fhirType) {
59
+ case 'string':
60
+ return { fieldType: 'text', inputType: 'string' };
61
+ case 'text':
62
+ return { fieldType: 'longtext' };
63
+ case 'boolean':
64
+ return { fieldType: 'boolean' };
65
+ case 'decimal':
66
+ return { fieldType: 'text', inputType: 'number' };
67
+ case 'integer':
68
+ if (itemControl === 'slider') {
69
+ return { fieldType: 'slider' };
70
+ }
71
+ return { fieldType: 'text', inputType: 'number' };
72
+ case 'date':
73
+ return { fieldType: 'text', inputType: 'date' };
74
+ case 'dateTime':
75
+ return { fieldType: 'text', inputType: 'datetime-local' };
76
+ case 'time':
77
+ return { fieldType: 'text', inputType: 'time' };
78
+ case 'url':
79
+ return { fieldType: 'text', inputType: 'url' };
80
+ case 'choice':
81
+ case 'open-choice':
82
+ return mapChoiceType(item, itemControl);
83
+ case 'group':
84
+ return { fieldType: 'section' };
85
+ case 'display':
86
+ return { fieldType: 'display' };
87
+ case 'attachment':
88
+ if (hasSignatureRequired(item.extension)) {
89
+ return { fieldType: 'signature' };
90
+ }
91
+ return { fieldType: 'diagram' };
92
+ case 'reference':
93
+ return { fieldType: 'text', subType: 'reference' };
94
+ case 'quantity':
95
+ return { fieldType: 'text', inputType: 'number', subType: 'quantity' };
96
+ default:
97
+ return { fieldType: 'text' };
98
+ }
99
+ }
100
+ function mapChoiceType(item, itemControl) {
101
+ const repeats = item.repeats ?? false;
102
+ if (itemControl === 'drop-down' || itemControl === 'autocomplete') {
103
+ return repeats
104
+ ? { fieldType: 'multiselectdropdown' }
105
+ : { fieldType: 'dropdown' };
106
+ }
107
+ if (itemControl === 'check-box') {
108
+ return { fieldType: 'check' };
109
+ }
110
+ if (itemControl === 'radio-button') {
111
+ return { fieldType: 'radio' };
112
+ }
113
+ // Default based on repeats
114
+ return repeats ? { fieldType: 'check' } : { fieldType: 'radio' };
115
+ }
116
+ /**
117
+ * Map an eSheet field type to FHIR item type.
118
+ */
119
+ export function mapEsheetTypeToFhir(esheetType, inputType, subType) {
120
+ switch (esheetType) {
121
+ case 'text':
122
+ return mapTextTypeToFhir(inputType);
123
+ case 'longtext':
124
+ return { type: 'text' };
125
+ case 'boolean':
126
+ return { type: 'boolean' };
127
+ case 'radio':
128
+ return { type: 'choice', itemControl: 'radio-button' };
129
+ case 'check':
130
+ return { type: 'choice', itemControl: 'check-box', repeats: true };
131
+ case 'dropdown':
132
+ return { type: 'choice', itemControl: 'drop-down' };
133
+ case 'multiselectdropdown':
134
+ return { type: 'choice', itemControl: 'drop-down', repeats: true };
135
+ case 'rating':
136
+ return { type: 'integer', itemControl: 'slider' };
137
+ case 'slider':
138
+ return { type: 'decimal', itemControl: 'slider' };
139
+ case 'section':
140
+ return { type: 'group' };
141
+ case 'display':
142
+ return { type: 'display' };
143
+ case 'signature':
144
+ return { type: 'attachment' };
145
+ case 'diagram':
146
+ return { type: 'attachment' };
147
+ case 'singlematrix':
148
+ case 'multimatrix':
149
+ return { type: 'group' };
150
+ case 'image':
151
+ case 'html':
152
+ return { type: 'display' };
153
+ default:
154
+ return { type: 'string' };
155
+ }
156
+ }
157
+ function mapTextTypeToFhir(inputType) {
158
+ switch (inputType) {
159
+ case 'number':
160
+ return { type: 'decimal' };
161
+ case 'date':
162
+ return { type: 'date' };
163
+ case 'datetime-local':
164
+ return { type: 'dateTime' };
165
+ case 'time':
166
+ return { type: 'time' };
167
+ case 'url':
168
+ return { type: 'url' };
169
+ default:
170
+ return { type: 'string' };
171
+ }
172
+ }
173
+ // ---------------------------------------------------------------------------
174
+ // Options Conversion
175
+ // ---------------------------------------------------------------------------
176
+ /**
177
+ * Convert a FHIR Coding to an eSheet FieldOption.
178
+ */
179
+ export function convertFhirCodingToOption(coding, existingIds, fallbackIndex) {
180
+ const id = coding.code ?? generateOptionId(existingIds, `opt-${fallbackIndex}`);
181
+ existingIds.add(id);
182
+ return {
183
+ id,
184
+ value: coding.code ?? '',
185
+ ...(coding.display ? { text: coding.display } : {}),
186
+ };
187
+ }
188
+ /**
189
+ * Convert a FHIR answerOption to an eSheet FieldOption.
190
+ */
191
+ export function convertAnswerOptionToFieldOption(option, existingIds, index) {
192
+ const opt = {
193
+ id: '',
194
+ value: '',
195
+ };
196
+ if (option.valueCoding) {
197
+ opt.id =
198
+ option.valueCoding.code ?? generateOptionId(existingIds, `opt-${index}`);
199
+ opt.value = option.valueCoding.code ?? '';
200
+ if (option.valueCoding.display) {
201
+ opt.text = option.valueCoding.display;
202
+ }
203
+ }
204
+ else if (option.valueString !== undefined) {
205
+ opt.id = toKebabCase(option.valueString) || `opt-${index}`;
206
+ opt.value = option.valueString;
207
+ }
208
+ else if (option.valueInteger !== undefined) {
209
+ opt.id = String(option.valueInteger);
210
+ opt.value = String(option.valueInteger);
211
+ }
212
+ else if (option.valueDate !== undefined) {
213
+ opt.id = `date-${index}`;
214
+ opt.value = option.valueDate;
215
+ }
216
+ else if (option.valueTime !== undefined) {
217
+ opt.id = `time-${index}`;
218
+ opt.value = option.valueTime;
219
+ }
220
+ else {
221
+ opt.id = generateOptionId(existingIds, `opt-${index}`);
222
+ }
223
+ existingIds.add(opt.id);
224
+ // Extract ordinalValue score from extension
225
+ const ordinalExt = option.extension?.find((e) => e.url === FHIR_EXT.ORDINAL_VALUE);
226
+ if (ordinalExt?.valueDecimal !== undefined) {
227
+ opt.score = ordinalExt.valueDecimal;
228
+ }
229
+ else if (ordinalExt?.valueInteger !== undefined) {
230
+ opt.score = ordinalExt.valueInteger;
231
+ }
232
+ return opt;
233
+ }
234
+ /**
235
+ * Convert an eSheet FieldOption to a FHIR answerOption.
236
+ */
237
+ export function convertOptionToFhirAnswerOption(option) {
238
+ const result = {};
239
+ // Prefer valueCoding for rich options (with display text or score)
240
+ if (option.text || option.score !== undefined) {
241
+ result.valueCoding = {
242
+ code: option.value,
243
+ display: option.text ?? option.value,
244
+ system: 'urn:esheet:options',
245
+ };
246
+ if (option.score !== undefined) {
247
+ result.extension = [
248
+ {
249
+ url: FHIR_EXT.ORDINAL_VALUE,
250
+ valueDecimal: option.score,
251
+ },
252
+ ];
253
+ }
254
+ }
255
+ else {
256
+ result.valueString = option.value;
257
+ }
258
+ return result;
259
+ }
260
+ // ---------------------------------------------------------------------------
261
+ // Condition/EnableWhen Conversion
262
+ // ---------------------------------------------------------------------------
263
+ /**
264
+ * Map a FHIR enableWhen operator to an eSheet condition operator.
265
+ */
266
+ export function mapFhirOperatorToEsheet(operator, answerBoolean) {
267
+ switch (operator) {
268
+ case '=':
269
+ return 'equals';
270
+ case '!=':
271
+ return 'notEquals';
272
+ case '>':
273
+ return 'greaterThan';
274
+ case '>=':
275
+ return 'greaterThanOrEqual';
276
+ case '<':
277
+ return 'lessThan';
278
+ case '<=':
279
+ return 'lessThanOrEqual';
280
+ case 'exists':
281
+ return answerBoolean === true ? 'notEmpty' : 'empty';
282
+ default:
283
+ return null;
284
+ }
285
+ }
286
+ /**
287
+ * Map an eSheet condition operator to a FHIR enableWhen operator.
288
+ */
289
+ export function mapEsheetOperatorToFhir(operator) {
290
+ switch (operator) {
291
+ case 'equals':
292
+ return { operator: '=' };
293
+ case 'notEquals':
294
+ return { operator: '!=' };
295
+ case 'greaterThan':
296
+ return { operator: '>' };
297
+ case 'greaterThanOrEqual':
298
+ return { operator: '>=' };
299
+ case 'lessThan':
300
+ return { operator: '<' };
301
+ case 'lessThanOrEqual':
302
+ return { operator: '<=' };
303
+ case 'empty':
304
+ return { operator: 'exists', answerBoolean: false };
305
+ case 'notEmpty':
306
+ return { operator: 'exists', answerBoolean: true };
307
+ case 'contains':
308
+ case 'includes':
309
+ // These require FHIRPath expressions, not supported in basic enableWhen
310
+ return null;
311
+ default:
312
+ return null;
313
+ }
314
+ }
315
+ /**
316
+ * Map FHIR enableBehavior to eSheet logic mode.
317
+ */
318
+ export function mapEnableBehaviorToLogic(behavior) {
319
+ return behavior === 'any' ? 'OR' : 'AND';
320
+ }
321
+ /**
322
+ * Extract the answer value from a FHIR enableWhen condition.
323
+ */
324
+ export function extractEnableWhenAnswer(enableWhen) {
325
+ if (enableWhen.answerBoolean !== undefined) {
326
+ return String(enableWhen.answerBoolean);
327
+ }
328
+ if (enableWhen.answerDecimal !== undefined) {
329
+ return String(enableWhen.answerDecimal);
330
+ }
331
+ if (enableWhen.answerInteger !== undefined) {
332
+ return String(enableWhen.answerInteger);
333
+ }
334
+ if (enableWhen.answerDate !== undefined) {
335
+ return enableWhen.answerDate;
336
+ }
337
+ if (enableWhen.answerDateTime !== undefined) {
338
+ return enableWhen.answerDateTime;
339
+ }
340
+ if (enableWhen.answerTime !== undefined) {
341
+ return enableWhen.answerTime;
342
+ }
343
+ if (enableWhen.answerString !== undefined) {
344
+ return enableWhen.answerString;
345
+ }
346
+ if (enableWhen.answerCoding?.code !== undefined) {
347
+ return enableWhen.answerCoding.code;
348
+ }
349
+ return undefined;
350
+ }
351
+ // ---------------------------------------------------------------------------
352
+ // Extension Helpers
353
+ // ---------------------------------------------------------------------------
354
+ /**
355
+ * Get the value of an extension by URL.
356
+ */
357
+ export function getExtensionValue(extensions, url) {
358
+ if (!extensions)
359
+ return undefined;
360
+ const ext = extensions.find((e) => e.url === url);
361
+ if (!ext)
362
+ return undefined;
363
+ // Return the first non-url value property
364
+ for (const key of Object.keys(ext)) {
365
+ if (key.startsWith('value')) {
366
+ return ext[key];
367
+ }
368
+ }
369
+ return undefined;
370
+ }
371
+ /**
372
+ * Get the itemControl code from extensions.
373
+ */
374
+ export function getItemControlCode(extensions) {
375
+ if (!extensions)
376
+ return undefined;
377
+ const ext = extensions.find((e) => e.url === FHIR_EXT.ITEM_CONTROL);
378
+ if (!ext)
379
+ return undefined;
380
+ // itemControl uses valueCodeableConcept
381
+ const coding = ext.valueCodeableConcept?.coding?.[0];
382
+ return coding?.code;
383
+ }
384
+ /**
385
+ * Check if the signatureRequired extension is present and true.
386
+ */
387
+ export function hasSignatureRequired(extensions) {
388
+ if (!extensions)
389
+ return false;
390
+ const ext = extensions.find((e) => e.url === FHIR_EXT.SIGNATURE_REQUIRED);
391
+ return ext?.valueBoolean === true;
392
+ }
393
+ /**
394
+ * Create an itemControl extension.
395
+ */
396
+ export function createItemControlExtension(controlType) {
397
+ return {
398
+ url: FHIR_EXT.ITEM_CONTROL,
399
+ valueCodeableConcept: {
400
+ coding: [
401
+ {
402
+ system: ITEM_CONTROL_SYSTEM,
403
+ code: controlType,
404
+ },
405
+ ],
406
+ },
407
+ };
408
+ }
409
+ /**
410
+ * Create a signatureRequired extension.
411
+ */
412
+ export function createSignatureRequiredExtension() {
413
+ return {
414
+ url: FHIR_EXT.SIGNATURE_REQUIRED,
415
+ valueBoolean: true,
416
+ };
417
+ }
418
+ // ---------------------------------------------------------------------------
419
+ // String Helpers
420
+ // ---------------------------------------------------------------------------
421
+ /**
422
+ * Convert a string to kebab-case for use as an ID.
423
+ */
424
+ export function toKebabCase(str) {
425
+ return str
426
+ .toLowerCase()
427
+ .replace(/[^a-z0-9]+/g, '-')
428
+ .replace(/^-|-$/g, '');
429
+ }
430
+ /**
431
+ * Generate a simple UUID v4.
432
+ */
433
+ export function generateUUID() {
434
+ // Simple UUID v4 implementation
435
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
436
+ const r = (Math.random() * 16) | 0;
437
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
438
+ return v.toString(16);
439
+ });
440
+ }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
- export { convertSurveyJS, convertSurveyJSToESheet, importFromSurveyJS, exportToSurveyJS, SURVEYJS_SYSTEM_PROMPT, } from './lib/surveyjs-converter.js';
2
- export { importFromMcp, exportToMcp, type McpElicitationSchema, type McpElicitationRequest, type McpProperty, type McpStringProp, type McpNumberProp, type McpBooleanProp, type McpArrayProp, type McpConstOption, } from './lib/mcp.js';
1
+ export { convertSurveyJS, convertSurveyJSToESheet, importFromSurveyJS, exportToSurveyJS, isSurveyJSSchema, SURVEYJS_SYSTEM_PROMPT, type SurveyJSDetectionSchema, } from './lib/surveyjs-converter.js';
2
+ export { importFromMcp, exportToMcp, isMcpElicitationRequest, type McpElicitationSchema, type McpElicitationRequest, type McpProperty, type McpStringProp, type McpNumberProp, type McpBooleanProp, type McpArrayProp, type McpConstOption, } from './lib/mcp.js';
3
+ export * from './fhir/index.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,aAAa,EACb,WAAW,EACX,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,aAAa,EACb,WAAW,EACX,uBAAuB,EACvB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAC;AACtB,cAAc,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // =============================================================================
2
2
  // @esheet/adapters - Convert external form schemas to eSheet FormDefinition
3
3
  // =============================================================================
4
- export { convertSurveyJS, convertSurveyJSToESheet, importFromSurveyJS, exportToSurveyJS, SURVEYJS_SYSTEM_PROMPT, } from './lib/surveyjs-converter.js';
5
- export { importFromMcp, exportToMcp, } from './lib/mcp.js';
4
+ export { convertSurveyJS, convertSurveyJSToESheet, importFromSurveyJS, exportToSurveyJS, isSurveyJSSchema, SURVEYJS_SYSTEM_PROMPT, } from './lib/surveyjs-converter.js';
5
+ export { importFromMcp, exportToMcp, isMcpElicitationRequest, } from './lib/mcp.js';
6
+ export * from './fhir/index.js';
package/dist/lib/mcp.d.ts CHANGED
@@ -96,6 +96,8 @@ export interface McpElicitationRequest {
96
96
  * `minimum`, `maximum`, `minItems`, `maxItems`) are preserved in each
97
97
  * field's `_sourceData` so they survive a round-trip export.
98
98
  */
99
+ /** Type guard — detects an MCP elicitation/create JSON-RPC envelope. */
100
+ export declare function isMcpElicitationRequest(value: unknown): value is McpElicitationRequest;
99
101
  export declare function importFromMcp(schema: McpElicitationSchema, options?: {
100
102
  formId?: string;
101
103
  title?: string;
@@ -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
@@ -20,6 +20,13 @@ import { generateOptionId } from '@esheet/core';
20
20
  * `minimum`, `maximum`, `minItems`, `maxItems`) are preserved in each
21
21
  * field's `_sourceData` so they survive a round-trip export.
22
22
  */
23
+ /** Type guard — detects an MCP elicitation/create JSON-RPC envelope. */
24
+ export function isMcpElicitationRequest(value) {
25
+ if (typeof value !== 'object' || value === null)
26
+ return false;
27
+ const v = value;
28
+ return v['jsonrpc'] === '2.0' && v['method'] === 'elicitation/create';
29
+ }
23
30
  export function importFromMcp(schema, options) {
24
31
  const existingIds = new Set();
25
32
  const requiredKeys = new Set(schema.required ?? []);
@@ -116,5 +116,15 @@ export declare const importFromSurveyJS: typeof convertSurveyJSToESheet;
116
116
  * Alias for importFromSurveyJS / convertSurveyJSToESheet.
117
117
  */
118
118
  export declare const convertSurveyJS: typeof convertSurveyJSToESheet;
119
+ /** Minimal SurveyJS schema shape for detection. */
120
+ export interface SurveyJSDetectionSchema {
121
+ pages?: unknown[];
122
+ elements?: unknown[];
123
+ }
124
+ /**
125
+ * Type guard — returns true if the value looks like a SurveyJS schema
126
+ * (has top-level `pages` or `elements` array but NOT eSheet's `fields` property).
127
+ */
128
+ export declare function isSurveyJSSchema(value: unknown): value is SurveyJSDetectionSchema;
119
129
  export {};
120
130
  //# sourceMappingURL=surveyjs-converter.d.ts.map
@@ -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":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,cAAc,EAOf,MAAM,cAAc,CAAC;AAMtB,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,kBAAkB;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,wBAAwB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,MAAM,GAAG,cAAc,CAAC,EAAE,CAAC;IACtC,IAAI,CAAC,EAAE,CAAC,MAAM,GAAG,kBAAkB,CAAC,EAAE,CAAC;IACvC,OAAO,CAAC,EAAE,CAAC,MAAM,GAAG,kBAAkB,CAAC,EAAE,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;IAE7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,KAAK,CAAC,EAAE,wBAAwB,EAAE,CAAC;CACpC;AAED,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;CAC9B;AAED,UAAU,kBAAkB;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACvC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gBAAgB,CAAC,EAAE,OAAO,EAAE,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;CACtB;AAED,UAAU,cAAe,SAAQ,kBAAkB;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;CAC9B;AAseD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,cAAc,GACrB,cAAc,CAiEhB;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,w1CAA8sC,CAAC;AAuLlvC;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,cAAc,CA0CrE;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,gCAA0B,CAAC;AAE1D;;;GAGG;AACH,eAAO,MAAM,eAAe,gCAA0B,CAAC;AAEvD,mDAAmD;AACnD,MAAM,WAAW,uBAAuB;IACtC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,uBAAuB,CAOlC"}
@@ -72,12 +72,15 @@ function convertChoice(choice, index) {
72
72
  if (typeof choice === 'string') {
73
73
  return { id: toKebabCase(choice) || `opt-${index}`, value: choice };
74
74
  }
75
- return {
75
+ const opt = {
76
76
  id: toKebabCase(choice.value) || `opt-${index}`,
77
77
  value: choice.value,
78
78
  text: choice.text,
79
- score: choice.score,
80
79
  };
80
+ if (choice.score !== undefined) {
81
+ opt.score = choice.score;
82
+ }
83
+ return opt;
81
84
  }
82
85
  function convertMatrixRow(item, index) {
83
86
  if (typeof item === 'string') {
@@ -92,11 +95,14 @@ function convertMatrixColumn(item, index) {
92
95
  if (typeof item === 'string') {
93
96
  return { id: toKebabCase(item) || `item-${index}`, value: item };
94
97
  }
95
- return {
98
+ const col = {
96
99
  id: toKebabCase(item.value) || `item-${index}`,
97
100
  value: item.text ?? item.value,
98
- score: item.score,
99
101
  };
102
+ if (item.score !== undefined) {
103
+ col.score = item.score;
104
+ }
105
+ return col;
100
106
  }
101
107
  /**
102
108
  * Parse SurveyJS visibleIf expression into eSheet rules.
@@ -418,8 +424,9 @@ export function convertSurveyJSToESheet(survey) {
418
424
  fields.push(...page.elements.map((el) => convertElement(el)));
419
425
  }
420
426
  else {
421
- // Multiple pages become sections
422
- const sectionId = toKebabCase(page.name ?? page.title ?? 'page');
427
+ // Multiple pages become sections — prefix with "page-" to avoid
428
+ // collisions when a page name matches one of its element names.
429
+ const sectionId = 'page-' + toKebabCase(page.name ?? page.title ?? 'page');
423
430
  const sectionAncestors = new Set([sectionId]);
424
431
  fields.push({
425
432
  id: sectionId,
@@ -696,3 +703,16 @@ export const importFromSurveyJS = convertSurveyJSToESheet;
696
703
  * Alias for importFromSurveyJS / convertSurveyJSToESheet.
697
704
  */
698
705
  export const convertSurveyJS = convertSurveyJSToESheet;
706
+ /**
707
+ * Type guard — returns true if the value looks like a SurveyJS schema
708
+ * (has top-level `pages` or `elements` array but NOT eSheet's `fields` property).
709
+ */
710
+ export function isSurveyJSSchema(value) {
711
+ if (typeof value !== 'object' || value === null)
712
+ return false;
713
+ const v = value;
714
+ const hasPages = Array.isArray(v['pages']);
715
+ const hasElements = Array.isArray(v['elements']);
716
+ const hasESheetFields = typeof v['fields'] !== 'undefined';
717
+ return (hasPages || hasElements) && !hasESheetFields;
718
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@esheet/adapters",
3
- "version": "0.0.3",
3
+ "version": "0.0.4-1",
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": "*",
35
+ "@esheet/core": "0.0.4-1",
36
36
  "tslib": "^2.3.0"
37
37
  },
38
38
  "devDependencies": {}