SUSHI (SUSHI Unshortens Short Hand Inputs)

repository·master·Indexed 41 days ago

https://github.com/fhir/sushi

A command-line compiler for FHIR Shorthand (FSH) version 3.20.1. It allows developers to define FHIR Implementation Guides (IGs), profiles, and extensions using a compact, text-based language. The CLI provides commands to initialize projects, build FSH files into FHIR artifacts, and update dependencies.

Tokens
14.2K
Snippets
44
Records
62
Agent score
52%

What's inside SUSHI

  1. Build JavaScript parser/lexer classes from FSH Grammar

    master

    After making changes to the .g4 grammar files, you must regenerate the parser and lexer classes. Run the following Gradle command from the antlr/ directory:

    ./gradlew generateGrammarSource

    This process generates the resulting parser/lexer files into the following directory: ../src/import/generated

  2. Install SUSHI for development

    master

    SUSHI is a TypeScript project. Developers should use Node.js 22. To set up the development environment, clone the repository and run npm install from the root folder.

    $ npm install
  3. Manage dependencies and security in SUSHI

    master

    When adding new dependencies to the project, follow these requirements:

    1. Use the latest versions: Always use the latest published version from npm. You can verify this using npm outdated.
    2. Document exceptions: If you must use a version other than the latest, add the dependency and the reason for the version choice to DEPENDENCY-NOTES.md.
    3. Check for vulnerabilities: Run npm audit to ensure no new security vulnerabilities are introduced by your changes.
    npm outdated
    npm audit
  4. Generate Implementation Guides (IG) with SUSHI

    master

    SUSHI supports publishing implementation guides using the template-based IG Publisher. SUSHI populates the output directory based on inputs from:

    1. FSH files
    2. sushi-config.yaml
    3. The IG project directory.

    For detailed information on IG projects, refer to the SUSHI documentation.

  5. Install SUSHI for users

    master

    SUSHI requires Node.js to be installed. While Node.js 18 and 20 are supported, Node.js 22 is the recommended version.

    To install or update SUSHI globally, use npm install -g fsh-sushi.

    $ npm install -g fsh-sushi
  6. Lint and format code in SUSHI

    master

    To maintain consistent code style, SUSHI uses ESLint for linting and Prettier for formatting. Use the following commands to check and fix issues:

    Linting (ESLint)

    • Check for issues: Run npm run lint.
    • Automatically fix issues: Run npm run lint:fix to apply ESLint's --fix option to as many problems as possible.

    Formatting (Prettier)

    • Check formatting: Run npm run prettier.
    • Automatically fix formatting: Run npm run prettier:fix to rewrite files using Prettier's --write option.
    npm run lint
    npm run lint:fix
    npm run prettier
    npm run prettier:fix
  7. Run tests and check coverage in SUSHI

    master

    SUSHI uses Jest for testing. To ensure your changes are correct and maintain high code quality, follow these steps:

    1. Run the full test suite: Execute npm test to verify all existing and new functionality.
    2. Review coverage: After running the tests, execute npm run coverage to generate a report. Ensure that your new code is fully covered by tests.
    npm test
    npm run coverage
  8. Manage and query FSH content with FSHTank

    master

    The FSHTank class acts as a central container for all parsed FSH (FHIR Structure Definition Language) content. It manages a collection of FSHDocument objects and a global Configuration. It provides high-level methods to retrieve all entities of a specific type (e.g., Profiles, Extensions, Resources) and powerful searching capabilities via the fish and fishAll methods.

    Key capabilities include:

    • Bulk Retrieval: Access all entities of a type (e.g., getAllProfiles(), getAllResources(), getAllValueSets()).
    • Entity Searching: Find specific entities by name, ID, URL, or version using the fish API.
    • Metadata Extraction: Retrieve FHIR-compatible metadata (ID, name, URL, version, resource type) for any entity using fishForMetadata.
    • Alias Resolution: Resolve FSH aliases to their actual definitions.
  9. Understand the `setImpliedPropertiesOnInstance` function

    master

    The setImpliedPropertiesOnInstance function is responsible for assigning values to elements within a FHIR Instance based on rules defined in a StructureDefinition. It iterates through elements breadth-first to ensure that implied properties (values assigned to parent elements or specific paths) are correctly propagated to the instance.

    Arguments

    • assignedResourcePaths: A list of paths from rules where the assigned value is an instance. When an instance is assigned at a path, the function skips checking for implied properties on that path's children.
    • knownSlices: A map where keys are element paths and values are the number of times that element appears. This is used for slice management.
      • In manual slice ordering mode, this is created by createUsefulSlices.
      • Otherwise, it is created by determineKnownSlices.
      • Example: A key component[Foo] with value 2 indicates the instance will have two Foo slices on the component element.
    • manualSliceOrdering: A boolean configuration flag that controls how slices are ordered.
  10. Configure ESLint for SUSHI development

    master

    The SUSHI project uses ESLint with the Flat Config format (eslint.config.mjs). The configuration integrates TypeScript parsing and Prettier to ensure code quality and consistent formatting.

    Key configuration details:

    • Parser: Uses @typescript-eslint/parser to handle TypeScript syntax.
    • Language Options: Configured for ecmaVersion: 2018 and sourceType: 'module'.
    • Base Rules: Extends @typescript-eslint/recommended and prettier via FlatCompat.

    Ignored Directories/Files: To prevent linting unnecessary or generated files, the following patterns are ignored:

    • dist/*
    • coverage/*
    • build*/*
    • **/*.d.ts
    • src/public/
    • src/types/
    • regression/output*
    • **/generated
    import tsParser from '@typescript-eslint/parser';
    import path from 'node:path';
    import { fileURLToPath } from 'node:url';
    import js from '@eslint/js';
    import { FlatCompat } from '@eslint/eslintrc';
    
    const __filename = fileURLToPath(import.meta.url);
    const __dirname = path.dirname(__filename);
    const compat = new FlatCompat({
      baseDirectory: __dirname,
      recommendedConfig: js.configs.recommended,
      allConfig: js.configs.all
    });
    
    export default [
      {
        ignores: [
          'dist/*',
          'coverage/*',
          'build*/*',
          '**/*.d.ts',
          'src/public/',
          'src/types/',
          'regression/output*',
          '**/generated'
        ]
      },
      ...compat.extends('plugin:@typescript-eslint/recommended', 'prettier'),
      {
        languageOptions: {
          parser: tsParser,
          ecmaVersion: 2018,
          sourceType: 'module'
        },
        rules: {
          semi: ['error', 'always'],
          quotes: ['error', 'single', { avoidEscape: true }],
          '@typescript-eslint/ban-ts-comment': 'off',
          '@typescript-eslint/explicit-function-return-type': 'off',
          '@typescript-eslint/no-empty-function': 'off',
          '@typescript-eslint/no-explicit-any': 'off',
          '@typescript-eslint/no-unsafe-declaration-merging': 'off'
        }
      }
    ];