Skip to content

Commit d86122f

Browse files
committed
feat: 🎸 support defining default languages
✅ Closes: #189
1 parent 16b1325 commit d86122f

File tree

5 files changed

+93
-47
lines changed

5 files changed

+93
-47
lines changed

Diff for: ‎src/autoProcess.ts

+36-15
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,20 @@ import {
1212
import { hasDepInstalled } from './modules/hasDepInstalled';
1313
import { concat } from './modules/concat';
1414
import { parseFile } from './modules/parseFile';
15-
import { addLanguageAlias } from './modules/language';
15+
import { addLanguageAlias, getLanguageFromAlias } from './modules/language';
1616
import { throwError } from './modules/errors';
1717

1818
type AutoPreprocessOptions = {
1919
markupTagName?: string;
2020
aliases?: Array<[string, string]>;
2121
preserve?: string[];
22+
defaults?: {
23+
markup?: string;
24+
style?: string;
25+
script?: string;
26+
};
27+
28+
// transformers
2229
typescript?: TransformerOptions<Options.Typescript>;
2330
scss?: TransformerOptions<Options.Sass>;
2431
sass?: TransformerOptions<Options.Sass>;
@@ -27,7 +34,7 @@ type AutoPreprocessOptions = {
2734
postcss?: TransformerOptions<Options.Postcss>;
2835
coffeescript?: TransformerOptions<Options.Coffeescript>;
2936
pug?: TransformerOptions<Options.Pug>;
30-
globalStyle?: Options.GlobalStyle;
37+
globalStyle?: Options.GlobalStyle | boolean;
3138
replace?: Options.Replace;
3239
// workaround while we don't have this
3340
// https://github.com/microsoft/TypeScript/issues/17867
@@ -50,6 +57,10 @@ export const runTransformer = async (
5057
options: TransformerOptions,
5158
{ content, map, filename, attributes }: TransformerArgs<any>,
5259
): Promise<Processed> => {
60+
if (options === false) {
61+
return { code: content };
62+
}
63+
5364
// remove any unnecessary indentation (useful for coffee, pug and sugarss)
5465
content = stripIndent(content);
5566

@@ -79,11 +90,19 @@ export function autoPreprocess(
7990
aliases,
8091
markupTagName = 'template',
8192
preserve = [],
93+
defaults,
8294
...rest
8395
}: AutoPreprocessOptions = {} as AutoPreprocessOptions,
8496
): PreprocessorGroup {
8597
markupTagName = markupTagName.toLocaleLowerCase();
8698

99+
const defaultLanguages = {
100+
markup: 'html',
101+
style: 'css',
102+
script: 'javascript',
103+
...defaults,
104+
};
105+
87106
const transformers = rest as Transformers;
88107
const markupPattern = new RegExp(
89108
`<${markupTagName}([\\s\\S]*?)(?:>([\\s\\S]*)<\\/${markupTagName}>|/>)`,
@@ -119,27 +138,29 @@ export function autoPreprocess(
119138
return (optionsCache[alias] = opts);
120139
};
121140

122-
const getTransformerTo = (targetLanguage: string): Preprocessor => async (
123-
svelteFile,
124-
) => {
125-
const {
141+
const getTransformerTo = (
142+
type: 'markup' | 'script' | 'style',
143+
targetLanguage: string,
144+
): Preprocessor => async (svelteFile) => {
145+
let {
126146
content,
127147
filename,
128148
lang,
129149
alias,
130150
dependencies,
131151
attributes,
132-
} = await parseFile(svelteFile, targetLanguage);
152+
} = await parseFile(svelteFile);
153+
154+
if (lang == null || alias == null) {
155+
alias = defaultLanguages[type];
156+
lang = getLanguageFromAlias(alias);
157+
}
133158

134159
if (preserve.includes(lang) || preserve.includes(alias)) {
135160
return;
136161
}
137162

138-
if (
139-
lang === targetLanguage ||
140-
transformers[lang] === false ||
141-
transformers[alias] === false
142-
) {
163+
if (lang === targetLanguage) {
143164
return { code: content, dependencies };
144165
}
145166

@@ -155,9 +176,9 @@ export function autoPreprocess(
155176
};
156177
};
157178

158-
const scriptTransformer = getTransformerTo('javascript');
159-
const cssTransformer = getTransformerTo('css');
160-
const markupTransformer = getTransformerTo('html');
179+
const scriptTransformer = getTransformerTo('script', 'javascript');
180+
const cssTransformer = getTransformerTo('style', 'css');
181+
const markupTransformer = getTransformerTo('markup', 'html');
161182

162183
return {
163184
async markup({ content, filename }) {

Diff for: ‎src/modules/language.ts

+13-10
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,27 @@ export const ALIAS_MAP = new Map([
1515
export const addLanguageAlias = (entries: Array<[string, string]>) =>
1616
entries.forEach((entry) => ALIAS_MAP.set(...entry));
1717

18-
export const getLanguage = (
19-
attributes: PreprocessorArgs['attributes'],
20-
defaultLang: string,
21-
) => {
22-
let lang = defaultLang;
18+
export const getLanguageFromAlias = (alias: string | null) => {
19+
return ALIAS_MAP.get(alias) || alias;
20+
};
21+
22+
export const getLanguage = (attributes: PreprocessorArgs['attributes']) => {
23+
let alias = null;
2324

2425
if (attributes.lang) {
2526
// istanbul ignore if
2627
if (typeof attributes.lang !== 'string') {
2728
throw new Error('lang attribute must be string');
2829
}
2930

30-
lang = attributes.lang;
31+
alias = attributes.lang;
3132
} else if (attributes.type) {
3233
// istanbul ignore if
3334
if (typeof attributes.type !== 'string') {
3435
throw new Error('type attribute must be string');
3536
}
3637

37-
lang = attributes.type.replace(/^(text|application)\/(.*)$/, '$2');
38+
alias = attributes.type.replace(/^(text|application)\/(.*)$/, '$2');
3839
} else if (attributes.src) {
3940
// istanbul ignore if
4041
if (typeof attributes.src !== 'string') {
@@ -43,11 +44,13 @@ export const getLanguage = (
4344

4445
const parts = basename(attributes.src).split('.');
4546

46-
lang = parts.length > 1 ? parts.pop() : defaultLang;
47+
if (parts.length > 1) {
48+
alias = parts.pop();
49+
}
4750
}
4851

4952
return {
50-
lang: ALIAS_MAP.get(lang) || lang,
51-
alias: lang,
53+
lang: getLanguageFromAlias(alias),
54+
alias,
5255
};
5356
};

Diff for: ‎src/modules/parseFile.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ async function doesFileExist(file: string) {
2121
return new Promise((resolve) => access(file, 0, (err) => resolve(!err)));
2222
}
2323

24-
export const parseFile = async (
25-
{ attributes, filename, content }: PreprocessorArgs,
26-
language: string,
27-
) => {
24+
export const parseFile = async ({
25+
attributes,
26+
filename,
27+
content,
28+
}: PreprocessorArgs) => {
2829
const dependencies = [];
2930

3031
/** only include src file if content of tag is empty */
@@ -48,7 +49,7 @@ export const parseFile = async (
4849
}
4950
}
5051

51-
const { lang, alias } = getLanguage(attributes, language);
52+
const { lang, alias } = getLanguage(attributes);
5253

5354
return {
5455
filename,

Diff for: ‎test/autoProcess/autoProcess.test.ts

+29-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ describe('detect - mimetype', () => {
1313
{ type: 'text/some-other', targetLanguage: 'some-other' },
1414
{ lang: 'stylus', targetLanguage: 'stylus' },
1515
{ src: '../foo.js', targetLanguage: 'javascript' },
16-
{ src: '../foo', targetLanguage: 'javascript' },
1716
{
1817
src: '../foo.custom',
1918
lang: 'customLanguage',
@@ -25,7 +24,7 @@ describe('detect - mimetype', () => {
2524
it(`should detect '${
2625
src || type || lang
2726
}' as '${targetLanguage}'`, async () => {
28-
const language = getLanguage({ type, lang, src }, targetLanguage);
27+
const language = getLanguage({ type, lang, src });
2928

3029
expect(language).toMatchObject({ lang: targetLanguage });
3130
});
@@ -137,4 +136,32 @@ describe('options', () => {
137136

138137
expect(await doesCompileThrow(input, opts)).toBe(true);
139138
});
139+
140+
it('should accept other languages as default', async () => {
141+
const input = `<template>markup</template><style>style</style><script>script</script>`;
142+
143+
const opts = getAutoPreprocess({
144+
defaults: {
145+
markup: 'customMarkup',
146+
script: 'customScript',
147+
style: 'customStyle',
148+
},
149+
globalStyle: false,
150+
customMarkup({ content }) {
151+
return { code: content.replace('markup', 'potato') };
152+
},
153+
customScript({ content }) {
154+
return { code: content.replace('script', 'potato') };
155+
},
156+
customStyle({ content }) {
157+
return { code: content.replace('style', 'potato') };
158+
},
159+
});
160+
161+
const preprocessed = await preprocess(input, opts);
162+
163+
expect(preprocessed.toString()).toContain(
164+
'potato<style>potato</style><script>potato</script>',
165+
);
166+
});
140167
});

Diff for: ‎test/modules.test.ts

+9-15
Original file line numberDiff line numberDiff line change
@@ -75,24 +75,18 @@ describe('globalifySelector', () => {
7575

7676
describe(`parse svelte file`, () => {
7777
it('should only include src files if content is empty', async () => {
78-
let parsedFile = await parseFile(
79-
{
80-
content: '',
81-
attributes: { src: './fixtures/style.scss' },
82-
filename: getTestAppFilename(),
83-
},
84-
'css',
85-
);
78+
let parsedFile = await parseFile({
79+
content: '',
80+
attributes: { src: './fixtures/style.scss' },
81+
filename: getTestAppFilename(),
82+
});
8683

8784
expect(parsedFile.content).toEqual(getFixtureContent('style.scss'));
8885

89-
parsedFile = await parseFile(
90-
{
91-
...parsedFile,
92-
attributes: { src: './fixtures/style.css' },
93-
},
94-
'css',
95-
);
86+
parsedFile = await parseFile({
87+
...parsedFile,
88+
attributes: { src: './fixtures/style.css' },
89+
});
9690

9791
expect(parsedFile.content).toEqual(getFixtureContent('style.scss'));
9892
});

0 commit comments

Comments
 (0)