mirror of
https://scm.univ-tours.fr/22107988t/rappaurio-sae501_502.git
synced 2025-08-30 02:15:58 +02:00
permet l'ajout des frameworks et des routes
This commit is contained in:
428
app/node_modules/express-handlebars/lib/express-handlebars.ts
generated
vendored
Normal file
428
app/node_modules/express-handlebars/lib/express-handlebars.ts
generated
vendored
Normal file
@@ -0,0 +1,428 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Yahoo Inc. All rights reserved.
|
||||
* Copyrights licensed under the New BSD License.
|
||||
* See the accompanying LICENSE file for terms.
|
||||
*/
|
||||
|
||||
import * as Handlebars from "handlebars";
|
||||
import * as fs from "graceful-fs";
|
||||
import * as path from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
import { glob } from "glob";
|
||||
import type {
|
||||
UnknownObject,
|
||||
HelperDelegateObject,
|
||||
ConfigOptions,
|
||||
Engine,
|
||||
TemplateSpecificationObject,
|
||||
TemplateDelegateObject,
|
||||
FsCache,
|
||||
PartialTemplateOptions,
|
||||
PartialsDirObject,
|
||||
RenderOptions,
|
||||
RenderViewOptions,
|
||||
RenderCallback,
|
||||
HandlebarsImport,
|
||||
CompiledCache,
|
||||
PrecompiledCache,
|
||||
RenameFunction,
|
||||
} from "../types";
|
||||
|
||||
const readFile = promisify(fs.readFile);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
const defaultConfig: ConfigOptions = {
|
||||
handlebars: Handlebars,
|
||||
extname: ".handlebars",
|
||||
encoding: "utf8",
|
||||
layoutsDir: undefined, // Default layouts directory is relative to `express settings.view` + `layouts/`
|
||||
partialsDir: undefined, // Default partials directory is relative to `express settings.view` + `partials/`
|
||||
defaultLayout: "main",
|
||||
helpers: undefined,
|
||||
compilerOptions: undefined,
|
||||
runtimeOptions: undefined,
|
||||
};
|
||||
|
||||
export default class ExpressHandlebars {
|
||||
config: ConfigOptions;
|
||||
engine: Engine;
|
||||
encoding: BufferEncoding;
|
||||
layoutsDir: string;
|
||||
extname: string;
|
||||
compiled: CompiledCache;
|
||||
precompiled: PrecompiledCache;
|
||||
_fsCache: FsCache;
|
||||
partialsDir: string|PartialsDirObject|(string|PartialsDirObject)[];
|
||||
compilerOptions: CompileOptions;
|
||||
runtimeOptions: RuntimeOptions;
|
||||
helpers: HelperDelegateObject;
|
||||
defaultLayout: string;
|
||||
handlebars: HandlebarsImport;
|
||||
|
||||
constructor (config: ConfigOptions = {}) {
|
||||
// Config properties with defaults.
|
||||
Object.assign(this, defaultConfig, config);
|
||||
|
||||
// save given config to override other settings.
|
||||
this.config = config;
|
||||
|
||||
// Express view engine integration point.
|
||||
this.engine = this.renderView.bind(this);
|
||||
|
||||
// Normalize `extname`.
|
||||
if (this.extname.charAt(0) !== ".") {
|
||||
this.extname = "." + this.extname;
|
||||
}
|
||||
|
||||
// Internal caches of compiled and precompiled templates.
|
||||
this.compiled = {};
|
||||
this.precompiled = {};
|
||||
|
||||
// Private internal file system cache.
|
||||
this._fsCache = {};
|
||||
}
|
||||
|
||||
async getPartials (options: PartialTemplateOptions = {}): Promise<TemplateSpecificationObject|TemplateDelegateObject> {
|
||||
if (typeof this.partialsDir === "undefined") {
|
||||
return {};
|
||||
}
|
||||
const partialsDirs = Array.isArray(this.partialsDir) ? this.partialsDir : [this.partialsDir];
|
||||
|
||||
const dirs = await Promise.all(partialsDirs.map(async dir => {
|
||||
let dirPath: string;
|
||||
let dirTemplates: TemplateDelegateObject;
|
||||
let dirNamespace: string;
|
||||
let dirRename: RenameFunction;
|
||||
|
||||
// Support `partialsDir` collection with object entries that contain a
|
||||
// templates promise and a namespace.
|
||||
if (typeof dir === "string") {
|
||||
dirPath = dir;
|
||||
} else if (typeof dir === "object") {
|
||||
dirTemplates = dir.templates;
|
||||
dirNamespace = dir.namespace;
|
||||
dirRename = dir.rename;
|
||||
dirPath = dir.dir;
|
||||
}
|
||||
|
||||
// We must have some path to templates, or templates themselves.
|
||||
if (!dirPath && !dirTemplates) {
|
||||
throw new Error("A partials dir must be a string or config object");
|
||||
}
|
||||
|
||||
const templates: HandlebarsTemplateDelegate|TemplateSpecification = dirTemplates || await this.getTemplates(dirPath, options);
|
||||
|
||||
return {
|
||||
templates: templates as HandlebarsTemplateDelegate|TemplateSpecification,
|
||||
namespace: dirNamespace,
|
||||
rename: dirRename,
|
||||
};
|
||||
}));
|
||||
|
||||
const partials: TemplateDelegateObject|TemplateSpecificationObject = {};
|
||||
|
||||
for (const dir of dirs) {
|
||||
const { templates, namespace, rename } = dir;
|
||||
const filePaths = Object.keys(templates);
|
||||
|
||||
const getTemplateNameFn = typeof rename === "function"
|
||||
? rename
|
||||
: this._getTemplateName.bind(this);
|
||||
|
||||
for (const filePath of filePaths) {
|
||||
const partialName = getTemplateNameFn(filePath, namespace);
|
||||
partials[partialName] = templates[filePath];
|
||||
}
|
||||
}
|
||||
|
||||
return partials;
|
||||
}
|
||||
|
||||
async getTemplate (filePath: string, options: PartialTemplateOptions = {}): Promise<HandlebarsTemplateDelegate|TemplateSpecification> {
|
||||
filePath = path.resolve(filePath);
|
||||
|
||||
const encoding = options.encoding || this.encoding;
|
||||
const cache: PrecompiledCache|CompiledCache = options.precompiled ? this.precompiled : this.compiled;
|
||||
const template: Promise<HandlebarsTemplateDelegate|TemplateSpecification> = options.cache && cache[filePath];
|
||||
|
||||
if (template) {
|
||||
return template;
|
||||
}
|
||||
|
||||
// Optimistically cache template promise to reduce file system I/O, but
|
||||
// remove from cache if there was a problem.
|
||||
try {
|
||||
cache[filePath] = this._getFile(filePath, { cache: options.cache, encoding })
|
||||
.then((file: string) => {
|
||||
const compileTemplate: (file: string, options: RuntimeOptions) => TemplateSpecification|HandlebarsTemplateDelegate = (options.precompiled ? this._precompileTemplate : this._compileTemplate).bind(this);
|
||||
return compileTemplate(file, this.compilerOptions);
|
||||
});
|
||||
return await cache[filePath];
|
||||
} catch (err) {
|
||||
delete cache[filePath];
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async getTemplates (dirPath: string, options: PartialTemplateOptions = {}): Promise<HandlebarsTemplateDelegate|TemplateSpecification> {
|
||||
const cache = options.cache;
|
||||
|
||||
const filePaths = await this._getDir(dirPath, { cache });
|
||||
const templates = await Promise.all(filePaths.map(filePath => {
|
||||
return this.getTemplate(path.join(dirPath, filePath), options);
|
||||
}));
|
||||
|
||||
const hash = {};
|
||||
for (let i = 0; i < filePaths.length; i++) {
|
||||
hash[filePaths[i]] = templates[i];
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
async render (filePath: string, context: UnknownObject = {}, options: RenderOptions = {}): Promise<string> {
|
||||
const encoding = options.encoding || this.encoding;
|
||||
const [template, partials] = await Promise.all([
|
||||
this.getTemplate(filePath, { cache: options.cache, encoding }) as Promise<HandlebarsTemplateDelegate>,
|
||||
(options.partials || this.getPartials({ cache: options.cache, encoding })) as Promise<TemplateDelegateObject>,
|
||||
]);
|
||||
const helpers: HelperDelegateObject = { ...this.helpers, ...options.helpers };
|
||||
const runtimeOptions = { ...this.runtimeOptions, ...options.runtimeOptions };
|
||||
|
||||
// Add ExpressHandlebars metadata to the data channel so that it's
|
||||
// accessible within the templates and helpers, namespaced under:
|
||||
// `@exphbs.*`
|
||||
const data = {
|
||||
...options.data,
|
||||
exphbs: {
|
||||
...options,
|
||||
filePath,
|
||||
helpers,
|
||||
partials,
|
||||
runtimeOptions,
|
||||
},
|
||||
};
|
||||
|
||||
const html = this._renderTemplate(template, context, {
|
||||
...runtimeOptions,
|
||||
data,
|
||||
helpers,
|
||||
partials,
|
||||
});
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
async renderView (viewPath: string): Promise<string>;
|
||||
async renderView (viewPath: string, options: RenderViewOptions): Promise<string>;
|
||||
async renderView (viewPath: string, callback: RenderCallback): Promise<null>;
|
||||
async renderView (viewPath: string, options: RenderViewOptions, callback: RenderCallback): Promise<null>;
|
||||
async renderView (viewPath: string, options: RenderViewOptions|RenderCallback = {}, callback: RenderCallback|null = null): Promise<string|null> {
|
||||
if (typeof options === "function") {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
const context = options as UnknownObject;
|
||||
|
||||
let promise: Promise<string>|null = null;
|
||||
if (!callback) {
|
||||
promise = new Promise((resolve, reject) => {
|
||||
callback = (err, value) => { err !== null ? reject(err) : resolve(value); };
|
||||
});
|
||||
}
|
||||
|
||||
// Express provides `settings.views` which is the path to the views dir that
|
||||
// the developer set on the Express app. When this value exists, it's used
|
||||
// to compute the view's name. Layouts and Partials directories are relative
|
||||
// to `settings.view` path
|
||||
let view: string;
|
||||
const views = options.settings && options.settings.views;
|
||||
const viewsPath = this._resolveViewsPath(views, viewPath);
|
||||
if (viewsPath) {
|
||||
view = this._getTemplateName(path.relative(viewsPath, viewPath));
|
||||
this.partialsDir = this.config.partialsDir || path.join(viewsPath, "partials/");
|
||||
this.layoutsDir = this.config.layoutsDir || path.join(viewsPath, "layouts/");
|
||||
}
|
||||
|
||||
const encoding = options.encoding || this.encoding;
|
||||
|
||||
// Merge render-level and instance-level helpers together.
|
||||
const helpers = { ...this.helpers, ...options.helpers };
|
||||
|
||||
// Merge render-level and instance-level partials together.
|
||||
const partials: TemplateDelegateObject = {
|
||||
...await this.getPartials({ cache: options.cache, encoding }) as TemplateDelegateObject,
|
||||
...(options.partials || {}),
|
||||
};
|
||||
|
||||
// Pluck-out ExpressHandlebars-specific options and Handlebars-specific
|
||||
// rendering options.
|
||||
const renderOptions = {
|
||||
cache: options.cache,
|
||||
encoding,
|
||||
view,
|
||||
layout: "layout" in options ? options.layout : this.defaultLayout,
|
||||
data: options.data,
|
||||
helpers,
|
||||
partials,
|
||||
runtimeOptions: options.runtimeOptions,
|
||||
};
|
||||
|
||||
try {
|
||||
let html = await this.render(viewPath, context, renderOptions);
|
||||
const layoutPath = this._resolveLayoutPath(renderOptions.layout);
|
||||
|
||||
if (layoutPath) {
|
||||
html = await this.render(
|
||||
layoutPath,
|
||||
{ ...context, body: html },
|
||||
{ ...renderOptions, layout: undefined },
|
||||
);
|
||||
}
|
||||
callback(null, html);
|
||||
} catch (err) {
|
||||
callback(err);
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
resetCache (filePathsOrFilter?: string | string[] | ((template: string) => boolean)) {
|
||||
let filePaths: string[] = [];
|
||||
|
||||
if (typeof filePathsOrFilter === "undefined") {
|
||||
filePaths = Object.keys(this._fsCache);
|
||||
} else if (typeof filePathsOrFilter === "string") {
|
||||
filePaths = [filePathsOrFilter];
|
||||
} else if (typeof filePathsOrFilter === "function") {
|
||||
filePaths = Object.keys(this._fsCache).filter(filePathsOrFilter);
|
||||
} else if (Array.isArray(filePathsOrFilter)) {
|
||||
filePaths = filePathsOrFilter;
|
||||
}
|
||||
|
||||
for (const filePath of filePaths) {
|
||||
delete this._fsCache[filePath];
|
||||
}
|
||||
}
|
||||
|
||||
// -- Protected Hooks ----------------------------------------------------------
|
||||
|
||||
protected _compileTemplate (template: string, options: RuntimeOptions = {}): HandlebarsTemplateDelegate {
|
||||
return this.handlebars.compile(template.trim(), options);
|
||||
}
|
||||
|
||||
protected _precompileTemplate (template: string, options: RuntimeOptions = {}): TemplateSpecification {
|
||||
return this.handlebars.precompile(template.trim(), options);
|
||||
}
|
||||
|
||||
protected _renderTemplate (template: HandlebarsTemplateDelegate, context: UnknownObject = {}, options: RuntimeOptions = {}): string {
|
||||
return template(context, options).trim();
|
||||
}
|
||||
|
||||
// -- Private ------------------------------------------------------------------
|
||||
|
||||
private async _getDir (dirPath: string, options: PartialTemplateOptions = {}): Promise<string[]> {
|
||||
dirPath = path.resolve(dirPath);
|
||||
|
||||
const cache = this._fsCache;
|
||||
let dir = options.cache && (cache[dirPath] as Promise<string[]>);
|
||||
|
||||
if (dir) {
|
||||
return [...await dir];
|
||||
}
|
||||
|
||||
const pattern = "**/*" + this.extname;
|
||||
|
||||
// Optimistically cache dir promise to reduce file system I/O, but remove
|
||||
// from cache if there was a problem.
|
||||
|
||||
try {
|
||||
dir = cache[dirPath] = glob(pattern, {
|
||||
cwd: dirPath,
|
||||
follow: true,
|
||||
posix: true,
|
||||
});
|
||||
// @ts-expect-error FIXME: not sure how to throw error in glob for test coverage
|
||||
if (options._throwTestError) {
|
||||
throw new Error("test");
|
||||
}
|
||||
|
||||
return [...await dir];
|
||||
} catch (err) {
|
||||
delete cache[dirPath];
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
private async _getFile (filePath: string, options: PartialTemplateOptions = {}): Promise<string> {
|
||||
filePath = path.resolve(filePath);
|
||||
|
||||
const cache = this._fsCache;
|
||||
const encoding = options.encoding || this.encoding;
|
||||
const file = options.cache && (cache[filePath] as Promise<string>);
|
||||
|
||||
if (file) {
|
||||
return file;
|
||||
}
|
||||
|
||||
// Optimistically cache file promise to reduce file system I/O, but remove
|
||||
// from cache if there was a problem.
|
||||
try {
|
||||
cache[filePath] = readFile(filePath, { encoding: encoding || "utf8" });
|
||||
return await cache[filePath] as string;
|
||||
} catch (err) {
|
||||
delete cache[filePath];
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
private _getTemplateName (filePath: string, namespace: string = null): string {
|
||||
let name = filePath;
|
||||
|
||||
if (name.endsWith(this.extname)) {
|
||||
name = name.substring(0, name.length - this.extname.length);
|
||||
}
|
||||
|
||||
if (namespace) {
|
||||
name = namespace + "/" + name;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
private _resolveViewsPath (views: string|string[], file: string): string|null {
|
||||
if (!Array.isArray(views)) {
|
||||
return views;
|
||||
}
|
||||
|
||||
let lastDir = path.resolve(file);
|
||||
let dir = path.dirname(lastDir);
|
||||
const absoluteViews = views.map(v => path.resolve(v));
|
||||
|
||||
// find the closest parent
|
||||
while (dir !== lastDir) {
|
||||
const index = absoluteViews.indexOf(dir);
|
||||
if (index >= 0) {
|
||||
return views[index];
|
||||
}
|
||||
lastDir = dir;
|
||||
dir = path.dirname(lastDir);
|
||||
}
|
||||
|
||||
// cannot resolve view
|
||||
return null;
|
||||
}
|
||||
|
||||
private _resolveLayoutPath (layoutPath: string): string|null {
|
||||
if (!layoutPath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!path.extname(layoutPath)) {
|
||||
layoutPath += this.extname;
|
||||
}
|
||||
|
||||
return path.resolve(this.layoutsDir || "", layoutPath);
|
||||
}
|
||||
}
|
21
app/node_modules/express-handlebars/lib/index.ts
generated
vendored
Normal file
21
app/node_modules/express-handlebars/lib/index.ts
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Yahoo Inc. All rights reserved.
|
||||
* Copyrights licensed under the New BSD License.
|
||||
* See the accompanying LICENSE file for terms.
|
||||
*/
|
||||
|
||||
import ExpressHandlebars from "./express-handlebars";
|
||||
import type {
|
||||
ConfigOptions,
|
||||
Engine,
|
||||
} from "../types";
|
||||
|
||||
export { ExpressHandlebars };
|
||||
|
||||
export function create (config: ConfigOptions = {}): ExpressHandlebars {
|
||||
return new ExpressHandlebars(config);
|
||||
}
|
||||
|
||||
export function engine (config: ConfigOptions = {}): Engine {
|
||||
return create(config).engine;
|
||||
}
|
Reference in New Issue
Block a user