diff --git a/src/commands/build/core/meta/utils.ts b/src/commands/build/core/meta/utils.ts index 611ceb58..b0f19dc6 100644 --- a/src/commands/build/core/meta/utils.ts +++ b/src/commands/build/core/meta/utils.ts @@ -1,18 +1,17 @@ import {composeFrontMatter, extractFrontMatter} from '@diplodoc/transform/lib/frontmatter'; export function addSourcePath(fileContent: string, sourcePath: string) { - const [frontMatter, strippedContent] = extractFrontMatter( - fileContent, - sourcePath, - ); + const [frontMatter, strippedContent] = extractFrontMatter(fileContent, sourcePath); if (frontMatter.sourcePath) { return fileContent; } - return composeFrontMatter({ - ...frontMatter, - sourcePath, - }, strippedContent); + return composeFrontMatter( + { + ...frontMatter, + sourcePath, + }, + strippedContent, + ); } - diff --git a/src/commands/build/core/vars/VarsService.ts b/src/commands/build/core/vars/VarsService.ts index dd4c39db..9678d7ee 100644 --- a/src/commands/build/core/vars/VarsService.ts +++ b/src/commands/build/core/vars/VarsService.ts @@ -5,7 +5,7 @@ import {merge} from 'lodash'; import {dump, load} from 'js-yaml'; import {Run} from '~/commands/build'; -import {freeze, own} from '~/utils'; +import {freeze, normalizePath, own} from '~/utils'; import {AsyncParallelHook, AsyncSeriesWaterfallHook} from 'tapable'; export type VarsServiceConfig = { @@ -31,6 +31,10 @@ type VarsServiceHooks = { export class VarsService { hooks: VarsServiceHooks; + get entries() { + return [...Object.entries(this.cache)]; + } + private run: Run; private logger: Run['logger']; @@ -50,10 +54,10 @@ export class VarsService { } async init() { - const presets = (await this.run.glob('**/presets.yaml', { + const presets = await this.run.glob('**/presets.yaml', { cwd: this.run.input, ignore: this.config.ignore, - })) as RelativePath[]; + }); for (const preset of presets) { await this.load(preset); @@ -61,6 +65,8 @@ export class VarsService { } async load(path: RelativePath) { + path = normalizePath(path); + const varsPreset = this.config.varsPreset || 'default'; const file = join(dirname(path), 'presets.yaml'); @@ -107,8 +113,4 @@ export class VarsService { lineWidth: 120, }); } - - entries() { - return Object.entries(this.cache); - } } diff --git a/src/commands/build/core/vars/index.spec.ts b/src/commands/build/core/vars/index.spec.ts index 4a910f4d..d36d3c0c 100644 --- a/src/commands/build/core/vars/index.spec.ts +++ b/src/commands/build/core/vars/index.spec.ts @@ -41,7 +41,7 @@ function prepare(content: string | Error | Hash, options: Option async function call(content: string | Error, options: Options = {}) { const service = prepare(content, options); - const result = await service.load('./presets.yaml' as RelativePath); + const result = await service.load('presets.yaml' as NormalizedPath); expect(service.dump(result)).toMatchSnapshot(); } @@ -158,7 +158,7 @@ describe('vars', () => { ); const result = await service.load( - './subfolder/subfolder/subfolder/presets.yaml' as RelativePath, + 'subfolder/subfolder/subfolder/presets.yaml' as NormalizedPath, ); expect(service.dump(result)).toMatchSnapshot(); @@ -174,7 +174,7 @@ describe('vars', () => { service.hooks.PresetsLoaded.tap('Test', spy); - await service.load('./presets.yaml' as RelativePath); + await service.load('presets.yaml' as NormalizedPath); expect(spy).toHaveBeenCalledWith({default: {field1: 'value1'}}, 'presets.yaml'); }); @@ -189,7 +189,7 @@ describe('vars', () => { service.hooks.Resolved.tap('Test', spy); - await service.load('./presets.yaml' as RelativePath); + await service.load('presets.yaml' as NormalizedPath); expect(spy).toHaveBeenCalledWith({field1: 'value1'}, 'presets.yaml'); }); @@ -206,7 +206,7 @@ describe('vars', () => { return presets; }); - const result = await service.load('./presets.yaml' as RelativePath); + const result = await service.load('presets.yaml' as NormalizedPath); expect(service.dump(result)).toMatchSnapshot(); }); @@ -223,7 +223,7 @@ describe('vars', () => { return presets; }); - const result = await service.load('./presets.yaml' as RelativePath); + const result = await service.load('presets.yaml' as NormalizedPath); expect(service.dump(result)).toMatchSnapshot(); }); @@ -239,7 +239,7 @@ describe('vars', () => { }); await expect(() => - service.load('./presets.yaml' as RelativePath), + service.load('presets.yaml' as NormalizedPath), ).rejects.toThrow(); }); @@ -254,7 +254,7 @@ describe('vars', () => { }); await expect(() => - service.load('./presets.yaml' as RelativePath), + service.load('presets.yaml' as NormalizedPath), ).rejects.toThrow(); }); @@ -270,8 +270,8 @@ describe('vars', () => { service.hooks.PresetsLoaded.tap('Test', spy1); service.hooks.Resolved.tap('Test', spy2); - await service.load('./presets.yaml' as RelativePath); - await service.load('./presets.yaml' as RelativePath); + await service.load('presets.yaml' as NormalizedPath); + await service.load('presets.yaml' as NormalizedPath); expect(spy1).toHaveBeenCalledOnce(); expect(spy2).toHaveBeenCalledOnce(); diff --git a/src/commands/build/features/linter/index.ts b/src/commands/build/features/linter/index.ts index 6cb3a405..dc398bb3 100644 --- a/src/commands/build/features/linter/index.ts +++ b/src/commands/build/features/linter/index.ts @@ -1,7 +1,7 @@ import type {Build} from '../..'; import type {Command} from '~/config'; -import {resolve} from 'path'; +import {resolve} from 'node:path'; import shell from 'shelljs'; import {LogLevels} from '@diplodoc/transform/lib/log'; diff --git a/src/commands/build/features/templating/index.spec.ts b/src/commands/build/features/templating/index.spec.ts index ff220f81..a1c3edfc 100644 --- a/src/commands/build/features/templating/index.spec.ts +++ b/src/commands/build/features/templating/index.spec.ts @@ -217,7 +217,7 @@ describe('Build template feature', () => { it('should not save presets.yaml for html build', async () => { const build = setupBuild({ globs: { - '**/presets.yaml': ['./presets.yaml'], + '**/presets.yaml': ['presets.yaml'] as NormalizedPath[], }, files: { './presets.yaml': dedent` @@ -238,7 +238,7 @@ describe('Build template feature', () => { it('should save presets.yaml for md build with disabled templating', async () => { const build = setupBuild({ globs: { - '**/presets.yaml': ['./presets.yaml'], + '**/presets.yaml': ['presets.yaml'] as NormalizedPath[], }, files: { './presets.yaml': dedent` @@ -259,7 +259,7 @@ describe('Build template feature', () => { it('should filter presets.yaml for md build with disabled templating', async () => { const build = setupBuild({ globs: { - '**/presets.yaml': ['./presets.yaml'], + '**/presets.yaml': ['presets.yaml'] as NormalizedPath[], }, files: { './presets.yaml': dedent` diff --git a/src/globals.d.ts b/src/globals.d.ts index 4e2317cf..3ea9d4c7 100644 --- a/src/globals.d.ts +++ b/src/globals.d.ts @@ -30,6 +30,9 @@ type RelativePath = string & | `./${string}` ); +/** + * This is unix-like relative path with truncated heading ./ + */ type NormalizedPath = string & { __type: 'path'; __mode: 'relative' & 'normalized'; diff --git a/src/logger/index.ts b/src/logger/index.ts index 43fa6e77..79837ae2 100644 --- a/src/logger/index.ts +++ b/src/logger/index.ts @@ -30,11 +30,6 @@ type LoggerOptions = Readonly<{ quiet: boolean; }>; -type MessageInfo = { - level: LogLevels; - message: string; -}; - type Color = typeof red; const Write = Symbol('write'); @@ -95,8 +90,6 @@ export class Logger implements LogConsumer { private consumer: LogConsumer | null = null; - private buffer: MessageInfo[] = []; - private filters: ((level: LogLevels, message: string) => string)[]; constructor( @@ -120,6 +113,9 @@ export class Logger implements LogConsumer { * So if child and parent has the same topic with name 'proc', * only local topic will be applied to message. * Message will be decorated by local topic and will be passed to parent as raw string. + * + * @param {LogConsumer} consumer - parent logger + * @returns {Logger} */ pipe(consumer: LogConsumer) { if (this.consumer && this.consumer !== consumer) { @@ -128,18 +124,17 @@ export class Logger implements LogConsumer { this.consumer = consumer; - for (const {level, message} of this.buffer) { - this.consumer[Symbol.for(level) as keyof LogConsumer](message); - } - - this.buffer.length = 0; - return this; } /** * Defines new write decorator to one of defined log channeld. * Each decorator adds colored prefix to messages and apply preconfigured filters. + * + * @param {LogLevels} level + * @param {string} prefix - any bounded text prefix, which will be colored + * @param {Color} [color] - prefix color + * @returns new topic */ topic(level: LogLevels, prefix: string, color?: Color) { const channel = Symbol.for(level) as keyof LogConsumer; @@ -177,14 +172,7 @@ export class Logger implements LogConsumer { return this; } - clear() { - this.buffer.length = 0; - - return this; - } - reset() { - this.clear(); for (const level of Object.values(LogLevel)) { this[level].count = 0; } @@ -200,6 +188,7 @@ export class Logger implements LogConsumer { if (this.consumer) { this.consumer[Symbol.for(level) as keyof LogConsumer](message); } else { + // eslint-disable-next-line no-console console[level](message); } } diff --git a/src/models.ts b/src/models.ts index e18bd010..cf35ab10 100644 --- a/src/models.ts +++ b/src/models.ts @@ -264,12 +264,12 @@ export interface ResolverOptions { export interface PathData { pathToFile: string; - resolvedPathToFile: string; + resolvedPathToFile: AbsolutePath; filename: string; fileBaseName: string; fileExtension: string; - outputDir: string; - outputPath: string; + outputDir: AbsolutePath; + outputPath: AbsolutePath; outputFormat: string; outputBundlePath: string; outputTocDir: string; diff --git a/src/pages/redirect.ts b/src/pages/redirect.ts index 21e8f63d..fefc252c 100644 --- a/src/pages/redirect.ts +++ b/src/pages/redirect.ts @@ -1,10 +1,10 @@ import {join} from 'path'; -import {BUNDLE_FOLDER, Lang, RTL_LANGS} from '../constants'; +import {BUNDLE_FOLDER, RTL_LANGS} from '../constants'; import {PluginService} from '../services'; import manifest from '@diplodoc/client/manifest'; -export function generateStaticRedirect(lang: Lang, link: string): string { +export function generateStaticRedirect(lang: string, link: string): string { const isRTL = RTL_LANGS.includes(lang); return ` diff --git a/src/services/preset.ts b/src/services/preset.ts index 13694c85..b67f31d3 100644 --- a/src/services/preset.ts +++ b/src/services/preset.ts @@ -8,7 +8,7 @@ export type PresetStorage = Map; let presetStorage: PresetStorage = new Map(); function init(vars: VarsService) { - for (const [path, values] of vars.entries()) { + for (const [path, values] of vars.entries) { presetStorage.set(dirname(path), values); } } diff --git a/src/utils/common.ts b/src/utils/common.ts index f9fcb53f..79310dc8 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -25,7 +25,7 @@ export function modifyValuesByKeys( modifyFn: (value: string) => string, ) { // Clone the object deeply with a customizer function that modifies matching keys - return cloneDeepWith(originalObj, function (value: unknown, key) { + return cloneDeepWith(originalObj, (value: unknown, key) => { if (keysToFind.includes(key as string) && isString(value)) { return modifyFn(value); } @@ -87,6 +87,7 @@ export type HookMeta = { type: string; }; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export function intercept | HookMap>>( service: string, hooks: T, @@ -98,7 +99,7 @@ export function intercept | HookMap>>( const meta = {service, hook, name, type}; if (type === 'promise') { - info.fn = async (...args: any[]) => { + info.fn = async (...args: unknown[]) => { try { return await fn(...args); } catch (error) { @@ -110,7 +111,7 @@ export function intercept | HookMap>>( } }; } else if (type === 'sync') { - info.fn = (...args: any[]) => { + info.fn = (...args: unknown[]) => { try { return fn(...args); } catch (error) { diff --git a/tests/integrations/services/metadataAuthors.test.ts b/tests/integrations/services/metadataAuthors.test.ts index 251e3a06..dc1fbe1a 100644 --- a/tests/integrations/services/metadataAuthors.test.ts +++ b/tests/integrations/services/metadataAuthors.test.ts @@ -37,12 +37,12 @@ describe('getContentWithUpdatedMetadata (Authors)', () => { metadataOptions = { pathData: { pathToFile: '', - resolvedPathToFile: '', + resolvedPathToFile: '' as AbsolutePath, filename: '', fileBaseName: '', fileExtension: '', - outputDir: '', - outputPath: '', + outputDir: '' as AbsolutePath, + outputPath: '' as AbsolutePath, outputFormat: '', outputBundlePath: '', outputTocDir: '', @@ -94,12 +94,12 @@ describe('getContentWithUpdatedMetadata (Authors)', () => { const metadataOptions: MetaDataOptions = { pathData: { pathToFile: '', - resolvedPathToFile: '', + resolvedPathToFile: '' as AbsolutePath, filename: '', fileBaseName: '', fileExtension: '', - outputDir: '', - outputPath: '', + outputDir: '' as AbsolutePath, + outputPath: '' as AbsolutePath, outputFormat: '', outputBundlePath: '', outputTocDir: '', diff --git a/tests/integrations/services/metadataContributors.test.ts b/tests/integrations/services/metadataContributors.test.ts index 93b37d56..6a239b0f 100644 --- a/tests/integrations/services/metadataContributors.test.ts +++ b/tests/integrations/services/metadataContributors.test.ts @@ -15,12 +15,12 @@ describe('getContentWithUpdatedMetadata (Contributors)', () => { const metadataOptions: MetaDataOptions = { pathData: { pathToFile: '', - resolvedPathToFile: '', + resolvedPathToFile: '' as AbsolutePath, filename: '', fileBaseName: '', fileExtension: '', - outputDir: '', - outputPath: '', + outputDir: '' as AbsolutePath, + outputPath: '' as AbsolutePath, outputFormat: '', outputBundlePath: '', outputTocDir: '', @@ -244,7 +244,7 @@ describe('getContentWithUpdatedMetadata (Contributors)', () => { contributors: getFileContributors(path), hasIncludes: item.getHasIncludes(path), }); - metadataOptions.pathData.resolvedPathToFile = withIncludesFilePath; + metadataOptions.pathData.resolvedPathToFile = withIncludesFilePath as AbsolutePath; const fileContent = readFileSync(withIncludesFilePath, 'utf8'); const updatedFileContent = await enrichWithFrontMatter({ diff --git a/tests/units/services/metadata.test.ts b/tests/units/services/metadata.test.ts index a68f6e66..dda159c1 100644 --- a/tests/units/services/metadata.test.ts +++ b/tests/units/services/metadata.test.ts @@ -48,12 +48,12 @@ describe('getUpdatedMetadata', () => { metaDataOptions = { pathData: { pathToFile: '', - resolvedPathToFile: '', + resolvedPathToFile: '' as AbsolutePath, filename: '', fileBaseName: '', fileExtension: '', - outputDir: '', - outputPath: '', + outputDir: '' as AbsolutePath, + outputPath: '' as AbsolutePath, outputFormat: '', outputBundlePath: '', outputTocDir: '',