test-project-host.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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.dev/license
  8. */
  9. Object.defineProperty(exports, "__esModule", { value: true });
  10. exports.TestProjectHost = void 0;
  11. const core_1 = require("@angular-devkit/core");
  12. const node_1 = require("@angular-devkit/core/node");
  13. const rxjs_1 = require("rxjs");
  14. /**
  15. * @deprecated
  16. */
  17. class TestProjectHost extends node_1.NodeJsSyncHost {
  18. _templateRoot;
  19. _currentRoot = null;
  20. _scopedSyncHost = null;
  21. constructor(_templateRoot) {
  22. super();
  23. this._templateRoot = _templateRoot;
  24. }
  25. root() {
  26. if (this._currentRoot === null) {
  27. throw new Error('TestProjectHost must be initialized before being used.');
  28. }
  29. return this._currentRoot;
  30. }
  31. scopedSync() {
  32. if (this._currentRoot === null || this._scopedSyncHost === null) {
  33. throw new Error('TestProjectHost must be initialized before being used.');
  34. }
  35. return this._scopedSyncHost;
  36. }
  37. initialize() {
  38. const recursiveList = (path) => this.list(path).pipe(
  39. // Emit each fragment individually.
  40. (0, rxjs_1.concatMap)((fragments) => (0, rxjs_1.from)(fragments)),
  41. // Join the path with fragment.
  42. (0, rxjs_1.map)((fragment) => (0, core_1.join)(path, fragment)),
  43. // Emit directory content paths instead of the directory path.
  44. (0, rxjs_1.mergeMap)((path) => this.isDirectory(path).pipe((0, rxjs_1.concatMap)((isDir) => (isDir ? recursiveList(path) : (0, rxjs_1.of)(path))))));
  45. // Find a unique folder that we can write to use as current root.
  46. return this.findUniqueFolderPath().pipe(
  47. // Save the path and create a scoped host for it.
  48. (0, rxjs_1.tap)((newFolderPath) => {
  49. this._currentRoot = newFolderPath;
  50. this._scopedSyncHost = new core_1.virtualFs.SyncDelegateHost(new core_1.virtualFs.ScopedHost(this, this.root()));
  51. }),
  52. // List all files in root.
  53. (0, rxjs_1.concatMap)(() => recursiveList(this._templateRoot)),
  54. // Copy them over to the current root.
  55. (0, rxjs_1.concatMap)((from) => {
  56. const to = (0, core_1.join)(this.root(), (0, core_1.relative)(this._templateRoot, from));
  57. return this.read(from).pipe((0, rxjs_1.concatMap)((buffer) => this.write(to, buffer)));
  58. }), (0, rxjs_1.map)(() => { }));
  59. }
  60. restore() {
  61. if (this._currentRoot === null) {
  62. return rxjs_1.EMPTY;
  63. }
  64. // Delete the current root and clear the variables.
  65. // Wait 50ms and retry up to 10 times, to give time for file locks to clear.
  66. return this.exists(this.root()).pipe((0, rxjs_1.delay)(50), (0, rxjs_1.concatMap)((exists) => (exists ? this.delete(this.root()) : rxjs_1.EMPTY)), (0, rxjs_1.retry)(10), (0, rxjs_1.finalize)(() => {
  67. this._currentRoot = null;
  68. this._scopedSyncHost = null;
  69. }));
  70. }
  71. writeMultipleFiles(files) {
  72. Object.keys(files).forEach((fileName) => {
  73. let content = files[fileName];
  74. if (typeof content == 'string') {
  75. content = core_1.virtualFs.stringToFileBuffer(content);
  76. }
  77. else if (content instanceof Buffer) {
  78. content = content.buffer.slice(content.byteOffset, content.byteOffset + content.byteLength);
  79. }
  80. this.scopedSync().write((0, core_1.normalize)(fileName), content);
  81. });
  82. }
  83. replaceInFile(path, match, replacement) {
  84. const content = core_1.virtualFs.fileBufferToString(this.scopedSync().read((0, core_1.normalize)(path)));
  85. this.scopedSync().write((0, core_1.normalize)(path), core_1.virtualFs.stringToFileBuffer(content.replace(match, replacement)));
  86. }
  87. appendToFile(path, str) {
  88. const content = core_1.virtualFs.fileBufferToString(this.scopedSync().read((0, core_1.normalize)(path)));
  89. this.scopedSync().write((0, core_1.normalize)(path), core_1.virtualFs.stringToFileBuffer(content.concat(str)));
  90. }
  91. fileMatchExists(dir, regex) {
  92. const [fileName] = this.scopedSync()
  93. .list((0, core_1.normalize)(dir))
  94. .filter((name) => name.match(regex));
  95. return fileName || undefined;
  96. }
  97. copyFile(from, to) {
  98. const content = this.scopedSync().read((0, core_1.normalize)(from));
  99. this.scopedSync().write((0, core_1.normalize)(to), content);
  100. }
  101. findUniqueFolderPath() {
  102. // 11 character alphanumeric string.
  103. const randomString = Math.random().toString(36).slice(2);
  104. const newFolderName = `test-project-host-${(0, core_1.basename)(this._templateRoot)}-${randomString}`;
  105. const newFolderPath = (0, core_1.join)((0, core_1.dirname)(this._templateRoot), newFolderName);
  106. return this.exists(newFolderPath).pipe((0, rxjs_1.concatMap)((exists) => (exists ? this.findUniqueFolderPath() : (0, rxjs_1.of)(newFolderPath))));
  107. }
  108. }
  109. exports.TestProjectHost = TestProjectHost;