UNPKG

7.99 kBJavaScriptView Raw
1"use strict";
2/**
3 * @license
4 * Copyright Google LLC All Rights Reserved.
5 *
6 * Use of this source code is governed by an MIT-style license that can be
7 * found in the LICENSE file at https://angular.io/license
8 */
9Object.defineProperty(exports, "__esModule", { value: true });
10exports.NodeJsSyncHost = exports.NodeJsAsyncHost = void 0;
11const node_fs_1 = require("node:fs");
12const node_path_1 = require("node:path");
13const rxjs_1 = require("rxjs");
14const src_1 = require("../src");
15async function exists(path) {
16 try {
17 await node_fs_1.promises.access(path, node_fs_1.constants.F_OK);
18 return true;
19 }
20 catch {
21 return false;
22 }
23}
24// This will only be initialized if the watch() method is called.
25// Otherwise chokidar appears only in type positions, and shouldn't be referenced
26// in the JavaScript output.
27let FSWatcher;
28function loadFSWatcher() {
29 if (!FSWatcher) {
30 try {
31 FSWatcher = require('chokidar').FSWatcher;
32 }
33 catch (e) {
34 if (e.code !== 'MODULE_NOT_FOUND') {
35 throw new Error('As of angular-devkit version 8.0, the "chokidar" package ' +
36 'must be installed in order to use watch() features.');
37 }
38 throw e;
39 }
40 }
41}
42/**
43 * An implementation of the Virtual FS using Node as the background. There are two versions; one
44 * synchronous and one asynchronous.
45 */
46class NodeJsAsyncHost {
47 get capabilities() {
48 return { synchronous: false };
49 }
50 write(path, content) {
51 return (0, rxjs_1.from)(node_fs_1.promises.mkdir((0, src_1.getSystemPath)((0, src_1.dirname)(path)), { recursive: true })).pipe((0, rxjs_1.mergeMap)(() => node_fs_1.promises.writeFile((0, src_1.getSystemPath)(path), new Uint8Array(content))));
52 }
53 read(path) {
54 return (0, rxjs_1.from)(node_fs_1.promises.readFile((0, src_1.getSystemPath)(path))).pipe((0, rxjs_1.map)((buffer) => new Uint8Array(buffer).buffer));
55 }
56 delete(path) {
57 return (0, rxjs_1.from)(node_fs_1.promises.rm((0, src_1.getSystemPath)(path), { force: true, recursive: true, maxRetries: 3 }));
58 }
59 rename(from, to) {
60 return (0, rxjs_1.from)(node_fs_1.promises.rename((0, src_1.getSystemPath)(from), (0, src_1.getSystemPath)(to)));
61 }
62 list(path) {
63 return (0, rxjs_1.from)(node_fs_1.promises.readdir((0, src_1.getSystemPath)(path))).pipe((0, rxjs_1.map)((names) => names.map((name) => (0, src_1.fragment)(name))));
64 }
65 exists(path) {
66 return (0, rxjs_1.from)(exists((0, src_1.getSystemPath)(path)));
67 }
68 isDirectory(path) {
69 return this.stat(path).pipe((0, rxjs_1.map)((stat) => stat.isDirectory()));
70 }
71 isFile(path) {
72 return this.stat(path).pipe((0, rxjs_1.map)((stat) => stat.isFile()));
73 }
74 // Some hosts may not support stat.
75 stat(path) {
76 return (0, rxjs_1.from)(node_fs_1.promises.stat((0, src_1.getSystemPath)(path)));
77 }
78 // Some hosts may not support watching.
79 watch(path, _options) {
80 return new rxjs_1.Observable((obs) => {
81 loadFSWatcher();
82 const watcher = new FSWatcher({ persistent: true });
83 watcher.add((0, src_1.getSystemPath)(path));
84 watcher
85 .on('change', (path) => {
86 obs.next({
87 path: (0, src_1.normalize)(path),
88 time: new Date(),
89 type: src_1.virtualFs.HostWatchEventType.Changed,
90 });
91 })
92 .on('add', (path) => {
93 obs.next({
94 path: (0, src_1.normalize)(path),
95 time: new Date(),
96 type: src_1.virtualFs.HostWatchEventType.Created,
97 });
98 })
99 .on('unlink', (path) => {
100 obs.next({
101 path: (0, src_1.normalize)(path),
102 time: new Date(),
103 type: src_1.virtualFs.HostWatchEventType.Deleted,
104 });
105 });
106 return () => {
107 void watcher.close();
108 };
109 }).pipe((0, rxjs_1.publish)(), (0, rxjs_1.refCount)());
110 }
111}
112exports.NodeJsAsyncHost = NodeJsAsyncHost;
113/**
114 * An implementation of the Virtual FS using Node as the backend, synchronously.
115 */
116class NodeJsSyncHost {
117 get capabilities() {
118 return { synchronous: true };
119 }
120 write(path, content) {
121 return new rxjs_1.Observable((obs) => {
122 (0, node_fs_1.mkdirSync)((0, src_1.getSystemPath)((0, src_1.dirname)(path)), { recursive: true });
123 (0, node_fs_1.writeFileSync)((0, src_1.getSystemPath)(path), new Uint8Array(content));
124 obs.next();
125 obs.complete();
126 });
127 }
128 read(path) {
129 return new rxjs_1.Observable((obs) => {
130 const buffer = (0, node_fs_1.readFileSync)((0, src_1.getSystemPath)(path));
131 obs.next(new Uint8Array(buffer).buffer);
132 obs.complete();
133 });
134 }
135 delete(path) {
136 return new rxjs_1.Observable((obs) => {
137 (0, node_fs_1.rmSync)((0, src_1.getSystemPath)(path), { force: true, recursive: true, maxRetries: 3 });
138 obs.complete();
139 });
140 }
141 rename(from, to) {
142 return new rxjs_1.Observable((obs) => {
143 const toSystemPath = (0, src_1.getSystemPath)(to);
144 (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(toSystemPath), { recursive: true });
145 (0, node_fs_1.renameSync)((0, src_1.getSystemPath)(from), toSystemPath);
146 obs.next();
147 obs.complete();
148 });
149 }
150 list(path) {
151 return new rxjs_1.Observable((obs) => {
152 const names = (0, node_fs_1.readdirSync)((0, src_1.getSystemPath)(path));
153 obs.next(names.map((name) => (0, src_1.fragment)(name)));
154 obs.complete();
155 });
156 }
157 exists(path) {
158 return new rxjs_1.Observable((obs) => {
159 obs.next((0, node_fs_1.existsSync)((0, src_1.getSystemPath)(path)));
160 obs.complete();
161 });
162 }
163 isDirectory(path) {
164 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
165 return this.stat(path).pipe((0, rxjs_1.map)((stat) => stat.isDirectory()));
166 }
167 isFile(path) {
168 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
169 return this.stat(path).pipe((0, rxjs_1.map)((stat) => stat.isFile()));
170 }
171 // Some hosts may not support stat.
172 stat(path) {
173 return new rxjs_1.Observable((obs) => {
174 obs.next((0, node_fs_1.statSync)((0, src_1.getSystemPath)(path)));
175 obs.complete();
176 });
177 }
178 // Some hosts may not support watching.
179 watch(path, _options) {
180 return new rxjs_1.Observable((obs) => {
181 loadFSWatcher();
182 const watcher = new FSWatcher({ persistent: false });
183 watcher.add((0, src_1.getSystemPath)(path));
184 watcher
185 .on('change', (path) => {
186 obs.next({
187 path: (0, src_1.normalize)(path),
188 time: new Date(),
189 type: src_1.virtualFs.HostWatchEventType.Changed,
190 });
191 })
192 .on('add', (path) => {
193 obs.next({
194 path: (0, src_1.normalize)(path),
195 time: new Date(),
196 type: src_1.virtualFs.HostWatchEventType.Created,
197 });
198 })
199 .on('unlink', (path) => {
200 obs.next({
201 path: (0, src_1.normalize)(path),
202 time: new Date(),
203 type: src_1.virtualFs.HostWatchEventType.Deleted,
204 });
205 });
206 return () => {
207 void watcher.close();
208 };
209 }).pipe((0, rxjs_1.publish)(), (0, rxjs_1.refCount)());
210 }
211}
212exports.NodeJsSyncHost = NodeJsSyncHost;