@modern-js/app-tools 2.53.0 → 2.53.1-alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. package/dist/cjs/plugins/deploy/dependencies/index.js +5 -13
  2. package/dist/cjs/plugins/deploy/platforms/netlify.js +1 -1
  3. package/dist/cjs/plugins/deploy/platforms/node.js +1 -1
  4. package/dist/cjs/plugins/deploy/platforms/vercel.js +1 -1
  5. package/dist/esm/plugins/deploy/dependencies/index.js +20 -28
  6. package/dist/esm/plugins/deploy/platforms/netlify.js +1 -1
  7. package/dist/esm/plugins/deploy/platforms/node.js +1 -1
  8. package/dist/esm/plugins/deploy/platforms/vercel.js +1 -1
  9. package/dist/esm-node/plugins/deploy/dependencies/index.js +6 -14
  10. package/dist/esm-node/plugins/deploy/platforms/netlify.js +1 -1
  11. package/dist/esm-node/plugins/deploy/platforms/node.js +1 -1
  12. package/dist/esm-node/plugins/deploy/platforms/vercel.js +1 -1
  13. package/dist/js/modern/analyze/constants.js +15 -0
  14. package/dist/js/modern/analyze/generateCode.js +179 -0
  15. package/dist/js/modern/analyze/getBundleEntry.js +75 -0
  16. package/dist/js/modern/analyze/getClientRoutes.js +219 -0
  17. package/dist/js/modern/analyze/getFileSystemEntry.js +74 -0
  18. package/dist/js/modern/analyze/getHtmlTemplate.js +82 -0
  19. package/dist/js/modern/analyze/getServerRoutes.js +192 -0
  20. package/dist/js/modern/analyze/index.js +148 -0
  21. package/dist/js/modern/analyze/isDefaultExportFunction.js +32 -0
  22. package/dist/js/modern/analyze/makeLegalIdentifier.js +16 -0
  23. package/dist/js/modern/analyze/templates.js +88 -0
  24. package/dist/js/modern/analyze/utils.js +92 -0
  25. package/dist/js/modern/commands/build.js +154 -0
  26. package/dist/js/modern/commands/deploy.js +5 -0
  27. package/dist/js/modern/commands/dev.js +95 -0
  28. package/dist/js/modern/commands/index.js +3 -0
  29. package/dist/js/modern/commands/inspect.js +69 -0
  30. package/dist/js/modern/commands/start.js +31 -0
  31. package/dist/js/modern/exports/server.js +1 -0
  32. package/dist/js/modern/hooks.js +21 -0
  33. package/dist/js/modern/index.js +109 -0
  34. package/dist/js/modern/locale/en.js +35 -0
  35. package/dist/js/modern/locale/index.js +9 -0
  36. package/dist/js/modern/locale/zh.js +35 -0
  37. package/dist/js/modern/utils/config.js +78 -0
  38. package/dist/js/modern/utils/createCompiler.js +61 -0
  39. package/dist/js/modern/utils/createServer.js +18 -0
  40. package/dist/js/modern/utils/getSpecifiedEntries.js +36 -0
  41. package/dist/js/modern/utils/language.js +5 -0
  42. package/dist/js/modern/utils/printInstructions.js +11 -0
  43. package/dist/js/modern/utils/routes.js +15 -0
  44. package/dist/js/modern/utils/types.js +0 -0
  45. package/dist/js/node/analyze/constants.js +36 -0
  46. package/dist/js/node/analyze/generateCode.js +208 -0
  47. package/dist/js/node/analyze/getBundleEntry.js +89 -0
  48. package/dist/js/node/analyze/getClientRoutes.js +241 -0
  49. package/dist/js/node/analyze/getFileSystemEntry.js +90 -0
  50. package/dist/js/node/analyze/getHtmlTemplate.js +106 -0
  51. package/dist/js/node/analyze/getServerRoutes.js +208 -0
  52. package/dist/js/node/analyze/index.js +178 -0
  53. package/dist/js/node/analyze/isDefaultExportFunction.js +50 -0
  54. package/dist/js/node/analyze/makeLegalIdentifier.js +24 -0
  55. package/dist/js/node/analyze/templates.js +106 -0
  56. package/dist/js/node/analyze/utils.js +113 -0
  57. package/dist/js/node/commands/build.js +174 -0
  58. package/dist/js/node/commands/deploy.js +14 -0
  59. package/dist/js/node/commands/dev.js +120 -0
  60. package/dist/js/node/commands/index.js +44 -0
  61. package/dist/js/node/commands/inspect.js +98 -0
  62. package/dist/js/node/commands/start.js +47 -0
  63. package/dist/js/node/exports/server.js +13 -0
  64. package/dist/js/node/hooks.js +39 -0
  65. package/dist/js/node/index.js +141 -0
  66. package/dist/js/node/locale/en.js +42 -0
  67. package/dist/js/node/locale/index.js +20 -0
  68. package/dist/js/node/locale/zh.js +42 -0
  69. package/dist/js/node/utils/config.js +103 -0
  70. package/dist/js/node/utils/createCompiler.js +81 -0
  71. package/dist/js/node/utils/createServer.js +35 -0
  72. package/dist/js/node/utils/getSpecifiedEntries.js +46 -0
  73. package/dist/js/node/utils/language.js +13 -0
  74. package/dist/js/node/utils/printInstructions.js +22 -0
  75. package/dist/js/node/utils/routes.js +25 -0
  76. package/dist/js/node/utils/types.js +0 -0
  77. package/dist/types/config/initialize/inits.d.ts +1 -1
  78. package/dist/types/plugins/deploy/dependencies/index.d.ts +2 -1
  79. package/package.json +5 -5
@@ -0,0 +1,219 @@
1
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
2
+
3
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
4
+
5
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
+
7
+ import path from 'path';
8
+ import { fs, createDebugger, findExists, normalizeToPosixPath } from '@modern-js/utils';
9
+ import { makeLegalIdentifier } from "./makeLegalIdentifier";
10
+ import { FILE_SYSTEM_ROUTES_COMPONENTS_DIR, FILE_SYSTEM_ROUTES_DYNAMIC_REGEXP, FILE_SYSTEM_ROUTES_GLOBAL_LAYOUT, FILE_SYSTEM_ROUTES_IGNORED_REGEX, FILE_SYSTEM_ROUTES_INDEX, FILE_SYSTEM_ROUTES_LAYOUT, JS_EXTENSIONS } from "./constants";
11
+ const debug = createDebugger('get-client-routes');
12
+
13
+ const findLayout = dir => findExists(JS_EXTENSIONS.map(ext => path.resolve(dir, `${FILE_SYSTEM_ROUTES_LAYOUT}${ext}`)));
14
+
15
+ const shouldSkip = file => {
16
+ // should not skip directory.
17
+ if (fs.statSync(file).isDirectory()) {
18
+ return false;
19
+ }
20
+
21
+ const ext = path.extname(file);
22
+
23
+ if (FILE_SYSTEM_ROUTES_IGNORED_REGEX.test(file) || !JS_EXTENSIONS.includes(ext) || FILE_SYSTEM_ROUTES_GLOBAL_LAYOUT === path.basename(file, ext)) {
24
+ return true;
25
+ }
26
+
27
+ return false;
28
+ };
29
+
30
+ const replaceWithAlias = (base, filePath, alias) => normalizeToPosixPath(path.join(alias, path.relative(base, filePath)));
31
+
32
+ const compName = (srcDirectory, filePath) => {
33
+ const legalCompName = makeLegalIdentifier(path.relative(srcDirectory, filePath));
34
+ return `Comp_${legalCompName}`;
35
+ };
36
+
37
+ const layoutNameAbbr = filePath => {
38
+ const prefix = 'L_';
39
+ const dirName = path.dirname(filePath).split('/').pop() || '';
40
+ return `${prefix}${makeLegalIdentifier(dirName)}`;
41
+ };
42
+
43
+ const parents = [];
44
+ /* eslint-disable no-param-reassign */
45
+
46
+ const recursiveReadDir = ({
47
+ dir,
48
+ routes,
49
+ basePath: _basePath = '/',
50
+ srcDirectory,
51
+ srcAlias
52
+ }) => {
53
+ let hasDynamicRoute = false;
54
+ let resetParent = false;
55
+ let parent = parents[parents.length - 1];
56
+ const layout = findLayout(dir);
57
+
58
+ if (layout) {
59
+ if (_basePath === '/') {
60
+ throw new Error(`should use _app instead of _layout in ${dir}`);
61
+ } else {
62
+ const alias = replaceWithAlias(srcDirectory, layout, srcAlias);
63
+ const componentName = compName(srcDirectory, layout);
64
+ const route = {
65
+ path: `${_basePath.substring(0, _basePath.length - 1)}`,
66
+ exact: false,
67
+ routes: [],
68
+ _component: alias,
69
+ component: componentName,
70
+ parent
71
+ };
72
+ parent = route;
73
+ resetParent = true;
74
+ routes.push(route);
75
+ parents.push(route);
76
+ routes = route.routes;
77
+ }
78
+ }
79
+
80
+ for (const relative of fs.readdirSync(dir)) {
81
+ const filePath = path.join(dir, relative);
82
+
83
+ if (!shouldSkip(filePath)) {
84
+ const filename = path.basename(filePath, path.extname(filePath));
85
+ const alias = replaceWithAlias(srcDirectory, filePath, srcAlias);
86
+ const componentName = compName(srcDirectory, filePath);
87
+ const dynamicRouteMatched = FILE_SYSTEM_ROUTES_DYNAMIC_REGEXP.exec(filename);
88
+
89
+ if (dynamicRouteMatched) {
90
+ if (hasDynamicRoute) {
91
+ throw new Error(`Can't set two dynamic route in one directory: ${dir}`);
92
+ } else {
93
+ hasDynamicRoute = true;
94
+ }
95
+ }
96
+
97
+ const route = {
98
+ path: `${_basePath}${dynamicRouteMatched ? `:${dynamicRouteMatched[1]}${dynamicRouteMatched[2]}` : filename}`,
99
+ _component: alias,
100
+ component: componentName,
101
+ exact: true,
102
+ parent
103
+ };
104
+
105
+ if (fs.statSync(filePath).isDirectory()) {
106
+ recursiveReadDir({
107
+ dir: filePath,
108
+ routes,
109
+ basePath: `${route.path}/`,
110
+ srcDirectory,
111
+ srcAlias
112
+ });
113
+ continue;
114
+ }
115
+
116
+ if (filename === FILE_SYSTEM_ROUTES_LAYOUT) {
117
+ continue;
118
+ }
119
+
120
+ if (filename === FILE_SYSTEM_ROUTES_INDEX) {
121
+ route.path = _basePath === '/' ? _basePath : `${_basePath.substring(0, _basePath.length - 1)}`;
122
+ }
123
+
124
+ if (filename === '404' && _basePath === '/') {
125
+ route.path = '*';
126
+ route.exact = false;
127
+ }
128
+
129
+ routes.push(route);
130
+ }
131
+ }
132
+
133
+ if (resetParent) {
134
+ parents.pop();
135
+ }
136
+ };
137
+ /* eslint-enable no-param-reassign */
138
+
139
+
140
+ const normalizeNestedRoutes = (nested, internalComponentsDir, internalDirectory, internalDirAlias) => {
141
+ const flat = routes => routes.reduce((memo, route) => memo.concat(Array.isArray(route.routes) ? flat(route.routes) : [route]), []);
142
+
143
+ const generate = route => {
144
+ const codes = [];
145
+ let lastComponent = route.component;
146
+ const imports = [`import React from 'react';`, `import ${lastComponent} from '${route._component}'`]; // eslint-disable-next-line no-param-reassign, no-cond-assign
147
+
148
+ while (route = route.parent) {
149
+ const layoutComponent = route.component;
150
+ const layoutComponentAbbr = layoutNameAbbr(route._component);
151
+ imports.push(`import ${layoutComponent} from '${route._component}';`);
152
+ const currentComponent = `${layoutComponentAbbr}_${lastComponent}`;
153
+ codes.push(`const ${currentComponent} = props => <${layoutComponent} Component={${lastComponent}} {...props} />;`);
154
+ lastComponent = currentComponent;
155
+ }
156
+
157
+ const file = path.resolve(internalComponentsDir, `${lastComponent}.jsx`);
158
+ fs.outputFileSync(file, `${imports.join('\n')}\n${codes.join('\n')}\nexport default ${lastComponent}`);
159
+ return {
160
+ component: lastComponent,
161
+ _component: replaceWithAlias(internalDirectory, file, internalDirAlias)
162
+ };
163
+ };
164
+
165
+ const normalized = flat(nested).map(route => route.parent ? _objectSpread(_objectSpread(_objectSpread({}, route), generate(route)), {}, {
166
+ parent: undefined
167
+ }) : _objectSpread(_objectSpread({}, route), {}, {
168
+ parent: undefined
169
+ }));
170
+ return normalized;
171
+ };
172
+
173
+ const getRouteWeight = route => route === '*' ? 999 : route.split(':').length - 1;
174
+
175
+ export const getClientRoutes = ({
176
+ entrypoint,
177
+ srcDirectory,
178
+ srcAlias,
179
+ internalDirectory,
180
+ internalDirAlias
181
+ }) => {
182
+ const {
183
+ entry,
184
+ entryName
185
+ } = entrypoint;
186
+
187
+ if (!fs.existsSync(entry)) {
188
+ throw new Error(`generate file system routes error, ${entry} directory not found.`);
189
+ }
190
+
191
+ if (!(fs.existsSync(entry) && fs.statSync(entry).isDirectory())) {
192
+ throw new Error(`generate file system routes error, ${entry} should be directory.`);
193
+ }
194
+
195
+ let routes = [];
196
+ recursiveReadDir({
197
+ dir: entry,
198
+ routes,
199
+ basePath: '/',
200
+ srcDirectory,
201
+ srcAlias
202
+ });
203
+ const internalComponentsDir = path.resolve(internalDirectory, `${entryName}/${FILE_SYSTEM_ROUTES_COMPONENTS_DIR}`);
204
+ fs.emptyDirSync(internalComponentsDir);
205
+ routes = normalizeNestedRoutes(routes, internalComponentsDir, internalDirectory, internalDirAlias);
206
+ parents.length = 0; // FIXME: support more situations
207
+
208
+ routes.sort((a, b) => {
209
+ const delta = getRouteWeight(a.path) - getRouteWeight(b.path);
210
+
211
+ if (delta === 0) {
212
+ return a.path.length - b.path.length;
213
+ }
214
+
215
+ return delta;
216
+ });
217
+ debug(`fileSystem routes: %o`, routes);
218
+ return routes;
219
+ };
@@ -0,0 +1,74 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { findExists, ensureAbsolutePath } from '@modern-js/utils';
4
+ import { isDefaultExportFunction } from "./isDefaultExportFunction";
5
+ import { JS_EXTENSIONS, INDEX_FILE_NAME, APP_FILE_NAME, PAGES_DIR_NAME, FILE_SYSTEM_ROUTES_GLOBAL_LAYOUT } from "./constants";
6
+
7
+ const hasIndex = dir => findExists(JS_EXTENSIONS.map(ext => path.resolve(dir, `${INDEX_FILE_NAME}${ext}`)));
8
+
9
+ const hasApp = dir => findExists(JS_EXTENSIONS.map(ext => path.resolve(dir, `${APP_FILE_NAME}${ext}`)));
10
+
11
+ const hasPages = dir => fs.existsSync(path.join(dir, PAGES_DIR_NAME));
12
+
13
+ const isBundleEntry = dir => hasApp(dir) || hasPages(dir) || hasIndex(dir);
14
+
15
+ const scanDir = dirs => dirs.map(dir => {
16
+ const indexFile = hasIndex(dir);
17
+ const customBootstrap = isDefaultExportFunction(indexFile) ? indexFile : false;
18
+ const entryName = path.basename(dir);
19
+
20
+ if (indexFile && !customBootstrap) {
21
+ return {
22
+ entryName,
23
+ entry: indexFile,
24
+ isAutoMount: false
25
+ };
26
+ }
27
+
28
+ if (hasApp(dir)) {
29
+ return {
30
+ entryName,
31
+ entry: path.join(dir, APP_FILE_NAME),
32
+ isAutoMount: true,
33
+ customBootstrap
34
+ };
35
+ } else if (hasPages(dir)) {
36
+ return {
37
+ entryName,
38
+ entry: path.join(dir, PAGES_DIR_NAME),
39
+ fileSystemRoutes: {
40
+ globalApp: findExists(JS_EXTENSIONS.map(ext => path.resolve(dir, `./${PAGES_DIR_NAME}/${FILE_SYSTEM_ROUTES_GLOBAL_LAYOUT}${ext}`)))
41
+ },
42
+ isAutoMount: true,
43
+ customBootstrap
44
+ };
45
+ } else {
46
+ return {
47
+ entryName,
48
+ entry: indexFile,
49
+ isAutoMount: false
50
+ };
51
+ }
52
+ });
53
+
54
+ export const getFileSystemEntry = (appContext, config) => {
55
+ const {
56
+ appDirectory
57
+ } = appContext;
58
+ const {
59
+ source: {
60
+ entriesDir
61
+ }
62
+ } = config;
63
+ const src = ensureAbsolutePath(appDirectory, entriesDir);
64
+
65
+ if (fs.existsSync(src)) {
66
+ if (fs.statSync(src).isDirectory()) {
67
+ return scanDir(isBundleEntry(src) ? [src] : fs.readdirSync(src).map(file => path.join(src, file)).filter(file => fs.statSync(file).isDirectory() && isBundleEntry(file)));
68
+ } else {
69
+ throw Error(`source.entriesDir accept a directory.`);
70
+ }
71
+ } else {
72
+ throw Error(`src dir ${entriesDir} not found.`);
73
+ }
74
+ };
@@ -0,0 +1,82 @@
1
+ import path from 'path';
2
+ import { fs, findExists, MAIN_ENTRY_NAME } from '@modern-js/utils';
3
+ import { HTML_PARTIALS_EXTENSIONS, HTML_PARTIALS_FOLDER } from "./constants";
4
+ import * as templates from "./templates";
5
+ var PartialPosition;
6
+
7
+ (function (PartialPosition) {
8
+ PartialPosition["TOP"] = "top";
9
+ PartialPosition["HEAD"] = "head";
10
+ PartialPosition["BODY"] = "body";
11
+ PartialPosition["BOTTOM"] = "bottom";
12
+ PartialPosition["INDEX"] = "index";
13
+ })(PartialPosition || (PartialPosition = {}));
14
+
15
+ const findPartials = (dir, entryName, position) => {
16
+ if (fs.existsSync(dir)) {
17
+ const base = findExists(HTML_PARTIALS_EXTENSIONS.map(ext => path.resolve(dir, `${position}${ext}`)));
18
+ const file = entryName ? findExists(HTML_PARTIALS_EXTENSIONS.map(ext => path.resolve(dir, entryName, `${position}${ext}`))) || base : base;
19
+ return file ? {
20
+ file,
21
+ content: fs.readFileSync(file, 'utf8')
22
+ } : null;
23
+ }
24
+
25
+ return null;
26
+ }; // generate html template for
27
+
28
+
29
+ export const getHtmlTemplate = async (entrypoints, api, {
30
+ appContext,
31
+ config
32
+ }) => {
33
+ const {
34
+ appDirectory,
35
+ internalDirectory
36
+ } = appContext;
37
+ const {
38
+ source: {
39
+ configDir
40
+ }
41
+ } = config;
42
+ const htmlDir = path.resolve(appDirectory, configDir, HTML_PARTIALS_FOLDER);
43
+ const htmlTemplates = {};
44
+
45
+ for (const entrypoint of entrypoints) {
46
+ const {
47
+ entryName
48
+ } = entrypoint;
49
+ const name = entrypoints.length === 1 && entryName === MAIN_ENTRY_NAME ? '' : entryName;
50
+ const customIndexTemplate = findPartials(htmlDir, name, PartialPosition.INDEX);
51
+
52
+ if (customIndexTemplate) {
53
+ htmlTemplates[entryName] = customIndexTemplate.file;
54
+ } else {
55
+ const hookRunners = api.useHookRunners();
56
+ const {
57
+ partials
58
+ } = await hookRunners.htmlPartials({
59
+ entrypoint,
60
+ partials: [PartialPosition.TOP, PartialPosition.HEAD, PartialPosition.BODY].reduce((previous, position) => {
61
+ const found = findPartials(htmlDir, name, position);
62
+ previous[position] = found ? [found.content] : [];
63
+ return previous;
64
+ }, {
65
+ top: [],
66
+ head: [],
67
+ body: []
68
+ })
69
+ });
70
+ const templatePath = path.resolve(internalDirectory, entryName, 'index.html');
71
+ fs.outputFileSync(templatePath, templates.html(partials), 'utf8');
72
+ htmlTemplates[entryName] = templatePath;
73
+ const bottomTemplate = findPartials(htmlDir, name, PartialPosition.BOTTOM);
74
+
75
+ if (bottomTemplate) {
76
+ htmlTemplates[`__${entryName}-bottom__`] = bottomTemplate.content;
77
+ }
78
+ }
79
+ }
80
+
81
+ return htmlTemplates;
82
+ };
@@ -0,0 +1,192 @@
1
+ const _excluded = ["path"],
2
+ _excluded2 = ["path"];
3
+
4
+ function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
5
+
6
+ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
7
+
8
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
9
+
10
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
11
+
12
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
13
+
14
+ import path from 'path';
15
+ import fs from 'fs';
16
+ import { urlJoin, isPlainObject, removeLeadingSlash, getEntryOptions, SERVER_BUNDLE_DIRECTORY, MAIN_ENTRY_NAME, removeTailSlash } from '@modern-js/utils';
17
+ import { walkDirectory } from "./utils";
18
+ /**
19
+ * Add base url for each server route.
20
+ * @param baseUrl - Base url from server.baseUrl
21
+ * @param routes - Server routes.
22
+ * @returns Server routes with baseUrl prefixed.
23
+ */
24
+
25
+ const applyBaseUrl = (baseUrl, routes) => {
26
+ if (baseUrl) {
27
+ if (Array.isArray(baseUrl)) {
28
+ return baseUrl.reduce((previous, current) => [...previous, ...applyBaseUrl(current, routes)], []);
29
+ } else {
30
+ return routes.map(route => {
31
+ const urlPath = urlJoin(baseUrl, route.urlPath);
32
+ return _objectSpread(_objectSpread({}, route), {}, {
33
+ urlPath: urlPath === '/' ? urlPath : removeTailSlash(urlPath)
34
+ });
35
+ });
36
+ }
37
+ }
38
+
39
+ return routes;
40
+ };
41
+ /**
42
+ *
43
+ * @param original - Original entrypoint route info.
44
+ * @param routeOptions - Custom entrypoint route config from server.routes.
45
+ * @returns
46
+ */
47
+
48
+
49
+ const applyRouteOptions = (original, routeOptions) => {
50
+ const {
51
+ route,
52
+ disableSpa
53
+ } = routeOptions;
54
+ original.isSPA = !disableSpa; // set entryPath as dir
55
+
56
+ !original.isSPA && (original.entryPath = path.dirname(original.entryPath));
57
+ let routes;
58
+
59
+ if (route) {
60
+ if (Array.isArray(route)) {
61
+ routes = route.map(url => {
62
+ if (isPlainObject(url)) {
63
+ const _ref = url,
64
+ {
65
+ path: urlPath
66
+ } = _ref,
67
+ other = _objectWithoutProperties(_ref, _excluded);
68
+
69
+ return _objectSpread(_objectSpread(_objectSpread({}, original), other), {}, {
70
+ urlPath
71
+ });
72
+ } else {
73
+ return _objectSpread(_objectSpread({}, original), {}, {
74
+ urlPath: url
75
+ });
76
+ }
77
+ });
78
+ } else if (isPlainObject(route)) {
79
+ const _ref2 = route,
80
+ {
81
+ path: urlPath
82
+ } = _ref2,
83
+ other = _objectWithoutProperties(_ref2, _excluded2);
84
+
85
+ routes = [_objectSpread(_objectSpread(_objectSpread({}, original), other), {}, {
86
+ urlPath
87
+ })];
88
+ } else {
89
+ routes = [_objectSpread(_objectSpread({}, original), {}, {
90
+ urlPath: route
91
+ })];
92
+ }
93
+ } else {
94
+ routes = [original];
95
+ }
96
+
97
+ return routes;
98
+ };
99
+ /**
100
+ * Collect routes from entrypoints.
101
+ * @param entrypoints - Bundle entrypoints.
102
+ * @param config - Normalized user config.
103
+ * @returns entrypoint Routes
104
+ */
105
+
106
+
107
+ const collectHtmlRoutes = (entrypoints, appContext, config) => {
108
+ const {
109
+ output: {
110
+ htmlPath,
111
+ disableHtmlFolder,
112
+ enableModernMode
113
+ },
114
+ server: {
115
+ baseUrl,
116
+ routes,
117
+ ssr,
118
+ ssrByEntries
119
+ }
120
+ } = config;
121
+ const {
122
+ packageName
123
+ } = appContext;
124
+ let htmlRoutes = entrypoints.reduce((previous, {
125
+ entryName
126
+ }) => {
127
+ const entryOptions = getEntryOptions(entryName, ssr, ssrByEntries, packageName);
128
+ const isSSR = Boolean(entryOptions);
129
+ const {
130
+ resHeaders
131
+ } = (routes === null || routes === void 0 ? void 0 : routes[entryName]) || {};
132
+ let route = {
133
+ urlPath: `/${entryName === MAIN_ENTRY_NAME ? '' : entryName}`,
134
+ entryName,
135
+ entryPath: removeLeadingSlash(path.posix.normalize(`${htmlPath}/${entryName}${disableHtmlFolder ? '.html' : '/index.html'}`)),
136
+ isSPA: true,
137
+ isSSR,
138
+ responseHeaders: resHeaders,
139
+ enableModernMode: Boolean(enableModernMode),
140
+ bundle: isSSR ? `${SERVER_BUNDLE_DIRECTORY}/${entryName}.js` : undefined
141
+ };
142
+
143
+ if (routes !== null && routes !== void 0 && routes.hasOwnProperty(entryName)) {
144
+ const routeOptions = isPlainObject(routes[entryName]) ? routes[entryName] : {
145
+ route: routes[entryName]
146
+ };
147
+ route = applyRouteOptions(route, routeOptions);
148
+ }
149
+
150
+ return Array.isArray(route) ? [...previous, ...route] : [...previous, route];
151
+ }, []);
152
+ htmlRoutes = applyBaseUrl(baseUrl, htmlRoutes);
153
+ return htmlRoutes;
154
+ };
155
+ /**
156
+ * Collect static public file routes from config/public folder.
157
+ * @param appContext - App context info.
158
+ * @param config - normalized user config.
159
+ * @returns Static public file routes.
160
+ */
161
+
162
+
163
+ const collectStaticRoutes = (appContext, config) => {
164
+ const {
165
+ appDirectory
166
+ } = appContext;
167
+ const {
168
+ source: {
169
+ configDir
170
+ },
171
+ server: {
172
+ publicRoutes = {}
173
+ }
174
+ } = config;
175
+ const publicFolder = path.resolve(appDirectory, configDir, 'public');
176
+ return fs.existsSync(publicFolder) ? walkDirectory(publicFolder).map(filePath => {
177
+ const urlPath = `${urlJoin(toPosix(filePath).slice(toPosix(publicFolder).length))}`;
178
+ return {
179
+ urlPath: publicRoutes[removeLeadingSlash(urlPath)] || urlPath,
180
+ isSPA: true,
181
+ isSSR: false,
182
+ entryPath: toPosix(path.relative(path.resolve(appDirectory, configDir), filePath))
183
+ };
184
+ }) : [];
185
+ };
186
+
187
+ export const getServerRoutes = (entrypoints, {
188
+ appContext,
189
+ config
190
+ }) => [...collectHtmlRoutes(entrypoints, appContext, config), ...collectStaticRoutes(appContext, config)];
191
+
192
+ const toPosix = pathStr => pathStr.split(path.sep).join(path.posix.sep);