Appearance
FSH generation
Writes lint case configs as a SUSHI project: one FSH file per case, a shared SUSHI config, and a linter config for each case that needs one. The same code writes the project of a package's cases and the one-case project of npm run demo.
Each case becomes one Questionnaire instance with Usage: #example. At every level, its extensions come first, then its raw fsh lines, then its items. A list of one extension has no index; a longer one starts each extension with [0] or [+] and refers back to it with [=]. Contained resources become inline instances, named and given the id <instance>-contained-<n> unless their fsh sets one. Only a Questionnaire gets a status.
yaml
# packages/core/test/cases/demo/contained.yaml
items:
- linkId: a
type: string
extensions:
- url: calculatedExpression
expression: '%missing'
contained:
- extensions:
- url: variable
name: c
expression: '%nope'fsh
Instance: demo-contained
InstanceOf: Questionnaire
Usage: #example
* status = #draft
* item[0].linkId = "a"
* item[=].type = #string
* item[=].extension.url = "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression"
* item[=].extension.valueExpression.language = #text/fhirpath
* item[=].extension.valueExpression.expression = "%missing"
* contained[0] = demo-contained-contained-1
Instance: demo-contained-contained-1
InstanceOf: Questionnaire
Usage: #inline
* status = #draft
* extension.url = "http://hl7.org/fhir/StructureDefinition/variable"
* extension.valueExpression.name = "c"
* extension.valueExpression.language = #text/fhirpath
* extension.valueExpression.expression = "%nope"A case gets a linter config, lint-config-<instance>.mjs, when it gives hostVariables, rules or suppress, or when the project lists plugins. It sits at the project root, because the linter resolves the FSH directories and the SUSHI index against the config's directory. It is an .mjs file, because only an .mjs config can list plugins; it imports each plugin's file by its URL.
The SUSHI config is the same for every project: FSH only, FHIR 4.0.1, and SDC 4.0.0 as the one dependency.
text
<project>/
sushi-config.yaml
lint-config-<instance>.mjs a case with a linter config
input/fsh/<instance>.fsh one per case
fsh-generated/resources/Questionnaire-<instance>.json written by SUSHI
fsh-generated/data/fsh-index.json written by SUSHI, read by source mappinggenerateProject fails when two cases have the same instance. It removes only what it and SUSHI write, sushi-config.yaml, input/ and fsh-generated/, so a wrong output directory cannot lose other files.
Schema
Code
In packages/lint-cases/src/generate-fsh.ts:
renderFsh: a config as FSH, withextensionLines,itemLinesandinstanceLinesfor each level.lintConfigFile: the name of a case's linter config, orundefinedwhen it needs none;lintConfigModulewrites it.sushiConfig: the SUSHI config.generateProject: writes the whole project.
packages/core/scripts/demo.ts uses generateProject with one config, then compiles and lints it.