mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
To increase the ease of development we are moving @angular/docs into the adev directory within this repo. While we are doing this to improve our development experience in the short term, efforts are also in place to maintain a division between this @angular/docs (shared) code and adev itself, so that it can be extracted back out in the future when components is ready to leverage it as well. PR Close #57132
94 lines
2.9 KiB
TypeScript
94 lines
2.9 KiB
TypeScript
import {glob} from 'fast-glob';
|
|
import {FileAndContentRecord, TutorialConfig} from '../../interfaces';
|
|
import {dirname, join} from 'path';
|
|
import {existsSync, readFileSync} from 'fs';
|
|
|
|
// See https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files for details
|
|
// on identifying file types with initial bytes.
|
|
/** Initial bytes of the buffer(aka magic numbers) to see if it's a JPG file. */
|
|
const jpgSignature = [0xff, 0xd8, 0xff];
|
|
/** Initial bytes of the buffer(aka magic numbers) to see if it's a GIF file. */
|
|
const gifSignature = [0x47, 0x49, 0x46];
|
|
/** Initial bytes of the buffer(aka magic numbers) to see if it's a PNG file. */
|
|
const pngSignature = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a];
|
|
|
|
/** List of initial bytes to check for matching files. */
|
|
const SIGNATURES = [jpgSignature, gifSignature, pngSignature];
|
|
|
|
/**
|
|
* Get the contents for the provided file, returning a string or Buffer as appropriate.
|
|
*/
|
|
export function getFileContents<T extends string | Uint8Array>(path: string): T;
|
|
export function getFileContents(path: string): string | Uint8Array {
|
|
const fileBuffer = readFileSync(path);
|
|
|
|
if (checkBufferMatchForSignatures(fileBuffer)) {
|
|
return fileBuffer;
|
|
}
|
|
|
|
return fileBuffer.toString();
|
|
}
|
|
|
|
/**
|
|
* Determine if the initial bytes of a buffer matches the expected bytes.
|
|
*/
|
|
function checkBufferMatchForSignatures(buffer: Uint8Array): boolean {
|
|
for (const initialByes of SIGNATURES) {
|
|
for (const [index, byte] of initialByes.entries()) {
|
|
if (buffer[index] !== byte) return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Add all files found in the provided directory into the provided object of file and contents.
|
|
* This overwrite already existing files in the object when encountered.
|
|
*/
|
|
export async function addDirectoryToFilesRecord(
|
|
files: FileAndContentRecord,
|
|
dir: string,
|
|
): Promise<void> {
|
|
const exampleFilePaths = await glob('**/*', {
|
|
cwd: dir,
|
|
onlyFiles: true,
|
|
});
|
|
|
|
for (let path of exampleFilePaths) {
|
|
files[path] = await getFileContents(join(dir, path));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Collect all of the config.json files in the provided directory and subdirectories.
|
|
*/
|
|
export async function findAllConfigs(dir: string): Promise<Record<string, TutorialConfig>> {
|
|
const configs: Record<string, TutorialConfig> = {};
|
|
|
|
const paths = await glob('**/config.json', {
|
|
cwd: dir,
|
|
onlyFiles: true,
|
|
});
|
|
|
|
for (const path of paths) {
|
|
const content = await getFileContents<string>(join(dir, path));
|
|
configs[dirname(path)] = JSON.parse(content) as TutorialConfig;
|
|
}
|
|
|
|
return configs;
|
|
}
|
|
|
|
/**
|
|
* Collect a single of the config.json file at the provided directory.
|
|
*/
|
|
export async function findConfig(dir: string): Promise<TutorialConfig> {
|
|
const configPath = join(dir, 'config.json');
|
|
|
|
if (!existsSync(configPath)) {
|
|
throw Error(`Unable config.json file found at: ${dir}`);
|
|
}
|
|
|
|
const content = await getFileContents<string>(configPath);
|
|
return JSON.parse(content) as TutorialConfig;
|
|
}
|