(file: string, content: string)
| 66 | } |
| 67 | |
| 68 | const extractModuleSince = (file: string, content: string): Effect.Effect<string, BarrelCodegenError> => { |
| 69 | const block = content.match(/^\s*(\/\*\*[\s\S]*?\*\/)/)?.[1] |
| 70 | if (block === undefined) { |
| 71 | return Effect.fail( |
| 72 | new BarrelCodegenError({ |
| 73 | path: file, |
| 74 | reason: "missing top-level module JSDoc" |
| 75 | }) |
| 76 | ) |
| 77 | } |
| 78 | const matches = Array.from(block.matchAll(/^\s*\*\s*@since(?:\s+(.*))?$/gm)) |
| 79 | if (matches.length !== 1) { |
| 80 | return Effect.fail( |
| 81 | new BarrelCodegenError({ |
| 82 | path: file, |
| 83 | reason: matches.length === 0 |
| 84 | ? "missing top-level module @since tag" |
| 85 | : "multiple top-level module @since tags" |
| 86 | }) |
| 87 | ) |
| 88 | } |
| 89 | const since = matches[0]?.[1]?.trim() ?? "" |
| 90 | if (since.length === 0) { |
| 91 | return Effect.fail( |
| 92 | new BarrelCodegenError({ |
| 93 | path: file, |
| 94 | reason: "empty top-level module @since tag" |
| 95 | }) |
| 96 | ) |
| 97 | } |
| 98 | return Effect.succeed(since) |
| 99 | } |
| 100 | |
| 101 | const renderExportJSDoc = (since: string): string => |
| 102 | `/** |
no test coverage detected