UNPKG

@oasisdigital/ng-doc-portal-plugin

Version:

Nx plugin for adding the ng-doc-portal system to your nx workspace

186 lines 8.55 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DocPageLoadersCompiler = void 0; const tslib_1 = require("tslib"); const devkit_1 = require("@nx/devkit"); const chalk_1 = require("chalk"); const chokidar_1 = require("chokidar"); const fast_glob_1 = require("fast-glob"); const rxjs_1 = require("rxjs"); const util_1 = require("./util"); const fs_1 = require("fs"); class DocPageLoadersCompiler { constructor(configFileLocation, docPageLoadersFileLocation, silenced = false) { this.configFileLocation = configFileLocation; this.docPageLoadersFileLocation = docPageLoadersFileLocation; this.silenced = silenced; if (!(0, fs_1.existsSync)(this.configFileLocation)) { throw new Error(`Could not find config file at ${this.configFileLocation}`); } const config = (0, devkit_1.readJsonFile)(this.configFileLocation); let patterns = config.globPatterns; if (!patterns && config.globPattern) { patterns = [config.globPattern]; } if (!patterns) { throw new Error('No glob patterns detected in configuration file'); } this.globPatterns = patterns; } runOnce() { return tslib_1.__awaiter(this, void 0, void 0, function* () { const initialFileEvent = this.buildInitialFileEvent(); const handledFileEvents = this.handleFileEvents(initialFileEvent); return yield (0, rxjs_1.firstValueFrom)(handledFileEvents); }); } watch() { const fileEvents = (0, rxjs_1.concat)(this.buildInitialFileEvent(), this.buildWatcher()); const handledFileEvents = this.handleFileEvents(fileEvents).pipe((0, rxjs_1.shareReplay)(1)); handledFileEvents.pipe((0, rxjs_1.take)(1)).subscribe(() => { console.log((0, chalk_1.blue)('Watching doc-portal files for changes...\n')); }); return handledFileEvents; } handleFileEvents(obs) { return obs.pipe((0, rxjs_1.concatMap)((event) => this.addPayloadToEvent(event)), (0, rxjs_1.filter)((fileEvent) => !!fileEvent), (0, rxjs_1.scan)(util_1.accumulatePayloads, new Array()), (0, rxjs_1.debounceTime)(500), (0, rxjs_1.map)((payloads) => this.detectAndHandleDuplicateTitles(payloads)), (0, rxjs_1.map)((eventPayloads) => eventPayloads.map((eventPayload) => (0, util_1.generateDocPageLoader)(eventPayload.filePath, eventPayload.title))), (0, rxjs_1.map)(util_1.wrapTypescriptBoilerplate), (0, rxjs_1.switchMap)((content) => (0, util_1.formatContent)(content)), (0, rxjs_1.switchMap)((content) => this.writeDynamicPageContentToFile(content))); } /** * Build an Observable that emits the initial list of file paths. * @private */ buildInitialFileEvent() { this.log((0, chalk_1.blue)('Searching for component document page files...')); const startTime = Date.now(); const patternStrings = (0, util_1.convertPatternOrGlobPatternArray)(this.globPatterns); return (0, rxjs_1.from)((0, fast_glob_1.glob)(patternStrings, { unique: true, dot: true, onlyFiles: true, ignore: ['node_modules'], })).pipe((0, rxjs_1.map)((filePaths) => ({ type: 'init', filePaths })), (0, rxjs_1.tap)(() => { const endTime = Date.now(); this.log((0, chalk_1.green)(`Searching complete in ${endTime - startTime}ms\n`)); })); } /** * Generate an Observable of the raw file events. * @private */ buildWatcher() { return new rxjs_1.Observable((observer) => { const patternStrings = (0, util_1.convertPatternOrGlobPatternArray)(this.globPatterns); const watcher = (0, chokidar_1.watch)(patternStrings, { ignored: 'node_modules', ignoreInitial: true, }).on('all', (event, rawFilePath) => tslib_1.__awaiter(this, void 0, void 0, function* () { observer.next(this.buildRawFileEvent(rawFilePath, event)); })); return () => { watcher.unwatch(patternStrings); watcher.close(); }; }); } /** * Create the RawFileEvent from the chokidar event. * * @param rawFilePath The file that was modified * @param event The type of chokidar change * @private */ buildRawFileEvent(rawFilePath, event) { const filePath = rawFilePath.replace(/\\/g, '/'); if (event === 'add' || event === 'addDir') { this.log((0, chalk_1.green)(`${(0, util_1.timeNow)()} - ADDED - ${filePath}`)); return { type: 'add', filePath }; } else if (event === 'unlink' || event === 'unlinkDir') { this.log((0, chalk_1.red)(`${(0, util_1.timeNow)()} - DELETED - ${filePath}`)); return { type: 'unlink', filePath }; } else { this.log((0, chalk_1.yellow)(`${(0, util_1.timeNow)()} - CHANGED - ${filePath}`)); return { type: 'change', filePath }; } } /** * Process a raw file event, adding loader string payloads. * * @param fileEvent The raw file event that describe which file(s) * is affected and what is happening. * @private */ addPayloadToEvent(fileEvent) { return tslib_1.__awaiter(this, void 0, void 0, function* () { try { if (fileEvent.type === 'init') { const payload = []; this.log((0, chalk_1.blue)('Compiling component document page files...')); const startTime = Number(new Date()); for (const filePath of fileEvent.filePaths) { const title = yield (0, util_1.extractTitleFromDocPageFile)(filePath, this.globPatterns); payload.push({ filePath, title }); } const endTime = Number(new Date()); this.log((0, chalk_1.green)(`Finished compiling component document page files in ${endTime - startTime}ms\n`)); return Object.assign(Object.assign({}, fileEvent), { payload }); } else if (fileEvent.type === 'add' || fileEvent.type === 'change') { const startTime = Date.now(); const title = yield (0, util_1.extractTitleFromDocPageFile)(fileEvent.filePath, this.globPatterns); const endTime = Date.now(); this.log((0, chalk_1.blue)(`${(0, util_1.timeNow)()} - COMPILE - recompiled in ${endTime - startTime}ms`)); return Object.assign(Object.assign({}, fileEvent), { title }); } else { return fileEvent; } } catch (error) { this.log((0, chalk_1.red)(`Unexpected error occurred while compiling...\n${error}`)); return null; } }); } detectAndHandleDuplicateTitles(eventPayloads) { let duplicatesDetected = false; const titles = {}; for (const payload of eventPayloads) { if (titles[payload.title] !== undefined) { duplicatesDetected = true; this.log((0, chalk_1.yellow)(`Duplicated title of "${payload.title}" detected in file '${payload.filePath}'`)); payload.title += ` ${++titles[payload.title]}`; } titles[payload.title] = 1; } if (duplicatesDetected) { this.log((0, chalk_1.yellow)('\nPlease resolve duplicated titles before publishing!\n')); } return eventPayloads; } /** * Generate a file to hold the loader content. * * @param content The loader content generated from our path files * @private */ writeDynamicPageContentToFile(content) { return tslib_1.__awaiter(this, void 0, void 0, function* () { try { (0, fs_1.writeFileSync)(this.docPageLoadersFileLocation, content); } catch (e) { console.error(e); this.log((0, chalk_1.red)(`\n\nUnexpected error occurred while generating doc-page-loaders.ts\n`)); } }); } log(message) { if (!this.silenced) { console.log(message); } } } exports.DocPageLoadersCompiler = DocPageLoadersCompiler; //# sourceMappingURL=doc-page-loaders-compiler.js.map