Files
2023-11-24 22:35:41 +01:00

142 lines
5.1 KiB
JavaScript

"use strict";
/*
* edge-supercharged
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Supercharged = void 0;
const slash_1 = __importDefault(require("slash"));
const path_1 = require("path");
const helpers_1 = require("@poppinss/utils/build/helpers");
/**
* Allows registering components path with an easy to use name
*/
class Supercharged {
constructor() {
/**
* List of registered components
*/
this.components = {};
/**
* Plugin fn for edge
*/
this.wire = (edge, firstRun) => {
/**
* Reset components on each run. The "discoverComponents"
* calls will collect them
*/
this.components = {};
Object.keys(edge.loader.mounted).forEach((diskName) => {
if (diskName === 'default') {
this.discoverComponents(edge.loader.mounted[diskName]);
}
else {
this.discoverComponents(edge.loader.mounted[diskName], {
prefix: diskName,
diskName: diskName,
});
}
});
/**
* Do not re-run the following code when it is a recurring
* run
*/
if (!firstRun) {
return;
}
/**
* Claim tags registered with supercharged
*/
edge.compiler.claimTag((name) => {
if (this.components[name]) {
return { seekable: true, block: true };
}
return null;
});
edge.asyncCompiler.claimTag((name) => {
if (this.components[name]) {
return { seekable: true, block: true };
}
return null;
});
/**
* Process tags
*/
edge.processor.process('tag', ({ tag }) => {
const component = this.components[tag.properties.name];
if (!component) {
return;
}
tag.properties.name = 'component';
if (tag.properties.jsArg.trim() === '') {
tag.properties.jsArg = `'${component.path}'`;
}
else {
tag.properties.jsArg = `'${component.path}',${tag.properties.jsArg}`;
}
});
};
}
/**
* Register a component
*/
registerComponent(name, path) {
this.components[name] = { path };
return this;
}
/**
* Discover components from a given directory
*/
discoverComponents(basePath, options = {}) {
const components = helpers_1.fsReadAll(path_1.join(basePath, 'components'), (file) => file.endsWith('.edge'));
options.prefix = options.prefix ? options.prefix : options.diskName;
components.forEach((file) => {
file = slash_1.default(file);
const name = file
.replace(/\.edge$/, '') // Drop extension
.split('/') // Split path
.map((segment) => helpers_1.string.camelCase(segment)) // Convert each segment to camelCase
.join('.'); // Join by .
/**
* Add prefix to name when defined
*/
const prefixedName = options.prefix ? `${options.prefix}.${name}` : name;
/**
* Do not normalize the path here. Edge wants unix style paths
*/
const componentPath = `${options.diskName ? `${options.diskName}::` : ''}components/${file}`;
/**
* Register the component
*/
this.registerComponent(prefixedName, componentPath);
/**
* Register components with `.index` with the parent name. Doing this can also
* run into race conditions as described below
*
* - There is a file called `components/modal.edge`
* - Then there is a file called `components/modal/index.edge`
* - The file discovered later will win over the file discovered first.
*
* So is this a bad practice?? Not really. Coz someone creating directory structure
* like this themselves opting into the confusion of which component they are
* intending to use.
*
* Infact this race condition will force them to re-think the directory structure. Something
* they should
*/
if (name.endsWith('.index')) {
this.registerComponent(prefixedName.replace(/\.index$/, ''), componentPath);
}
});
return this;
}
}
exports.Supercharged = Supercharged;