Repository: foxglove/schemas (language: python)

Issue:
Add typescript schema export utility
### Public-Facing Changes
None

### Description
Add typescript schema export utility. This will be used in studio to import schema definitions in order to make them available for use in user scripts.



Discussion / hints:
@foxymiles "schemata" is a cute spelling...but the name of this repo is foxglove/schemas, so I think we should probably stick with that plural form 😬 

<img width="349" alt="image" src="https://github.com/foxglove/schemas/assets/14237/b57e4637-83c0-40b5-b2c9-d1678954b2c7">


Fix patch:
diff --git a/internal/exportTypescriptSchemata.ts b/internal/exportTypeScriptSchemas.ts
similarity index 55%
rename from internal/exportTypescriptSchemata.ts
rename to internal/exportTypeScriptSchemas.ts
index 10d6b08..552b37e 100644
--- a/internal/exportTypescriptSchemata.ts
+++ b/internal/exportTypeScriptSchemas.ts
@@ -2,23 +2,23 @@ import { DURATION_TS, TIME_TS, generateTypeScript } from "./generateTypeScript";
 import { foxgloveEnumSchemas, foxgloveMessageSchemas } from "./schemas";
 
 /**
- * Export typescript schema as source, keyed by the schema name.
+ * Export schemas as TypeScript source code, keyed by the file base name (without `.ts` suffix).
  *
- * @returns a record of schema name => schema source.
+ * @returns a map of file base name => schema source.
  */
-export function exportTypescriptSchemata(): Record<string, string> {
-  const schemas: Record<string, string> = {};
+export function exportTypeScriptSchemas(): Map<string, string> {
+  const schemas = new Map<string, string>();
 
   for (const schema of Object.values(foxgloveMessageSchemas)) {
-    schemas[schema.name] = generateTypeScript(schema);
+    schemas.set(schema.name, generateTypeScript(schema));
   }
 
   for (const schema of Object.values(foxgloveEnumSchemas)) {
-    schemas[schema.name] = generateTypeScript(schema);
+    schemas.set(schema.name, generateTypeScript(schema));
   }
 
-  schemas["Duration"] = DURATION_TS;
-  schemas["Time"] = TIME_TS;
+  schemas.set("Duration", DURATION_TS);
+  schemas.set("Time", TIME_TS);
 
   const allSchemaNames = [
     ...Object.values(foxgloveMessageSchemas),
@@ -28,7 +28,7 @@ export function exportTypescriptSchemata(): Record<string, string> {
   for (const schema of allSchemaNames) {
     indexTS += `export * from "./${schema.name}";\n`;
   }
-  schemas["index"] = indexTS;
+  schemas.set("index", indexTS);
 
   return schemas;
 }
diff --git a/internal/index.ts b/internal/index.ts
index a7d6b0c..dd22a61 100644
--- a/internal/index.ts
+++ b/internal/index.ts
@@ -1,4 +1,5 @@
-export * from "./exportTypescriptSchemata";
+export * from "./exportTypeScriptSchemas";
+export * from "./generateTypeScript";
 export * from "./generateJsonSchema";
 export * from "./generateProto";
 export * from "./generateRos";
diff --git a/package.json b/package.json
index c80641a..db2caef 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@foxglove/schemas",
-  "version": "1.4.0",
+  "version": "1.5.0",
   "description": "Foxglove-defined message schemas for ROS, Protobuf, and JSON",
   "license": "MIT",
   "repository": {
diff --git a/scripts/updateGeneratedFiles.ts b/scripts/updateGeneratedFiles.ts
index b310bd5..bff8efc 100644
--- a/scripts/updateGeneratedFiles.ts
+++ b/scripts/updateGeneratedFiles.ts
@@ -4,7 +4,7 @@ import path from "path";
 import rimraf from "rimraf";
 
 import { generateRosMsg, generateRosMsgDefinition } from "../internal";
-import { exportTypescriptSchemata } from "../internal/exportTypescriptSchemata";
+import { exportTypeScriptSchemas } from "../internal/exportTypeScriptSchemas";
 import {
   BYTE_VECTOR_FB,
   DURATION_FB,
@@ -101,8 +101,8 @@ async function main({ outDir, rosOutDir }: { outDir: string; rosOutDir: string }
 
   await logProgress("Generating TypeScript definitions", async () => {
     await fs.mkdir(path.join(outDir, "typescript"), { recursive: true });
-    const schemas = exportTypescriptSchemata();
-    for (const [name, source] of Object.entries(schemas)) {
+    const schemas = exportTypeScriptSchemas();
+    for (const [name, source] of schemas.entries()) {
       await fs.writeFile(path.join(outDir, "typescript", `${name}.ts`), source);
     }
   });


Test patch:
diff --git a/internal/__snapshots__/exportTypescriptSchemata.test.ts.snap b/internal/__snapshots__/exportTypeScriptSchemas.test.ts.snap
similarity index 89%
rename from internal/__snapshots__/exportTypescriptSchemata.test.ts.snap
rename to internal/__snapshots__/exportTypeScriptSchemas.test.ts.snap
index 52c4af4..6d716e1 100644
--- a/internal/__snapshots__/exportTypescriptSchemata.test.ts.snap
+++ b/internal/__snapshots__/exportTypeScriptSchemas.test.ts.snap
@@ -1,8 +1,8 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`exportTypescriptSchemata exports schemata 1`] = `
-{
-  "ArrowPrimitive": "// Generated by https://github.com/foxglove/schemas
+exports[`exportTypeScriptSchemas exports schemas 1`] = `
+Map {
+  "ArrowPrimitive" => "// Generated by https://github.com/foxglove/schemas
 
 import { Color } from "./Color";
 import { Pose } from "./Pose";
@@ -28,7 +28,7 @@ export type ArrowPrimitive = {
   color: Color;
 };
 ",
-  "CameraCalibration": "// Generated by https://github.com/foxglove/schemas
+  "CameraCalibration" => "// Generated by https://github.com/foxglove/schemas
 
 import { Time } from "./Time";
 
@@ -108,7 +108,7 @@ export type CameraCalibration = {
   P: [number, number, number, number, number, number, number, number, number, number, number, number];
 };
 ",
-  "CircleAnnotation": "// Generated by https://github.com/foxglove/schemas
+  "CircleAnnotation" => "// Generated by https://github.com/foxglove/schemas
 
 import { Color } from "./Color";
 import { Point2 } from "./Point2";
@@ -135,7 +135,7 @@ export type CircleAnnotation = {
   outline_color: Color;
 };
 ",
-  "Color": "// Generated by https://github.com/foxglove/schemas
+  "Color" => "// Generated by https://github.com/foxglove/schemas
 
 /** A color in RGBA format */
 export type Color = {
@@ -152,7 +152,7 @@ export type Color = {
   a: number;
 };
 ",
-  "CompressedImage": "// Generated by https://github.com/foxglove/schemas
+  "CompressedImage" => "// Generated by https://github.com/foxglove/schemas
 
 import { Time } from "./Time";
 
@@ -175,25 +175,7 @@ export type CompressedImage = {
   format: string;
 };
 ",
-  "CubePrimitive": "// Generated by https://github.com/foxglove/schemas
-
-import { Color } from "./Color";
-import { Pose } from "./Pose";
-import { Vector3 } from "./Vector3";
-
-/** A primitive representing a cube or rectangular prism */
-export type CubePrimitive = {
-  /** Position of the center of the cube and orientation of the cube */
-  pose: Pose;
-
-  /** Size of the cube along each axis */
-  size: Vector3;
-
-  /** Color of the cube */
-  color: Color;
-};
-",
-  "CylinderPrimitive": "// Generated by https://github.com/foxglove/schemas
+  "CylinderPrimitive" => "// Generated by https://github.com/foxglove/schemas
 
 import { Color } from "./Color";
 import { Pose } from "./Pose";
@@ -217,12 +199,25 @@ export type CylinderPrimitive = {
   color: Color;
 };
 ",
-  "Duration": "export type Duration = {
-  sec: number;
-  nsec: number;
+  "CubePrimitive" => "// Generated by https://github.com/foxglove/schemas
+
+import { Color } from "./Color";
+import { Pose } from "./Pose";
+import { Vector3 } from "./Vector3";
+
+/** A primitive representing a cube or rectangular prism */
+export type CubePrimitive = {
+  /** Position of the center of the cube and orientation of the cube */
+  pose: Pose;
+
+  /** Size of the cube along each axis */
+  size: Vector3;
+
+  /** Color of the cube */
+  color: Color;
 };
 ",
-  "FrameTransform": "// Generated by https://github.com/foxglove/schemas
+  "FrameTransform" => "// Generated by https://github.com/foxglove/schemas
 
 import { Quaternion } from "./Quaternion";
 import { Time } from "./Time";
@@ -246,7 +241,7 @@ export type FrameTransform = {
   rotation: Quaternion;
 };
 ",
-  "FrameTransforms": "// Generated by https://github.com/foxglove/schemas
+  "FrameTransforms" => "// Generated by https://github.com/foxglove/schemas
 
 import { FrameTransform } from "./FrameTransform";
 
@@ -256,7 +251,7 @@ export type FrameTransforms = {
   transforms: FrameTransform[];
 };
 ",
-  "GeoJSON": "// Generated by https://github.com/foxglove/schemas
+  "GeoJSON" => "// Generated by https://github.com/foxglove/schemas
 
 /** GeoJSON data for annotating maps */
 export type GeoJSON = {
@@ -264,7 +259,7 @@ export type GeoJSON = {
   geojson: string;
 };
 ",
-  "Grid": "// Generated by https://github.com/foxglove/schemas
+  "Grid" => "// Generated by https://github.com/foxglove/schemas
 
 import { PackedElementField } from "./PackedElementField";
 import { Pose } from "./Pose";
@@ -301,7 +296,7 @@ export type Grid = {
   data: Uint8Array;
 };
 ",
-  "ImageAnnotations": "// Generated by https://github.com/foxglove/schemas
+  "ImageAnnotations" => "// Generated by https://github.com/foxglove/schemas
 
 import { CircleAnnotation } from "./CircleAnnotation";
 import { PointsAnnotation } from "./PointsAnnotation";
@@ -319,7 +314,7 @@ export type ImageAnnotations = {
   texts: TextAnnotation[];
 };
 ",
-  "KeyValuePair": "// Generated by https://github.com/foxglove/schemas
+  "KeyValuePair" => "// Generated by https://github.com/foxglove/schemas
 
 /** A key with its associated value */
 export type KeyValuePair = {
@@ -330,7 +325,7 @@ export type KeyValuePair = {
   value: string;
 };
 ",
-  "LaserScan": "// Generated by https://github.com/foxglove/schemas
+  "LaserScan" => "// Generated by https://github.com/foxglove/schemas
 
 import { Pose } from "./Pose";
 import { Time } from "./Time";
@@ -359,7 +354,7 @@ export type LaserScan = {
   intensities: number[];
 };
 ",
-  "LinePrimitive": "// Generated by https://github.com/foxglove/schemas
+  "LinePrimitive" => "// Generated by https://github.com/foxglove/schemas
 
 import { Color } from "./Color";
 import { LineType } from "./LineType";
@@ -397,21 +392,7 @@ export type LinePrimitive = {
   indices: number[];
 };
 ",
-  "LineType": "// Generated by https://github.com/foxglove/schemas
-
-/** An enumeration indicating how input points should be interpreted to create lines */
-export enum LineType {
-  /** Connected line segments: 0-1, 1-2, ..., (n-1)-n */
-  LINE_STRIP = 0,
-
-  /** Closed polygon: 0-1, 1-2, ..., (n-1)-n, n-0 */
-  LINE_LOOP = 1,
-
-  /** Individual line segments: 0-1, 2-3, 4-5, ... */
-  LINE_LIST = 2,
-}
-",
-  "LocationFix": "// Generated by https://github.com/foxglove/schemas
+  "LocationFix" => "// Generated by https://github.com/foxglove/schemas
 
 import { PositionCovarianceType } from "./PositionCovarianceType";
 import { Time } from "./Time";
@@ -440,7 +421,7 @@ export type LocationFix = {
   position_covariance_type: PositionCovarianceType;
 };
 ",
-  "Log": "// Generated by https://github.com/foxglove/schemas
+  "Log" => "// Generated by https://github.com/foxglove/schemas
 
 import { LogLevel } from "./LogLevel";
 import { Time } from "./Time";
@@ -466,24 +447,97 @@ export type Log = {
   line: number;
 };
 ",
-  "LogLevel": "// Generated by https://github.com/foxglove/schemas
+  "SceneEntityDeletion" => "// Generated by https://github.com/foxglove/schemas
 
-/** Log level */
-export enum LogLevel {
-  UNKNOWN = 0,
+import { SceneEntityDeletionType } from "./SceneEntityDeletionType";
+import { Time } from "./Time";
 
-  DEBUG = 1,
+/** Command to remove previously published entities */
+export type SceneEntityDeletion = {
+  /** Timestamp of the deletion. Only matching entities earlier than this timestamp will be deleted. */
+  timestamp: Time;
 
-  INFO = 2,
+  /** Type of deletion action to perform */
+  type: SceneEntityDeletionType;
 
-  WARNING = 3,
+  /** Identifier which must match if \`type\` is \`MATCHING_ID\`. */
+  id: string;
+};
+",
+  "SceneEntity" => "// Generated by https://github.com/foxglove/schemas
 
-  ERROR = 4,
+import { ArrowPrimitive } from "./ArrowPrimitive";
+import { CubePrimitive } from "./CubePrimitive";
+import { CylinderPrimitive } from "./CylinderPrimitive";
+import { Duration } from "./Duration";
+import { KeyValuePair } from "./KeyValuePair";
+import { LinePrimitive } from "./LinePrimitive";
+import { ModelPrimitive } from "./ModelPrimitive";
+import { SpherePrimitive } from "./SpherePrimitive";
+import { TextPrimitive } from "./TextPrimitive";
+import { Time } from "./Time";
+import { TriangleListPrimitive } from "./TriangleListPrimitive";
 
-  FATAL = 5,
-}
+/** A visual element in a 3D scene. An entity may be composed of multiple primitives which all share the same frame of reference. */
+export type SceneEntity = {
+  /** Timestamp of the entity */
+  timestamp: Time;
+
+  /** Frame of reference */
+  frame_id: string;
+
+  /** Identifier for the entity. A entity will replace any prior entity on the same topic with the same \`id\`. */
+  id: string;
+
+  /** Length of time (relative to \`timestamp\`) after which the entity should be automatically removed. Zero value indicates the entity should remain visible until it is replaced or deleted. */
+  lifetime: Duration;
+
+  /** Whether the entity should keep its location in the fixed frame (false) or follow the frame specified in \`frame_id\` as it moves relative to the fixed frame (true) */
+  frame_locked: boolean;
+
+  /** Additional user-provided metadata associated with the entity. Keys must be unique. */
+  metadata: KeyValuePair[];
+
+  /** Arrow primitives */
+  arrows: ArrowPrimitive[];
+
+  /** Cube primitives */
+  cubes: CubePrimitive[];
+
+  /** Sphere primitives */
+  spheres: SpherePrimitive[];
+
+  /** Cylinder primitives */
+  cylinders: CylinderPrimitive[];
+
+  /** Line primitives */
+  lines: LinePrimitive[];
+
+  /** Triangle list primitives */
+  triangles: TriangleListPrimitive[];
+
+  /** Text primitives */
+  texts: TextPrimitive[];
+
+  /** Model primitives */
+  models: ModelPrimitive[];
+};
+",
+  "SceneUpdate" => "// Generated by https://github.com/foxglove/schemas
+
+import { SceneEntity } from "./SceneEntity";
+import { SceneEntityDeletion } from "./SceneEntityDeletion";
+
+/** An update to the entities displayed in a 3D scene */
+export type SceneUpdate = {
+  /** Scene entities to delete */
+  deletions: SceneEntityDeletion[];
+
+  /** Scene entities to add or replace */
+  entities: SceneEntity[];
+};
 ",
-  "ModelPrimitive": "// Generated by https://github.com/foxglove/schemas
+  "ModelPrimitive" => "// Generated by https://github.com/foxglove/schemas
 
 import { Color } from "./Color";
 import { Pose } from "./Pose";
@@ -513,30 +567,7 @@ export type ModelPrimitive = {
   data: Uint8Array;
 };
 ",
-  "NumericType": "// Generated by https://github.com/foxglove/schemas
-
-/** Numeric type */
-export enum NumericType {
-  UNKNOWN = 0,
-
-  UINT8 = 1,
-
-  INT8 = 2,
-
-  UINT16 = 3,
-
-  INT16 = 4,
-
-  UINT32 = 5,
-
-  INT32 = 6,
-
-  FLOAT32 = 7,
-
-  FLOAT64 = 8,
-}
-",
-  "PackedElementField": "// Generated by https://github.com/foxglove/schemas
+  "PackedElementField" => "// Generated by https://github.com/foxglove/schemas
 
 import { NumericType } from "./NumericType";
 
@@ -552,7 +583,7 @@ export type PackedElementField = {
   type: NumericType;
 };
 ",
-  "Point2": "// Generated by https://github.com/foxglove/schemas
+  "Point2" => "// Generated by https://github.com/foxglove/schemas
 
 /** A point representing a position in 2D space */
 export type Point2 = {
@@ -563,7 +594,7 @@ export type Point2 = {
   y: number;
 };
 ",
-  "Point3": "// Generated by https://github.com/foxglove/schemas
+  "Point3" => "// Generated by https://github.com/foxglove/schemas
 
 /** A point representing a position in 3D space */
 export type Point3 = {
@@ -577,7 +608,7 @@ export type Point3 = {
   z: number;
 };
 ",
-  "PointCloud": "// Generated by https://github.com/foxglove/schemas
+  "PointCloud" => "// Generated by https://github.com/foxglove/schemas
 
 import { PackedElementField } from "./PackedElementField";
 import { Pose } from "./Pose";
@@ -604,7 +635,7 @@ export type PointCloud = {
   data: Uint8Array;
 };
 ",
-  "PointsAnnotation": "// Generated by https://github.com/foxglove/schemas
+  "PointsAnnotation" => "// Generated by https://github.com/foxglove/schemas
 
 import { Color } from "./Color";
 import { Point2 } from "./Point2";
@@ -635,26 +666,7 @@ export type PointsAnnotation = {
   thickness: number;
 };
 ",
-  "PointsAnnotationType": "// Generated by https://github.com/foxglove/schemas
-
-/** Type of points annotation */
-export enum PointsAnnotationType {
-  UNKNOWN = 0,
-
-  /** Individual points: 0, 1, 2, ... */
-  POINTS = 1,
-
-  /** Closed polygon: 0-1, 1-2, ..., (n-1)-n, n-0 */
-  LINE_LOOP = 2,
-
-  /** Connected line segments: 0-1, 1-2, ..., (n-1)-n */
-  LINE_STRIP = 3,
-
-  /** Individual line segments: 0-1, 2-3, 4-5, ... */
-  LINE_LIST = 4,
-}
-",
-  "Pose": "// Generated by https://github.com/foxglove/schemas
+  "Pose" => "// Generated by https://github.com/foxglove/schemas
 
 import { Quaternion } from "./Quaternion";
 import { Vector3 } from "./Vector3";
@@ -668,7 +680,7 @@ export type Pose = {
   orientation: Quaternion;
 };
 ",
-  "PoseInFrame": "// Generated by https://github.com/foxglove/schemas
+  "PoseInFrame" => "// Generated by https://github.com/foxglove/schemas
 
 import { Pose } from "./Pose";
 import { Time } from "./Time";
@@ -685,7 +697,7 @@ export type PoseInFrame = {
   pose: Pose;
 };
 ",
-  "PosesInFrame": "// Generated by https://github.com/foxglove/schemas
+  "PosesInFrame" => "// Generated by https://github.com/foxglove/schemas
 
 import { Pose } from "./Pose";
 import { Time } from "./Time";
@@ -702,20 +714,7 @@ export type PosesInFrame = {
   poses: Pose[];
 };
 ",
-  "PositionCovarianceType": "// Generated by https://github.com/foxglove/schemas
-
-/** Type of position covariance */
-export enum PositionCovarianceType {
-  UNKNOWN = 0,
-
-  APPROXIMATED = 1,
-
-  DIAGONAL_KNOWN = 2,
-
-  KNOWN = 3,
-}
-",
-  "Quaternion": "// Generated by https://github.com/foxglove/schemas
+  "Quaternion" => "// Generated by https://github.com/foxglove/schemas
 
 /** A [quaternion](https://eater.net/quaternions) representing a rotation in 3D space */
 export type Quaternion = {
@@ -732,7 +731,7 @@ export type Quaternion = {
   w: number;
 };
 ",
-  "RawImage": "// Generated by https://github.com/foxglove/schemas
+  "RawImage" => "// Generated by https://github.com/foxglove/schemas
 
 import { Time } from "./Time";
 
@@ -764,108 +763,7 @@ export type RawImage = {
   data: Uint8Array;
 };
 ",
-  "SceneEntity": "// Generated by https://github.com/foxglove/schemas
-
-import { ArrowPrimitive } from "./ArrowPrimitive";
-import { CubePrimitive } from "./CubePrimitive";
-import { CylinderPrimitive } from "./CylinderPrimitive";
-import { Duration } from "./Duration";
-import { KeyValuePair } from "./KeyValuePair";
-import { LinePrimitive } from "./LinePrimitive";
-import { ModelPrimitive } from "./ModelPrimitive";
-import { SpherePrimitive } from "./SpherePrimitive";
-import { TextPrimitive } from "./TextPrimitive";
-import { Time } from "./Time";
-import { TriangleListPrimitive } from "./TriangleListPrimitive";
-
-/** A visual element in a 3D scene. An entity may be composed of multiple primitives which all share the same frame of reference. */
-export type SceneEntity = {
-  /** Timestamp of the entity */
-  timestamp: Time;
-
-  /** Frame of reference */
-  frame_id: string;
-
-  /** Identifier for the entity. A entity will replace any prior entity on the same topic with the same \`id\`. */
-  id: string;
-
-  /** Length of time (relative to \`timestamp\`) after which the entity should be automatically removed. Zero value indicates the entity should remain visible until it is replaced or deleted. */
-  lifetime: Duration;
-
-  /** Whether the entity should keep its location in the fixed frame (false) or follow the frame specified in \`frame_id\` as it moves relative to the fixed frame (true) */
-  frame_locked: boolean;
-
-  /** Additional user-provided metadata associated with the entity. Keys must be unique. */
-  metadata: KeyValuePair[];
-
-  /** Arrow primitives */
-  arrows: ArrowPrimitive[];
-
-  /** Cube primitives */
-  cubes: CubePrimitive[];
-
-  /** Sphere primitives */
-  spheres: SpherePrimitive[];
-
-  /** Cylinder primitives */
-  cylinders: CylinderPrimitive[];
-
-  /** Line primitives */
-  lines: LinePrimitive[];
-
-  /** Triangle list primitives */
-  triangles: TriangleListPrimitive[];
-
-  /** Text primitives */
-  texts: TextPrimitive[];
-
-  /** Model primitives */
-  models: ModelPrimitive[];
-};
-",
-  "SceneEntityDeletion": "// Generated by https://github.com/foxglove/schemas
-
-import { SceneEntityDeletionType } from "./SceneEntityDeletionType";
-import { Time } from "./Time";
-
-/** Command to remove previously published entities */
-export type SceneEntityDeletion = {
-  /** Timestamp of the deletion. Only matching entities earlier than this timestamp will be deleted. */
-  timestamp: Time;
-
-  /** Type of deletion action to perform */
-  type: SceneEntityDeletionType;
-
-  /** Identifier which must match if \`type\` is \`MATCHING_ID\`. */
-  id: string;
-};
-",
-  "SceneEntityDeletionType": "// Generated by https://github.com/foxglove/schemas
-
-/** An enumeration indicating which entities should match a SceneEntityDeletion command */
-export enum SceneEntityDeletionType {
-  /** Delete the existing entity on the same topic that has the provided \`id\` */
-  MATCHING_ID = 0,
-
-  /** Delete all existing entities on the same topic */
-  ALL = 1,
-}
-",
-  "SceneUpdate": "// Generated by https://github.com/foxglove/schemas
-
-import { SceneEntity } from "./SceneEntity";
-import { SceneEntityDeletion } from "./SceneEntityDeletion";
-
-/** An update to the entities displayed in a 3D scene */
-export type SceneUpdate = {
-  /** Scene entities to delete */
-  deletions: SceneEntityDeletion[];
-
-  /** Scene entities to add or replace */
-  entities: SceneEntity[];
-};
-",
-  "SpherePrimitive": "// Generated by https://github.com/foxglove/schemas
+  "SpherePrimitive" => "// Generated by https://github.com/foxglove/schemas
 
 import { Color } from "./Color";
 import { Pose } from "./Pose";
@@ -883,7 +781,7 @@ export type SpherePrimitive = {
   color: Color;
 };
 ",
-  "TextAnnotation": "// Generated by https://github.com/foxglove/schemas
+  "TextAnnotation" => "// Generated by https://github.com/foxglove/schemas
 
 import { Color } from "./Color";
 import { Point2 } from "./Point2";
@@ -910,7 +808,7 @@ export type TextAnnotation = {
   background_color: Color;
 };
 ",
-  "TextPrimitive": "// Generated by https://github.com/foxglove/schemas
+  "TextPrimitive" => "// Generated by https://github.com/foxglove/schemas
 
 import { Color } from "./Color";
 import { Pose } from "./Pose";
@@ -936,12 +834,7 @@ export type TextPrimitive = {
   text: string;
 };
 ",
-  "Time": "export type Time = {
-  sec: number;
-  nsec: number;
-};
-",
-  "TriangleListPrimitive": "// Generated by https://github.com/foxglove/schemas
+  "TriangleListPrimitive" => "// Generated by https://github.com/foxglove/schemas
 
 import { Color } from "./Color";
 import { Point3 } from "./Point3";
@@ -969,7 +862,7 @@ export type TriangleListPrimitive = {
   indices: number[];
 };
 ",
-  "Vector2": "// Generated by https://github.com/foxglove/schemas
+  "Vector2" => "// Generated by https://github.com/foxglove/schemas
 
 /** A vector in 2D space that represents a direction only */
 export type Vector2 = {
@@ -980,7 +873,7 @@ export type Vector2 = {
   y: number;
 };
 ",
-  "Vector3": "// Generated by https://github.com/foxglove/schemas
+  "Vector3" => "// Generated by https://github.com/foxglove/schemas
 
 /** A vector in 3D space that represents a direction only */
 export type Vector3 = {
@@ -994,7 +887,114 @@ export type Vector3 = {
   z: number;
 };
 ",
-  "index": "export * from "./ArrowPrimitive";
+  "LineType" => "// Generated by https://github.com/foxglove/schemas
+
+/** An enumeration indicating how input points should be interpreted to create lines */
+export enum LineType {
+  /** Connected line segments: 0-1, 1-2, ..., (n-1)-n */
+  LINE_STRIP = 0,
+
+  /** Closed polygon: 0-1, 1-2, ..., (n-1)-n, n-0 */
+  LINE_LOOP = 1,
+
+  /** Individual line segments: 0-1, 2-3, 4-5, ... */
+  LINE_LIST = 2,
+}
+",
+  "LogLevel" => "// Generated by https://github.com/foxglove/schemas
+
+/** Log level */
+export enum LogLevel {
+  UNKNOWN = 0,
+
+  DEBUG = 1,
+
+  INFO = 2,
+
+  WARNING = 3,
+
+  ERROR = 4,
+
+  FATAL = 5,
+}
+",
+  "SceneEntityDeletionType" => "// Generated by https://github.com/foxglove/schemas
+
+/** An enumeration indicating which entities should match a SceneEntityDeletion command */
+export enum SceneEntityDeletionType {
+  /** Delete the existing entity on the same topic that has the provided \`id\` */
+  MATCHING_ID = 0,
+
+  /** Delete all existing entities on the same topic */
+  ALL = 1,
+}
+",
+  "NumericType" => "// Generated by https://github.com/foxglove/schemas
+
+/** Numeric type */
+export enum NumericType {
+  UNKNOWN = 0,
+
+  UINT8 = 1,
+
+  INT8 = 2,
+
+  UINT16 = 3,
+
+  INT16 = 4,
+
+  UINT32 = 5,
+
+  INT32 = 6,
+
+  FLOAT32 = 7,
+
+  FLOAT64 = 8,
+}
+",
+  "PointsAnnotationType" => "// Generated by https://github.com/foxglove/schemas
+
+/** Type of points annotation */
+export enum PointsAnnotationType {
+  UNKNOWN = 0,
+
+  /** Individual points: 0, 1, 2, ... */
+  POINTS = 1,
+
+  /** Closed polygon: 0-1, 1-2, ..., (n-1)-n, n-0 */
+  LINE_LOOP = 2,
+
+  /** Connected line segments: 0-1, 1-2, ..., (n-1)-n */
+  LINE_STRIP = 3,
+
+  /** Individual line segments: 0-1, 2-3, 4-5, ... */
+  LINE_LIST = 4,
+}
+",
+  "PositionCovarianceType" => "// Generated by https://github.com/foxglove/schemas
+
+/** Type of position covariance */
+export enum PositionCovarianceType {
+  UNKNOWN = 0,
+
+  APPROXIMATED = 1,
+
+  DIAGONAL_KNOWN = 2,
+
+  KNOWN = 3,
+}
+",
+  "Duration" => "export type Duration = {
+  sec: number;
+  nsec: number;
+};
+",
+  "Time" => "export type Time = {
+  sec: number;
+  nsec: number;
+};
+",
+  "index" => "export * from "./ArrowPrimitive";
 export * from "./CameraCalibration";
 export * from "./CircleAnnotation";
 export * from "./Color";
diff --git a/internal/exportTypeScriptSchemas.test.ts b/internal/exportTypeScriptSchemas.test.ts
new file mode 100644
index 0000000..25dfa26
--- /dev/null
+++ b/internal/exportTypeScriptSchemas.test.ts
@@ -0,0 +1,8 @@
+import { exportTypeScriptSchemas } from "./exportTypeScriptSchemas";
+
+describe("exportTypeScriptSchemas", () => {
+  it("exports schemas", () => {
+    const schemas = exportTypeScriptSchemas();
+    expect(schemas).toMatchSnapshot();
+  });
+});
diff --git a/internal/exportTypescriptSchemata.test.ts b/internal/exportTypescriptSchemata.test.ts
deleted file mode 100644
index e29a874..0000000
--- a/internal/exportTypescriptSchemata.test.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { exportTypescriptSchemata } from "./exportTypescriptSchemata";
-
-describe("exportTypescriptSchemata", () => {
-  it("exports schemata", () => {
-    const schemas = exportTypescriptSchemata();
-    expect(schemas).toMatchSnapshot();
-  });
-});