(public ctx: Context)
| 167 | registry: Record<string, string> = {}; |
| 168 | |
| 169 | constructor(public ctx: Context) { |
| 170 | super(ctx, 'template'); |
| 171 | const that = this; |
| 172 | ctx.on('handler/create', async (h) => { |
| 173 | h.user = h.context.HydroContext.user as any; |
| 174 | h.domain = h.context.HydroContext.domain as any; |
| 175 | h.translate = h.translate.bind(h); |
| 176 | h.url = h.url.bind(h); |
| 177 | h.ctx = h.ctx.extend({ domain: h.domain }); |
| 178 | h.renderHTML = ((orig) => function (name: string, args: Record<string, any>) { |
| 179 | const s = name.split('.'); |
| 180 | let templateName = `${s[0]}.${h.domain._id}.${s[1]}`; |
| 181 | if (!that.registry[templateName]) templateName = name; |
| 182 | return orig(templateName, args); |
| 183 | })(h.renderHTML).bind(h); |
| 184 | }); |
| 185 | |
| 186 | class Loader extends nunjucks.Loader { |
| 187 | getSource(name) { |
| 188 | const src = that.registry[name]; |
| 189 | const ref = that.registry[`${name}.source`]; |
| 190 | if (!process.env.DEV) { |
| 191 | if (!src) throw new Error(`Cannot get template ${name}`); |
| 192 | return { |
| 193 | src, |
| 194 | path: name, |
| 195 | noCache: false, |
| 196 | }; |
| 197 | } |
| 198 | let fullpath: string | null = null; |
| 199 | const p = path.resolve(template, name); |
| 200 | if (fs.existsSync(p)) fullpath = p; |
| 201 | if (!fullpath && ref && fs.existsSync(ref)) fullpath = ref; |
| 202 | if (!fullpath) { |
| 203 | if (src) { |
| 204 | return { |
| 205 | src, |
| 206 | path: name, |
| 207 | noCache: true, |
| 208 | }; |
| 209 | } |
| 210 | throw new Error(`Cannot get template ${name}`); |
| 211 | } |
| 212 | return { |
| 213 | src: fs.readFileSync(fullpath, 'utf-8'), |
| 214 | path: fullpath, |
| 215 | noCache: true, |
| 216 | }; |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | const env = new Nunjucks(Loader); |
| 221 | env.addGlobal('findSubModule', (prefix) => Object.keys(that.registry).filter((n) => n.startsWith(prefix))); |
| 222 | env.addGlobal('templateExists', (name) => !!that.registry[name]); |
| 223 | |
| 224 | const render = (name: string, state: any) => new Promise<string>((resolve, reject) => { |
| 225 | const start = Date.now(); |
| 226 | env.render(name, { |
nothing calls this directly
no test coverage detected