UNPKG

pcf-scripts

Version:

This package contains a module for building PowerApps Component Framework (PCF) controls. See project homepage how to install.

144 lines (142 loc) 5.83 kB
"use strict"; // Copyright (C) Microsoft Corporation. All rights reserved. Object.defineProperty(exports, "__esModule", { value: true }); exports.PCFFileWatcher = void 0; const chokidar = require("chokidar"); const path = require("path"); const constants = require("./constants"); const designTypesTask_1 = require("./tasks/designTypesTask"); const manifestTypesTask_1 = require("./tasks/manifestTypesTask"); const outputTask_1 = require("./tasks/outputTask"); const validateTask_1 = require("./tasks/validateTask"); class PCFFileWatcher { constructor() { this._isReady = false; this._errorsExist = false; } // Returning promise is resolved only when watcher is ready. Mainly needed for testing purposes. async start(context, watchBehavior) { try { const pathsToWatchArr = await this.getUpdatedPathsToWatch(context); const pathsToWatch = pathsToWatchArr[0]; return new Promise((resolve, _reject) => { this._watcher = chokidar .watch(pathsToWatch, { awaitWriteFinish: { stabilityThreshold: 2000, pollInterval: 100, }, }) .on("ready", () => { this._isReady = true; return resolve("Watch is now ready"); }) .on("change", (filePath) => { if (!this._isReady) { return; } if (watchBehavior) { watchBehavior(context); } else { this.processFileChange(filePath, context).catch(() => context.getDiagnostic().flush(true)); } }); }); } catch { context.getDiagnostic().flush(true); return Promise.reject(new Error()); } } async getUpdatedPathsToWatch(context) { const pathsToWatch = []; return context.mapControls((control) => { const manifestPath = path.resolve(control.getControlPath(), constants.MANIFEST_INPUT_FILE_NAME); pathsToWatch.push(manifestPath); const resourcePaths = control.getControlManifest().getResources(true); for (const resourcePath of resourcePaths) { pathsToWatch.push(path.resolve(control.getControlPath(), resourcePath)); } return Promise.resolve(pathsToWatch); }); } async processFileChange(filePath, context) { if (filePath.includes(constants.INDEX_FILE_NAME)) { if (this._errorsExist) { return Promise.reject(new Error()); } return Promise.resolve(); } else if (filePath.includes(constants.MANIFEST_INPUT_FILE_NAME)) { return this.recompileWatchedFiles(context) .then(() => { this._errorsExist = false; // eslint-disable-next-line promise/no-return-wrap return Promise.resolve(); }) .catch(() => { this._errorsExist = true; // eslint-disable-next-line promise/no-return-wrap return Promise.reject(new Error()); }); } else { const createOutputTask = new outputTask_1.CreateOutputTask(); return createOutputTask.run(context).catch(() => { this._errorsExist = true; // eslint-disable-next-line promise/no-return-wrap return Promise.reject(new Error()); }); } } async recompileWatchedFiles(context) { const diag = context.getDiagnostic(); context.getDiagnostic().clear(); return context .mapControls((control) => { return Promise.resolve(control.reloadManifest(diag)); }) .then(async () => { const validateManifestTask = new validateTask_1.ValidateManifestTask(); const generateManifestTypesTask = new manifestTypesTask_1.GenerateManifestTypesTask(); const generateDesignTypesTask = new designTypesTask_1.GenerateDesignTypesTask(); const createOutputTask = new outputTask_1.CreateOutputTask(); await validateManifestTask.run(context); await generateManifestTypesTask.run(context); await generateDesignTypesTask.run(context); await createOutputTask.run(context); await this.updateWatchedPaths(context); }); } async updateWatchedPaths(context) { const oldWatchedPaths = this.getPreviousPathsToWatch(); const newWatchedPathsArr = await this.getUpdatedPathsToWatch(context); const newWatchedPaths = newWatchedPathsArr[0]; const unwatchPaths = []; oldWatchedPaths.forEach((watchedPath) => { if (!newWatchedPaths.includes(watchedPath)) { unwatchPaths.push(watchedPath); } }); this._watcher?.unwatch(unwatchPaths); this._watcher?.add(newWatchedPaths); return Promise.resolve(); } stop() { if (!this._watcher) { return; } void this._watcher.close(); } getPreviousPathsToWatch() { const watchedPathsObject = this._watcher?.getWatched(); if (!watchedPathsObject) { return []; } const watchedPaths = Object.entries(watchedPathsObject).flatMap(([directoryPath, pathsArr]) => pathsArr.map((filePath) => path.join(directoryPath, filePath))); return watchedPaths; } } exports.PCFFileWatcher = PCFFileWatcher; //# sourceMappingURL=pcfFileWatcher.js.map