Updated the files.

This commit is contained in:
Batuhan Berk Başoğlu 2024-02-08 19:38:41 -05:00
parent 1553e6b971
commit 753967d4f5
23418 changed files with 3784666 additions and 0 deletions

View file

@ -0,0 +1,49 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { BaseException, Path } from '@angular-devkit/core';
export declare class UnknownActionException extends BaseException {
constructor(action: Action);
}
export type Action = CreateFileAction | OverwriteFileAction | RenameFileAction | DeleteFileAction;
export interface ActionBase {
readonly id: number;
readonly parent: number;
readonly path: Path;
}
export declare class ActionList implements Iterable<Action> {
private _actions;
protected _action(action: Partial<Action>): void;
create(path: Path, content: Buffer): void;
overwrite(path: Path, content: Buffer): void;
rename(path: Path, to: Path): void;
delete(path: Path): void;
optimize(): void;
push(action: Action): void;
get(i: number): Action;
has(action: Action): boolean;
find(predicate: (value: Action) => boolean): Action | null;
forEach(fn: (value: Action, index: number, array: Action[]) => void, thisArg?: {}): void;
get length(): number;
[Symbol.iterator](): IterableIterator<Action>;
}
export declare function isContentAction(action: Action): action is CreateFileAction | OverwriteFileAction;
export interface CreateFileAction extends ActionBase {
readonly kind: 'c';
readonly content: Buffer;
}
export interface OverwriteFileAction extends ActionBase {
readonly kind: 'o';
readonly content: Buffer;
}
export interface RenameFileAction extends ActionBase {
readonly kind: 'r';
readonly to: Path;
}
export interface DeleteFileAction extends ActionBase {
readonly kind: 'd';
}

View file

@ -0,0 +1,137 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.isContentAction = exports.ActionList = exports.UnknownActionException = void 0;
const core_1 = require("@angular-devkit/core");
class UnknownActionException extends core_1.BaseException {
constructor(action) {
super(`Unknown action: "${action.kind}".`);
}
}
exports.UnknownActionException = UnknownActionException;
let _id = 1;
class ActionList {
_actions = [];
_action(action) {
this._actions.push({
...action,
id: _id++,
parent: this._actions[this._actions.length - 1]?.id ?? 0,
});
}
create(path, content) {
this._action({ kind: 'c', path, content });
}
overwrite(path, content) {
this._action({ kind: 'o', path, content });
}
rename(path, to) {
this._action({ kind: 'r', path, to });
}
delete(path) {
this._action({ kind: 'd', path });
}
optimize() {
const toCreate = new Map();
const toRename = new Map();
const toOverwrite = new Map();
const toDelete = new Set();
for (const action of this._actions) {
switch (action.kind) {
case 'c':
toCreate.set(action.path, action.content);
break;
case 'o':
if (toCreate.has(action.path)) {
toCreate.set(action.path, action.content);
}
else {
toOverwrite.set(action.path, action.content);
}
break;
case 'd':
toDelete.add(action.path);
break;
case 'r':
const maybeCreate = toCreate.get(action.path);
const maybeOverwrite = toOverwrite.get(action.path);
if (maybeCreate) {
toCreate.delete(action.path);
toCreate.set(action.to, maybeCreate);
}
if (maybeOverwrite) {
toOverwrite.delete(action.path);
toOverwrite.set(action.to, maybeOverwrite);
}
let maybeRename = undefined;
for (const [from, to] of toRename.entries()) {
if (to == action.path) {
maybeRename = from;
break;
}
}
if (maybeRename) {
toRename.set(maybeRename, action.to);
}
if (!maybeCreate && !maybeOverwrite && !maybeRename) {
toRename.set(action.path, action.to);
}
break;
}
}
this._actions = [];
toDelete.forEach((x) => {
this.delete(x);
});
toRename.forEach((to, from) => {
this.rename(from, to);
});
toCreate.forEach((content, path) => {
this.create(path, content);
});
toOverwrite.forEach((content, path) => {
this.overwrite(path, content);
});
}
push(action) {
this._actions.push(action);
}
get(i) {
return this._actions[i];
}
has(action) {
for (let i = 0; i < this._actions.length; i++) {
const a = this._actions[i];
if (a.id == action.id) {
return true;
}
if (a.id > action.id) {
return false;
}
}
return false;
}
find(predicate) {
return this._actions.find(predicate) || null;
}
forEach(fn, thisArg) {
this._actions.forEach(fn, thisArg);
}
get length() {
return this._actions.length;
}
[Symbol.iterator]() {
return this._actions[Symbol.iterator]();
}
}
exports.ActionList = ActionList;
function isContentAction(action) {
return action.kind == 'c' || action.kind == 'o';
}
exports.isContentAction = isContentAction;

View file

@ -0,0 +1,32 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { JsonValue } from '@angular-devkit/core';
import { Action } from './action';
import { DirEntry, FileEntry, FileVisitor, MergeStrategy, Tree, UpdateRecorder } from './interface';
export declare class DelegateTree implements Tree {
protected _other: Tree;
constructor(_other: Tree);
branch(): Tree;
merge(other: Tree, strategy?: MergeStrategy): void;
get root(): DirEntry;
read(path: string): Buffer | null;
readText(path: string): string;
readJson(path: string): JsonValue;
exists(path: string): boolean;
get(path: string): FileEntry | null;
getDir(path: string): DirEntry;
visit(visitor: FileVisitor): void;
overwrite(path: string, content: Buffer | string): void;
beginUpdate(path: string): UpdateRecorder;
commitUpdate(record: UpdateRecorder): void;
create(path: string, content: Buffer | string): void;
delete(path: string): void;
rename(from: string, to: string): void;
apply(action: Action, strategy?: MergeStrategy): void;
get actions(): Action[];
}

View file

@ -0,0 +1,78 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.DelegateTree = void 0;
const interface_1 = require("./interface");
class DelegateTree {
_other;
constructor(_other) {
this._other = _other;
}
branch() {
return this._other.branch();
}
merge(other, strategy) {
this._other.merge(other, strategy);
}
get root() {
return this._other.root;
}
// Readonly.
read(path) {
return this._other.read(path);
}
readText(path) {
return this._other.readText(path);
}
readJson(path) {
return this._other.readJson(path);
}
exists(path) {
return this._other.exists(path);
}
get(path) {
return this._other.get(path);
}
getDir(path) {
return this._other.getDir(path);
}
visit(visitor) {
return this._other.visit(visitor);
}
// Change content of host files.
overwrite(path, content) {
return this._other.overwrite(path, content);
}
beginUpdate(path) {
return this._other.beginUpdate(path);
}
commitUpdate(record) {
return this._other.commitUpdate(record);
}
// Structural methods.
create(path, content) {
return this._other.create(path, content);
}
delete(path) {
return this._other.delete(path);
}
rename(from, to) {
return this._other.rename(from, to);
}
apply(action, strategy) {
return this._other.apply(action, strategy);
}
get actions() {
return this._other.actions;
}
[interface_1.TreeSymbol]() {
return this;
}
}
exports.DelegateTree = DelegateTree;

View file

@ -0,0 +1,11 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { HostTree } from './host-tree';
export declare class EmptyTree extends HostTree {
constructor();
}

View file

@ -0,0 +1,17 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.EmptyTree = void 0;
const host_tree_1 = require("./host-tree");
class EmptyTree extends host_tree_1.HostTree {
constructor() {
super();
}
}
exports.EmptyTree = EmptyTree;

View file

@ -0,0 +1,24 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { Path } from '@angular-devkit/core';
import { FileEntry } from './interface';
export declare class SimpleFileEntry implements FileEntry {
private _path;
private _content;
constructor(_path: Path, _content: Buffer);
get path(): Path;
get content(): Buffer;
}
export declare class LazyFileEntry implements FileEntry {
private _path;
private _load;
private _content;
constructor(_path: Path, _load: (path?: Path) => Buffer);
get path(): Path;
get content(): Buffer;
}

View file

@ -0,0 +1,41 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.LazyFileEntry = exports.SimpleFileEntry = void 0;
class SimpleFileEntry {
_path;
_content;
constructor(_path, _content) {
this._path = _path;
this._content = _content;
}
get path() {
return this._path;
}
get content() {
return this._content;
}
}
exports.SimpleFileEntry = SimpleFileEntry;
class LazyFileEntry {
_path;
_load;
_content = null;
constructor(_path, _load) {
this._path = _path;
this._load = _load;
}
get path() {
return this._path;
}
get content() {
return this._content || (this._content = this._load(this._path));
}
}
exports.LazyFileEntry = LazyFileEntry;

View file

@ -0,0 +1,64 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { JsonValue, Path, PathFragment, virtualFs } from '@angular-devkit/core';
import { Action } from './action';
import { DirEntry, FileEntry, FilePredicate, FileVisitor, MergeStrategy, Tree, UpdateRecorder } from './interface';
export declare class HostDirEntry implements DirEntry {
readonly parent: DirEntry | null;
readonly path: Path;
protected _host: virtualFs.SyncDelegateHost;
protected _tree: Tree;
constructor(parent: DirEntry | null, path: Path, _host: virtualFs.SyncDelegateHost, _tree: Tree);
get subdirs(): PathFragment[];
get subfiles(): PathFragment[];
dir(name: PathFragment): DirEntry;
file(name: PathFragment): FileEntry | null;
visit(visitor: FileVisitor): void;
private getSubfilesRecursively;
}
export declare class HostTree implements Tree {
protected _backend: virtualFs.ReadonlyHost<{}>;
private readonly _id;
private _record;
private _recordSync;
private _ancestry;
private _dirCache;
static isHostTree(tree: Tree): tree is HostTree;
constructor(_backend?: virtualFs.ReadonlyHost<{}>);
protected _normalizePath(path: string): Path;
protected _willCreate(path: Path): boolean;
protected _willOverwrite(path: Path): boolean;
protected _willDelete(path: Path): boolean;
protected _willRename(path: Path): boolean;
branch(): Tree;
private isAncestorOf;
merge(other: Tree, strategy?: MergeStrategy): void;
get root(): DirEntry;
read(path: string): Buffer | null;
readText(path: string): string;
readJson(path: string): JsonValue;
exists(path: string): boolean;
get(path: string): FileEntry | null;
getDir(path: string): DirEntry;
visit(visitor: FileVisitor): void;
overwrite(path: string, content: Buffer | string): void;
beginUpdate(path: string): UpdateRecorder;
commitUpdate(record: UpdateRecorder): void;
create(path: string, content: Buffer | string): void;
delete(path: string): void;
rename(from: string, to: string): void;
apply(action: Action, strategy?: MergeStrategy): void;
private generateActions;
get actions(): Action[];
}
export declare class HostCreateTree extends HostTree {
constructor(host: virtualFs.ReadonlyHost);
}
export declare class FilterHostTree extends HostTree {
constructor(tree: HostTree, filter?: FilePredicate<boolean>);
}

View file

@ -0,0 +1,442 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.FilterHostTree = exports.HostCreateTree = exports.HostTree = exports.HostDirEntry = void 0;
const core_1 = require("@angular-devkit/core");
const jsonc_parser_1 = require("jsonc-parser");
const rxjs_1 = require("rxjs");
const util_1 = require("util");
const exception_1 = require("../exception/exception");
const delegate_1 = require("./delegate");
const entry_1 = require("./entry");
const interface_1 = require("./interface");
const recorder_1 = require("./recorder");
const scoped_1 = require("./scoped");
let _uniqueId = 0;
class HostDirEntry {
parent;
path;
_host;
_tree;
constructor(parent, path, _host, _tree) {
this.parent = parent;
this.path = path;
this._host = _host;
this._tree = _tree;
}
get subdirs() {
return this._host
.list(this.path)
.filter((fragment) => this._host.isDirectory((0, core_1.join)(this.path, fragment)));
}
get subfiles() {
return this._host
.list(this.path)
.filter((fragment) => this._host.isFile((0, core_1.join)(this.path, fragment)));
}
dir(name) {
return this._tree.getDir((0, core_1.join)(this.path, name));
}
file(name) {
return this._tree.get((0, core_1.join)(this.path, name));
}
visit(visitor) {
try {
this.getSubfilesRecursively().forEach((file) => visitor(file.path, file));
}
catch (e) {
if (e !== interface_1.FileVisitorCancelToken) {
throw e;
}
}
}
getSubfilesRecursively() {
function _recurse(entry) {
return entry.subdirs.reduce((files, subdir) => [...files, ..._recurse(entry.dir(subdir))], entry.subfiles.map((subfile) => entry.file(subfile)));
}
return _recurse(this);
}
}
exports.HostDirEntry = HostDirEntry;
class HostTree {
_backend;
_id = --_uniqueId;
_record;
_recordSync;
_ancestry = new Set();
_dirCache = new Map();
[interface_1.TreeSymbol]() {
return this;
}
static isHostTree(tree) {
if (tree instanceof HostTree) {
return true;
}
if (typeof tree === 'object' && typeof tree._ancestry === 'object') {
return true;
}
return false;
}
constructor(_backend = new core_1.virtualFs.Empty()) {
this._backend = _backend;
this._record = new core_1.virtualFs.CordHost(new core_1.virtualFs.SafeReadonlyHost(_backend));
this._recordSync = new core_1.virtualFs.SyncDelegateHost(this._record);
}
_normalizePath(path) {
return (0, core_1.normalize)('/' + path);
}
_willCreate(path) {
return this._record.willCreate(path);
}
_willOverwrite(path) {
return this._record.willOverwrite(path);
}
_willDelete(path) {
return this._record.willDelete(path);
}
_willRename(path) {
return this._record.willRename(path);
}
branch() {
const branchedTree = new HostTree(this._backend);
branchedTree._record = this._record.clone();
branchedTree._recordSync = new core_1.virtualFs.SyncDelegateHost(branchedTree._record);
branchedTree._ancestry = new Set(this._ancestry).add(this._id);
return branchedTree;
}
isAncestorOf(tree) {
if (tree instanceof HostTree) {
return tree._ancestry.has(this._id);
}
if (tree instanceof delegate_1.DelegateTree) {
return this.isAncestorOf(tree._other);
}
if (tree instanceof scoped_1.ScopedTree) {
return this.isAncestorOf(tree._base);
}
return false;
}
merge(other, strategy = interface_1.MergeStrategy.Default) {
if (other === this) {
// Merging with yourself? Tsk tsk. Nothing to do at least.
return;
}
if (this.isAncestorOf(other)) {
// Workaround for merging a branch back into one of its ancestors
// More complete branch point tracking is required to avoid
strategy |= interface_1.MergeStrategy.Overwrite;
}
const creationConflictAllowed = (strategy & interface_1.MergeStrategy.AllowCreationConflict) == interface_1.MergeStrategy.AllowCreationConflict;
const overwriteConflictAllowed = (strategy & interface_1.MergeStrategy.AllowOverwriteConflict) == interface_1.MergeStrategy.AllowOverwriteConflict;
const deleteConflictAllowed = (strategy & interface_1.MergeStrategy.AllowDeleteConflict) == interface_1.MergeStrategy.AllowDeleteConflict;
other.actions.forEach((action) => {
switch (action.kind) {
case 'c': {
const { path, content } = action;
if (this._willCreate(path) || this._willOverwrite(path) || this.exists(path)) {
const existingContent = this.read(path);
if (existingContent && content.equals(existingContent)) {
// Identical outcome; no action required
return;
}
if (!creationConflictAllowed) {
throw new exception_1.MergeConflictException(path);
}
this._record.overwrite(path, content).subscribe();
}
else {
this._record.create(path, content).subscribe();
}
return;
}
case 'o': {
const { path, content } = action;
if (this._willDelete(path) && !overwriteConflictAllowed) {
throw new exception_1.MergeConflictException(path);
}
// Ignore if content is the same (considered the same change).
if (this._willOverwrite(path)) {
const existingContent = this.read(path);
if (existingContent && content.equals(existingContent)) {
// Identical outcome; no action required
return;
}
if (!overwriteConflictAllowed) {
throw new exception_1.MergeConflictException(path);
}
}
// We use write here as merge validation has already been done, and we want to let
// the CordHost do its job.
this._record.write(path, content).subscribe();
return;
}
case 'r': {
const { path, to } = action;
if (this._willDelete(path)) {
throw new exception_1.MergeConflictException(path);
}
if (this._willRename(path)) {
if (this._record.willRenameTo(path, to)) {
// Identical outcome; no action required
return;
}
// No override possible for renaming.
throw new exception_1.MergeConflictException(path);
}
this.rename(path, to);
return;
}
case 'd': {
const { path } = action;
if (this._willDelete(path)) {
// TODO: This should technically check the content (e.g., hash on delete)
// Identical outcome; no action required
return;
}
if (!this.exists(path) && !deleteConflictAllowed) {
throw new exception_1.MergeConflictException(path);
}
this._recordSync.delete(path);
return;
}
}
});
}
get root() {
return this.getDir('/');
}
// Readonly.
read(path) {
const entry = this.get(path);
return entry ? entry.content : null;
}
readText(path) {
const data = this.read(path);
if (data === null) {
throw new exception_1.FileDoesNotExistException(path);
}
const decoder = new util_1.TextDecoder('utf-8', { fatal: true });
try {
// With the `fatal` option enabled, invalid data will throw a TypeError
return decoder.decode(data);
}
catch (e) {
if (e instanceof TypeError) {
throw new Error(`Failed to decode "${path}" as UTF-8 text.`);
}
throw e;
}
}
readJson(path) {
const content = this.readText(path);
const errors = [];
const result = (0, jsonc_parser_1.parse)(content, errors, { allowTrailingComma: true });
// If there is a parse error throw with the error information
if (errors[0]) {
const { error, offset } = errors[0];
throw new Error(`Failed to parse "${path}" as JSON. ${(0, jsonc_parser_1.printParseErrorCode)(error)} at offset: ${offset}.`);
}
return result;
}
exists(path) {
return this._recordSync.isFile(this._normalizePath(path));
}
get(path) {
const p = this._normalizePath(path);
if (this._recordSync.isDirectory(p)) {
throw new core_1.PathIsDirectoryException(p);
}
if (!this._recordSync.exists(p)) {
return null;
}
return new entry_1.LazyFileEntry(p, () => Buffer.from(this._recordSync.read(p)));
}
getDir(path) {
const p = this._normalizePath(path);
if (this._recordSync.isFile(p)) {
throw new core_1.PathIsFileException(p);
}
let maybeCache = this._dirCache.get(p);
if (!maybeCache) {
let parent = (0, core_1.dirname)(p);
if (p === parent) {
parent = null;
}
maybeCache = new HostDirEntry(parent && this.getDir(parent), p, this._recordSync, this);
this._dirCache.set(p, maybeCache);
}
return maybeCache;
}
visit(visitor) {
this.root.visit((path, entry) => {
visitor(path, entry);
});
}
// Change content of host files.
overwrite(path, content) {
const p = this._normalizePath(path);
if (!this._recordSync.exists(p)) {
throw new exception_1.FileDoesNotExistException(p);
}
const c = typeof content == 'string' ? Buffer.from(content) : content;
this._record.overwrite(p, c).subscribe();
}
beginUpdate(path) {
const entry = this.get(path);
if (!entry) {
throw new exception_1.FileDoesNotExistException(path);
}
return recorder_1.UpdateRecorderBase.createFromFileEntry(entry);
}
commitUpdate(record) {
if (record instanceof recorder_1.UpdateRecorderBase) {
const path = record.path;
const entry = this.get(path);
if (!entry) {
throw new exception_1.ContentHasMutatedException(path);
}
else {
const newContent = record.apply(entry.content);
if (!newContent.equals(entry.content)) {
this.overwrite(path, newContent);
}
}
}
else {
throw new exception_1.InvalidUpdateRecordException();
}
}
// Structural methods.
create(path, content) {
const p = this._normalizePath(path);
if (this._recordSync.exists(p)) {
throw new exception_1.FileAlreadyExistException(p);
}
const c = typeof content == 'string' ? Buffer.from(content) : content;
this._record.create(p, c).subscribe();
}
delete(path) {
this._recordSync.delete(this._normalizePath(path));
}
rename(from, to) {
this._recordSync.rename(this._normalizePath(from), this._normalizePath(to));
}
apply(action, strategy) {
throw new exception_1.SchematicsException('Apply not implemented on host trees.');
}
*generateActions() {
for (const record of this._record.records()) {
switch (record.kind) {
case 'create':
yield {
id: this._id,
parent: 0,
kind: 'c',
path: record.path,
content: Buffer.from(record.content),
};
break;
case 'overwrite':
yield {
id: this._id,
parent: 0,
kind: 'o',
path: record.path,
content: Buffer.from(record.content),
};
break;
case 'rename':
yield {
id: this._id,
parent: 0,
kind: 'r',
path: record.from,
to: record.to,
};
break;
case 'delete':
yield {
id: this._id,
parent: 0,
kind: 'd',
path: record.path,
};
break;
}
}
}
get actions() {
// Create a list of all records until we hit our original backend. This is to support branches
// that diverge from each others.
return Array.from(this.generateActions());
}
}
exports.HostTree = HostTree;
class HostCreateTree extends HostTree {
constructor(host) {
super();
const tempHost = new HostTree(host);
tempHost.visit((path) => {
const content = tempHost.read(path);
if (content) {
this.create(path, content);
}
});
}
}
exports.HostCreateTree = HostCreateTree;
class FilterHostTree extends HostTree {
constructor(tree, filter = () => true) {
const newBackend = new core_1.virtualFs.SimpleMemoryHost();
// cast to allow access
const originalBackend = tree._backend;
const recurse = (base) => {
return originalBackend.list(base).pipe((0, rxjs_1.mergeMap)((x) => x), (0, rxjs_1.map)((path) => (0, core_1.join)(base, path)), (0, rxjs_1.concatMap)((path) => {
let isDirectory = false;
originalBackend.isDirectory(path).subscribe((val) => (isDirectory = val));
if (isDirectory) {
return recurse(path);
}
let isFile = false;
originalBackend.isFile(path).subscribe((val) => (isFile = val));
if (!isFile || !filter(path)) {
return rxjs_1.EMPTY;
}
let content = null;
originalBackend.read(path).subscribe((val) => (content = val));
if (!content) {
return rxjs_1.EMPTY;
}
return newBackend.write(path, content);
}));
};
recurse((0, core_1.normalize)('/')).subscribe();
super(newBackend);
for (const action of tree.actions) {
if (!filter(action.path)) {
continue;
}
switch (action.kind) {
case 'c':
this.create(action.path, action.content);
break;
case 'd':
this.delete(action.path);
break;
case 'o':
this.overwrite(action.path, action.content);
break;
case 'r':
this.rename(action.path, action.to);
break;
}
}
}
}
exports.FilterHostTree = FilterHostTree;

View file

@ -0,0 +1,82 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { JsonValue, Path, PathFragment } from '@angular-devkit/core';
import { Action } from './action';
export declare enum MergeStrategy {
AllowOverwriteConflict = 2,
AllowCreationConflict = 4,
AllowDeleteConflict = 8,
Default = 0,
Error = 1,
ContentOnly = 2,
Overwrite = 14
}
export declare const FileVisitorCancelToken: symbol;
export type FileVisitor = FilePredicate<void>;
export interface FileEntry {
readonly path: Path;
readonly content: Buffer;
}
export interface DirEntry {
readonly parent: DirEntry | null;
readonly path: Path;
readonly subdirs: PathFragment[];
readonly subfiles: PathFragment[];
dir(name: PathFragment): DirEntry;
file(name: PathFragment): FileEntry | null;
visit(visitor: FileVisitor): void;
}
export interface FilePredicate<T> {
(path: Path, entry?: Readonly<FileEntry> | null): T;
}
export declare const TreeSymbol: symbol;
export interface Tree {
branch(): Tree;
merge(other: Tree, strategy?: MergeStrategy): void;
readonly root: DirEntry;
read(path: string): Buffer | null;
/**
* Reads a file from the Tree as a UTF-8 encoded text file.
*
* @param path The path of the file to read.
* @returns A string containing the contents of the file.
* @throws {@link FileDoesNotExistException} if the file is not found.
* @throws An error if the file contains invalid UTF-8 characters.
*/
readText(path: string): string;
/**
* Reads and parses a file from the Tree as a UTF-8 encoded JSON file.
* Supports parsing JSON (RFC 8259) with the following extensions:
* * Single-line and multi-line JavaScript comments
* * Trailing commas within objects and arrays
*
* @param path The path of the file to read.
* @returns A JsonValue containing the parsed contents of the file.
* @throws {@link FileDoesNotExistException} if the file is not found.
* @throws An error if the file contains invalid UTF-8 characters.
* @throws An error if the file contains malformed JSON.
*/
readJson(path: string): JsonValue;
exists(path: string): boolean;
get(path: string): FileEntry | null;
getDir(path: string): DirEntry;
visit(visitor: FileVisitor): void;
overwrite(path: string, content: Buffer | string): void;
beginUpdate(path: string): UpdateRecorder;
commitUpdate(record: UpdateRecorder): void;
create(path: string, content: Buffer | string): void;
delete(path: string): void;
rename(from: string, to: string): void;
apply(action: Action, strategy?: MergeStrategy): void;
readonly actions: Action[];
}
export interface UpdateRecorder {
insertLeft(index: number, content: Buffer | string): UpdateRecorder;
insertRight(index: number, content: Buffer | string): UpdateRecorder;
remove(index: number, length: number): UpdateRecorder;
}

View file

@ -0,0 +1,47 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.TreeSymbol = exports.FileVisitorCancelToken = exports.MergeStrategy = void 0;
var MergeStrategy;
(function (MergeStrategy) {
MergeStrategy[MergeStrategy["AllowOverwriteConflict"] = 2] = "AllowOverwriteConflict";
MergeStrategy[MergeStrategy["AllowCreationConflict"] = 4] = "AllowCreationConflict";
MergeStrategy[MergeStrategy["AllowDeleteConflict"] = 8] = "AllowDeleteConflict";
// Uses the default strategy.
MergeStrategy[MergeStrategy["Default"] = 0] = "Default";
// Error out if 2 files have the same path. It is useful to have a different value than
// Default in this case as the tooling Default might differ.
MergeStrategy[MergeStrategy["Error"] = 1] = "Error";
// Only content conflicts are overwritten.
MergeStrategy[MergeStrategy["ContentOnly"] = 2] = "ContentOnly";
// Overwrite everything with the latest change.
MergeStrategy[MergeStrategy["Overwrite"] = 14] = "Overwrite";
})(MergeStrategy || (exports.MergeStrategy = MergeStrategy = {}));
// eslint-disable-next-line @typescript-eslint/no-inferrable-types
exports.FileVisitorCancelToken = Symbol();
exports.TreeSymbol = (function () {
const globalSymbol = (typeof window == 'object' && window.window === window && window.Symbol) ||
(typeof self == 'object' && self.self === self && self.Symbol) ||
(typeof global == 'object' && global.global === global && global.Symbol);
if (!globalSymbol) {
return Symbol('schematic-tree');
}
if (!globalSymbol.schematicTree) {
globalSymbol.schematicTree = Symbol('schematic-tree');
}
return globalSymbol.schematicTree;
})();
// eslint-disable-next-line @typescript-eslint/no-namespace
var Tree;
(function (Tree) {
function isTree(maybeTree) {
return exports.TreeSymbol in maybeTree;
}
Tree.isTree = isTree;
})(Tree || (Tree = {}));

View file

@ -0,0 +1,44 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { BaseException, JsonValue, Path, PathFragment } from '@angular-devkit/core';
import { Action } from './action';
import { DirEntry, MergeStrategy, Tree, UpdateRecorder } from './interface';
export declare class CannotCreateFileException extends BaseException {
constructor(path: string);
}
export declare class NullTreeDirEntry implements DirEntry {
readonly path: Path;
get parent(): DirEntry | null;
constructor(path: Path);
readonly subdirs: PathFragment[];
readonly subfiles: PathFragment[];
dir(name: PathFragment): DirEntry;
file(_name: PathFragment): null;
visit(): void;
}
export declare class NullTree implements Tree {
branch(): Tree;
merge(_other: Tree, _strategy?: MergeStrategy): void;
readonly root: DirEntry;
exists(_path: string): boolean;
read(_path: string): null;
readText(path: string): string;
readJson(path: string): JsonValue;
get(_path: string): null;
getDir(path: string): NullTreeDirEntry;
visit(): void;
beginUpdate(path: string): never;
commitUpdate(record: UpdateRecorder): never;
copy(path: string, _to: string): never;
delete(path: string): never;
create(path: string, _content: Buffer | string): never;
rename(path: string, _to: string): never;
overwrite(path: string, _content: Buffer | string): never;
apply(_action: Action, _strategy?: MergeStrategy): void;
get actions(): Action[];
}

View file

@ -0,0 +1,97 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.NullTree = exports.NullTreeDirEntry = exports.CannotCreateFileException = void 0;
const core_1 = require("@angular-devkit/core");
const exception_1 = require("../exception/exception");
const interface_1 = require("./interface");
const recorder_1 = require("./recorder");
class CannotCreateFileException extends core_1.BaseException {
constructor(path) {
super(`Cannot create file "${path}".`);
}
}
exports.CannotCreateFileException = CannotCreateFileException;
class NullTreeDirEntry {
path;
get parent() {
return this.path == '/' ? null : new NullTreeDirEntry((0, core_1.dirname)(this.path));
}
constructor(path) {
this.path = path;
}
subdirs = [];
subfiles = [];
dir(name) {
return new NullTreeDirEntry((0, core_1.join)(this.path, name));
}
file(_name) {
return null;
}
visit() { }
}
exports.NullTreeDirEntry = NullTreeDirEntry;
class NullTree {
[interface_1.TreeSymbol]() {
return this;
}
branch() {
return new NullTree();
}
merge(_other, _strategy) { }
root = new NullTreeDirEntry((0, core_1.normalize)('/'));
// Simple readonly file system operations.
exists(_path) {
return false;
}
read(_path) {
return null;
}
readText(path) {
throw new exception_1.FileDoesNotExistException(path);
}
readJson(path) {
throw new exception_1.FileDoesNotExistException(path);
}
get(_path) {
return null;
}
getDir(path) {
return new NullTreeDirEntry((0, core_1.normalize)('/' + path));
}
visit() { }
// Change content of host files.
beginUpdate(path) {
throw new exception_1.FileDoesNotExistException(path);
}
commitUpdate(record) {
throw new exception_1.FileDoesNotExistException(record instanceof recorder_1.UpdateRecorderBase ? record.path : '<unknown>');
}
// Change structure of the host.
copy(path, _to) {
throw new exception_1.FileDoesNotExistException(path);
}
delete(path) {
throw new exception_1.FileDoesNotExistException(path);
}
create(path, _content) {
throw new CannotCreateFileException(path);
}
rename(path, _to) {
throw new exception_1.FileDoesNotExistException(path);
}
overwrite(path, _content) {
throw new exception_1.FileDoesNotExistException(path);
}
apply(_action, _strategy) { }
get actions() {
return [];
}
}
exports.NullTree = NullTree;

View file

@ -0,0 +1,28 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { UpdateBufferBase } from '../utility/update-buffer';
import { FileEntry, UpdateRecorder } from './interface';
export declare class UpdateRecorderBase implements UpdateRecorder {
protected _path: string;
protected _original: Buffer;
protected _content: UpdateBufferBase;
constructor(entry: FileEntry);
static createFromFileEntry(entry: FileEntry): UpdateRecorderBase;
get path(): string;
insertLeft(index: number, content: Buffer | string): UpdateRecorder;
insertRight(index: number, content: Buffer | string): UpdateRecorder;
remove(index: number, length: number): UpdateRecorder;
apply(content: Buffer): Buffer;
}
export declare class UpdateRecorderBom extends UpdateRecorderBase {
private _delta;
constructor(entry: FileEntry, _delta?: number);
insertLeft(index: number, content: Buffer | string): UpdateRecorder;
insertRight(index: number, content: Buffer | string): UpdateRecorder;
remove(index: number, length: number): UpdateRecorder;
}

View file

@ -0,0 +1,78 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.UpdateRecorderBom = exports.UpdateRecorderBase = void 0;
const exception_1 = require("../exception/exception");
const update_buffer_1 = require("../utility/update-buffer");
class UpdateRecorderBase {
_path;
_original;
_content;
constructor(entry) {
this._original = Buffer.from(entry.content);
this._content = update_buffer_1.UpdateBufferBase.create(entry.path, entry.content);
this._path = entry.path;
}
static createFromFileEntry(entry) {
const c0 = entry.content.byteLength > 0 && entry.content.readUInt8(0);
const c1 = entry.content.byteLength > 1 && entry.content.readUInt8(1);
const c2 = entry.content.byteLength > 2 && entry.content.readUInt8(2);
// Check if we're BOM.
if (c0 == 0xef && c1 == 0xbb && c2 == 0xbf) {
return new UpdateRecorderBom(entry);
}
else if (c0 === 0xff && c1 == 0xfe) {
return new UpdateRecorderBom(entry);
}
else if (c0 === 0xfe && c1 == 0xff) {
return new UpdateRecorderBom(entry);
}
return new UpdateRecorderBase(entry);
}
get path() {
return this._path;
}
// These just record changes.
insertLeft(index, content) {
this._content.insertLeft(index, typeof content == 'string' ? Buffer.from(content) : content);
return this;
}
insertRight(index, content) {
this._content.insertRight(index, typeof content == 'string' ? Buffer.from(content) : content);
return this;
}
remove(index, length) {
this._content.remove(index, length);
return this;
}
apply(content) {
if (!content.equals(this._content.original)) {
throw new exception_1.ContentHasMutatedException(this.path);
}
return this._content.generate();
}
}
exports.UpdateRecorderBase = UpdateRecorderBase;
class UpdateRecorderBom extends UpdateRecorderBase {
_delta;
constructor(entry, _delta = 1) {
super(entry);
this._delta = _delta;
}
insertLeft(index, content) {
return super.insertLeft(index + this._delta, content);
}
insertRight(index, content) {
return super.insertRight(index + this._delta, content);
}
remove(index, length) {
return super.remove(index + this._delta, length);
}
}
exports.UpdateRecorderBom = UpdateRecorderBom;

View file

@ -0,0 +1,48 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { JsonValue, Path, PathFragment } from '@angular-devkit/core';
import { Action } from './action';
import { DirEntry, FileEntry, FileVisitor, MergeStrategy, Tree, UpdateRecorder } from './interface';
declare class ScopedDirEntry implements DirEntry {
private _base;
readonly scope: Path;
constructor(_base: DirEntry, scope: Path);
get parent(): DirEntry | null;
get path(): Path;
get subdirs(): PathFragment[];
get subfiles(): PathFragment[];
dir(name: PathFragment): DirEntry;
file(name: PathFragment): FileEntry | null;
visit(visitor: FileVisitor): void;
}
export declare class ScopedTree implements Tree {
private _base;
readonly _root: ScopedDirEntry;
constructor(_base: Tree, scope: string);
get root(): DirEntry;
branch(): Tree;
merge(other: Tree, strategy?: MergeStrategy): void;
read(path: string): Buffer | null;
readText(path: string): string;
readJson(path: string): JsonValue;
exists(path: string): boolean;
get(path: string): FileEntry | null;
getDir(path: string): DirEntry;
visit(visitor: FileVisitor): void;
overwrite(path: string, content: Buffer | string): void;
beginUpdate(path: string): UpdateRecorder;
commitUpdate(record: UpdateRecorder): void;
create(path: string, content: Buffer | string): void;
delete(path: string): void;
rename(from: string, to: string): void;
apply(action: Action, strategy?: MergeStrategy): void;
get actions(): Action[];
private _fullPath;
private _fullPathAction;
}
export {};

View file

@ -0,0 +1,181 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ScopedTree = void 0;
const core_1 = require("@angular-devkit/core");
const delegate_1 = require("./delegate");
const interface_1 = require("./interface");
class ScopedFileEntry {
_base;
scope;
constructor(_base, scope) {
this._base = _base;
this.scope = scope;
}
get path() {
return (0, core_1.join)(core_1.NormalizedRoot, (0, core_1.relative)(this.scope, this._base.path));
}
get content() {
return this._base.content;
}
}
class ScopedDirEntry {
_base;
scope;
constructor(_base, scope) {
this._base = _base;
this.scope = scope;
}
get parent() {
if (!this._base.parent || this._base.path == this.scope) {
return null;
}
return new ScopedDirEntry(this._base.parent, this.scope);
}
get path() {
return (0, core_1.join)(core_1.NormalizedRoot, (0, core_1.relative)(this.scope, this._base.path));
}
get subdirs() {
return this._base.subdirs;
}
get subfiles() {
return this._base.subfiles;
}
dir(name) {
const entry = this._base.dir(name);
return entry && new ScopedDirEntry(entry, this.scope);
}
file(name) {
const entry = this._base.file(name);
return entry && new ScopedFileEntry(entry, this.scope);
}
visit(visitor) {
return this._base.visit((path, entry) => {
visitor((0, core_1.join)(core_1.NormalizedRoot, (0, core_1.relative)(this.scope, path)), entry && new ScopedFileEntry(entry, this.scope));
});
}
}
class ScopedTree {
_base;
_root;
constructor(_base, scope) {
this._base = _base;
const normalizedScope = (0, core_1.normalize)('/' + scope);
this._root = new ScopedDirEntry(this._base.getDir(normalizedScope), normalizedScope);
}
get root() {
return this._root;
}
branch() {
return new ScopedTree(this._base.branch(), this._root.scope);
}
merge(other, strategy) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const self = this;
const delegate = new (class extends delegate_1.DelegateTree {
get actions() {
return other.actions.map((action) => self._fullPathAction(action));
}
})(other);
this._base.merge(delegate, strategy);
}
// Readonly.
read(path) {
return this._base.read(this._fullPath(path));
}
readText(path) {
return this._base.readText(this._fullPath(path));
}
readJson(path) {
return this._base.readJson(this._fullPath(path));
}
exists(path) {
return this._base.exists(this._fullPath(path));
}
get(path) {
const entry = this._base.get(this._fullPath(path));
return entry && new ScopedFileEntry(entry, this._root.scope);
}
getDir(path) {
const entry = this._base.getDir(this._fullPath(path));
return entry && new ScopedDirEntry(entry, this._root.scope);
}
visit(visitor) {
return this._root.visit(visitor);
}
// Change content of host files.
overwrite(path, content) {
return this._base.overwrite(this._fullPath(path), content);
}
beginUpdate(path) {
return this._base.beginUpdate(this._fullPath(path));
}
commitUpdate(record) {
return this._base.commitUpdate(record);
}
// Structural methods.
create(path, content) {
return this._base.create(this._fullPath(path), content);
}
delete(path) {
return this._base.delete(this._fullPath(path));
}
rename(from, to) {
return this._base.rename(this._fullPath(from), this._fullPath(to));
}
apply(action, strategy) {
return this._base.apply(this._fullPathAction(action), strategy);
}
get actions() {
const scopedActions = [];
for (const action of this._base.actions) {
if (!action.path.startsWith(this._root.scope + '/')) {
continue;
}
if (action.kind !== 'r') {
scopedActions.push({
...action,
path: (0, core_1.join)(core_1.NormalizedRoot, (0, core_1.relative)(this._root.scope, action.path)),
});
}
else if (action.to.startsWith(this._root.scope + '/')) {
scopedActions.push({
...action,
path: (0, core_1.join)(core_1.NormalizedRoot, (0, core_1.relative)(this._root.scope, action.path)),
to: (0, core_1.join)(core_1.NormalizedRoot, (0, core_1.relative)(this._root.scope, action.to)),
});
}
}
return scopedActions;
}
[interface_1.TreeSymbol]() {
return this;
}
_fullPath(path) {
return (0, core_1.join)(this._root.scope, (0, core_1.normalize)('/' + path));
}
_fullPathAction(action) {
let fullPathAction;
if (action.kind === 'r') {
fullPathAction = {
...action,
path: this._fullPath(action.path),
to: this._fullPath(action.to),
};
}
else {
fullPathAction = {
...action,
path: this._fullPath(action.path),
};
}
return fullPathAction;
}
}
exports.ScopedTree = ScopedTree;

View file

@ -0,0 +1,13 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { HostTree } from './host-tree';
import { FilePredicate, MergeStrategy, Tree } from './interface';
export declare function empty(): HostTree;
export declare function branch(tree: Tree): Tree;
export declare function merge(tree: Tree, other: Tree, strategy?: MergeStrategy): Tree;
export declare function partition(tree: Tree, predicate: FilePredicate<boolean>): [Tree, Tree];

View file

@ -0,0 +1,38 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.partition = exports.merge = exports.branch = exports.empty = void 0;
const exception_1 = require("../exception/exception");
const host_tree_1 = require("./host-tree");
const interface_1 = require("./interface");
function empty() {
return new host_tree_1.HostTree();
}
exports.empty = empty;
function branch(tree) {
return tree.branch();
}
exports.branch = branch;
function merge(tree, other, strategy = interface_1.MergeStrategy.Default) {
tree.merge(other, strategy);
return tree;
}
exports.merge = merge;
function partition(tree, predicate) {
if (tree instanceof host_tree_1.HostTree) {
return [
new host_tree_1.FilterHostTree(tree, predicate),
new host_tree_1.FilterHostTree(tree, (path, entry) => !predicate(path, entry)),
];
}
else {
throw new exception_1.SchematicsException('Tree type is not supported.');
}
}
exports.partition = partition;