Skip to content

Commit 7bdd782

Browse files
committed
✨ add ability to compile localized headers
close #87
1 parent 8187d30 commit 7bdd782

File tree

16 files changed

+465
-295
lines changed

16 files changed

+465
-295
lines changed

lib/const.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const DEFAULT_LOCALE_KEY = '';

lib/features/default-tags.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1+
import { DEFAULT_LOCALE_KEY } from '..//const';
12
import { UserscriptPluginInstance } from '../types';
23
import { Feature } from './feature';
34

45
export class SetDefaultTags extends Feature {
56
public readonly name = 'SetDefaultTags';
67

78
public apply({ hooks }: UserscriptPluginInstance): void {
8-
hooks.headers.tap(this.constructor.name, (headers) => {
9-
if (headers.include === undefined && headers.match === undefined) {
9+
hooks.headers.tap(this.constructor.name, (headers, { locale }) => {
10+
if (
11+
locale === DEFAULT_LOCALE_KEY &&
12+
headers.include === undefined &&
13+
headers.match === undefined
14+
) {
1015
return {
1116
...headers,
1217
match: '*://*/*',

lib/features/load-headers.ts

Lines changed: 0 additions & 156 deletions
This file was deleted.

lib/features/load-headers/impl.ts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { DEFAULT_LOCALE_KEY } from '../../const';
2+
import {
3+
HeadersProps,
4+
UserscriptPluginInstance,
5+
WaterfallContext,
6+
} from '../../types';
7+
import { Feature } from '../feature';
8+
import {
9+
FileLoader,
10+
HeadersFile,
11+
HeadersProvider,
12+
ObjectLoader,
13+
PackageLoader,
14+
ProviderLoader,
15+
} from './loaders';
16+
17+
export type HeadersOption = HeadersProps | HeadersFile | HeadersProvider;
18+
19+
export interface LoadHeadersOptions {
20+
root?: string;
21+
headers?: HeadersOption;
22+
i18n?: Record<string, HeadersOption>;
23+
}
24+
25+
export class LoadHeaders extends Feature<LoadHeadersOptions> {
26+
public readonly name = 'LoadHeaders';
27+
28+
private packageLoader!: PackageLoader;
29+
private objectLoaders: Map<string, ObjectLoader> = new Map();
30+
private fileLoaders: Map<string, FileLoader> = new Map();
31+
private providerLoaders: Map<string, ProviderLoader> = new Map();
32+
33+
public apply({ hooks }: UserscriptPluginInstance): void {
34+
const { headers: headersOption, i18n = {}, root } = this.options;
35+
36+
this.packageLoader = new PackageLoader(root);
37+
38+
if (headersOption) {
39+
this.addLoader(DEFAULT_LOCALE_KEY, headersOption);
40+
}
41+
42+
for (const [locale, i18nHeadersOption] of Object.entries(i18n)) {
43+
this.addLoader(locale, i18nHeadersOption);
44+
}
45+
46+
hooks.init.tapPromise(this.name, async (compiler) => {
47+
await this.packageLoader.load(compiler);
48+
});
49+
50+
if (this.fileLoaders.size > 0) {
51+
hooks.preprocess.tapPromise(this.name, async (compilation) => {
52+
await Promise.all(
53+
Array.from(this.fileLoaders.values()).map((fileLoader) =>
54+
fileLoader.load(compilation),
55+
),
56+
);
57+
});
58+
}
59+
60+
hooks.headers.tapPromise(this.name, async (_, ctx) =>
61+
this.provideHeaders(ctx),
62+
);
63+
}
64+
65+
private addLoader(locale: string, headersOption: HeadersOption): void {
66+
if (typeof headersOption === 'object') {
67+
this.objectLoaders.set(locale, new ObjectLoader(headersOption));
68+
69+
return;
70+
}
71+
72+
if (typeof headersOption === 'string') {
73+
this.fileLoaders.set(
74+
locale,
75+
new FileLoader(headersOption, this.options.root),
76+
);
77+
78+
return;
79+
}
80+
81+
this.providerLoaders.set(locale, new ProviderLoader(headersOption));
82+
}
83+
84+
private async provideHeaders(ctx: WaterfallContext): Promise<HeadersProps> {
85+
const { locale } = ctx;
86+
const headersBase = {};
87+
88+
if (locale === DEFAULT_LOCALE_KEY) {
89+
Object.assign(headersBase, this.packageLoader.headers);
90+
}
91+
Object.assign(headersBase, this.objectLoaders.get(locale)?.headers);
92+
Object.assign(headersBase, this.fileLoaders.get(locale)?.headers);
93+
94+
return (
95+
this.providerLoaders.get(locale)?.load(headersBase, ctx) ?? headersBase
96+
);
97+
}
98+
}

lib/features/load-headers/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './impl';
2+
export * from './loaders';

0 commit comments

Comments
 (0)