summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-09-04 15:22:06 +0100
committerMichael Williamson <mike@zwobble.org>2026-09-04 15:25:14 +0100
commit94ca8de6bc11f194bdf3a0415aad2eb66e222c45 (patch)
tree691279348a97897379c03d8c5f66ea63333babb1
parent8b1ee9a26a378a4456e800be314ab765be94b368 (diff)
Add custom code to TypeScript output
-rw-r--r--examples/01-struct/output/typescript/src/point.ts12
-rw-r--r--examples/02-struct-singleton/output/typescript/src/point.ts9
-rw-r--r--examples/03-sum/output/typescript/src/shapes.ts12
-rw-r--r--examples/04-enum/output/typescript/src/numbers.ts6
-rw-r--r--examples/05-custom-code/hobgoblin.json54
-rw-r--r--examples/05-custom-code/output/typescript/.gitignore1
l---------examples/05-custom-code/output/typescript/package.json1
-rw-r--r--examples/05-custom-code/output/typescript/pnpm-lock.yaml834
-rw-r--r--examples/05-custom-code/output/typescript/src/shapes.test.ts10
-rw-r--r--examples/05-custom-code/output/typescript/src/shapes.ts23
l---------examples/05-custom-code/output/typescript/tsconfig.json1
-rw-r--r--examples/08-box/output/typescript/src/point.ts12
-rw-r--r--examples/09-list/output/typescript/src/point.ts12
-rw-r--r--examples/12-inductive-data-types/output/typescript/src/arithmetic.ts12
-rw-r--r--examples/14-struct-generic/output/typescript/src/point.ts24
-rw-r--r--hobgoblin/src/output/lang/typescript/ast.hob6
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriter.java37
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptCustomArea.java32
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriterTests.java24
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptCustomAreaMatcher.java41
20 files changed, 1101 insertions, 12 deletions
diff --git a/examples/01-struct/output/typescript/src/point.ts b/examples/01-struct/output/typescript/src/point.ts
index fccae01..a0bc777 100644
--- a/examples/01-struct/output/typescript/src/point.ts
+++ b/examples/01-struct/output/typescript/src/point.ts
@@ -1,5 +1,8 @@
// Generated by hobgoblin.
+// Custom area start: imports
+// Custom area end: imports
+
/**
* A straight line from one point to another.
*/
@@ -12,6 +15,9 @@ class Line {
this.start = start;
this.end = end;
}
+
+ // Custom area start: Line, body
+ // Custom area end: Line, body
}
export {Line};
@@ -28,6 +34,12 @@ class Point {
this.x = x;
this.y = y;
}
+
+ // Custom area start: Point, body
+ // Custom area end: Point, body
}
export {Point};
+
+// Custom area start: body
+// Custom area end: body
diff --git a/examples/02-struct-singleton/output/typescript/src/point.ts b/examples/02-struct-singleton/output/typescript/src/point.ts
index f0761ce..19392a3 100644
--- a/examples/02-struct-singleton/output/typescript/src/point.ts
+++ b/examples/02-struct-singleton/output/typescript/src/point.ts
@@ -1,10 +1,19 @@
// Generated by hobgoblin.
+// Custom area start: imports
+// Custom area end: imports
+
class Origin {
public static readonly INSTANCE = new Origin();
private constructor() {
}
+
+ // Custom area start: Origin, body
+ // Custom area end: Origin, body
}
export {Origin};
+
+// Custom area start: body
+// Custom area end: body
diff --git a/examples/03-sum/output/typescript/src/shapes.ts b/examples/03-sum/output/typescript/src/shapes.ts
index 88a476f..9758cd6 100644
--- a/examples/03-sum/output/typescript/src/shapes.ts
+++ b/examples/03-sum/output/typescript/src/shapes.ts
@@ -1,5 +1,8 @@
// Generated by hobgoblin.
+// Custom area start: imports
+// Custom area end: imports
+
type Shape = Rectangle | Triangle;
export {type Shape};
@@ -17,6 +20,9 @@ class Rectangle {
this.width = width;
this.height = height;
}
+
+ // Custom area start: Rectangle, body
+ // Custom area end: Rectangle, body
}
export {Rectangle};
@@ -34,6 +40,12 @@ class Triangle {
this.width = width;
this.height = height;
}
+
+ // Custom area start: Triangle, body
+ // Custom area end: Triangle, body
}
export {Triangle};
+
+// Custom area start: body
+// Custom area end: body
diff --git a/examples/04-enum/output/typescript/src/numbers.ts b/examples/04-enum/output/typescript/src/numbers.ts
index 80a3c6b..14c8905 100644
--- a/examples/04-enum/output/typescript/src/numbers.ts
+++ b/examples/04-enum/output/typescript/src/numbers.ts
@@ -1,5 +1,8 @@
// Generated by hobgoblin.
+// Custom area start: imports
+// Custom area end: imports
+
const SmallNumber$Zero: unique symbol = Symbol();
const SmallNumber$One: unique symbol = Symbol();
@@ -15,3 +18,6 @@ const SmallNumber = {
type SmallNumber = typeof SmallNumber$Zero | typeof SmallNumber$One | typeof SmallNumber$Two;
export {SmallNumber};
+
+// Custom area start: body
+// Custom area end: body
diff --git a/examples/05-custom-code/hobgoblin.json5 b/examples/05-custom-code/hobgoblin.json5
index 1d08a40..3a19740 100644
--- a/examples/05-custom-code/hobgoblin.json5
+++ b/examples/05-custom-code/hobgoblin.json5
@@ -14,6 +14,10 @@
generator: "rust-types",
path: "output/rust/src/gen",
},
+ {
+ generator: "typescript-types",
+ path: "output/typescript/src",
+ }
],
},
}
diff --git a/examples/05-custom-code/output/typescript/.gitignore b/examples/05-custom-code/output/typescript/.gitignore
new file mode 100644
index 0000000..07e6e47
--- /dev/null
+++ b/examples/05-custom-code/output/typescript/.gitignore
@@ -0,0 +1 @@
+/node_modules
diff --git a/examples/05-custom-code/output/typescript/package.json b/examples/05-custom-code/output/typescript/package.json
new file mode 120000
index 0000000..0bc7349
--- /dev/null
+++ b/examples/05-custom-code/output/typescript/package.json
@@ -0,0 +1 @@
+../../../templates/typescript/package.json \ No newline at end of file
diff --git a/examples/05-custom-code/output/typescript/pnpm-lock.yaml b/examples/05-custom-code/output/typescript/pnpm-lock.yaml
new file mode 100644
index 0000000..016d629
--- /dev/null
+++ b/examples/05-custom-code/output/typescript/pnpm-lock.yaml
@@ -0,0 +1,834 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ devDependencies:
+ '@types/mocha':
+ specifier: ^10.0.10
+ version: 10.0.10
+ '@types/node':
+ specifier: ^26.4.0
+ version: 26.4.1
+ mocha:
+ specifier: ^11.8.0
+ version: 11.8.0
+ typescript:
+ specifier: ^7.0.2
+ version: 7.0.2
+
+packages:
+
+ '@isaacs/cliui@8.0.2':
+ resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
+ engines: {node: '>=12'}
+
+ '@pkgjs/parseargs@0.11.0':
+ resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
+ engines: {node: '>=14'}
+
+ '@types/mocha@10.0.10':
+ resolution: {integrity: sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==}
+
+ '@types/node@26.4.1':
+ resolution: {integrity: sha512-k97ENvZWtvA6yqz5/FS6a7duDgOPEeOQOc2iKS/nY6mX6qJUKtLnWzQS+Xj6tXweyj6ZcTAK2Qecetnvi9nCLA==}
+
+ '@typescript/typescript-aix-ppc64@7.0.2':
+ resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==}
+ engines: {node: '>=16.20.0'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@typescript/typescript-darwin-arm64@7.0.2':
+ resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==}
+ engines: {node: '>=16.20.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@typescript/typescript-darwin-x64@7.0.2':
+ resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==}
+ engines: {node: '>=16.20.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@typescript/typescript-freebsd-arm64@7.0.2':
+ resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==}
+ engines: {node: '>=16.20.0'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@typescript/typescript-freebsd-x64@7.0.2':
+ resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==}
+ engines: {node: '>=16.20.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@typescript/typescript-linux-arm64@7.0.2':
+ resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==}
+ engines: {node: '>=16.20.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@typescript/typescript-linux-arm@7.0.2':
+ resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==}
+ engines: {node: '>=16.20.0'}
+ cpu: [arm]
+ os: [linux]
+
+ '@typescript/typescript-linux-loong64@7.0.2':
+ resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==}
+ engines: {node: '>=16.20.0'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@typescript/typescript-linux-mips64el@7.0.2':
+ resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==}
+ engines: {node: '>=16.20.0'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@typescript/typescript-linux-ppc64@7.0.2':
+ resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==}
+ engines: {node: '>=16.20.0'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@typescript/typescript-linux-riscv64@7.0.2':
+ resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==}
+ engines: {node: '>=16.20.0'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@typescript/typescript-linux-s390x@7.0.2':
+ resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==}
+ engines: {node: '>=16.20.0'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@typescript/typescript-linux-x64@7.0.2':
+ resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==}
+ engines: {node: '>=16.20.0'}
+ cpu: [x64]
+ os: [linux]
+
+ '@typescript/typescript-netbsd-arm64@7.0.2':
+ resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==}
+ engines: {node: '>=16.20.0'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@typescript/typescript-netbsd-x64@7.0.2':
+ resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==}
+ engines: {node: '>=16.20.0'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@typescript/typescript-openbsd-arm64@7.0.2':
+ resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==}
+ engines: {node: '>=16.20.0'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@typescript/typescript-openbsd-x64@7.0.2':
+ resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==}
+ engines: {node: '>=16.20.0'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@typescript/typescript-sunos-x64@7.0.2':
+ resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==}
+ engines: {node: '>=16.20.0'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@typescript/typescript-win32-arm64@7.0.2':
+ resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==}
+ engines: {node: '>=16.20.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@typescript/typescript-win32-x64@7.0.2':
+ resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==}
+ engines: {node: '>=16.20.0'}
+ cpu: [x64]
+ os: [win32]
+
+ ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+
+ ansi-regex@6.3.0:
+ resolution: {integrity: sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==}
+ engines: {node: '>=12'}
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
+ ansi-styles@6.2.3:
+ resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
+ engines: {node: '>=12'}
+
+ argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ brace-expansion@2.1.4:
+ resolution: {integrity: sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==}
+
+ browser-stdout@1.3.1:
+ resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==}
+
+ camelcase@6.3.0:
+ resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
+ engines: {node: '>=10'}
+
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+
+ chokidar@4.0.3:
+ resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
+ engines: {node: '>= 14.16.0'}
+
+ cliui@8.0.1:
+ resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
+ engines: {node: '>=12'}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ cross-spawn@7.0.6:
+ resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
+ engines: {node: '>= 8'}
+
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ decamelize@4.0.0:
+ resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==}
+ engines: {node: '>=10'}
+
+ diff@7.0.0:
+ resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==}
+ engines: {node: '>=0.3.1'}
+
+ eastasianwidth@0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+
+ emoji-regex@8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
+ emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
+ escalade@3.2.0:
+ resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
+ engines: {node: '>=6'}
+
+ escape-string-regexp@4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
+
+ find-up@5.0.0:
+ resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+ engines: {node: '>=10'}
+
+ flat@5.0.2:
+ resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
+ hasBin: true
+
+ foreground-child@3.3.1:
+ resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
+ engines: {node: '>=14'}
+
+ get-caller-file@2.0.5:
+ resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
+ engines: {node: 6.* || 8.* || >= 10.*}
+
+ glob@10.5.0:
+ resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==}
+ deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
+ hasBin: true
+
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ he@1.2.0:
+ resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
+ hasBin: true
+
+ is-fullwidth-code-point@3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
+ is-path-inside@3.0.3:
+ resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
+ engines: {node: '>=8'}
+
+ is-plain-obj@2.1.0:
+ resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==}
+ engines: {node: '>=8'}
+
+ is-unicode-supported@0.1.0:
+ resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
+ engines: {node: '>=10'}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ jackspeak@3.4.3:
+ resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
+
+ js-yaml@4.3.2:
+ resolution: {integrity: sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==}
+ hasBin: true
+
+ locate-path@6.0.0:
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+ engines: {node: '>=10'}
+
+ log-symbols@4.1.0:
+ resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
+ engines: {node: '>=10'}
+
+ lru-cache@10.4.3:
+ resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
+
+ minimatch@9.0.9:
+ resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ minipass@7.1.3:
+ resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ mocha@11.8.0:
+ resolution: {integrity: sha512-VyCeUdGN3A9lmCTTgG4yuvY9ixxaDk+xt2R/7/+1AP6EqNG+G9OKkzBwhVtVYoNX8YsxNSgAl8mOv3IAeOpFbw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ hasBin: true
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ p-limit@3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+
+ p-locate@5.0.0:
+ resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+ engines: {node: '>=10'}
+
+ package-json-from-dist@1.0.1:
+ resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
+
+ path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ path-scurry@1.11.1:
+ resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
+ engines: {node: '>=16 || 14 >=14.18'}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ randombytes@2.1.0:
+ resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
+
+ readdirp@4.1.2:
+ resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
+ engines: {node: '>= 14.18.0'}
+
+ require-directory@2.1.1:
+ resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
+ engines: {node: '>=0.10.0'}
+
+ safe-buffer@5.2.1:
+ resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+
+ serialize-javascript@6.0.2:
+ resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
+ string-width@4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+
+ string-width@5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
+
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+
+ strip-ansi@7.2.0:
+ resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==}
+ engines: {node: '>=12'}
+
+ strip-json-comments@3.1.1:
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
+ engines: {node: '>=8'}
+
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ supports-color@8.1.1:
+ resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
+ engines: {node: '>=10'}
+
+ typescript@7.0.2:
+ resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==}
+ engines: {node: '>=16.20.0'}
+ hasBin: true
+
+ undici-types@8.3.0:
+ resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==}
+
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
+ workerpool@9.3.4:
+ resolution: {integrity: sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==}
+
+ wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+
+ wrap-ansi@8.1.0:
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
+ engines: {node: '>=12'}
+
+ y18n@5.0.8:
+ resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
+ engines: {node: '>=10'}
+
+ yargs-parser@21.1.1:
+ resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
+ engines: {node: '>=12'}
+
+ yargs-unparser@2.0.0:
+ resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==}
+ engines: {node: '>=10'}
+
+ yargs@17.7.3:
+ resolution: {integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==}
+ engines: {node: '>=12'}
+
+ yocto-queue@0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
+
+snapshots:
+
+ '@isaacs/cliui@8.0.2':
+ dependencies:
+ string-width: 5.1.2
+ string-width-cjs: string-width@4.2.3
+ strip-ansi: 7.2.0
+ strip-ansi-cjs: strip-ansi@6.0.1
+ wrap-ansi: 8.1.0
+ wrap-ansi-cjs: wrap-ansi@7.0.0
+
+ '@pkgjs/parseargs@0.11.0':
+ optional: true
+
+ '@types/mocha@10.0.10': {}
+
+ '@types/node@26.4.1':
+ dependencies:
+ undici-types: 8.3.0
+
+ '@typescript/typescript-aix-ppc64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-darwin-arm64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-darwin-x64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-freebsd-arm64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-freebsd-x64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-linux-arm64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-linux-arm@7.0.2':
+ optional: true
+
+ '@typescript/typescript-linux-loong64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-linux-mips64el@7.0.2':
+ optional: true
+
+ '@typescript/typescript-linux-ppc64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-linux-riscv64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-linux-s390x@7.0.2':
+ optional: true
+
+ '@typescript/typescript-linux-x64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-netbsd-arm64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-netbsd-x64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-openbsd-arm64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-openbsd-x64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-sunos-x64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-win32-arm64@7.0.2':
+ optional: true
+
+ '@typescript/typescript-win32-x64@7.0.2':
+ optional: true
+
+ ansi-regex@5.0.1: {}
+
+ ansi-regex@6.3.0: {}
+
+ ansi-styles@4.3.0:
+ dependencies:
+ color-convert: 2.0.1
+
+ ansi-styles@6.2.3: {}
+
+ argparse@2.0.1: {}
+
+ balanced-match@1.0.2: {}
+
+ brace-expansion@2.1.4:
+ dependencies:
+ balanced-match: 1.0.2
+
+ browser-stdout@1.3.1: {}
+
+ camelcase@6.3.0: {}
+
+ chalk@4.1.2:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
+ chokidar@4.0.3:
+ dependencies:
+ readdirp: 4.1.2
+
+ cliui@8.0.1:
+ dependencies:
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ wrap-ansi: 7.0.0
+
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
+
+ color-name@1.1.4: {}
+
+ cross-spawn@7.0.6:
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
+ debug@4.4.3(supports-color@8.1.1):
+ dependencies:
+ ms: 2.1.3
+ optionalDependencies:
+ supports-color: 8.1.1
+
+ decamelize@4.0.0: {}
+
+ diff@7.0.0: {}
+
+ eastasianwidth@0.2.0: {}
+
+ emoji-regex@8.0.0: {}
+
+ emoji-regex@9.2.2: {}
+
+ escalade@3.2.0: {}
+
+ escape-string-regexp@4.0.0: {}
+
+ find-up@5.0.0:
+ dependencies:
+ locate-path: 6.0.0
+ path-exists: 4.0.0
+
+ flat@5.0.2: {}
+
+ foreground-child@3.3.1:
+ dependencies:
+ cross-spawn: 7.0.6
+ signal-exit: 4.1.0
+
+ get-caller-file@2.0.5: {}
+
+ glob@10.5.0:
+ dependencies:
+ foreground-child: 3.3.1
+ jackspeak: 3.4.3
+ minimatch: 9.0.9
+ minipass: 7.1.3
+ package-json-from-dist: 1.0.1
+ path-scurry: 1.11.1
+
+ has-flag@4.0.0: {}
+
+ he@1.2.0: {}
+
+ is-fullwidth-code-point@3.0.0: {}
+
+ is-path-inside@3.0.3: {}
+
+ is-plain-obj@2.1.0: {}
+
+ is-unicode-supported@0.1.0: {}
+
+ isexe@2.0.0: {}
+
+ jackspeak@3.4.3:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+ optionalDependencies:
+ '@pkgjs/parseargs': 0.11.0
+
+ js-yaml@4.3.2:
+ dependencies:
+ argparse: 2.0.1
+
+ locate-path@6.0.0:
+ dependencies:
+ p-locate: 5.0.0
+
+ log-symbols@4.1.0:
+ dependencies:
+ chalk: 4.1.2
+ is-unicode-supported: 0.1.0
+
+ lru-cache@10.4.3: {}
+
+ minimatch@9.0.9:
+ dependencies:
+ brace-expansion: 2.1.4
+
+ minipass@7.1.3: {}
+
+ mocha@11.8.0:
+ dependencies:
+ browser-stdout: 1.3.1
+ chokidar: 4.0.3
+ debug: 4.4.3(supports-color@8.1.1)
+ diff: 7.0.0
+ escape-string-regexp: 4.0.0
+ find-up: 5.0.0
+ glob: 10.5.0
+ he: 1.2.0
+ is-path-inside: 3.0.3
+ js-yaml: 4.3.2
+ log-symbols: 4.1.0
+ minimatch: 9.0.9
+ ms: 2.1.3
+ picocolors: 1.1.1
+ serialize-javascript: 6.0.2
+ strip-json-comments: 3.1.1
+ supports-color: 8.1.1
+ workerpool: 9.3.4
+ yargs: 17.7.3
+ yargs-parser: 21.1.1
+ yargs-unparser: 2.0.0
+
+ ms@2.1.3: {}
+
+ p-limit@3.1.0:
+ dependencies:
+ yocto-queue: 0.1.0
+
+ p-locate@5.0.0:
+ dependencies:
+ p-limit: 3.1.0
+
+ package-json-from-dist@1.0.1: {}
+
+ path-exists@4.0.0: {}
+
+ path-key@3.1.1: {}
+
+ path-scurry@1.11.1:
+ dependencies:
+ lru-cache: 10.4.3
+ minipass: 7.1.3
+
+ picocolors@1.1.1: {}
+
+ randombytes@2.1.0:
+ dependencies:
+ safe-buffer: 5.2.1
+
+ readdirp@4.1.2: {}
+
+ require-directory@2.1.1: {}
+
+ safe-buffer@5.2.1: {}
+
+ serialize-javascript@6.0.2:
+ dependencies:
+ randombytes: 2.1.0
+
+ shebang-command@2.0.0:
+ dependencies:
+ shebang-regex: 3.0.0
+
+ shebang-regex@3.0.0: {}
+
+ signal-exit@4.1.0: {}
+
+ string-width@4.2.3:
+ dependencies:
+ emoji-regex: 8.0.0
+ is-fullwidth-code-point: 3.0.0
+ strip-ansi: 6.0.1
+
+ string-width@5.1.2:
+ dependencies:
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.2.0
+
+ strip-ansi@6.0.1:
+ dependencies:
+ ansi-regex: 5.0.1
+
+ strip-ansi@7.2.0:
+ dependencies:
+ ansi-regex: 6.3.0
+
+ strip-json-comments@3.1.1: {}
+
+ supports-color@7.2.0:
+ dependencies:
+ has-flag: 4.0.0
+
+ supports-color@8.1.1:
+ dependencies:
+ has-flag: 4.0.0
+
+ typescript@7.0.2:
+ optionalDependencies:
+ '@typescript/typescript-aix-ppc64': 7.0.2
+ '@typescript/typescript-darwin-arm64': 7.0.2
+ '@typescript/typescript-darwin-x64': 7.0.2
+ '@typescript/typescript-freebsd-arm64': 7.0.2
+ '@typescript/typescript-freebsd-x64': 7.0.2
+ '@typescript/typescript-linux-arm': 7.0.2
+ '@typescript/typescript-linux-arm64': 7.0.2
+ '@typescript/typescript-linux-loong64': 7.0.2
+ '@typescript/typescript-linux-mips64el': 7.0.2
+ '@typescript/typescript-linux-ppc64': 7.0.2
+ '@typescript/typescript-linux-riscv64': 7.0.2
+ '@typescript/typescript-linux-s390x': 7.0.2
+ '@typescript/typescript-linux-x64': 7.0.2
+ '@typescript/typescript-netbsd-arm64': 7.0.2
+ '@typescript/typescript-netbsd-x64': 7.0.2
+ '@typescript/typescript-openbsd-arm64': 7.0.2
+ '@typescript/typescript-openbsd-x64': 7.0.2
+ '@typescript/typescript-sunos-x64': 7.0.2
+ '@typescript/typescript-win32-arm64': 7.0.2
+ '@typescript/typescript-win32-x64': 7.0.2
+
+ undici-types@8.3.0: {}
+
+ which@2.0.2:
+ dependencies:
+ isexe: 2.0.0
+
+ workerpool@9.3.4: {}
+
+ wrap-ansi@7.0.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ wrap-ansi@8.1.0:
+ dependencies:
+ ansi-styles: 6.2.3
+ string-width: 5.1.2
+ strip-ansi: 7.2.0
+
+ y18n@5.0.8: {}
+
+ yargs-parser@21.1.1: {}
+
+ yargs-unparser@2.0.0:
+ dependencies:
+ camelcase: 6.3.0
+ decamelize: 4.0.0
+ flat: 5.0.2
+ is-plain-obj: 2.1.0
+
+ yargs@17.7.3:
+ dependencies:
+ cliui: 8.0.1
+ escalade: 3.2.0
+ get-caller-file: 2.0.5
+ require-directory: 2.1.1
+ string-width: 4.2.3
+ y18n: 5.0.8
+ yargs-parser: 21.1.1
+
+ yocto-queue@0.1.0: {}
diff --git a/examples/05-custom-code/output/typescript/src/shapes.test.ts b/examples/05-custom-code/output/typescript/src/shapes.test.ts
new file mode 100644
index 0000000..956e08b
--- /dev/null
+++ b/examples/05-custom-code/output/typescript/src/shapes.test.ts
@@ -0,0 +1,10 @@
+import * as assert from "node:assert";
+
+import {test} from "mocha";
+
+import {Square} from "./shapes.ts";
+
+test("can use custom code", () => {
+ const square = new Square(10);
+ assert.strictEqual(square.area(), 100);
+});
diff --git a/examples/05-custom-code/output/typescript/src/shapes.ts b/examples/05-custom-code/output/typescript/src/shapes.ts
new file mode 100644
index 0000000..a75e9d2
--- /dev/null
+++ b/examples/05-custom-code/output/typescript/src/shapes.ts
@@ -0,0 +1,23 @@
+// Generated by hobgoblin.
+
+// Custom area start: imports
+// Custom area end: imports
+
+class Square {
+ public readonly width: number;
+
+ public constructor(width: number) {
+ this.width = width;
+ }
+
+ // Custom area start: Square, body
+ public area(): number {
+ return this.width * this.width;
+ }
+ // Custom area end: Square, body
+}
+
+export {Square};
+
+// Custom area start: body
+// Custom area end: body
diff --git a/examples/05-custom-code/output/typescript/tsconfig.json b/examples/05-custom-code/output/typescript/tsconfig.json
new file mode 120000
index 0000000..3c7cb2a
--- /dev/null
+++ b/examples/05-custom-code/output/typescript/tsconfig.json
@@ -0,0 +1 @@
+../../../templates/typescript/tsconfig.json \ No newline at end of file
diff --git a/examples/08-box/output/typescript/src/point.ts b/examples/08-box/output/typescript/src/point.ts
index fccae01..a0bc777 100644
--- a/examples/08-box/output/typescript/src/point.ts
+++ b/examples/08-box/output/typescript/src/point.ts
@@ -1,5 +1,8 @@
// Generated by hobgoblin.
+// Custom area start: imports
+// Custom area end: imports
+
/**
* A straight line from one point to another.
*/
@@ -12,6 +15,9 @@ class Line {
this.start = start;
this.end = end;
}
+
+ // Custom area start: Line, body
+ // Custom area end: Line, body
}
export {Line};
@@ -28,6 +34,12 @@ class Point {
this.x = x;
this.y = y;
}
+
+ // Custom area start: Point, body
+ // Custom area end: Point, body
}
export {Point};
+
+// Custom area start: body
+// Custom area end: body
diff --git a/examples/09-list/output/typescript/src/point.ts b/examples/09-list/output/typescript/src/point.ts
index feff2b3..104ea1e 100644
--- a/examples/09-list/output/typescript/src/point.ts
+++ b/examples/09-list/output/typescript/src/point.ts
@@ -1,11 +1,17 @@
// Generated by hobgoblin.
+// Custom area start: imports
+// Custom area end: imports
+
class Path {
public readonly points: ReadonlyArray<Point>;
public constructor(points: ReadonlyArray<Point>) {
this.points = points;
}
+
+ // Custom area start: Path, body
+ // Custom area end: Path, body
}
export {Path};
@@ -19,6 +25,12 @@ class Point {
this.x = x;
this.y = y;
}
+
+ // Custom area start: Point, body
+ // Custom area end: Point, body
}
export {Point};
+
+// Custom area start: body
+// Custom area end: body
diff --git a/examples/12-inductive-data-types/output/typescript/src/arithmetic.ts b/examples/12-inductive-data-types/output/typescript/src/arithmetic.ts
index 9599968..486ac66 100644
--- a/examples/12-inductive-data-types/output/typescript/src/arithmetic.ts
+++ b/examples/12-inductive-data-types/output/typescript/src/arithmetic.ts
@@ -1,5 +1,8 @@
// Generated by hobgoblin.
+// Custom area start: imports
+// Custom area end: imports
+
type Expression = Add | Const;
export {type Expression};
@@ -17,6 +20,9 @@ class Add {
this.left = left;
this.right = right;
}
+
+ // Custom area start: Add, body
+ // Custom area end: Add, body
}
export {Add};
@@ -31,6 +37,12 @@ class Const {
public constructor(value: number) {
this.value = value;
}
+
+ // Custom area start: Const, body
+ // Custom area end: Const, body
}
export {Const};
+
+// Custom area start: body
+// Custom area end: body
diff --git a/examples/14-struct-generic/output/typescript/src/point.ts b/examples/14-struct-generic/output/typescript/src/point.ts
index 4088b92..f3ecdec 100644
--- a/examples/14-struct-generic/output/typescript/src/point.ts
+++ b/examples/14-struct-generic/output/typescript/src/point.ts
@@ -1,5 +1,8 @@
// Generated by hobgoblin.
+// Custom area start: imports
+// Custom area end: imports
+
/**
* A set of drawings.
*/
@@ -12,6 +15,9 @@ class OwnedLineDrawing<TPoint> {
this.drawing = drawing;
this.owner = owner;
}
+
+ // Custom area start: OwnedLineDrawing, body
+ // Custom area end: OwnedLineDrawing, body
}
export {OwnedLineDrawing};
@@ -25,6 +31,9 @@ class LineDrawing2D {
public constructor(lines: ReadonlyArray<Line<Point2D>>) {
this.lines = lines;
}
+
+ // Custom area start: LineDrawing2D, body
+ // Custom area end: LineDrawing2D, body
}
export {LineDrawing2D};
@@ -38,6 +47,9 @@ class LineDrawing<TPoint> {
public constructor(lines: ReadonlyArray<Line<TPoint>>) {
this.lines = lines;
}
+
+ // Custom area start: LineDrawing, body
+ // Custom area end: LineDrawing, body
}
export {LineDrawing};
@@ -54,6 +66,9 @@ class BezierCurve<TPoint> {
this.start = start;
this.end = end;
}
+
+ // Custom area start: BezierCurve, body
+ // Custom area end: BezierCurve, body
}
export {BezierCurve};
@@ -70,6 +85,9 @@ class Line<TPoint> {
this.start = start;
this.end = end;
}
+
+ // Custom area start: Line, body
+ // Custom area end: Line, body
}
export {Line};
@@ -86,6 +104,12 @@ class Point2D {
this.x = x;
this.y = y;
}
+
+ // Custom area start: Point2D, body
+ // Custom area end: Point2D, body
}
export {Point2D};
+
+// Custom area start: body
+// Custom area end: body
diff --git a/hobgoblin/src/output/lang/typescript/ast.hob b/hobgoblin/src/output/lang/typescript/ast.hob
index 68aebda..14ad052 100644
--- a/hobgoblin/src/output/lang/typescript/ast.hob
+++ b/hobgoblin/src/output/lang/typescript/ast.hob
@@ -168,3 +168,9 @@ struct TypescriptTypeUnion {
struct TypescriptIdentifier {
field value: String;
}
+
+// == Custom areas ==
+
+struct TypescriptCustomArea {
+ field name: String;
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriter.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriter.java
index ebb7aba..d177b58 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriter.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriter.java
@@ -48,20 +48,24 @@ public class TypescriptWriter implements AutoCloseable {
public void writeModule(TypescriptModule module) throws IOException {
this.writer.writeHeader();
- if (module.body().isEmpty()) {
- return;
- }
+ writeCustomArea(new TypescriptCustomArea("imports"));
+ this.writer.newLine();
- writeWithSeparator(
- module.body(),
- this::writeStatement,
- () -> {
- writer.newLine();
- writer.newLine();
- }
- );
+ if (!module.body().isEmpty()) {
+ writeWithSeparator(
+ module.body(),
+ this::writeStatement,
+ () -> {
+ writer.newLine();
+ writer.newLine();
+ }
+ );
- this.writer.newLine();
+ this.writer.newLine();
+ this.writer.newLine();
+ }
+
+ writeCustomArea(new TypescriptCustomArea("body"));
}
// == Statements ==
@@ -117,8 +121,11 @@ public class TypescriptWriter implements AutoCloseable {
}
);
this.writer.newLine();
+ this.writer.newLine();
}
+ writeCustomArea(new TypescriptCustomArea(classDeclaration.name().value() + ", body"));
+
this.writer.dedent();
this.writer.write("}");
}
@@ -440,4 +447,10 @@ public class TypescriptWriter implements AutoCloseable {
private void writeIdentifier(TypescriptIdentifier name) throws IOException {
this.writer.write(name.value());
}
+
+ // == Custom areas ==
+
+ private void writeCustomArea(TypescriptCustomArea customArea) throws IOException {
+ this.writer.writeCustomArea(customArea.name());
+ }
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptCustomArea.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptCustomArea.java
new file mode 100644
index 0000000..cd3fd54
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptCustomArea.java
@@ -0,0 +1,32 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.typescript.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea imports
+
+public record TypescriptCustomArea(
+ String name
+) {
+ public static org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea.Builder("");
+ }
+
+ public record Builder(
+ String name
+ ) {
+ public org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea build() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea(name);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea.Builder withName(String name) {
+ return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea.Builder(name);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea body
+}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriterTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriterTests.java
index a5081d0..56c51f5 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriterTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/TypescriptWriterTests.java
@@ -25,6 +25,11 @@ public class TypescriptWriterTests {
assertThat(string, equalTo("""
// Generated by hobgoblin.
+ // Custom area start: imports
+ // Custom area end: imports
+
+ // Custom area start: body
+ // Custom area end: body
"""
));
}
@@ -45,11 +50,21 @@ public class TypescriptWriterTests {
assertThat(string, equalTo("""
// Generated by hobgoblin.
+ // Custom area start: imports
+ // Custom area end: imports
+
class X {
+ // Custom area start: X, body
+ // Custom area end: X, body
}
class Y {
+ // Custom area start: Y, body
+ // Custom area end: Y, body
}
+
+ // Custom area start: body
+ // Custom area end: body
"""
));
}
@@ -68,6 +83,8 @@ public class TypescriptWriterTests {
assertThat(string, equalTo("""
class X {
+ // Custom area start: X, body
+ // Custom area end: X, body
}"""
));
}
@@ -84,6 +101,8 @@ public class TypescriptWriterTests {
assertThat(string, equalTo("""
class X<Y, Z> {
+ // Custom area start: X, body
+ // Custom area end: X, body
}"""
));
}
@@ -110,6 +129,9 @@ public class TypescriptWriterTests {
public a;
public b;
+
+ // Custom area start: X, body
+ // Custom area end: X, body
}"""
));
}
@@ -129,6 +151,8 @@ public class TypescriptWriterTests {
* def
*/
class X {
+ // Custom area start: X, body
+ // Custom area end: X, body
}"""
));
}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptCustomAreaMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptCustomAreaMatcher.java
new file mode 100644
index 0000000..8d8a077
--- /dev/null
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/typescript/ast/TypescriptCustomAreaMatcher.java
@@ -0,0 +1,41 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.output.lang.typescript.ast;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomAreaMatcher imports
+// Custom area end: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomAreaMatcher imports
+
+public final class TypescriptCustomAreaMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> {
+ public static org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomAreaMatcher isTypescriptCustomArea() {
+ return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomAreaMatcher(java.util.List.of());
+ }
+
+ private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea>> submatchers;
+
+ private TypescriptCustomAreaMatcher(
+ java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea>> submatchers
+ ) {
+ this.submatchers = submatchers;
+ }
+
+ public org.zwobble.precisely.MatchResult match(java.lang.Object actual) {
+ return this.toMatcher().match(actual);
+ }
+
+ public org.zwobble.precisely.TextTree describe() {
+ return this.toMatcher().describe();
+ }
+
+ private org.zwobble.precisely.Matcher<java.lang.Object> toMatcher() {
+ return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea.class, this.submatchers);
+ }
+
+ public org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomAreaMatcher withName(org.zwobble.precisely.Matcher<? super String> name) {
+ var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea>>(this.submatchers);
+ submatchers.add(org.zwobble.precisely.Matchers.has("name", org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomArea::name, (org.zwobble.precisely.Matcher) name));
+ return new org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomAreaMatcher(submatchers);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomAreaMatcher body
+ // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.typescript.ast.TypescriptCustomAreaMatcher body
+}