@hanzo/runtime 0.0.0-dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,640 @@
1
+ // Copyright 2025 Daytona Platforms Inc.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ // @ts-check
5
+ /* eslint-disable no-useless-escape */
6
+
7
+ import { MarkdownPageEvent } from 'typedoc-plugin-markdown'
8
+
9
+ /**
10
+ * @param {import('typedoc-plugin-markdown').MarkdownApplication} app
11
+ */
12
+ export function load(app) {
13
+ // --- TITLE HACK ---
14
+ app.renderer.markdownHooks.on('page.begin', () => {
15
+ // We'll add the title later in the END event
16
+ return '---\ntitle: ""\nhideTitleOnPage: true\n---\n'
17
+ })
18
+
19
+ // --- CONTENT HACKS ---
20
+ app.renderer.on(MarkdownPageEvent.END, (page) => {
21
+ if (!page.contents) return
22
+
23
+ // Extract title from filename and capitalize first letter of each word
24
+ let title = ''
25
+ if (page.filename) {
26
+ const filename = page.filename
27
+ // Get the last part of the filename (after the last dot)
28
+ const baseFilename = filename.split('/').pop()?.replace(/\.md$/, '').split('.').pop() || ''
29
+ // Split into words and capitalize each word
30
+ const words = baseFilename.split(/[-_]/)
31
+ title = words
32
+ .map((word) => {
33
+ if (word.length === 0) return ''
34
+ return word.charAt(0).toUpperCase() + word.slice(1)
35
+ })
36
+ .join('')
37
+ }
38
+
39
+ // Replace the empty title with the actual title
40
+ page.contents = page.contents.replace(/title: ""/, `title: "${title}"`)
41
+
42
+ page.contents = transformContent(page.contents)
43
+ page.filename = transformFilename(page.filename)
44
+ })
45
+ }
46
+
47
+ function transformContent(contents) {
48
+ return [
49
+ removeInternalLinks,
50
+ escapePromiseSpecialCharacters,
51
+ transformExtendsSection,
52
+ transformInheritedSections,
53
+ transformParametersSection,
54
+ transformReturnsSection,
55
+ transformPropertiesSection,
56
+ transformExamplesSection,
57
+ transformEnumSection,
58
+ transformThrowsSection,
59
+ transformTypeDeclarationSection,
60
+ fixFormattingArtifacts,
61
+ ].reduce((acc, fn) => fn(acc), contents)
62
+ }
63
+
64
+ function transformFilename(filename) {
65
+ return filename.replace(/\/([^/]+)\.md$/, (_, name) => {
66
+ const formatted = name
67
+ .split('.')
68
+ .pop()
69
+ .replace(/([a-z])([A-Z])/g, '$1-$2') // Add hyphen between lowercase & uppercase
70
+ .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2') // Add hyphen between uppercase followed by lowercase
71
+ .replace(/([0-9])([A-Za-z])/g, '$1-$2') // Add hyphen between number & letter
72
+ .toLowerCase() // Convert to lowercase
73
+ return `/${formatted}.mdx`
74
+ })
75
+ }
76
+
77
+ function removeInternalLinks(contents) {
78
+ return contents.replace(/\[([^\]]+)]\([^)]+\)/g, '$1')
79
+ }
80
+
81
+ function escapePromiseSpecialCharacters(contents) {
82
+ return contents.replace(/`Promise`\s*\\<((?:`?[^`<>]+`?|<[^<>]+>)*?)>/g, (_match, typeContent) => {
83
+ return '`Promise<' + typeContent.replace(/[`\\]/g, '') + '>`'
84
+ })
85
+ }
86
+
87
+ function transformParametersSection(contents) {
88
+ for (let i = 6; i > 1; i--) {
89
+ let paramsRegex = new RegExp(`\#{${i}} Parameters\\s*\\n\\n([\\s\\S]*?)(?=\\n\#{1,${i}} |$)`, 'g')
90
+ if (i == 6) {
91
+ paramsRegex = new RegExp(
92
+ `\#{${i}} Parameters\\s*\\n\\n([\\s\\S]*?)(?=\\n\#{1,${
93
+ i - 1
94
+ }} |\#{1,${i}} Returns|\#{1,${i}} Example|\#{1,${i}} Examples|$)`,
95
+ 'g',
96
+ )
97
+ }
98
+ contents = contents.replace(paramsRegex, (match, paramsContent) => {
99
+ const paramHeadingLevel = i == 6 ? 6 : i + 1
100
+ const headingHashes = '#'.repeat(paramHeadingLevel)
101
+ const headingHashesShorter = Array.from({ length: paramHeadingLevel }, (_, k) => '#'.repeat(k + 1)).join('|')
102
+
103
+ const paramBlockRegex = new RegExp(
104
+ `${headingHashes} ([^\\n]+)\\n\\n` + // parameter name
105
+ '([^\\n]+)' + // type line
106
+ `(?:\\n\\n((?:(?!${headingHashes} |${headingHashesShorter} |\\*\\*\\*|#{1,6} ).+[\\r\\n]*)*))?`, // safe multiline description
107
+ 'g',
108
+ )
109
+
110
+ const parameters = []
111
+ let paramMatch
112
+
113
+ while ((paramMatch = paramBlockRegex.exec(paramsContent)) !== null) {
114
+ const [, name, typeLine, rawDescription = ''] = paramMatch
115
+
116
+ const lines = rawDescription
117
+ .split('\n')
118
+ .map((line) => line.trim())
119
+ .filter((line) => line.length > 0)
120
+
121
+ parameters.push({
122
+ name,
123
+ typeLine,
124
+ mainDescription: lines[0] || '',
125
+ otherLines: lines.slice(1),
126
+ })
127
+ }
128
+
129
+ if (parameters.length === 0) return match
130
+
131
+ let result = '**Parameters**:\n\n'
132
+
133
+ for (const { name, typeLine, mainDescription, otherLines } of parameters) {
134
+ let type = typeLine.replace(/`/g, '').trim()
135
+ type = type.replace(/readonly\s+/, '').trim()
136
+ type = type.replace(/(?<!\\)([*_`[\]()<>|])/g, '\\$1')
137
+
138
+ result += `- \`${name}\` _${type}_`
139
+ if (mainDescription) result += ` - ${mainDescription}`
140
+ result += '\n'
141
+
142
+ for (const line of otherLines) {
143
+ result += ` ${line}\n`
144
+ }
145
+ }
146
+
147
+ return result + '\n'
148
+ })
149
+ }
150
+
151
+ return contents
152
+ }
153
+
154
+ function transformReturnsSection(contents) {
155
+ return contents.replace(
156
+ /^#{1,6} Returns\s*\n+`([^`]+)`\n+((?:(?!^#{1,6} |\*\*\*).*\n?)*)/gm,
157
+ (_, type, rawDescription) => {
158
+ const lines = rawDescription
159
+ .split('\n')
160
+ .map((l) => l.trim())
161
+ .filter((l) => l && !/^#{1,6} /.test(l) && l !== '***') // ignore headings and separators
162
+
163
+ let result = '**Returns**:\n\n- `' + type + '`'
164
+ if (lines.length > 0) {
165
+ result += ' - ' + lines[0] + '\n'
166
+ for (const line of lines.slice(1)) {
167
+ result += ` ${line}\n`
168
+ }
169
+ } else {
170
+ result += '\n'
171
+ }
172
+ result += '\n'
173
+ return result
174
+ },
175
+ )
176
+ }
177
+
178
+ function transformPropertiesSection(contents) {
179
+ contents = transformPropsOrTypeDeclaration(contents, 'Properties')
180
+
181
+ // Move Properties section right after each class/interface description
182
+ const sections = contents.split(/^## /gm)
183
+ const updatedSections = sections.map((section, i) => {
184
+ if (i === 0) return section // Skip content before first ##
185
+
186
+ const sectionLines = section.split('\n')
187
+ const classHeader = sectionLines[0].trim()
188
+ const body = sectionLines.slice(1).join('\n')
189
+
190
+ const propsMatch = body.match(/\*\*Properties\*\*:\s*\n\n([\s\S]*?)(?=\n###|\n\*\*|\n## |\n# |$)/)
191
+ if (!propsMatch) return '## ' + section
192
+
193
+ const fullPropsBlock = propsMatch[0]
194
+ const bodyWithoutProps = body.replace(fullPropsBlock, '').trim()
195
+
196
+ let descEnd = bodyWithoutProps.search(/\n{2,}(?=###|\*\*|$)|(?=^\s*$)/m)
197
+ if (descEnd === -1) {
198
+ const trimmed = bodyWithoutProps.trim()
199
+
200
+ if (!trimmed.includes('\n') && !trimmed.startsWith('#') && !trimmed.startsWith('**')) {
201
+ descEnd = bodyWithoutProps.length
202
+ }
203
+ }
204
+ let newBody
205
+
206
+ if (descEnd !== -1) {
207
+ const desc = bodyWithoutProps.slice(0, descEnd).trim()
208
+ const rest = bodyWithoutProps.slice(descEnd).trim()
209
+ newBody = `${desc}\n\n${fullPropsBlock}\n\n${rest}`
210
+ } else {
211
+ newBody = `${fullPropsBlock}\n\n${bodyWithoutProps}`
212
+ }
213
+
214
+ return `## ${classHeader}\n\n${newBody.trim()}`
215
+ })
216
+
217
+ return updatedSections.join('\n')
218
+ }
219
+
220
+ function transformExamplesSection(contents) {
221
+ return contents.replace(/^#{1,10}\s*(Example|Examples)$/gm, '**$1:**')
222
+ }
223
+
224
+ function transformExtendsSection(contents) {
225
+ return contents.replace(/^#{1,10}\s*(Extends)$/gm, '**$1:**')
226
+ }
227
+
228
+ function transformInheritedSections(contents) {
229
+ // Transform "##### Inherited from" sections into inline inheritance notes
230
+ // Handle both simple and complex patterns (with Memberof sections and code blocks)
231
+
232
+ const hasInheritedFrom = contents.includes('##### Inherited from')
233
+
234
+ if (!hasInheritedFrom) {
235
+ return contents
236
+ }
237
+
238
+ // Use line-by-line processing for maximum reliability
239
+ const lines = contents.split('\n')
240
+ let modified = false
241
+
242
+ for (let i = 0; i < lines.length; i++) {
243
+ // Look for "##### Inherited from" lines
244
+ if (lines[i].trim() === '##### Inherited from') {
245
+ // Look backwards for property definition (list item or heading)
246
+ let propertyLineIndex = -1
247
+ let propertyLine = ''
248
+
249
+ // Search backwards up to 20 lines
250
+ for (let j = i - 1; j >= Math.max(0, i - 20); j--) {
251
+ const line = lines[j].trim()
252
+ // Property heading format: #### propertyName
253
+ if (line.match(/^#### [^#]+$/)) {
254
+ propertyLineIndex = j
255
+ propertyLine = lines[j]
256
+ break
257
+ }
258
+ // Property list item format: - `property` _type_ - description
259
+ if (line.match(/^- `[^`]+` _[^_]+_/)) {
260
+ propertyLineIndex = j
261
+ propertyLine = lines[j]
262
+ break
263
+ }
264
+ }
265
+
266
+ // Look forwards for inheritance info
267
+ let inheritanceInfo = ''
268
+ let memberofInfo = ''
269
+ let endIndex = i
270
+
271
+ // Check for code block format
272
+ for (let k = i + 1; k < Math.min(lines.length, i + 5); k++) {
273
+ if (lines[k].trim() === '```ts' && k + 2 < lines.length) {
274
+ const nextLine = lines[k + 1].trim()
275
+ if (nextLine && lines[k + 2].trim() === '```') {
276
+ inheritanceInfo = nextLine
277
+ endIndex = k + 2
278
+ break
279
+ }
280
+ }
281
+ // Check for simple format: `Class`.`property`
282
+ if (lines[k].trim().match(/^`[^`]+`\.`[^`]+`$/)) {
283
+ inheritanceInfo = lines[k].trim().replace(/`/g, '')
284
+ endIndex = k
285
+ break
286
+ }
287
+ }
288
+
289
+ // Look backwards for Memberof info
290
+ for (let m = i - 1; m >= Math.max(0, i - 5); m--) {
291
+ if (lines[m].trim() === '##### Memberof') {
292
+ // Look for the memberof value in the next few lines
293
+ for (let n = m + 1; n < Math.min(lines.length, m + 5); n++) {
294
+ if (lines[n].trim() === '```ts' && n + 2 < lines.length) {
295
+ const memberofLine = lines[n + 1].trim()
296
+ if (memberofLine && lines[n + 2].trim() === '```') {
297
+ memberofInfo = memberofLine
298
+ break
299
+ }
300
+ }
301
+ // Check for simple format: `ClassName`
302
+ if (lines[n].trim().match(/^`[^`]+`$/)) {
303
+ memberofInfo = lines[n].trim().replace(/`/g, '')
304
+ break
305
+ }
306
+ // Check for plain text format: ClassName
307
+ if (lines[n].trim().length > 0 && !lines[n].trim().startsWith('#') && !lines[n].trim().startsWith('```')) {
308
+ memberofInfo = lines[n].trim()
309
+ break
310
+ }
311
+ }
312
+ break
313
+ }
314
+ }
315
+
316
+ // If we found both property and inheritance info, transform it
317
+ if (propertyLineIndex >= 0 && inheritanceInfo) {
318
+ // Use memberof info if available, otherwise use inheritance info
319
+ let finalInheritanceInfo
320
+ if (memberofInfo && inheritanceInfo.includes('.')) {
321
+ // Extract property name from inheritance info and combine with memberof class
322
+ const propertyName = inheritanceInfo.split('.').pop()
323
+ finalInheritanceInfo = `${memberofInfo}.${propertyName}`
324
+ } else {
325
+ finalInheritanceInfo = inheritanceInfo
326
+ }
327
+
328
+ // Add inheritance info to property line
329
+ if (propertyLine.startsWith('#### ')) {
330
+ // For headings, add after the heading
331
+ lines[propertyLineIndex] = propertyLine + `\n\n_Inherited from_: \`${finalInheritanceInfo}\``
332
+ } else if (propertyLine.startsWith('- `')) {
333
+ // For list items, add as a sub-item
334
+ lines[propertyLineIndex] = propertyLine + `\n - _Inherited from_: \`${finalInheritanceInfo}\``
335
+ }
336
+
337
+ // Remove the inheritance section
338
+ // Find the start of the section (might include Memberof)
339
+ let startIndex = i
340
+ for (let m = i - 1; m >= Math.max(0, i - 5); m--) {
341
+ if (lines[m].trim() === '##### Memberof') {
342
+ startIndex = m
343
+ break
344
+ }
345
+ // Also check for empty lines to find the start of the inheritance block
346
+ if (lines[m].trim() === '' && m > 0 && lines[m - 1].trim() !== '') {
347
+ startIndex = m
348
+ break
349
+ }
350
+ }
351
+
352
+ // Remove all lines from startIndex to endIndex (inclusive)
353
+ for (let r = endIndex; r >= startIndex; r--) {
354
+ lines.splice(r, 1)
355
+ }
356
+
357
+ // Adjust our loop index since we removed lines
358
+ i = propertyLineIndex
359
+ modified = true
360
+ }
361
+ }
362
+ }
363
+
364
+ // Remove any remaining standalone "##### Memberof" sections
365
+ if (modified) {
366
+ const finalLines = lines.join('\n').split('\n')
367
+ for (let i = finalLines.length - 1; i >= 0; i--) {
368
+ if (finalLines[i].trim() === '##### Memberof') {
369
+ // Remove the Memberof line and any following content until next heading or empty line
370
+ let endMemberof = i
371
+ for (let j = i + 1; j < finalLines.length; j++) {
372
+ if (finalLines[j].trim() === '' || finalLines[j].match(/^#{1,6} /)) {
373
+ break
374
+ }
375
+ endMemberof = j
376
+ }
377
+ finalLines.splice(i, endMemberof - i + 1)
378
+ }
379
+ }
380
+
381
+ // Also remove any standalone class name lines that might be leftover
382
+ const cleanedContent = finalLines
383
+ .join('\n')
384
+ .replace(/\n\s*\n\s*([A-Z][a-zA-Z]*)\s*\n\s*\n/g, '\n\n') // Remove standalone class names between empty lines
385
+ .replace(/\n\s*([A-Z][a-zA-Z]*)\s*\n(?=\s*-|\s*\*\*)/g, '\n') // Remove class names before property lists or sections
386
+
387
+ return cleanedContent
388
+ }
389
+
390
+ return modified ? lines.join('\n') : contents
391
+ }
392
+
393
+ function transformEnumSection(contents) {
394
+ // First, find all sections with "Enumeration Members" headings
395
+ const sections = contents.split(/^## /gm)
396
+ let newContent = ''
397
+
398
+ for (let i = 0; i < sections.length; i++) {
399
+ const section = sections[i]
400
+
401
+ if (i === 0) {
402
+ // This is content before the first ## heading
403
+ newContent += section
404
+ continue
405
+ }
406
+
407
+ // Add back the ## that was removed in the split
408
+ const sectionWithHeader = '## ' + section
409
+
410
+ // Check if this section contains an enum
411
+ if (sectionWithHeader.includes('### Enumeration Members')) {
412
+ // Split at the enum members heading
413
+ const [headerPart, membersPart] = sectionWithHeader.split('### Enumeration Members')
414
+
415
+ // Parse and extract all enum values
416
+ const enumValues = []
417
+ const regex = /#### ([A-Z0-9_]+)[\s\S]*?```ts[\s\S]*?\1:\s*"([^"]+)"/g
418
+ let match
419
+
420
+ const memberPartCopy = membersPart
421
+ while ((match = regex.exec(memberPartCopy)) !== null) {
422
+ enumValues.push({
423
+ name: match[1],
424
+ value: match[2],
425
+ })
426
+ }
427
+
428
+ // Create the transformed section
429
+ let transformedSection = headerPart + '**Enum Members**:\n\n'
430
+
431
+ if (enumValues.length > 0) {
432
+ enumValues.forEach((entry) => {
433
+ transformedSection += `- \`${entry.name}\` ("${entry.value}")\n`
434
+ })
435
+ transformedSection += '\n'
436
+ } else {
437
+ // If we couldn't parse any values, just keep the original content
438
+ transformedSection = sectionWithHeader
439
+ }
440
+
441
+ newContent += transformedSection
442
+ } else {
443
+ // Non-enum section, just add it back unchanged
444
+ newContent += sectionWithHeader
445
+ }
446
+ }
447
+
448
+ return newContent
449
+ }
450
+
451
+ function transformThrowsSection(contents) {
452
+ // Process "Throws" headers from level 2 to level 7
453
+ for (let level = 2; level <= 7; level++) {
454
+ const throwsHeader = '#'.repeat(level) + ' Throws' // Generate header (e.g., ## Throws, ### Throws)
455
+ const sectionHeaderRegex = new RegExp(`(?=^#{${level - 1}} .+)`, 'gm') // Regex for section start (parent level)
456
+ const throwsRegex = new RegExp(`(\n${throwsHeader}\n)`, 'g') // Matches only the "Throws" header itself
457
+
458
+ if (!contents) continue
459
+
460
+ // Split document into sections at parent level
461
+ const sections = contents.split(sectionHeaderRegex)
462
+
463
+ contents = sections
464
+ .map((section) => {
465
+ if (!section.includes(`\n${throwsHeader}`)) return section // Skip if no "Throws" found at this level
466
+
467
+ // Capture all occurrences of "Throws" headers at this specific level
468
+ const throwsMatches = [...section.matchAll(throwsRegex)]
469
+
470
+ if (throwsMatches.length <= 1) {
471
+ // Transform single occurrence
472
+ return section.replace(throwsRegex, '\n**Throws**:\n')
473
+ }
474
+
475
+ // Keep the first "Throws" header and remove only subsequent ones
476
+ let headerRemovedCount = 0
477
+ const cleanedSection = section.replace(throwsRegex, () => {
478
+ return headerRemovedCount++ === 0 ? '\n**Throws**:\n' : '' // Transform first one to bold, remove others
479
+ })
480
+
481
+ return cleanedSection
482
+ })
483
+ .join('')
484
+ }
485
+
486
+ return contents
487
+ }
488
+
489
+ function fixFormattingArtifacts(content) {
490
+ return content.replace(/`~~([^`]+?)\?~~`/g, '~~`$1?`~~')
491
+ }
492
+
493
+ function transformTypeDeclarationSection(contents) {
494
+ return transformPropsOrTypeDeclaration(contents, 'Type declaration')
495
+ }
496
+
497
+ function transformPropsOrTypeDeclaration(contents, headerTitle) {
498
+ for (let i = 5; i > 1; i--) {
499
+ contents = contents.replace(
500
+ new RegExp(`\#{${i}} ${headerTitle}\\s*\\n\\n([\\s\\S]*?)(?=\\n\#{1,${i}} |$)`, 'g'),
501
+ (match, sectionContent) => {
502
+ const itemHeadingLevel = i + 1
503
+ const headingHashes = '#'.repeat(itemHeadingLevel)
504
+ const headingHashesShorter = Array.from({ length: itemHeadingLevel }, (_, k) => '#'.repeat(k + 1)).join('|')
505
+ const itemBlockRegex = new RegExp(
506
+ `${headingHashes} ([^\\n]+)\\n\\n` + // #### propName
507
+ '(?:_Inherited from_: `([^`]+)`\\n\\n)?' + // optional inheritance info
508
+ '(?:([A-Za-z]+)\\n)?' + // optional leftover memberof text (like "Workspace")
509
+ '(?:\\n)?' + // optional empty line after leftover text
510
+ '```ts\\n([^\\n]+);\\n```\\n' + // code block
511
+ '([\\s\\S]*?)' + // description block (may include Index Signature)
512
+ `(?=(?:\\n\\*\\*\\*\\n)?(?=\\n${headingHashes} )|\\n(?:${headingHashesShorter}) |$)`,
513
+ 'g',
514
+ )
515
+
516
+ const items = []
517
+ let itemMatch
518
+
519
+ while ((itemMatch = itemBlockRegex.exec(sectionContent)) !== null) {
520
+ const [, name, inheritanceInfo, leftoverText, typeLine, rawDescription] = itemMatch
521
+
522
+ const lines = rawDescription
523
+ .trim()
524
+ .split('\n')
525
+ .map((line) => line.trim())
526
+ .filter((line) => !line.includes('***'))
527
+
528
+ let deprecation = ''
529
+ const contentLines = []
530
+ const indexSignatureLines = []
531
+ let inIndexSignature = false
532
+
533
+ for (let i = 0; i < lines.length; i++) {
534
+ if (new RegExp(`^\#{${itemHeadingLevel + 1}}? Index Signature`, 'i').test(lines[i])) {
535
+ inIndexSignature = true
536
+ indexSignatureLines.push(lines[i])
537
+ continue
538
+ }
539
+
540
+ if (inIndexSignature) {
541
+ indexSignatureLines.push(lines[i])
542
+ continue
543
+ }
544
+
545
+ if (new RegExp(`^\#{${itemHeadingLevel + 1}}? Overrides`, 'i').test(lines[i])) {
546
+ let j = i + 1
547
+ while (j < lines.length && !lines[j].trim().startsWith('#')) j++
548
+ i = j - 1
549
+ } else if (new RegExp(`^\#{${itemHeadingLevel + 1}}? Deprecated`, 'i').test(lines[i])) {
550
+ let j = i + 1
551
+ while (j < lines.length && lines[j].trim() === '') j++
552
+ if (j < lines.length) {
553
+ deprecation = lines[j].trim()
554
+ i = j
555
+ }
556
+ } else {
557
+ contentLines.push(lines[i])
558
+ }
559
+ }
560
+
561
+ const mainDescription = contentLines[0] || ''
562
+ const otherLines = contentLines.slice(1)
563
+
564
+ // Extract index signature type if present
565
+ let indexSignatureType = null
566
+ for (const line of indexSignatureLines) {
567
+ if (line.includes('[') && line.includes(']:')) {
568
+ indexSignatureType = line.trim()
569
+ break
570
+ }
571
+ }
572
+
573
+ items.push({
574
+ name,
575
+ typeLine,
576
+ mainDescription,
577
+ otherLines,
578
+ deprecation,
579
+ inheritanceInfo,
580
+ indexSignatureType,
581
+ })
582
+ }
583
+
584
+ if (items.length === 0) return match
585
+
586
+ let result = `**${headerTitle}**:\n\n`
587
+
588
+ for (const {
589
+ name,
590
+ typeLine,
591
+ mainDescription,
592
+ otherLines,
593
+ deprecation,
594
+ inheritanceInfo,
595
+ indexSignatureType,
596
+ } of items) {
597
+ const typeMatch = typeLine.match(/:\s*([^;]+)/)
598
+ if (!typeMatch) continue
599
+
600
+ let type = typeMatch[1].trim()
601
+ type = type.replace(/readonly\s+/, '').trim()
602
+
603
+ // Use index signature type if available, otherwise use the original type
604
+ if (indexSignatureType) {
605
+ type = indexSignatureType
606
+ }
607
+
608
+ type = type.replace(/([*_`\[\]()<>|])/g, '\\$1')
609
+
610
+ if (!mainDescription && deprecation) {
611
+ result += `- \`${name}\` _${type}_ - **_Deprecated_** - ${deprecation}\n`
612
+ continue
613
+ }
614
+
615
+ result += `- \`${name}\` _${type}_`
616
+ if (mainDescription) result += ` - ${mainDescription}`
617
+ result += '\n'
618
+
619
+ for (const line of otherLines) {
620
+ result += ` ${line}\n`
621
+ }
622
+
623
+ if (deprecation) {
624
+ result += ` - **_Deprecated_** - ${deprecation}\n`
625
+ }
626
+
627
+ if (inheritanceInfo) {
628
+ result += ` - _Inherited from_: \`${inheritanceInfo}\`\n`
629
+ }
630
+ }
631
+
632
+ result = result.replace(/^\s{4}\*\*\*/gm, '***')
633
+
634
+ return result + '\n'
635
+ },
636
+ )
637
+ }
638
+
639
+ return contents
640
+ }
package/jest.config.js ADDED
@@ -0,0 +1,15 @@
1
+ /*
2
+ * Copyright 2025 Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ /** @type {import('ts-jest').JestConfigWithTsJest} */
7
+ module.exports = {
8
+ preset: 'ts-jest',
9
+ testEnvironment: 'node',
10
+ transform: {
11
+ '^.+\\.tsx?$': 'ts-jest',
12
+ },
13
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
14
+ testMatch: ['**/__tests__/**/*.test.ts'],
15
+ }
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@hanzo/runtime",
3
+ "version": "0.0.0-dev",
4
+ "description": "TypeScript SDK for Hanzo Runtime",
5
+ "main": "./src/index.js",
6
+ "types": "./src/index.d.ts",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/hanzoai/runtime.git"
10
+ },
11
+ "author": "Hanzo Industries Inc",
12
+ "license": "Apache-2.0",
13
+ "bugs": {
14
+ "url": "https://github.com/hanzoai/runtime/issues"
15
+ },
16
+ "homepage": "https://github.com/hanzoai/runtime",
17
+ "config": {
18
+ "docsDir": "../../apps/docs/src/content/docs/typescript-sdk"
19
+ },
20
+ "scripts": {
21
+ "docs": "bash -O extglob -c 'rm -rf $npm_package_config_docsDir/!(index.mdx)' && typedoc && rm -f $npm_package_config_docsDir/readme.mdx"
22
+ },
23
+ "keywords": []
24
+ }