From f031ab583741639c75a9bcdaea8b415454da9aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20P=C3=B6hls?= Date: Sun, 10 Dec 2023 06:16:34 +0100 Subject: [PATCH 1/3] add withoutLayout helper function to view builder --- packages/contracts/src/view/config-builder.ts | 5 +++++ packages/view/src/view-config-builder.ts | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/packages/contracts/src/view/config-builder.ts b/packages/contracts/src/view/config-builder.ts index 3246618f..2e4bb99c 100644 --- a/packages/contracts/src/view/config-builder.ts +++ b/packages/contracts/src/view/config-builder.ts @@ -5,4 +5,9 @@ export interface ViewConfigBuilder { * the file name of the layout file in the configured layouts folder. */ layout(name: string): this + + /** + * Render this view without a base layout. + */ + withoutLayout(): this } diff --git a/packages/view/src/view-config-builder.ts b/packages/view/src/view-config-builder.ts index 54971b77..9b8371ef 100644 --- a/packages/view/src/view-config-builder.ts +++ b/packages/view/src/view-config-builder.ts @@ -24,4 +24,13 @@ export class ViewConfigBuilder implements ViewConfigBuilderContract { this.config.layout = name }) } + + /** + * Render this view without a base layout. + */ + withoutLayout (): this { + this.layout('') + + return this + } } From 0c383a95e2410a9382e06c0aa3287b7d0ab407e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20P=C3=B6hls?= Date: Mon, 11 Dec 2023 12:34:52 +0100 Subject: [PATCH 2/3] minor view refactorings --- CHANGELOG.md | 6 ++++++ .../base-driver.ts} | 2 +- .../handlebars/handlebars-driver.ts} | 20 +++++++++---------- .../handlebars/helpers/append.ts | 0 .../handlebars/helpers/json.ts | 0 .../handlebars/helpers/prepend.ts | 0 .../handlebars/helpers/raw.ts | 0 .../handlebars/helpers/stack.ts | 0 packages/view/src/drivers/handlebars/index.ts | 2 ++ .../view/src/{engines => drivers}/index.ts | 0 packages/view/src/engines/handlebars/index.ts | 2 -- packages/view/src/index.ts | 2 +- packages/view/src/view-config-builder.ts | 11 +++++++--- packages/view/src/view-manager.ts | 4 ++-- packages/view/src/view-response.ts | 8 ++++---- 15 files changed, 34 insertions(+), 23 deletions(-) rename packages/view/src/{engines/handlebars/base-compiler.ts => drivers/base-driver.ts} (97%) rename packages/view/src/{engines/handlebars/compiler.ts => drivers/handlebars/handlebars-driver.ts} (96%) rename packages/view/src/{engines => drivers}/handlebars/helpers/append.ts (100%) rename packages/view/src/{engines => drivers}/handlebars/helpers/json.ts (100%) rename packages/view/src/{engines => drivers}/handlebars/helpers/prepend.ts (100%) rename packages/view/src/{engines => drivers}/handlebars/helpers/raw.ts (100%) rename packages/view/src/{engines => drivers}/handlebars/helpers/stack.ts (100%) create mode 100644 packages/view/src/drivers/handlebars/index.ts rename packages/view/src/{engines => drivers}/index.ts (100%) delete mode 100644 packages/view/src/engines/handlebars/index.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b170d9d..e8257df6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - `@supercharge/contracts` - allow users to define only selected hashing driver constructros in `HashConfig#drivers` - export a `ViteConfig` interface + - extend `ViewConfigBuilder` interface: add `withoutLayout` method - `@supercharge/core` - bypass import cache when dynamically importing routes from file path - `@supercharge/vite` @@ -22,10 +23,15 @@ - bump dependencies - `@supercharge/vite` - add Vite `^5.0.0` as a peer dependency +- `@supercharge/view` + - implement `withoutLayout` method on `ViewConfigBuilder` instance + - rename view `engines` folder to `drivers` ### Breaking Changes - `@supercharge/vite` - require Vite `>=4.0.0` as a peer dependency +- `@supercharge/view` + - rename `HandlebarsCompiler` to `HandlebarsDriver` ## [4.0.0-alpha.1](https://github.com/supercharge/framework/compare/v4.0.0-alpha.0...v4.0.0-alpha.1) - 2023-11-18 diff --git a/packages/view/src/engines/handlebars/base-compiler.ts b/packages/view/src/drivers/base-driver.ts similarity index 97% rename from packages/view/src/engines/handlebars/base-compiler.ts rename to packages/view/src/drivers/base-driver.ts index 46d48575..e8737773 100644 --- a/packages/view/src/engines/handlebars/base-compiler.ts +++ b/packages/view/src/drivers/base-driver.ts @@ -1,7 +1,7 @@ import { ViewSharedData } from '@supercharge/contracts' -export class ViewBaseCompiler { +export class ViewBaseDriver { /** * Stores the data that is available to all view templates. */ diff --git a/packages/view/src/engines/handlebars/compiler.ts b/packages/view/src/drivers/handlebars/handlebars-driver.ts similarity index 96% rename from packages/view/src/engines/handlebars/compiler.ts rename to packages/view/src/drivers/handlebars/handlebars-driver.ts index 11c5ce12..60bddb6a 100644 --- a/packages/view/src/engines/handlebars/compiler.ts +++ b/packages/view/src/drivers/handlebars/handlebars-driver.ts @@ -4,15 +4,19 @@ import Fs from '@supercharge/fs' import { fileURLToPath } from 'node:url' import { Str } from '@supercharge/strings' import { Collect } from '@supercharge/collections' -import { ViewBaseCompiler } from './base-compiler.js' +import { ViewBaseDriver } from '../base-driver.js' import Handlebars, { HelperDelegate } from 'handlebars' import { resolveDefaultImport, tap } from '@supercharge/goodies' import { Logger, ViewConfig, ViewEngine, ViewResponseConfig } from '@supercharge/contracts' +interface ReadTemplateConfig { + isLayout?: boolean +} + // eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = Path.dirname(fileURLToPath(import.meta.url)) -export class HandlebarsCompiler extends ViewBaseCompiler implements ViewEngine { +export class HandlebarsDriver extends ViewBaseDriver implements ViewEngine { /** * The handlebars renderer instance. */ @@ -55,7 +59,7 @@ export class HandlebarsCompiler extends ViewBaseCompiler implements ViewEngine { return layoutLocation } - throw new Error(`Path to view layouts not existing. Received ${layoutLocation}`) + throw new Error(`Path to view layouts not existing. Received "${layoutLocation}"`) } /** @@ -75,7 +79,7 @@ export class HandlebarsCompiler extends ViewBaseCompiler implements ViewEngine { return viewsLocation } - throw new Error(`Path to view files not existing. Received ${viewsLocation}`) + throw new Error(`Path to view files not existing. Received "${viewsLocation}"`) } /** @@ -248,7 +252,7 @@ export class HandlebarsCompiler extends ViewBaseCompiler implements ViewEngine { /** * Returns the rendered HTML view. */ - async render (view: string, data: any, viewConfig: ViewResponseConfig = {}): Promise { + async render (view: string, data: any, viewConfig: ViewResponseConfig): Promise { return this.hasLayout(viewConfig) ? await this.renderWithLayout(view, data, viewConfig) : await this.renderView(view, data) @@ -322,7 +326,7 @@ export class HandlebarsCompiler extends ViewBaseCompiler implements ViewEngine { const file = this.ensureExtension(view) if (await Fs.notExists(file)) { - throw new Error(`View file does not exist. Tried to load ${file}`) + throw new Error(`View file does not exist. Tried to load "${file}"`) } } @@ -333,7 +337,3 @@ export class HandlebarsCompiler extends ViewBaseCompiler implements ViewEngine { return Str(template).finish(this.extension).get() } } - -interface ReadTemplateConfig { - isLayout?: boolean -} diff --git a/packages/view/src/engines/handlebars/helpers/append.ts b/packages/view/src/drivers/handlebars/helpers/append.ts similarity index 100% rename from packages/view/src/engines/handlebars/helpers/append.ts rename to packages/view/src/drivers/handlebars/helpers/append.ts diff --git a/packages/view/src/engines/handlebars/helpers/json.ts b/packages/view/src/drivers/handlebars/helpers/json.ts similarity index 100% rename from packages/view/src/engines/handlebars/helpers/json.ts rename to packages/view/src/drivers/handlebars/helpers/json.ts diff --git a/packages/view/src/engines/handlebars/helpers/prepend.ts b/packages/view/src/drivers/handlebars/helpers/prepend.ts similarity index 100% rename from packages/view/src/engines/handlebars/helpers/prepend.ts rename to packages/view/src/drivers/handlebars/helpers/prepend.ts diff --git a/packages/view/src/engines/handlebars/helpers/raw.ts b/packages/view/src/drivers/handlebars/helpers/raw.ts similarity index 100% rename from packages/view/src/engines/handlebars/helpers/raw.ts rename to packages/view/src/drivers/handlebars/helpers/raw.ts diff --git a/packages/view/src/engines/handlebars/helpers/stack.ts b/packages/view/src/drivers/handlebars/helpers/stack.ts similarity index 100% rename from packages/view/src/engines/handlebars/helpers/stack.ts rename to packages/view/src/drivers/handlebars/helpers/stack.ts diff --git a/packages/view/src/drivers/handlebars/index.ts b/packages/view/src/drivers/handlebars/index.ts new file mode 100644 index 00000000..ee3b2064 --- /dev/null +++ b/packages/view/src/drivers/handlebars/index.ts @@ -0,0 +1,2 @@ + +export * from './handlebars-driver.js' diff --git a/packages/view/src/engines/index.ts b/packages/view/src/drivers/index.ts similarity index 100% rename from packages/view/src/engines/index.ts rename to packages/view/src/drivers/index.ts diff --git a/packages/view/src/engines/handlebars/index.ts b/packages/view/src/engines/handlebars/index.ts deleted file mode 100644 index 6e9a4df0..00000000 --- a/packages/view/src/engines/handlebars/index.ts +++ /dev/null @@ -1,2 +0,0 @@ - -export * from './compiler.js' diff --git a/packages/view/src/index.ts b/packages/view/src/index.ts index 5495b547..41ea00c7 100644 --- a/packages/view/src/index.ts +++ b/packages/view/src/index.ts @@ -1,5 +1,5 @@ -export { HandlebarsCompiler } from './engines/index.js' +export { HandlebarsDriver } from './drivers/index.js' export { ViewConfigBuilder } from './view-config-builder.js' export { ViewManager } from './view-manager.js' export { ViewResponse } from './view-response.js' diff --git a/packages/view/src/view-config-builder.ts b/packages/view/src/view-config-builder.ts index 9b8371ef..47dffada 100644 --- a/packages/view/src/view-config-builder.ts +++ b/packages/view/src/view-config-builder.ts @@ -15,6 +15,13 @@ export class ViewConfigBuilder implements ViewConfigBuilderContract { this.config = config } + /** + * Create a new view config builder instance. + */ + static from (config: ViewResponseConfig): ViewConfigBuilder { + return new this(config) + } + /** * Set the base layout used to render this view. The given `name` identifies * the file name of the layout file in the configured layouts folder. @@ -29,8 +36,6 @@ export class ViewConfigBuilder implements ViewConfigBuilderContract { * Render this view without a base layout. */ withoutLayout (): this { - this.layout('') - - return this + return this.layout('') } } diff --git a/packages/view/src/view-manager.ts b/packages/view/src/view-manager.ts index 96f93807..182678c4 100644 --- a/packages/view/src/view-manager.ts +++ b/packages/view/src/view-manager.ts @@ -2,7 +2,7 @@ import { tap } from '@supercharge/goodies' import { HelperDelegate } from 'handlebars' import { Manager } from '@supercharge/manager' -import { HandlebarsCompiler } from './engines/handlebars/index.js' +import { HandlebarsDriver } from './drivers/handlebars/index.js' import { Application, ViewConfig, ViewEngine, ViewResponseConfig, ViewSharedData } from '@supercharge/contracts' export class ViewManager extends Manager implements ViewEngine { @@ -53,7 +53,7 @@ export class ViewManager extends Manager implements ViewEngine { * Create a Handlebars view renderer instance. */ protected createHandlebarsDriver (): ViewEngine { - return new HandlebarsCompiler(this.app.logger(), this.meta.config.handlebars) + return new HandlebarsDriver(this.app.logger(), this.meta.config.handlebars) } /** diff --git a/packages/view/src/view-response.ts b/packages/view/src/view-response.ts index bf2eee67..8fb7052e 100644 --- a/packages/view/src/view-response.ts +++ b/packages/view/src/view-response.ts @@ -40,7 +40,7 @@ export class ViewResponse { /** * Assigns the rendered HTML of the given `template` as the response payload. */ - private async renderView (template: string, data?: any, viewBuilder?: ViewBuilderCallback): Promise { + private async renderView (template: string, data?: any, viewBuilderCallback?: ViewBuilderCallback): Promise { const viewData = { ...this.response.state().all(), ...this.viewEngine.sharedData(), @@ -49,9 +49,9 @@ export class ViewResponse { const viewConfig: ViewResponseConfig = {} - if (typeof viewBuilder === 'function') { - viewBuilder( - new ViewConfigBuilder(viewConfig) + if (typeof viewBuilderCallback === 'function') { + viewBuilderCallback( + ViewConfigBuilder.from(viewConfig) ) } From 945ff91269b8afb631f97a85c60bd083b0fe15b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20P=C3=B6hls?= Date: Mon, 11 Dec 2023 12:38:05 +0100 Subject: [PATCH 3/3] fix tests --- packages/view/src/drivers/handlebars/handlebars-driver.ts | 2 +- packages/view/test/view-manager.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/view/src/drivers/handlebars/handlebars-driver.ts b/packages/view/src/drivers/handlebars/handlebars-driver.ts index 60bddb6a..667d9142 100644 --- a/packages/view/src/drivers/handlebars/handlebars-driver.ts +++ b/packages/view/src/drivers/handlebars/handlebars-driver.ts @@ -252,7 +252,7 @@ export class HandlebarsDriver extends ViewBaseDriver implements ViewEngine { /** * Returns the rendered HTML view. */ - async render (view: string, data: any, viewConfig: ViewResponseConfig): Promise { + async render (view: string, data: any, viewConfig: ViewResponseConfig = {}): Promise { return this.hasLayout(viewConfig) ? await this.renderWithLayout(view, data, viewConfig) : await this.renderView(view, data) diff --git a/packages/view/test/view-manager.js b/packages/view/test/view-manager.js index efb347dd..5e20b2df 100644 --- a/packages/view/test/view-manager.js +++ b/packages/view/test/view-manager.js @@ -53,7 +53,7 @@ test('throws for invalid views path', async () => { await expect(async () => { return view.render('test-view') - }).rejects.toThrow(`Path to view files not existing. Received ${viewsPath}`) + }).rejects.toThrow(`Path to view files not existing. Received "${viewsPath}"`) }) test('throws when rendering a view with not-existing layout', async () => { @@ -77,7 +77,7 @@ test('throws for misconfigured layouts path', async () => { await expect(async () => { await view.render('test-view', { name: 'Supercharge ' }, { layout: 'test' }) - }).rejects.toThrow(`Path to view layouts not existing. Received ${layoutsPath}`) + }).rejects.toThrow(`Path to view layouts not existing. Received "${layoutsPath}"`) }) test('throws when rendering a view with not-existing layout', async () => {