(pathname: string)
| 99 | } |
| 100 | |
| 101 | async readFile(pathname: string): Promise<StaticFile | null> { |
| 102 | const processed = this.#processedFiles.get(pathname); |
| 103 | if (processed !== undefined) { |
| 104 | return { |
| 105 | hash: processed.hash, |
| 106 | readable: processed.content, |
| 107 | size: processed.content.byteLength, |
| 108 | contentType: processed.contentType, |
| 109 | close: () => {}, |
| 110 | }; |
| 111 | } |
| 112 | |
| 113 | const unprocessed = this.#unprocessedFiles.get(pathname); |
| 114 | if (unprocessed !== undefined) { |
| 115 | try { |
| 116 | const [stat, file] = await Promise.all([ |
| 117 | Deno.stat(unprocessed), |
| 118 | Deno.open(unprocessed, { read: true }), |
| 119 | ]); |
| 120 | |
| 121 | return { |
| 122 | hash: null, |
| 123 | size: stat.size, |
| 124 | readable: file.readable, |
| 125 | contentType: getContentType(unprocessed), |
| 126 | close: () => file.close(), |
| 127 | }; |
| 128 | } catch { |
| 129 | return null; |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | const stripped = pathname.startsWith("/") ? pathname.slice(1) : pathname; |
| 134 | |
| 135 | for (const staticDir of this.#config.staticDir) { |
| 136 | const entry = path.join(staticDir, stripped); |
| 137 | const relative = path.relative(staticDir, entry); |
| 138 | if (relative.startsWith("..")) { |
| 139 | throw new Error( |
| 140 | `Processed file resolved outside of static dir ${entry}`, |
| 141 | ); |
| 142 | } |
| 143 | |
| 144 | // Might be a file that we still need to process |
| 145 | const transformed = await this.#transformer.process( |
| 146 | entry, |
| 147 | "development", |
| 148 | this.#config.target, |
| 149 | ); |
| 150 | |
| 151 | if (transformed !== null) { |
| 152 | for (let i = 0; i < transformed.length; i++) { |
| 153 | const file = transformed[i]; |
| 154 | const rel = path.relative(staticDir, file.path); |
| 155 | if (rel.startsWith("..")) { |
| 156 | throw new Error( |
| 157 | `Processed file resolved outside of static dir ${file.path}`, |
| 158 | ); |
nothing calls this directly
no test coverage detected