forked from akveo/react-native-ui-kitten
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate-doc-app-navigation.ts
90 lines (74 loc) · 3.68 KB
/
create-doc-app-navigation.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import * as fs from 'fs';
import * as path from 'path';
import { pascalCase } from 'change-case';
interface ShowcaseMap {
[componentName: string]: ComponentShowcase;
}
interface ComponentShowcase {
showcases: ShowcaseInfo[];
}
interface ShowcaseInfo {
name: string;
routeName: string;
path: string;
}
interface ShowcaseRouteMap {
[showcaseName: string]: string;
}
export const createDocAppNavigation = (showcasePath: string): string => {
const showcaseDirs: string[] = fs.readdirSync(showcasePath).filter((dirOrFile: string) => {
return !dirOrFile.endsWith('.tsx');
});
const showcaseMap: ShowcaseMap = showcaseDirs.reduce((map, component: string) => {
return { ...map, [component]: createComponentShowcase(showcasePath, component) };
}, {});
const showcaseRouteMap: ShowcaseRouteMap = Object.keys(showcaseMap).reduce((routes, component: string) => {
const componentShowcaseRouteMap: ShowcaseRouteMap = createShowcaseRouteMap(showcaseMap, component);
return { ...routes, ...componentShowcaseRouteMap };
}, {});
const importStatements: string[] = Object.keys(showcaseMap).reduce((statements, component: string) => {
const componentImportStatements: string[] = createShowcaseImportStatements(showcaseMap, component);
return [...statements, componentImportStatements.join('\n')];
}, []);
const routesStatement: string = createRoutesStatement(showcaseRouteMap);
return createOutput(importStatements, [routesStatement]);
};
const createShowcaseRouteMap = (map: ShowcaseMap, component: string): ShowcaseRouteMap => {
return map[component].showcases.reduce((componentShowcases, showcaseInfo: ShowcaseInfo) => {
const container = showcaseInfo.name.endsWith(`ThemingShowcase`) ? 'ShowcaseThemingIFrame' : 'ShowcaseIFrame';
const showcaseScreenStatement = `() => ${container}(${showcaseInfo.name}, '${showcaseInfo.routeName}')`;
return { ...componentShowcases, [showcaseInfo.routeName]: showcaseScreenStatement };
}, {});
};
const createShowcaseImportStatements = (map: ShowcaseMap, component: string): string[] => {
return map[component].showcases.map((showcaseInfo: ShowcaseInfo): string => {
const platformComponentPath: string = path.parse(showcaseInfo.path).name;
return `import { ${showcaseInfo.name} } from '../components/${component}/${platformComponentPath}';`;
});
};
const createComponentShowcase = (showcasePath: string, component: string): ComponentShowcase => {
const showcaseFiles: string[] = fs.readdirSync(path.resolve(showcasePath, component));
return showcaseFiles.reduce((showcaseAcc: ComponentShowcase, showcaseFile: string) => {
const routeName: string = pascalCase(`${showcaseFile.split('.component.tsx')[0]}`);
const showcaseInfo: ShowcaseInfo = { name: `${routeName}Showcase`, routeName, path: showcaseFile };
return { ...showcaseAcc, showcases: [...showcaseAcc.showcases, showcaseInfo] };
}, { showcases: [] });
};
const createOutput = (imports: string[], statements: string[]): string => {
return [
'import React from \'react\';',
'import { createBrowserApp } from \'@react-navigation/web\';',
'import { createStackNavigator } from \'react-navigation-stack\';',
'import { ShowcaseIFrame } from \'../components/showcaseIFrame.component\';',
'import { ShowcaseThemingIFrame } from \'../components/showcaseThemingIFrame.component\';',
...imports,
'',
...statements,
'',
`const AppStack = createStackNavigator(routes, { headerMode: 'none' });`,
`export const AppNavigator = createBrowserApp(AppStack, { history: 'hash' });`,
].join('\n');
};
const createRoutesStatement = (map: ShowcaseRouteMap): string => {
return `const routes = ${JSON.stringify(map, null, 2).replace(/"/g, '')};`;
};