Skip to content

Commit 93b9f0f

Browse files
committed
extract writers
1 parent 8119f27 commit 93b9f0f

File tree

7 files changed

+119
-86
lines changed

7 files changed

+119
-86
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@ interface Configuration {
2020
build?: boolean,
2121
},
2222
routes?: {
23-
build?: true,
23+
build?: boolean,
2424
type?: 'tsx'|'jsx',
25+
overridePathMappings?: {
26+
[filesystemPath: string]: string,
27+
},
2528
},
2629
htmlMinify?: {
2730
collapseBooleanAttributes?: boolean,
@@ -37,9 +40,6 @@ interface Configuration {
3740
},
3841
fileFinder?: {
3942
fileName?: string,
40-
overridePathMappings?: {
41-
[filesystemPath: string]: string,
42-
},
4343
pagesRoot?: string,
4444
distJSRoot?: string,
4545
},

src/configuration.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export interface Configuration {
3535
}
3636

3737
export default (cwd: string, cliArguments: string[]): Configuration => {
38-
const config = {
38+
const config: Configuration = {
3939
sitemap: {
4040
build: true,
4141
domain: '',
@@ -68,7 +68,7 @@ export default (cwd: string, cliArguments: string[]): Configuration => {
6868
};
6969
const configFile = cwd + '/.idrinth-react-file-based-routes.json';
7070
if (existsSync(configFile)) {
71-
const userconfig = JSON.parse(readFileSync(configFile, 'utf-8'));
71+
const userconfig: Partial<Configuration> = JSON.parse(readFileSync(configFile, 'utf-8'));
7272
if (typeof userconfig === 'object') {
7373
for (const prop of Object.keys(config)) {
7474
if (typeof userconfig[prop] === 'object' && typeof config[prop] === 'object') {
@@ -85,13 +85,11 @@ export default (cwd: string, cliArguments: string[]): Configuration => {
8585
if (param.startsWith('--')) {
8686
const [setting, value,] = param.substring(2).split('=');
8787
const [group, detail,] = setting.split('.');
88-
if (group && typeof config[group] === 'object') {
89-
if (detail) {
90-
if (typeof config[group][detail] === 'boolean') {
91-
config[group][detail] = !config[group][detail];
92-
} else if(typeof config[group][detail] === 'string' && value) {
93-
config[group][detail] = value;
94-
}
88+
if (group && typeof config[group] === 'object' && detail) {
89+
if (typeof config[group][detail] === 'boolean') {
90+
config[group][detail] = !config[group][detail];
91+
} else if(typeof config[group][detail] === 'string' && value) {
92+
config[group][detail] = value;
9593
}
9694
}
9795
}

src/generate-routes.ts

Lines changed: 19 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,34 @@
11
import {readdirSync, statSync, writeFileSync,} from 'fs';
22
import paddedDate from './padded-date.js';
33
import {Configuration} from "./configuration.js";
4+
import TsxWriter from "./tsx-writer";
5+
import JsxWriter from "./jsx-writer";
6+
import SitemapWriter from "./sitemap-writer";
7+
import Writer from "./writer";
48

59
export default (cwd: string, configuration: Configuration) => {
6-
let xml = '<?xml version="1.0" encoding="UTF-8"?>';
7-
let jsx = 'import React, {\n' +
8-
' lazy,\n' +
9-
' Suspense,\n' +
10-
'} from \'react\';\n' +
11-
'export default (Loader) => [';
12-
let tsx = 'import React, {\n' +
13-
' lazy,\n' +
14-
' Suspense,\n' +
15-
' ElementType,\n' +
16-
'} from \'react\';\n' +
17-
'export default (Loader: ElementType) => [';
18-
xml += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
10+
const writers: Writer[] = [];
11+
if (configuration.routes.build && configuration.routes.type === 'tsx') {
12+
writers.push(new TsxWriter())
13+
}
14+
if (configuration.routes.build && configuration.routes.type === 'jsx') {
15+
writers.push(new JsxWriter())
16+
}
17+
if (configuration.sitemap.build) {
18+
writers.push(new SitemapWriter());
19+
}
1920
for (const file of readdirSync(cwd + '/' + configuration.fileFinder.pagesRoot, {encoding: 'utf8', recursive: true})) {
2021
if (file.endsWith('/' + configuration.fileFinder.fileName) || file.endsWith('\\' + configuration.fileFinder.fileName)) {
2122
const mtime = statSync(cwd + '/' + configuration.fileFinder.pagesRoot + '/' + file).mtime;
2223
const changed = paddedDate(mtime);
2324
const path = file.replace(/\\/ug, '/').substring(0, file.length - configuration.fileFinder.fileName.length - 1);
24-
if (typeof configuration.routes.overridePathMappings[path] === 'string') {
25-
if (configuration.routes.overridePathMappings[path] !== '*') {
26-
xml += `<url><loc>https://${ configuration.sitemap.domain }${configuration.routes.overridePathMappings[path]}/</loc>`;
27-
xml += `<lastmod>${changed}</lastmod></url>`;
28-
}
29-
jsx += '\n ' + `(() => {
30-
const LazyElement = lazy(() => import(
31-
\`./pages/${path}/index.tsx\`,
32-
),);
33-
return {
34-
path: '${ configuration.routes.overridePathMappings[path] }',
35-
exact: true,
36-
element: <Suspense fallback={<Loader/>}><LazyElement/></Suspense>,
37-
};
38-
})(),`;
39-
tsx += `(() => {
40-
const LazyElement = lazy(() => import(
41-
\`./pages/${path}/index.tsx\`,
42-
),);
43-
return {
44-
path: '${ configuration.routes.overridePathMappings[path] }',
45-
exact: true,
46-
element: <Suspense fallback={<Loader/>}><LazyElement/></Suspense>,
47-
};
48-
})(),`;
49-
} else {
50-
xml += `<url><loc>https://${configuration.sitemap.domain}/${path}/</loc>`;
51-
xml += `<lastmod>${changed}</lastmod></url>`;
52-
jsx += '\n ' + `(() => {
53-
const LazyElement = lazy(() => import(
54-
\`./pages/${path}/index.tsx\`,
55-
),);
56-
return {
57-
path: '/${path}/',
58-
exact: true,
59-
element: <Suspense fallback={<Loader/>}><LazyElement/></Suspense>,
60-
};
61-
})(),`;
62-
tsx += '\n ' + `(() => {
63-
const LazyElement = lazy(() => import(
64-
\'./pages/${ path }/index.tsx\',
65-
),);
66-
return {
67-
path: '/${ path }/',
68-
exact: true,
69-
element: <Suspense fallback={<Loader/>}><LazyElement/></Suspense>,
70-
};
71-
})(),`;
25+
const url = typeof configuration.routes.overridePathMappings[path] === 'string' ? configuration.routes.overridePathMappings[path] : `/${path}/`;
26+
for (const writer of writers) {
27+
writer.add(path, url, configuration.sitemap.domain, changed);
7228
}
7329
}
7430
}
75-
xml += '</urlset>';
76-
jsx += '\n];'
77-
tsx += '\n];'
78-
79-
if (configuration.routes.build && configuration.routes.type === 'jsx') {
80-
writeFileSync(cwd + '/src/routes.jsx', jsx);
81-
}
82-
if (configuration.routes.build && configuration.routes.type === 'tsx') {
83-
writeFileSync(cwd + '/src/routes.tsx', tsx);
84-
}
85-
if (configuration.sitemap.build) {
86-
writeFileSync(cwd + '/public/sitemap.xml', xml);
31+
for (const writer of writers) {
32+
writeFileSync(cwd + '/' + writer.fileName(), writer.toString());
8733
}
8834
};

src/jsx-writer.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import Writer from './writer.js';
2+
3+
export default class JsxWriter implements Writer {
4+
fileName(): string {
5+
return 'src/routes.jsx';
6+
}
7+
private items: string[] = [];
8+
add(path: string, url: string, domain: string, changed: string): void
9+
{
10+
this.items.push(' ' + `(() => {
11+
const LazyElement = lazy(() => import(
12+
\'./pages/${path}/index.tsx\',
13+
),);
14+
return {
15+
path: \'${url}\',
16+
exact: true,
17+
element: <Suspense fallback={<Loader/>}><LazyElement/></Suspense>,
18+
};
19+
})(),`);
20+
}
21+
toString(): string {
22+
return 'import React, {\n' +
23+
' lazy,\n' +
24+
' Suspense,\n' +
25+
'} from \'react\';\n' +
26+
'export default (Loader) => [\n '
27+
+ this.items.join('\n ')
28+
+ '\n];'
29+
}
30+
}

src/sitemap-writer.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import Writer from './writer.js';
2+
3+
export default class SitemapWriter implements Writer {
4+
fileName(): string {
5+
return 'public/sitemap.xml';
6+
}
7+
private items: string[] = [];
8+
add(path: string, url: string, domain: string, changed: string): void
9+
{
10+
if (url === '*') {
11+
return;
12+
}
13+
this.items.push(`<url><loc>https://${domain}/${url}/</loc><lastmod>${changed}</lastmod></url>`);
14+
}
15+
toString(): string {
16+
return '<?xml version="1.0" encoding="UTF-8"?>' +
17+
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'
18+
+ this.items.join('')
19+
+ '</urlset>'
20+
21+
}
22+
}

src/tsx-writer.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import Writer from './writer.js';
2+
3+
export default class TsxWriter implements Writer {
4+
fileName(): string {
5+
return 'src/routes.tsx';
6+
}
7+
private items: string[] = [];
8+
add(path: string, url: string, domain: string, changed: string): void
9+
{
10+
this.items.push(' ' + `(() => {
11+
const LazyElement = lazy(() => import(
12+
\'./pages/${path}/index.tsx\',
13+
),);
14+
return {
15+
path: \'${url}\',
16+
exact: true,
17+
element: <Suspense fallback={<Loader/>}><LazyElement/></Suspense>,
18+
};
19+
})(),`);
20+
}
21+
toString(): string {
22+
return 'import React, {\n' +
23+
' lazy,\n' +
24+
' Suspense,\n' +
25+
' ElementType,\n' +
26+
'} from \'react\';\n' +
27+
'export default (Loader: ElementType) => [\n '
28+
+ this.items.join('\n ')
29+
+ '\n];'
30+
31+
}
32+
}

src/writer.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default interface Writer {
2+
add(path: string, url: string, domain: string, changed: string): void;
3+
toString(): string;
4+
fileName(): string;
5+
}

0 commit comments

Comments
 (0)