# Code generation JupyterGIS leverages code generation to share information about data structures across Python and TypeScript packages. ## Overview There are 3 code generation targets: the schema registry, TypeScript types, and Python types. Code generation tasks are defined in `packages/schema/package.json`. You can run all code generation tasks with `jlpm run build:schema`, or run them individually using the commands in the diagram below. ```mermaid flowchart TD package-manifest["package.json"] npm-script-schema-registry{{"build:schema:registry"}} npm-script-schema-js{{"build:schema:js"}} npm-script-schema-py{{"build:schema:py"}} combined-schema[("Combined schema
(forms.json)")] schema-registry[["schemaregistry.ts"]] react-forms[["React forms"]] ts-types[("TypeScript type definitions")] tmp-schema[("Temporary schema
(rewritten $ref paths)")] py-types[("Python type definitions")] package-manifest -->|jlpm run| npm-script-schema-registry package-manifest -->|jlpm run| npm-script-schema-js package-manifest -->|jlpm run| npm-script-schema-py npm-script-schema-registry -->|scripts/dereference-and-combine-schemas-for-registry.js| combined-schema -->|read| schema-registry -->|react-jsonschema-form| react-forms npm-script-schema-js -->|json-schema-to-typescript| ts-types npm-script-schema-js -->|scripts/add-schema-version.ts| ts-types npm-script-schema-py -->|scripts/preprocess-schemas-for-python-type-generation.js| tmp-schema --> |datamodel-code-generator| py-types ``` ## Schema registry The schema registry is built for use in TypeScript code. It's used by [`react-jsonschema-form` (RJSF)](https://github.com/rjsf-team/react-jsonschema-form) to generate forms (React components) from JSONSchema. Prior to generating the schema registry, we dereference (i.e. inline `$ref`s) our schemas and combine them into one JSON file which contains a mapping from schema names to schema data for each schema. :::{note} Combining the schemas into `forms.json` is vestigial. Before we had a schema registry, we would directly index into this data to find a schema. Now that we're building a schema registry for interfacing with schemas, perhaps we don't need a combined `forms.json` schema. ::: ## TypeScript types TypeScript types are generated from the JSONSchema files using [`json-schema-to-typescript`](https://github.com/bcherny/json-schema-to-typescript). We additionally run a custom script (`scripts/add-schema-version.ts`) to generate a version number variable. ## Python types Python types are generated from the JSONSchema files using [`datamodel-code-generator`](https://github.com/koxudaxi/datamodel-code-generator). ### Weirdness with `$ref` paths Unfortunately, `datamodel-code-generator` expects `$ref` paths to be expressed differently from `json-schema-to-typescript`. The former expects "relative" paths, and the latter expects "absolute" paths. For example, if we have two schema files: ```text ├── referent.json └── subdir └── referrer.json ``` ...`json-schema-to-typescript` would expect `referrer.json` to contain a reference like: ```json "$ref": "referent.json", ``` ...and `datamodel-code-generator` would expect the reference in `referrer.json` to look like: ```json "$ref": "../referent.json", ``` **For this reason, we chose to write our schema files in the way `json-schema-to-typescript` expects, and pre-process them into a temp directory so they look the way `datamodel-code-generator` expects before generating Python types.**