diff --git a/goldens/public-api/angular_devkit/schematics/index.md b/goldens/public-api/angular_devkit/schematics/index.md index 2d9f6a616bb1..67d13a878814 100644 --- a/goldens/public-api/angular_devkit/schematics/index.md +++ b/goldens/public-api/angular_devkit/schematics/index.md @@ -495,13 +495,13 @@ export class HostSink extends SimpleSinkBase { // (undocumented) _done(): Observable; // (undocumented) - protected _filesToCreate: Map; + protected _filesToCreate: Map; // (undocumented) protected _filesToDelete: Set; // (undocumented) protected _filesToRename: Set<[Path, Path]>; // (undocumented) - protected _filesToUpdate: Map; + protected _filesToUpdate: Map; // (undocumented) protected _force: boolean; // (undocumented) diff --git a/packages/angular/pwa/pwa/index.ts b/packages/angular/pwa/pwa/index.ts index 03627ca5a615..2b4996f0f324 100644 --- a/packages/angular/pwa/pwa/index.ts +++ b/packages/angular/pwa/pwa/index.ts @@ -167,12 +167,7 @@ export default function (options: PwaOptions): Rule { return chain([ externalSchematic('@schematics/angular', 'service-worker', swOptions), mergeWith(apply(url('./files/root'), [template({ ...options }), move(sourcePath)])), - mergeWith( - apply(url('./files/assets'), [ - template({ ...options }), - move(posix.join(sourcePath, 'assets')), - ]), - ), + mergeWith(apply(url('./files/assets'), [move(posix.join(sourcePath, 'assets'))])), ...[...indexFiles].map((path) => updateIndexFile(path)), ]); }; diff --git a/packages/angular_devkit/schematics/src/sink/dryrun.ts b/packages/angular_devkit/schematics/src/sink/dryrun.ts index 33799f2ddf2c..db4b296b81d6 100644 --- a/packages/angular_devkit/schematics/src/sink/dryrun.ts +++ b/packages/angular_devkit/schematics/src/sink/dryrun.ts @@ -117,10 +117,10 @@ export class DryRunSink extends HostSink { return; } - this._subject.next({ kind: 'create', path, content: content.generate() }); + this._subject.next({ kind: 'create', path, content }); }); this._filesToUpdate.forEach((content, path) => { - this._subject.next({ kind: 'update', path, content: content.generate() }); + this._subject.next({ kind: 'update', path, content }); }); this._subject.complete(); diff --git a/packages/angular_devkit/schematics/src/sink/host.ts b/packages/angular_devkit/schematics/src/sink/host.ts index a83fc568503e..10da1a67a8d1 100644 --- a/packages/angular_devkit/schematics/src/sink/host.ts +++ b/packages/angular_devkit/schematics/src/sink/host.ts @@ -17,14 +17,13 @@ import { reduce, } from 'rxjs'; import { CreateFileAction } from '../tree/action'; -import { UpdateBufferBase } from '../utility/update-buffer'; import { SimpleSinkBase } from './sink'; export class HostSink extends SimpleSinkBase { protected _filesToDelete = new Set(); protected _filesToRename = new Set<[Path, Path]>(); - protected _filesToCreate = new Map(); - protected _filesToUpdate = new Map(); + protected _filesToCreate = new Map(); + protected _filesToUpdate = new Map(); constructor(protected _host: virtualFs.Host, protected _force = false) { super(); @@ -56,20 +55,23 @@ export class HostSink extends SimpleSinkBase { } protected _overwriteFile(path: Path, content: Buffer): Observable { - this._filesToUpdate.set(path, UpdateBufferBase.create(content)); + this._filesToUpdate.set(path, content); return EMPTY; } + protected _createFile(path: Path, content: Buffer): Observable { - this._filesToCreate.set(path, UpdateBufferBase.create(content)); + this._filesToCreate.set(path, content); return EMPTY; } + protected _renameFile(from: Path, to: Path): Observable { this._filesToRename.add([from, to]); return EMPTY; } + protected _deleteFile(path: Path): Observable { if (this._filesToCreate.has(path)) { this._filesToCreate.delete(path); @@ -91,14 +93,10 @@ export class HostSink extends SimpleSinkBase { concatMap(([_, [path, to]]) => this._host.rename(path, to)), ), observableFrom([...this._filesToCreate.entries()]).pipe( - concatMap(([path, buffer]) => { - return this._host.write(path, buffer.generate() as {} as virtualFs.FileBuffer); - }), + concatMap(([path, buffer]) => this._host.write(path, buffer)), ), observableFrom([...this._filesToUpdate.entries()]).pipe( - concatMap(([path, buffer]) => { - return this._host.write(path, buffer.generate() as {} as virtualFs.FileBuffer); - }), + concatMap(([path, buffer]) => this._host.write(path, buffer)), ), ).pipe(reduce(() => {})); } diff --git a/packages/angular_devkit/schematics/src/tree/recorder.ts b/packages/angular_devkit/schematics/src/tree/recorder.ts index 236996306dce..13551fea0c0c 100644 --- a/packages/angular_devkit/schematics/src/tree/recorder.ts +++ b/packages/angular_devkit/schematics/src/tree/recorder.ts @@ -17,7 +17,7 @@ export class UpdateRecorderBase implements UpdateRecorder { constructor(entry: FileEntry) { this._original = Buffer.from(entry.content); - this._content = UpdateBufferBase.create(entry.content); + this._content = UpdateBufferBase.create(entry.path, entry.content); this._path = entry.path; } diff --git a/packages/angular_devkit/schematics/src/utility/update-buffer.ts b/packages/angular_devkit/schematics/src/utility/update-buffer.ts index d520e4dd4805..eac10b8d4079 100644 --- a/packages/angular_devkit/schematics/src/utility/update-buffer.ts +++ b/packages/angular_devkit/schematics/src/utility/update-buffer.ts @@ -8,6 +8,7 @@ import { BaseException } from '@angular-devkit/core'; import MagicString from 'magic-string'; +import { TextDecoder } from 'node:util'; export class IndexOutOfBoundException extends BaseException { constructor(index: number, min: number, max = Infinity) { @@ -32,11 +33,23 @@ export abstract class UpdateBufferBase { /** * Creates an UpdateBufferBase instance. * + * @param contentPath The path of the update buffer instance. * @param originalContent The original content of the update buffer instance. * @returns An UpdateBufferBase instance. */ - static create(originalContent: Buffer): UpdateBufferBase { - return new UpdateBuffer(originalContent); + static create(contentPath: string, originalContent: Buffer): UpdateBufferBase { + try { + // We only support utf8 encoding. + new TextDecoder('utf8', { fatal: true }).decode(originalContent); + + return new UpdateBuffer(originalContent); + } catch (e) { + if (e instanceof TypeError) { + throw new Error(`Failed to decode "${contentPath}" as UTF-8 text.`); + } + + throw e; + } } }