Skip to content

Commit

Permalink
Merge pull request #187 from mizdra/support-arbitrary-extensions
Browse files Browse the repository at this point in the history
Support `--arbitraryExtensions` option
  • Loading branch information
mizdra committed Mar 23, 2023
2 parents 07857fa + e13d1c6 commit b7822b5
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 12 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Options:
--lessIncludePaths The option compatible with less's `--include-path`. [array]
--webpackResolveAlias The option compatible with webpack's `resolve.alias`. [string]
--postcssConfig The option compatible with postcss's `--config`. [string]
--arbitraryExtensions Generate `.d.css.ts` instead of `.css.d.ts`. [boolean] [default: true]
--cache Only generate .d.ts and .d.ts.map for changed files. [boolean] [default: true]
--cacheStrategy Strategy for the cache to use for detecting changed files.[choices: "content", "metadata"] [default: "content"]
--logLevel What level of logs to report. [choices: "debug", "info", "silent"] [default: "info"]
Expand Down
5 changes: 5 additions & 0 deletions src/cli.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { parseArgv } from './cli.js';
import { DEFAULT_ARBITRARY_EXTENSIONS } from './config.js';

const baseArgs = ['node', 'hcm'];

Expand Down Expand Up @@ -56,6 +57,10 @@ describe('parseArgv', () => {
'postcss.config.js',
);
});
test('--arbitraryExtensions', () => {
expect(parseArgv([...baseArgs, '1.css']).arbitraryExtensions).toBe(DEFAULT_ARBITRARY_EXTENSIONS);
expect(parseArgv([...baseArgs, '1.css', '--arbitraryExtensions']).arbitraryExtensions).toBe(true);
});
test('--cache', () => {
expect(parseArgv([...baseArgs, '1.css']).cache).toBe(true);
expect(parseArgv([...baseArgs, '1.css', '--cache']).cache).toBe(true);
Expand Down
7 changes: 7 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import { DEFAULT_ARBITRARY_EXTENSIONS } from './config.js';
import { type RunnerOptions } from './runner.js';
import { getPackageJson } from './util.js';

Expand Down Expand Up @@ -56,6 +57,11 @@ export function parseArgv(argv: string[]): RunnerOptions {
string: true,
describe: "The option compatible with postcss's `--config`.",
})
.option('arbitraryExtensions', {
type: 'boolean',
default: DEFAULT_ARBITRARY_EXTENSIONS,
describe: 'Generate `.d.css.ts` instead of `.css.d.ts`.',
})
.option('cache', {
type: 'boolean',
default: true,
Expand Down Expand Up @@ -106,6 +112,7 @@ export function parseArgv(argv: string[]): RunnerOptions {
lessIncludePaths: parsedArgv.lessIncludePaths?.map((item) => item.toString()),
webpackResolveAlias: parsedArgv.webpackResolveAlias ? JSON.parse(parsedArgv.webpackResolveAlias) : undefined,
postcssConfig: parsedArgv.postcssConfig,
arbitraryExtensions: parsedArgv.arbitraryExtensions,
cache: parsedArgv.cache,
cacheStrategy: parsedArgv.cacheStrategy,
logLevel: parsedArgv.logLevel,
Expand Down
1 change: 1 addition & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const DEFAULT_ARBITRARY_EXTENSIONS = false;
5 changes: 4 additions & 1 deletion src/emitter/dts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ const locator = new Locator();
const isExternalFile = () => false;

test('getDtsFilePath', () => {
expect(getDtsFilePath('/app/src/dir/1.css')).toBe('/app/src/dir/1.css.d.ts');
expect(getDtsFilePath('/app/src/dir/1.css', false)).toBe('/app/src/dir/1.css.d.ts');
expect(getDtsFilePath('/app/src/dir/1.scss', false)).toBe('/app/src/dir/1.scss.d.ts');
expect(getDtsFilePath('/app/src/dir/1.css', true)).toBe('/app/src/dir/1.d.css.ts');
expect(getDtsFilePath('/app/src/dir/1.scss', true)).toBe('/app/src/dir/1.d.scss.ts');
});

describe('generateDtsContentWithSourceMap', () => {
Expand Down
12 changes: 9 additions & 3 deletions src/emitter/dts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EOL } from 'os';
import { basename } from 'path';
import { basename, parse, join } from 'path';
import camelcase from 'camelcase';
import { SourceNode, type CodeWithSourceMap } from '../library/source-map/index.js';
import { type Token } from '../locator/index.js';
Expand All @@ -9,10 +9,16 @@ import { getRelativePath, type DtsFormatOptions } from './index.js';
/**
* Get .d.ts file path.
* @param filePath The path to the source file (i.e. `/dir/foo.css`). It is absolute.
* @param arbitraryExtensions Generate `.d.css.ts` instead of `.css.d.ts`.
* @returns The path to the .d.ts file. It is absolute.
*/
export function getDtsFilePath(filePath: string): string {
return filePath + '.d.ts';
export function getDtsFilePath(filePath: string, arbitraryExtensions: boolean): string {
if (arbitraryExtensions) {
const { dir, name, ext } = parse(filePath);
return join(dir, name + '.d' + ext + '.ts');
} else {
return filePath + '.d.ts';
}
}

function dashesCamelCase(str: string): string {
Expand Down
20 changes: 16 additions & 4 deletions src/emitter/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { dirname, isAbsolute, relative } from 'path';
import { DEFAULT_ARBITRARY_EXTENSIONS } from '../config.js';
import { type Token } from '../locator/index.js';
import { type LocalsConvention } from '../runner.js';
import { exists } from '../util.js';
Expand All @@ -20,7 +21,16 @@ export function isSubDirectoryFile(fromDirectory: string, toFilePath: string): b
}

export type DtsFormatOptions = {
/**
* Style of exported class names.
* @default undefined
*/
localsConvention?: LocalsConvention;
/**
* Generate `.d.css.ts` instead of `.css.d.ts`.
* @default false
*/
arbitraryExtensions?: boolean | undefined;
};

/** The options for emitter. */
Expand All @@ -44,8 +54,9 @@ export async function emitGeneratedFiles({
dtsFormatOptions,
isExternalFile,
}: EmitterOptions): Promise<void> {
const dtsFilePath = getDtsFilePath(filePath);
const sourceMapFilePath = getSourceMapFilePath(filePath);
const arbitraryExtensions = dtsFormatOptions?.arbitraryExtensions ?? DEFAULT_ARBITRARY_EXTENSIONS;
const dtsFilePath = getDtsFilePath(filePath, arbitraryExtensions);
const sourceMapFilePath = getSourceMapFilePath(filePath, arbitraryExtensions);
const { dtsContent, sourceMap } = generateDtsContentWithSourceMap(
filePath,
dtsFilePath,
Expand All @@ -72,9 +83,10 @@ export async function emitGeneratedFiles({
export async function isGeneratedFilesExist(
filePath: string,
emitDeclarationMap: boolean | undefined,
arbitraryExtensions: boolean,
): Promise<boolean> {
const dtsFilePath = getDtsFilePath(filePath);
const sourceMapFilePath = getSourceMapFilePath(filePath);
const dtsFilePath = getDtsFilePath(filePath, arbitraryExtensions);
const sourceMapFilePath = getSourceMapFilePath(filePath, arbitraryExtensions);
if (emitDeclarationMap && !(await exists(sourceMapFilePath))) {
return false;
}
Expand Down
5 changes: 4 additions & 1 deletion src/emitter/source-map.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { EOL } from 'os';
import { getSourceMapFilePath, generateSourceMappingURLComment } from './source-map.js';

test('getSourceMapFilePath', () => {
expect(getSourceMapFilePath('/app/src/dir/1.css')).toBe('/app/src/dir/1.css.d.ts.map');
expect(getSourceMapFilePath('/app/src/dir/1.css', false)).toBe('/app/src/dir/1.css.d.ts.map');
expect(getSourceMapFilePath('/app/src/dir/1.scss', false)).toBe('/app/src/dir/1.scss.d.ts.map');
expect(getSourceMapFilePath('/app/src/dir/1.css', true)).toBe('/app/src/dir/1.d.css.ts.map');
expect(getSourceMapFilePath('/app/src/dir/1.scss', true)).toBe('/app/src/dir/1.d.scss.ts.map');
});

test('generateSourceMappingURLComment', () => {
Expand Down
5 changes: 3 additions & 2 deletions src/emitter/source-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import { getRelativePath } from './index.js';
/**
* Get .d.ts.map file path.
* @param filePath The path to the source file (i.e. `foo.css`). It is absolute.
* @param arbitraryExtensions Generate `.d.css.ts` instead of `.css.d.ts`.
* @returns The path to the .d.ts.map file. It is absolute.
*/
export function getSourceMapFilePath(filePath: string): string {
return getDtsFilePath(filePath) + '.map';
export function getSourceMapFilePath(filePath: string, arbitraryExtensions: boolean): string {
return getDtsFilePath(filePath, arbitraryExtensions) + '.map';
}

export function generateSourceMappingURLComment(dtsFilePath: string, sourceMapFilePath: string): string {
Expand Down
17 changes: 16 additions & 1 deletion src/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import AwaitLock from 'await-lock';
import chalk from 'chalk';
import * as chokidar from 'chokidar';
import _glob from 'glob';
import { DEFAULT_ARBITRARY_EXTENSIONS } from './config.js';
import { isGeneratedFilesExist, emitGeneratedFiles } from './emitter/index.js';
import { Locator } from './locator/index.js';
import { Logger } from './logger.js';
Expand All @@ -26,6 +27,10 @@ export type LocalsConvention = 'camelCase' | 'camelCaseOnly' | 'dashes' | 'dashe
export interface RunnerOptions {
pattern: string;
watch?: boolean | undefined;
/**
* Style of exported class names.
* @default undefined
*/
localsConvention?: LocalsConvention | undefined;
declarationMap?: boolean | undefined;
transformer?: Transformer | undefined;
Expand Down Expand Up @@ -55,6 +60,11 @@ export interface RunnerOptions {
* @example '/home/user/repository/src'
*/
postcssConfig?: string | undefined;
/**
* Generate `.d.css.ts` instead of `.css.d.ts`.
* @default false
*/
arbitraryExtensions?: boolean | undefined;
/**
* Only generate .d.ts and .d.ts.map for changed files.
* @default true
Expand Down Expand Up @@ -126,7 +136,11 @@ export async function run(options: RunnerOptions): Promise<Watcher | void> {
await lock.acquireAsync();

try {
const _isGeneratedFilesExist = await isGeneratedFilesExist(filePath, options.declarationMap);
const _isGeneratedFilesExist = await isGeneratedFilesExist(
filePath,
options.declarationMap,
options.arbitraryExtensions ?? DEFAULT_ARBITRARY_EXTENSIONS,
);
const _isChangedFile = await isChangedFile(filePath);
// Generate .d.ts and .d.ts.map only when the file has been updated.
// However, if .d.ts or .d.ts.map has not yet been generated, always generate.
Expand All @@ -142,6 +156,7 @@ export async function run(options: RunnerOptions): Promise<Watcher | void> {
emitDeclarationMap: options.declarationMap,
dtsFormatOptions: {
localsConvention: options.localsConvention,
arbitraryExtensions: options.arbitraryExtensions,
},
isExternalFile,
});
Expand Down

0 comments on commit b7822b5

Please sign in to comment.