@expo/cli 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/README.md +1 -1
  2. package/build/bin/cli +12 -3
  3. package/build/bin/cli.map +1 -1
  4. package/build/src/api/getExpoGoIntermediateCertificate.js +0 -2
  5. package/build/src/api/getExpoGoIntermediateCertificate.js.map +1 -1
  6. package/build/src/api/getProjectDevelopmentCertificate.js +0 -2
  7. package/build/src/api/getProjectDevelopmentCertificate.js.map +1 -1
  8. package/build/src/api/graphql/queries/AppQuery.js +39 -0
  9. package/build/src/api/graphql/queries/AppQuery.js.map +1 -0
  10. package/build/src/api/graphql/queries/UserQuery.js +10 -3
  11. package/build/src/api/graphql/queries/UserQuery.js.map +1 -1
  12. package/build/src/api/graphql/types/App.js +23 -0
  13. package/build/src/api/graphql/types/App.js.map +1 -0
  14. package/build/src/api/signManifest.js +0 -12
  15. package/build/src/api/signManifest.js.map +1 -1
  16. package/build/src/api/user/UserSettings.js.map +1 -1
  17. package/build/src/api/user/user.js.map +1 -1
  18. package/build/src/config/configAsync.js +3 -0
  19. package/build/src/config/configAsync.js.map +1 -1
  20. package/build/src/customize/customizeAsync.js +3 -0
  21. package/build/src/customize/customizeAsync.js.map +1 -1
  22. package/build/src/export/createBundles.js +7 -3
  23. package/build/src/export/createBundles.js.map +1 -1
  24. package/build/src/export/embed/exportEmbedAsync.js +24 -0
  25. package/build/src/export/embed/exportEmbedAsync.js.map +1 -0
  26. package/build/src/export/embed/index.js +117 -0
  27. package/build/src/export/embed/index.js.map +1 -0
  28. package/build/src/export/embed/resolveOptions.js +63 -0
  29. package/build/src/export/embed/resolveOptions.js.map +1 -0
  30. package/build/src/export/exportApp.js +56 -29
  31. package/build/src/export/exportApp.js.map +1 -1
  32. package/build/src/export/exportAssets.js +17 -0
  33. package/build/src/export/exportAssets.js.map +1 -1
  34. package/build/src/export/exportAsync.js +3 -0
  35. package/build/src/export/exportAsync.js.map +1 -1
  36. package/build/src/export/exportStaticAsync.js +179 -0
  37. package/build/src/export/exportStaticAsync.js.map +1 -0
  38. package/build/src/export/fork-bundleAsync.js +15 -42
  39. package/build/src/export/fork-bundleAsync.js.map +1 -1
  40. package/build/src/export/html.js +21 -0
  41. package/build/src/export/html.js.map +1 -0
  42. package/build/src/export/printBundleSizes.js +2 -2
  43. package/build/src/export/printBundleSizes.js.map +1 -1
  44. package/build/src/export/web/exportWebAsync.js +3 -0
  45. package/build/src/export/web/exportWebAsync.js.map +1 -1
  46. package/build/src/export/writeContents.js +5 -2
  47. package/build/src/export/writeContents.js.map +1 -1
  48. package/build/src/graphql/generated.js +462 -0
  49. package/build/src/graphql/generated.js.map +1 -0
  50. package/build/src/install/installAsync.js +3 -0
  51. package/build/src/install/installAsync.js.map +1 -1
  52. package/build/src/prebuild/clearNativeFolder.js +6 -1
  53. package/build/src/prebuild/clearNativeFolder.js.map +1 -1
  54. package/build/src/prebuild/ensureConfigAsync.js +1 -12
  55. package/build/src/prebuild/ensureConfigAsync.js.map +1 -1
  56. package/build/src/prebuild/prebuildAsync.js +7 -2
  57. package/build/src/prebuild/prebuildAsync.js.map +1 -1
  58. package/build/src/prebuild/resolveOptions.js +7 -8
  59. package/build/src/prebuild/resolveOptions.js.map +1 -1
  60. package/build/src/prebuild/resolveTemplate.js +5 -0
  61. package/build/src/prebuild/resolveTemplate.js.map +1 -1
  62. package/build/src/prebuild/updateFromTemplate.js +6 -1
  63. package/build/src/prebuild/updateFromTemplate.js.map +1 -1
  64. package/build/src/prebuild/validateTemplatePlatforms.js +48 -0
  65. package/build/src/prebuild/validateTemplatePlatforms.js.map +1 -0
  66. package/build/src/run/android/runAndroidAsync.js +4 -0
  67. package/build/src/run/android/runAndroidAsync.js.map +1 -1
  68. package/build/src/run/ios/appleDevice/AppleDevice.js +25 -19
  69. package/build/src/run/ios/appleDevice/AppleDevice.js.map +1 -1
  70. package/build/src/run/ios/appleDevice/client/InstallationProxyClient.js.map +1 -1
  71. package/build/src/run/ios/options/resolveNativeScheme.js +13 -4
  72. package/build/src/run/ios/options/resolveNativeScheme.js.map +1 -1
  73. package/build/src/run/ios/runIosAsync.js +3 -0
  74. package/build/src/run/ios/runIosAsync.js.map +1 -1
  75. package/build/src/run/startBundler.js +4 -0
  76. package/build/src/run/startBundler.js.map +1 -1
  77. package/build/src/start/doctor/Prerequisite.js.map +1 -1
  78. package/build/src/start/doctor/dependencies/ensureDependenciesAsync.js +12 -6
  79. package/build/src/start/doctor/dependencies/ensureDependenciesAsync.js.map +1 -1
  80. package/build/src/start/doctor/dependencies/validateDependenciesVersions.js +1 -3
  81. package/build/src/start/doctor/dependencies/validateDependenciesVersions.js.map +1 -1
  82. package/build/src/start/doctor/typescript/TypeScriptProjectPrerequisite.js +31 -5
  83. package/build/src/start/doctor/typescript/TypeScriptProjectPrerequisite.js.map +1 -1
  84. package/build/src/start/doctor/typescript/updateTSConfig.js +6 -0
  85. package/build/src/start/doctor/typescript/updateTSConfig.js.map +1 -1
  86. package/build/src/start/doctor/web/WebSupportProjectPrerequisite.js +1 -0
  87. package/build/src/start/doctor/web/WebSupportProjectPrerequisite.js.map +1 -1
  88. package/build/src/start/platforms/android/adb.js +1 -1
  89. package/build/src/start/platforms/android/adb.js.map +1 -1
  90. package/build/src/start/platforms/ios/AppleDeviceManager.js +1 -1
  91. package/build/src/start/platforms/ios/AppleDeviceManager.js.map +1 -1
  92. package/build/src/start/server/BundlerDevServer.js +16 -2
  93. package/build/src/start/server/BundlerDevServer.js.map +1 -1
  94. package/build/src/start/server/DevServerManager.js +33 -2
  95. package/build/src/start/server/DevServerManager.js.map +1 -1
  96. package/build/src/start/server/getStaticRenderFunctions.js +166 -0
  97. package/build/src/start/server/getStaticRenderFunctions.js.map +1 -0
  98. package/build/src/start/server/metro/MetroBundlerDevServer.js +279 -3
  99. package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
  100. package/build/src/start/server/metro/MetroTerminalReporter.js +2 -34
  101. package/build/src/start/server/metro/MetroTerminalReporter.js.map +1 -1
  102. package/build/src/start/server/metro/externals.js +95 -0
  103. package/build/src/start/server/metro/externals.js.map +1 -0
  104. package/build/src/start/server/metro/getCssModulesFromBundler.js +77 -0
  105. package/build/src/start/server/metro/getCssModulesFromBundler.js.map +1 -0
  106. package/build/src/start/server/metro/inspector-proxy/index.js +2 -2
  107. package/build/src/start/server/metro/inspector-proxy/index.js.map +1 -1
  108. package/build/src/start/server/metro/inspector-proxy/proxy.js +1 -3
  109. package/build/src/start/server/metro/inspector-proxy/proxy.js.map +1 -1
  110. package/build/src/start/server/metro/instantiateMetro.js +44 -48
  111. package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
  112. package/build/src/start/server/metro/metroErrorInterface.js +114 -0
  113. package/build/src/start/server/metro/metroErrorInterface.js.map +1 -0
  114. package/build/src/start/server/metro/metroWatchTypeScriptFiles.js +51 -0
  115. package/build/src/start/server/metro/metroWatchTypeScriptFiles.js.map +1 -0
  116. package/build/src/start/server/metro/resolveFromProject.js +26 -3
  117. package/build/src/start/server/metro/resolveFromProject.js.map +1 -1
  118. package/build/src/start/server/metro/router.js +4 -0
  119. package/build/src/start/server/metro/router.js.map +1 -1
  120. package/build/src/start/server/metro/runServer-fork.js +108 -0
  121. package/build/src/start/server/metro/runServer-fork.js.map +1 -0
  122. package/build/src/start/server/metro/symbolicate.js +6 -0
  123. package/build/src/start/server/metro/symbolicate.js.map +1 -0
  124. package/build/src/start/server/metro/waitForMetroToObserveTypeScriptFile.js +70 -0
  125. package/build/src/start/server/metro/waitForMetroToObserveTypeScriptFile.js.map +1 -0
  126. package/build/src/start/server/metro/withMetroMultiPlatform.js +181 -44
  127. package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
  128. package/build/src/start/server/middleware/ClassicManifestMiddleware.js +8 -1
  129. package/build/src/start/server/middleware/ClassicManifestMiddleware.js.map +1 -1
  130. package/build/src/start/server/middleware/CreateFileMiddleware.js.map +1 -1
  131. package/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js +38 -32
  132. package/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js.map +1 -1
  133. package/build/src/start/server/middleware/ManifestMiddleware.js +53 -19
  134. package/build/src/start/server/middleware/ManifestMiddleware.js.map +1 -1
  135. package/build/src/start/server/type-generation/expo-env.js +27 -0
  136. package/build/src/start/server/type-generation/expo-env.js.map +1 -0
  137. package/build/src/start/server/type-generation/index.js +49 -0
  138. package/build/src/start/server/type-generation/index.js.map +1 -0
  139. package/build/src/start/server/type-generation/routes.js +292 -0
  140. package/build/src/start/server/type-generation/routes.js.map +1 -0
  141. package/build/src/start/server/type-generation/tsconfig.js +89 -0
  142. package/build/src/start/server/type-generation/tsconfig.js.map +1 -0
  143. package/build/src/start/server/webTemplate.js +20 -4
  144. package/build/src/start/server/webTemplate.js.map +1 -1
  145. package/build/src/start/server/webpack/WebpackBundlerDevServer.js +4 -6
  146. package/build/src/start/server/webpack/WebpackBundlerDevServer.js.map +1 -1
  147. package/build/src/start/startAsync.js +30 -8
  148. package/build/src/start/startAsync.js.map +1 -1
  149. package/build/src/utils/FileNotifier.js +11 -4
  150. package/build/src/utils/FileNotifier.js.map +1 -1
  151. package/build/src/utils/analytics/getMetroProperties.js +1 -1
  152. package/build/src/utils/analytics/getMetroProperties.js.map +1 -1
  153. package/build/src/utils/analytics/rudderstackClient.js +2 -2
  154. package/build/src/utils/codesigning.js +31 -7
  155. package/build/src/utils/codesigning.js.map +1 -1
  156. package/build/src/utils/env.js +3 -0
  157. package/build/src/utils/env.js.map +1 -1
  158. package/build/src/utils/mergeGitIgnorePaths.js +42 -0
  159. package/build/src/utils/mergeGitIgnorePaths.js.map +1 -1
  160. package/build/src/utils/nodeEnv.js +11 -0
  161. package/build/src/utils/nodeEnv.js.map +1 -0
  162. package/build/src/utils/resolveArgs.js +43 -0
  163. package/build/src/utils/resolveArgs.js.map +1 -1
  164. package/build/src/utils/template.js +21 -0
  165. package/build/src/utils/template.js.map +1 -0
  166. package/build/src/utils/tsconfig/evaluateTsConfig.js +61 -0
  167. package/build/src/utils/tsconfig/evaluateTsConfig.js.map +1 -0
  168. package/build/src/utils/tsconfig/loadTsConfigPaths.js +69 -0
  169. package/build/src/utils/tsconfig/loadTsConfigPaths.js.map +1 -0
  170. package/build/src/utils/tsconfig/matchTsConfigPathAlias.js +88 -0
  171. package/build/src/utils/tsconfig/matchTsConfigPathAlias.js.map +1 -0
  172. package/build/src/utils/tsconfig/resolveWithTsConfigPaths.js +41 -0
  173. package/build/src/utils/tsconfig/resolveWithTsConfigPaths.js.map +1 -0
  174. package/package.json +16 -8
  175. package/static/template/metro.config.js +4 -1
  176. package/build/src/api/getProject.js +0 -19
  177. package/build/src/api/getProject.js.map +0 -1
  178. package/build/src/api/graphql/generated.js +0 -113
  179. package/build/src/api/graphql/generated.js.map +0 -1
@@ -0,0 +1,292 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ exports.setupTypedRoutes = setupTypedRoutes;
6
+ exports.getTypedRoutesUtils = getTypedRoutesUtils;
7
+ exports.extrapolateGroupRoutes = extrapolateGroupRoutes;
8
+ exports.setToUnionType = exports.CAPTURE_GROUP_REGEX = exports.ARRAY_GROUP_REGEX = exports.SLUG = exports.CATCH_ALL = exports.CAPTURE_DYNAMIC_PARAMS = void 0;
9
+ var _promises = _interopRequireDefault(require("fs/promises"));
10
+ var _lodash = require("lodash");
11
+ var _path = _interopRequireDefault(require("path"));
12
+ var _template = require("../../../utils/template");
13
+ var _metroWatchTypeScriptFiles = require("../metro/metroWatchTypeScriptFiles");
14
+ var _router = require("../metro/router");
15
+ function _interopRequireDefault(obj) {
16
+ return obj && obj.__esModule ? obj : {
17
+ default: obj
18
+ };
19
+ }
20
+ const CAPTURE_DYNAMIC_PARAMS = /\[(?:\.{3})?(\w*?)[\]$]/g;
21
+ exports.CAPTURE_DYNAMIC_PARAMS = CAPTURE_DYNAMIC_PARAMS;
22
+ const CATCH_ALL = /\[\.\.\..+?\]/g;
23
+ exports.CATCH_ALL = CATCH_ALL;
24
+ const SLUG = /\[.+?\]/g;
25
+ exports.SLUG = SLUG;
26
+ const ARRAY_GROUP_REGEX = /\(\w+?,.*?\)/g;
27
+ exports.ARRAY_GROUP_REGEX = ARRAY_GROUP_REGEX;
28
+ const CAPTURE_GROUP_REGEX = /[\\(,](\w+?)(?=[,\\)])/g;
29
+ exports.CAPTURE_GROUP_REGEX = CAPTURE_GROUP_REGEX;
30
+ async function setupTypedRoutes({ server , metro , typesDirectory , projectRoot }) {
31
+ const appRoot = (0, _router).getExpoRouterRootDirectory(projectRoot);
32
+ const { filePathToRoute , staticRoutes , dynamicRoutes , addFilePath } = getTypedRoutesUtils(appRoot);
33
+ if (metro) {
34
+ // Setup out watcher first
35
+ (0, _metroWatchTypeScriptFiles).metroWatchTypeScriptFiles({
36
+ projectRoot: appRoot,
37
+ server,
38
+ metro,
39
+ eventTypes: [
40
+ "add",
41
+ "delete",
42
+ "change"
43
+ ],
44
+ async callback ({ filePath , type }) {
45
+ let shouldRegenerate = false;
46
+ if (type === "delete") {
47
+ const route = filePathToRoute(filePath);
48
+ staticRoutes.delete(route);
49
+ dynamicRoutes.delete(route);
50
+ shouldRegenerate = true;
51
+ } else {
52
+ shouldRegenerate = addFilePath(filePath);
53
+ }
54
+ if (shouldRegenerate) {
55
+ regenerateRouterDotTS(typesDirectory, new Set([
56
+ ...staticRoutes.values()
57
+ ].flatMap((v)=>Array.from(v)
58
+ )), new Set([
59
+ ...dynamicRoutes.values()
60
+ ].flatMap((v)=>Array.from(v)
61
+ )), new Set(dynamicRoutes.keys()));
62
+ }
63
+ }
64
+ });
65
+ }
66
+ // Do we need to walk the entire tree on startup?
67
+ // Idea: Store the list of files in the last write, then simply check Git for what files have changed
68
+ await walk(appRoot, addFilePath);
69
+ regenerateRouterDotTS(typesDirectory, new Set([
70
+ ...staticRoutes.values()
71
+ ].flatMap((v)=>Array.from(v)
72
+ )), new Set([
73
+ ...dynamicRoutes.values()
74
+ ].flatMap((v)=>Array.from(v)
75
+ )), new Set(dynamicRoutes.keys()));
76
+ }
77
+ /**
78
+ * Generate a router.d.ts file that contains all of the routes in the project.
79
+ * Should be debounced as its very common for developers to make changes to multiple files at once (eg Save All)
80
+ */ const regenerateRouterDotTS = (0, _lodash).debounce((typesDir, staticRoutes, dynamicRoutes, dynamicRouteTemplates)=>{
81
+ _promises.default.writeFile(_path.default.resolve(typesDir, "./router.d.ts"), routerDotTSTemplate({
82
+ staticRoutes: setToUnionType(staticRoutes),
83
+ dynamicRoutes: setToUnionType(dynamicRoutes),
84
+ dynamicRouteParams: setToUnionType(dynamicRouteTemplates)
85
+ }));
86
+ }, 100);
87
+ function getTypedRoutesUtils(appRoot) {
88
+ const staticRoutes = new Map([
89
+ [
90
+ "/",
91
+ new Set("/")
92
+ ]
93
+ ]);
94
+ const dynamicRoutes = new Map();
95
+ const filePathToRoute = (filePath)=>{
96
+ return filePath.replace(appRoot, "").replace(/index.[jt]sx?/, "").replace(/\.[jt]sx?$/, "");
97
+ };
98
+ const addFilePath = (filePath)=>{
99
+ if (filePath.match(/_layout\.[tj]sx?$/)) {
100
+ return false;
101
+ }
102
+ const route1 = filePathToRoute(filePath);
103
+ // We have already processed this file
104
+ if (staticRoutes.has(route1) || dynamicRoutes.has(route1)) {
105
+ return false;
106
+ }
107
+ const dynamicParams = new Set([
108
+ ...route1.matchAll(CAPTURE_DYNAMIC_PARAMS)
109
+ ].map((match)=>match[1]
110
+ ));
111
+ const isDynamic = dynamicParams.size > 0;
112
+ const addRoute = (originalRoute, route)=>{
113
+ if (isDynamic) {
114
+ let set = dynamicRoutes.get(originalRoute);
115
+ if (!set) {
116
+ set = new Set();
117
+ dynamicRoutes.set(originalRoute, set);
118
+ }
119
+ set.add(route.replaceAll(CATCH_ALL, "${CatchAllSlug<T>}").replaceAll(SLUG, "${SafeSlug<T>}"));
120
+ } else {
121
+ let set = staticRoutes.get(originalRoute);
122
+ if (!set) {
123
+ set = new Set();
124
+ staticRoutes.set(originalRoute, set);
125
+ }
126
+ set.add(route);
127
+ }
128
+ };
129
+ if (!route1.match(ARRAY_GROUP_REGEX)) {
130
+ addRoute(route1, route1);
131
+ }
132
+ // Does this route have a group? eg /(group)
133
+ if (route1.includes("/(")) {
134
+ const routeWithoutGroups = route1.replace(/\/\(.+?\)/g, "");
135
+ addRoute(route1, routeWithoutGroups);
136
+ // If there are multiple groups, we need to expand them
137
+ // eg /(test1,test2)/page => /test1/page & /test2/page
138
+ for (const routeWithSingleGroup of extrapolateGroupRoutes(route1)){
139
+ addRoute(route1, routeWithSingleGroup);
140
+ }
141
+ }
142
+ return true;
143
+ };
144
+ return {
145
+ staticRoutes,
146
+ dynamicRoutes,
147
+ filePathToRoute,
148
+ addFilePath
149
+ };
150
+ }
151
+ const setToUnionType = (set)=>{
152
+ return set.size > 0 ? [
153
+ ...set
154
+ ].map((s)=>`\`${s}\``
155
+ ).join(" | ") : "never";
156
+ };
157
+ exports.setToUnionType = setToUnionType;
158
+ /**
159
+ * Recursively walk a directory and call the callback with the file path.
160
+ */ async function walk(directory, callback) {
161
+ const files = await _promises.default.readdir(directory);
162
+ for (const file of files){
163
+ const p = _path.default.join(directory, file);
164
+ if ((await _promises.default.stat(p)).isDirectory()) {
165
+ await walk(p, callback);
166
+ } else {
167
+ // Normalise the paths so they are easier to convert to URLs
168
+ const normalizedPath = p.replaceAll(_path.default.sep, "/").replaceAll(" ", "_");
169
+ callback(normalizedPath);
170
+ }
171
+ }
172
+ }
173
+ function extrapolateGroupRoutes(route, routes = new Set()) {
174
+ // Create a version with no groups. We will then need to cleanup double and/or trailing slashes
175
+ routes.add(route.replaceAll(ARRAY_GROUP_REGEX, "").replaceAll(/\/+/g, "/").replace(/\/$/, ""));
176
+ const match = route.match(ARRAY_GROUP_REGEX);
177
+ if (!match) {
178
+ routes.add(route);
179
+ return routes;
180
+ }
181
+ const groupsMatch = match[0];
182
+ for (const group of groupsMatch.matchAll(CAPTURE_GROUP_REGEX)){
183
+ extrapolateGroupRoutes(route.replace(groupsMatch, `(${group[1]})`), routes);
184
+ }
185
+ return routes;
186
+ }
187
+ /**
188
+ * NOTE: This code refers to a specific version of `expo-router` and is therefore unsafe to
189
+ * mix with arbitrary versions.
190
+ * TODO: Version this code with `expo-router` or version expo-router with `@expo/cli`.
191
+ */ const routerDotTSTemplate = _template.unsafeTemplate`declare module "expo-router" {
192
+ import type { LinkProps as OriginalLinkProps } from "expo-router/build/link/Link";
193
+ export * from "expo-router/build";
194
+
195
+ type StaticRoutes = ${"staticRoutes"}
196
+ type DynamicRoutes<T extends string> = ${"dynamicRoutes"}
197
+ type DynamicRouteTemplate = ${"dynamicRouteParams"}
198
+
199
+ type SearchOrHash = \`?\${string}\` | \`#\${string}\`;
200
+
201
+ type RelativePathString = \`./\${string}\` | \`../\${string}\` | '..';
202
+
203
+ type Suffix = "" | SearchOrHash;
204
+
205
+ type SafeSlug<S extends string> = S extends \`\${string}/\${string}\`
206
+ ? never
207
+ : S extends \`\${string}\${SearchOrHash}\`
208
+ ? never
209
+ : S extends ""
210
+ ? never
211
+ : S;
212
+
213
+ type CatchAllSlug<S extends string> = S extends \`\${string}\${SearchOrHash}\`
214
+ ? never
215
+ : S extends ""
216
+ ? never
217
+ : S;
218
+
219
+ type InvaildPartialSlug = | \`\${string | never}\${'[' | ']'}\${string | never}\`
220
+
221
+ type IsParameter<Part> = Part extends \`[\${infer ParamName}]\`
222
+ ? ParamName
223
+ : never;
224
+
225
+ type FilteredParts<Path> = Path extends \`\${infer PartA}/\${infer PartB}\`
226
+ ? IsParameter<PartA> | FilteredParts<PartB>
227
+ : IsParameter<Path>;
228
+
229
+ type RouteParams<Path> = {
230
+ [Key in FilteredParts<Path> as Key extends \`...\${infer Name}\` ? Name : Key]:
231
+ Key extends \`...\${string}\` ? string[] : string;
232
+ };
233
+
234
+ type Route<T> = T extends DynamicRouteTemplate
235
+ ? never
236
+ :
237
+ | StaticRoutes
238
+ | RelativePathString
239
+ | \`\${StaticRoutes}\${Suffix}\`
240
+ | (T extends \`\${DynamicRoutes<infer P>}\${Suffix}\`
241
+ ? P extends InvaildPartialSlug
242
+ ? never
243
+ : T
244
+ : never);
245
+
246
+ export type Href<T> = Route<T> | HrefObject<T> | DynamicRouteTemplate
247
+
248
+ export type HrefObject<T> = {
249
+ pathname: Route<T> | DynamicRouteTemplate
250
+ } & HrefObjectParams<T>;
251
+
252
+ type HrefObjectParams<T> = T extends RelativePathString
253
+ ? { params?: Record<string, string> }
254
+ : T extends { pathname: DynamicRouteTemplate }
255
+ ? { params: RouteParams<InferPathName<T>> }
256
+ : unknown;
257
+
258
+ /** Returns the search parameters for a route **/
259
+ export type SearchParams<T extends DynamicRouteTemplate | StaticRoutes | RelativePathString> =
260
+ T extends DynamicRouteTemplate ? RouteParams<T> : {};
261
+
262
+ type InferPathName<T> = T extends { pathname: infer P } ? P : never;
263
+
264
+ export interface LinkProps<T> extends OriginalLinkProps {
265
+ href: T extends DynamicRouteTemplate ? HrefObject<T> : Href<T>;
266
+ }
267
+
268
+ export interface LinkComponent {
269
+ <T>(props: React.PropsWithChildren<LinkProps<T>>): JSX.Element;
270
+ /** Helper method to resolve an Href object into a string. */
271
+ resolveHref: <T>(href: Href<T>) => string;
272
+ }
273
+
274
+ export const Link: LinkComponent;
275
+
276
+ export type Router = {
277
+ /** Navigate to the provided href. */
278
+ push: <T>(href: Href<T>) => void;
279
+ /** Navigate to route without appending to the history. */
280
+ replace: <T>(href: Href<T>) => void;
281
+ /** Go back in the history. */
282
+ back: () => void;
283
+ /** Update the current route query params. */
284
+ setParams: <T extends string = ''>(params?: T extends '' ? Record<string, string> : RouteParams<T>) => void;
285
+ };
286
+
287
+ export function useRouter<T>(): Router<T>
288
+ export function useLocalSearchParams<T extends DynamicRouteTemplate | StaticRoutes | RelativePathString>(): SearchParams<T>
289
+ }
290
+ `;
291
+
292
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/start/server/type-generation/routes.ts"],"sourcesContent":["import fs from 'fs/promises';\nimport { debounce } from 'lodash';\nimport { Server } from 'metro';\nimport path from 'path';\n\nimport { unsafeTemplate } from '../../../utils/template';\nimport { ServerLike } from '../BundlerDevServer';\nimport { metroWatchTypeScriptFiles } from '../metro/metroWatchTypeScriptFiles';\nimport { getExpoRouterRootDirectory } from '../metro/router';\n\n// /test/[...param1]/[param2]/[param3] - captures [\"param1\", \"param2\", \"param3\"]\nexport const CAPTURE_DYNAMIC_PARAMS = /\\[(?:\\.{3})?(\\w*?)[\\]$]/g;\n// /[...param1]/ - Match [...param1]\nexport const CATCH_ALL = /\\[\\.\\.\\..+?\\]/g;\n// /[param1] - Match [param1]\nexport const SLUG = /\\[.+?\\]/g;\n// /(group1,group2,group3)/test - match (group1,group2,group3)\nexport const ARRAY_GROUP_REGEX = /\\(\\w+?,.*?\\)/g;\n// /(group1,group2,group3)/test - captures [\"group1\", \"group2\", \"group3\"]\nexport const CAPTURE_GROUP_REGEX = /[\\\\(,](\\w+?)(?=[,\\\\)])/g;\n\nexport interface SetupTypedRoutesOptions {\n server: ServerLike;\n metro?: Server | null;\n typesDirectory: string;\n projectRoot: string;\n}\n\nexport async function setupTypedRoutes({\n server,\n metro,\n typesDirectory,\n projectRoot,\n}: SetupTypedRoutesOptions) {\n const appRoot = getExpoRouterRootDirectory(projectRoot);\n\n const { filePathToRoute, staticRoutes, dynamicRoutes, addFilePath } =\n getTypedRoutesUtils(appRoot);\n\n if (metro) {\n // Setup out watcher first\n metroWatchTypeScriptFiles({\n projectRoot: appRoot,\n server,\n metro,\n eventTypes: ['add', 'delete', 'change'],\n async callback({ filePath, type }) {\n let shouldRegenerate = false;\n if (type === 'delete') {\n const route = filePathToRoute(filePath);\n staticRoutes.delete(route);\n dynamicRoutes.delete(route);\n shouldRegenerate = true;\n } else {\n shouldRegenerate = addFilePath(filePath);\n }\n\n if (shouldRegenerate) {\n regenerateRouterDotTS(\n typesDirectory,\n new Set([...staticRoutes.values()].flatMap((v) => Array.from(v))),\n new Set([...dynamicRoutes.values()].flatMap((v) => Array.from(v))),\n new Set(dynamicRoutes.keys())\n );\n }\n },\n });\n }\n\n // Do we need to walk the entire tree on startup?\n // Idea: Store the list of files in the last write, then simply check Git for what files have changed\n await walk(appRoot, addFilePath);\n\n regenerateRouterDotTS(\n typesDirectory,\n new Set([...staticRoutes.values()].flatMap((v) => Array.from(v))),\n new Set([...dynamicRoutes.values()].flatMap((v) => Array.from(v))),\n new Set(dynamicRoutes.keys())\n );\n}\n\n/**\n * Generate a router.d.ts file that contains all of the routes in the project.\n * Should be debounced as its very common for developers to make changes to multiple files at once (eg Save All)\n */\nconst regenerateRouterDotTS = debounce(\n (\n typesDir: string,\n staticRoutes: Set<string>,\n dynamicRoutes: Set<string>,\n dynamicRouteTemplates: Set<string>\n ) => {\n fs.writeFile(\n path.resolve(typesDir, './router.d.ts'),\n routerDotTSTemplate({\n staticRoutes: setToUnionType(staticRoutes),\n dynamicRoutes: setToUnionType(dynamicRoutes),\n dynamicRouteParams: setToUnionType(dynamicRouteTemplates),\n })\n );\n },\n 100\n);\n\n/**\n * Utility functions for typed routes\n *\n * These are extracted for easier testing\n */\nexport function getTypedRoutesUtils(appRoot: string) {\n const staticRoutes = new Map<string, Set<string>>([['/', new Set('/')]]);\n const dynamicRoutes = new Map<string, Set<string>>();\n\n const filePathToRoute = (filePath: string) => {\n return filePath\n .replace(appRoot, '')\n .replace(/index.[jt]sx?/, '')\n .replace(/\\.[jt]sx?$/, '');\n };\n\n const addFilePath = (filePath: string): boolean => {\n if (filePath.match(/_layout\\.[tj]sx?$/)) {\n return false;\n }\n\n const route = filePathToRoute(filePath);\n\n // We have already processed this file\n if (staticRoutes.has(route) || dynamicRoutes.has(route)) {\n return false;\n }\n\n const dynamicParams = new Set(\n [...route.matchAll(CAPTURE_DYNAMIC_PARAMS)].map((match) => match[1])\n );\n const isDynamic = dynamicParams.size > 0;\n\n const addRoute = (originalRoute: string, route: string) => {\n if (isDynamic) {\n let set = dynamicRoutes.get(originalRoute);\n\n if (!set) {\n set = new Set();\n dynamicRoutes.set(originalRoute, set);\n }\n\n set.add(\n route.replaceAll(CATCH_ALL, '${CatchAllSlug<T>}').replaceAll(SLUG, '${SafeSlug<T>}')\n );\n } else {\n let set = staticRoutes.get(originalRoute);\n\n if (!set) {\n set = new Set();\n staticRoutes.set(originalRoute, set);\n }\n\n set.add(route);\n }\n };\n\n if (!route.match(ARRAY_GROUP_REGEX)) {\n addRoute(route, route);\n }\n\n // Does this route have a group? eg /(group)\n if (route.includes('/(')) {\n const routeWithoutGroups = route.replace(/\\/\\(.+?\\)/g, '');\n addRoute(route, routeWithoutGroups);\n\n // If there are multiple groups, we need to expand them\n // eg /(test1,test2)/page => /test1/page & /test2/page\n for (const routeWithSingleGroup of extrapolateGroupRoutes(route)) {\n addRoute(route, routeWithSingleGroup);\n }\n }\n\n return true;\n };\n\n return {\n staticRoutes,\n dynamicRoutes,\n filePathToRoute,\n addFilePath,\n };\n}\n\nexport const setToUnionType = <T>(set: Set<T>) => {\n return set.size > 0 ? [...set].map((s) => `\\`${s}\\``).join(' | ') : 'never';\n};\n\n/**\n * Recursively walk a directory and call the callback with the file path.\n */\nasync function walk(directory: string, callback: (filePath: string) => void) {\n const files = await fs.readdir(directory);\n for (const file of files) {\n const p = path.join(directory, file);\n if ((await fs.stat(p)).isDirectory()) {\n await walk(p, callback);\n } else {\n // Normalise the paths so they are easier to convert to URLs\n const normalizedPath = p.replaceAll(path.sep, '/').replaceAll(' ', '_');\n callback(normalizedPath);\n }\n }\n}\n\n/**\n * Given a route, return all possible routes that could be generated from it.\n */\nexport function extrapolateGroupRoutes(\n route: string,\n routes: Set<string> = new Set()\n): Set<string> {\n // Create a version with no groups. We will then need to cleanup double and/or trailing slashes\n routes.add(route.replaceAll(ARRAY_GROUP_REGEX, '').replaceAll(/\\/+/g, '/').replace(/\\/$/, ''));\n\n const match = route.match(ARRAY_GROUP_REGEX);\n\n if (!match) {\n routes.add(route);\n return routes;\n }\n\n const groupsMatch = match[0];\n\n for (const group of groupsMatch.matchAll(CAPTURE_GROUP_REGEX)) {\n extrapolateGroupRoutes(route.replace(groupsMatch, `(${group[1]})`), routes);\n }\n\n return routes;\n}\n\n/**\n * NOTE: This code refers to a specific version of `expo-router` and is therefore unsafe to\n * mix with arbitrary versions.\n * TODO: Version this code with `expo-router` or version expo-router with `@expo/cli`.\n */\nconst routerDotTSTemplate = unsafeTemplate`declare module \"expo-router\" {\n import type { LinkProps as OriginalLinkProps } from \"expo-router/build/link/Link\";\n export * from \"expo-router/build\";\n\n type StaticRoutes = ${'staticRoutes'}\n type DynamicRoutes<T extends string> = ${'dynamicRoutes'}\n type DynamicRouteTemplate = ${'dynamicRouteParams'} \n\n type SearchOrHash = \\`?\\${string}\\` | \\`#\\${string}\\`;\n\n type RelativePathString = \\`./\\${string}\\` | \\`../\\${string}\\` | '..';\n\n type Suffix = \"\" | SearchOrHash;\n\n type SafeSlug<S extends string> = S extends \\`\\${string}/\\${string}\\`\n ? never\n : S extends \\`\\${string}\\${SearchOrHash}\\`\n ? never\n : S extends \"\"\n ? never\n : S;\n\n type CatchAllSlug<S extends string> = S extends \\`\\${string}\\${SearchOrHash}\\`\n ? never\n : S extends \"\"\n ? never\n : S;\n\n type InvaildPartialSlug = | \\`\\${string | never}\\${'[' | ']'}\\${string | never}\\`\n\n type IsParameter<Part> = Part extends \\`[\\${infer ParamName}]\\`\n ? ParamName\n : never;\n\n type FilteredParts<Path> = Path extends \\`\\${infer PartA}/\\${infer PartB}\\`\n ? IsParameter<PartA> | FilteredParts<PartB>\n : IsParameter<Path>;\n\n type RouteParams<Path> = {\n [Key in FilteredParts<Path> as Key extends \\`...\\${infer Name}\\` ? Name : Key]: \n Key extends \\`...\\${string}\\` ? string[] : string;\n };\n\n type Route<T> = T extends DynamicRouteTemplate\n ? never\n :\n | StaticRoutes\n | RelativePathString\n | \\`\\${StaticRoutes}\\${Suffix}\\`\n | (T extends \\`\\${DynamicRoutes<infer P>}\\${Suffix}\\`\n ? P extends InvaildPartialSlug\n ? never\n : T\n : never);\n\n export type Href<T> = Route<T> | HrefObject<T> | DynamicRouteTemplate\n\n export type HrefObject<T> = {\n pathname: Route<T> | DynamicRouteTemplate\n } & HrefObjectParams<T>;\n\n type HrefObjectParams<T> = T extends RelativePathString\n ? { params?: Record<string, string> }\n : T extends { pathname: DynamicRouteTemplate }\n ? { params: RouteParams<InferPathName<T>> }\n : unknown;\n\n /** Returns the search parameters for a route **/\n export type SearchParams<T extends DynamicRouteTemplate | StaticRoutes | RelativePathString> =\n T extends DynamicRouteTemplate ? RouteParams<T> : {};\n\n type InferPathName<T> = T extends { pathname: infer P } ? P : never;\n\n export interface LinkProps<T> extends OriginalLinkProps {\n href: T extends DynamicRouteTemplate ? HrefObject<T> : Href<T>;\n }\n\n export interface LinkComponent {\n <T>(props: React.PropsWithChildren<LinkProps<T>>): JSX.Element;\n /** Helper method to resolve an Href object into a string. */\n resolveHref: <T>(href: Href<T>) => string;\n }\n\n export const Link: LinkComponent;\n\n export type Router = {\n /** Navigate to the provided href. */\n push: <T>(href: Href<T>) => void;\n /** Navigate to route without appending to the history. */\n replace: <T>(href: Href<T>) => void;\n /** Go back in the history. */\n back: () => void;\n /** Update the current route query params. */\n setParams: <T extends string = ''>(params?: T extends '' ? Record<string, string> : RouteParams<T>) => void;\n };\n\n export function useRouter<T>(): Router<T>\n export function useLocalSearchParams<T extends DynamicRouteTemplate | StaticRoutes | RelativePathString>(): SearchParams<T>\n}\n`;\n"],"names":["setupTypedRoutes","getTypedRoutesUtils","extrapolateGroupRoutes","CAPTURE_DYNAMIC_PARAMS","CATCH_ALL","SLUG","ARRAY_GROUP_REGEX","CAPTURE_GROUP_REGEX","server","metro","typesDirectory","projectRoot","appRoot","getExpoRouterRootDirectory","filePathToRoute","staticRoutes","dynamicRoutes","addFilePath","metroWatchTypeScriptFiles","eventTypes","callback","filePath","type","shouldRegenerate","route","delete","regenerateRouterDotTS","Set","values","flatMap","v","Array","from","keys","walk","debounce","typesDir","dynamicRouteTemplates","fs","writeFile","path","resolve","routerDotTSTemplate","setToUnionType","dynamicRouteParams","Map","replace","match","has","dynamicParams","matchAll","map","isDynamic","size","addRoute","originalRoute","set","get","add","replaceAll","includes","routeWithoutGroups","routeWithSingleGroup","s","join","directory","files","readdir","file","p","stat","isDirectory","normalizedPath","sep","routes","groupsMatch","group","unsafeTemplate"],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ exports.forceUpdateTSConfig = forceUpdateTSConfig;
6
+ exports.getTSConfigUpdates = getTSConfigUpdates;
7
+ exports.forceRemovalTSConfig = forceRemovalTSConfig;
8
+ exports.getTSConfigRemoveUpdates = getTSConfigRemoveUpdates;
9
+ var _jsonFile = _interopRequireDefault(require("@expo/json-file"));
10
+ var _chalk = _interopRequireDefault(require("chalk"));
11
+ var _path = _interopRequireDefault(require("path"));
12
+ var _log = require("../../../log");
13
+ function _interopRequireDefault(obj) {
14
+ return obj && obj.__esModule ? obj : {
15
+ default: obj
16
+ };
17
+ }
18
+ async function forceUpdateTSConfig(projectRoot) {
19
+ // This runs after the TypeScript prerequisite, so we know the tsconfig.json exists
20
+ const tsConfigPath = _path.default.join(projectRoot, "tsconfig.json");
21
+ const { tsConfig , updates } = getTSConfigUpdates(_jsonFile.default.read(tsConfigPath, {
22
+ json5: true
23
+ }));
24
+ await writeUpdates(tsConfigPath, tsConfig, updates);
25
+ }
26
+ function getTSConfigUpdates(tsConfig) {
27
+ const updates = new Set();
28
+ if (!tsConfig.include) {
29
+ tsConfig.include = [
30
+ "**/*.ts",
31
+ "**/*.tsx",
32
+ ".expo/types/**/*.ts",
33
+ "expo-env.d.ts"
34
+ ];
35
+ updates.add("include");
36
+ } else if (Array.isArray(tsConfig.include)) {
37
+ if (!tsConfig.include.includes(".expo/types/**/*.ts")) {
38
+ tsConfig.include = [
39
+ ...tsConfig.include,
40
+ ".expo/types/**/*.ts"
41
+ ];
42
+ updates.add("include");
43
+ }
44
+ if (!tsConfig.include.includes("expo-env.d.ts")) {
45
+ tsConfig.include = [
46
+ ...tsConfig.include,
47
+ "expo-env.d.ts"
48
+ ];
49
+ updates.add("include");
50
+ }
51
+ }
52
+ return {
53
+ tsConfig,
54
+ updates
55
+ };
56
+ }
57
+ async function forceRemovalTSConfig(projectRoot) {
58
+ // This runs after the TypeScript prerequisite, so we know the tsconfig.json exists
59
+ const tsConfigPath = _path.default.join(projectRoot, "tsconfig.json");
60
+ const { tsConfig , updates } = getTSConfigRemoveUpdates(_jsonFile.default.read(tsConfigPath, {
61
+ json5: true
62
+ }));
63
+ await writeUpdates(tsConfigPath, tsConfig, updates);
64
+ }
65
+ function getTSConfigRemoveUpdates(tsConfig) {
66
+ const updates = new Set();
67
+ if (Array.isArray(tsConfig.include)) {
68
+ const filtered = tsConfig.include.filter((i)=>i !== "expo-env.d.ts" && i !== ".expo/types/**/*.ts"
69
+ );
70
+ if (filtered.length !== tsConfig.include.length) {
71
+ updates.add("include");
72
+ }
73
+ tsConfig.include = filtered;
74
+ }
75
+ return {
76
+ tsConfig,
77
+ updates
78
+ };
79
+ }
80
+ async function writeUpdates(tsConfigPath, tsConfig, updates) {
81
+ if (updates.size) {
82
+ await _jsonFile.default.writeAsync(tsConfigPath, tsConfig);
83
+ for (const update of updates){
84
+ _log.Log.log(_chalk.default`{bold TypeScript}: The {cyan tsconfig.json#${update}} property has been updated`);
85
+ }
86
+ }
87
+ }
88
+
89
+ //# sourceMappingURL=tsconfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/start/server/type-generation/tsconfig.ts"],"sourcesContent":["import JsonFile, { JSONObject } from '@expo/json-file';\nimport chalk from 'chalk';\nimport path from 'path';\n\nimport { Log } from '../../../log';\n\n/**\n * Force updates a project tsconfig with Expo values.\n */\nexport async function forceUpdateTSConfig(projectRoot: string) {\n // This runs after the TypeScript prerequisite, so we know the tsconfig.json exists\n const tsConfigPath = path.join(projectRoot, 'tsconfig.json');\n const { tsConfig, updates } = getTSConfigUpdates(\n JsonFile.read(tsConfigPath, {\n json5: true,\n })\n );\n\n await writeUpdates(tsConfigPath, tsConfig, updates);\n}\n\nexport function getTSConfigUpdates(tsConfig: JSONObject) {\n const updates = new Set<string>();\n\n if (!tsConfig.include) {\n tsConfig.include = ['**/*.ts', '**/*.tsx', '.expo/types/**/*.ts', 'expo-env.d.ts'];\n updates.add('include');\n } else if (Array.isArray(tsConfig.include)) {\n if (!tsConfig.include.includes('.expo/types/**/*.ts')) {\n tsConfig.include = [...tsConfig.include, '.expo/types/**/*.ts'];\n updates.add('include');\n }\n\n if (!tsConfig.include.includes('expo-env.d.ts')) {\n tsConfig.include = [...tsConfig.include, 'expo-env.d.ts'];\n updates.add('include');\n }\n }\n\n return { tsConfig, updates };\n}\n\nexport async function forceRemovalTSConfig(projectRoot: string) {\n // This runs after the TypeScript prerequisite, so we know the tsconfig.json exists\n const tsConfigPath = path.join(projectRoot, 'tsconfig.json');\n const { tsConfig, updates } = getTSConfigRemoveUpdates(\n JsonFile.read(tsConfigPath, {\n json5: true,\n })\n );\n\n await writeUpdates(tsConfigPath, tsConfig, updates);\n}\n\nexport function getTSConfigRemoveUpdates(tsConfig: JSONObject) {\n const updates = new Set<string>();\n\n if (Array.isArray(tsConfig.include)) {\n const filtered = (tsConfig.include as string[]).filter(\n (i) => i !== 'expo-env.d.ts' && i !== '.expo/types/**/*.ts'\n );\n\n if (filtered.length !== tsConfig.include.length) {\n updates.add('include');\n }\n\n tsConfig.include = filtered;\n }\n\n return { tsConfig, updates };\n}\n\nasync function writeUpdates(tsConfigPath: string, tsConfig: JSONObject, updates: Set<string>) {\n if (updates.size) {\n await JsonFile.writeAsync(tsConfigPath, tsConfig);\n for (const update of updates) {\n Log.log(\n chalk`{bold TypeScript}: The {cyan tsconfig.json#${update}} property has been updated`\n );\n }\n }\n}\n"],"names":["forceUpdateTSConfig","getTSConfigUpdates","forceRemovalTSConfig","getTSConfigRemoveUpdates","projectRoot","tsConfigPath","path","join","tsConfig","updates","JsonFile","read","json5","writeUpdates","Set","include","add","Array","isArray","includes","filtered","filter","i","length","size","writeAsync","update","Log","log","chalk"],"mappings":"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"}
@@ -8,13 +8,14 @@ var _config = require("@expo/config");
8
8
  var _fs = _interopRequireDefault(require("fs"));
9
9
  var _path = _interopRequireDefault(require("path"));
10
10
  var _templates = require("../../customize/templates");
11
+ var _html = require("../../export/html");
11
12
  var _env = require("../../utils/env");
12
13
  function _interopRequireDefault(obj) {
13
14
  return obj && obj.__esModule ? obj : {
14
15
  default: obj
15
16
  };
16
17
  }
17
- async function createTemplateHtmlFromExpoConfigAsync(projectRoot, { scripts , exp =(0, _config).getConfig(projectRoot, {
18
+ async function createTemplateHtmlFromExpoConfigAsync(projectRoot, { scripts , cssLinks , exp =(0, _config).getConfig(projectRoot, {
18
19
  skipSDKVersionRequirement: true
19
20
  }).exp }) {
20
21
  var ref, ref1, ref2;
@@ -22,6 +23,7 @@ async function createTemplateHtmlFromExpoConfigAsync(projectRoot, { scripts , ex
22
23
  return createTemplateHtmlAsync(projectRoot, {
23
24
  langIsoCode: (ref3 = (ref = exp.web) == null ? void 0 : ref.lang) != null ? ref3 : "en",
24
25
  scripts,
26
+ cssLinks,
25
27
  title: (_webName = (0, _config).getNameFromConfig(exp).webName) != null ? _webName : "Expo App",
26
28
  description: (ref1 = exp.web) == null ? void 0 : ref1.description,
27
29
  themeColor: (ref2 = exp.web) == null ? void 0 : ref2.themeColor
@@ -46,13 +48,27 @@ function getFileFromLocalPublicFolder(projectRoot, { publicFolder , filePath })
46
48
  }
47
49
  return _fs.default.promises.readFile(filePath, "utf8");
48
50
  }
49
- async function createTemplateHtmlAsync(projectRoot, { scripts , description , langIsoCode , title , themeColor }) {
51
+ async function createTemplateHtmlAsync(projectRoot, { scripts , cssLinks , description , langIsoCode , title , themeColor }) {
50
52
  // Resolve the best possible index.html template file.
51
53
  let contents = await getTemplateIndexHtmlAsync(projectRoot);
52
54
  contents = contents.replace("%LANG_ISO_CODE%", langIsoCode);
53
55
  contents = contents.replace("%WEB_TITLE%", title);
54
- contents = contents.replace("</body>", scripts.map((url)=>`<script src="${url}"></script>`
55
- ).join("") + "</body>");
56
+ contents = (0, _html).appendScriptsToHtml(contents, scripts);
57
+ if (cssLinks) {
58
+ contents = (0, _html).appendLinkToHtml(contents, cssLinks.map((href)=>[
59
+ // NOTE: We probably don't have to preload the CSS files for SPA-styled websites.
60
+ {
61
+ as: "style",
62
+ rel: "preload",
63
+ href
64
+ },
65
+ {
66
+ rel: "stylesheet",
67
+ href
68
+ },
69
+ ]
70
+ ).flat());
71
+ }
56
72
  if (themeColor) {
57
73
  contents = addMeta(contents, `name="theme-color" content="${themeColor}"`);
58
74
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/start/server/webTemplate.ts"],"sourcesContent":["import { ExpoConfig, getConfig, getNameFromConfig } from '@expo/config';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { TEMPLATES } from '../../customize/templates';\nimport { env } from '../../utils/env';\n\n/**\n * Create a static HTML for SPA styled websites.\n * This method attempts to reuse the same patterns as `@expo/webpack-config`.\n */\nexport async function createTemplateHtmlFromExpoConfigAsync(\n projectRoot: string,\n {\n scripts,\n exp = getConfig(projectRoot, { skipSDKVersionRequirement: true }).exp,\n }: {\n scripts: string[];\n exp?: ExpoConfig;\n }\n) {\n return createTemplateHtmlAsync(projectRoot, {\n langIsoCode: exp.web?.lang ?? 'en',\n scripts,\n title: getNameFromConfig(exp).webName ?? 'Expo App',\n description: exp.web?.description,\n themeColor: exp.web?.themeColor,\n });\n}\n\nfunction getFileFromLocalPublicFolder(\n projectRoot: string,\n { publicFolder, filePath }: { publicFolder: string; filePath: string }\n): string | null {\n const localFilePath = path.resolve(projectRoot, publicFolder, filePath);\n if (!fs.existsSync(localFilePath)) {\n return null;\n }\n return localFilePath;\n}\n\n/** Attempt to read the `index.html` from the local project before falling back on the template `index.html`. */\nasync function getTemplateIndexHtmlAsync(projectRoot: string): Promise<string> {\n let filePath = getFileFromLocalPublicFolder(projectRoot, {\n // TODO: Maybe use the app.json override.\n publicFolder: env.EXPO_PUBLIC_FOLDER,\n filePath: 'index.html',\n });\n if (!filePath) {\n filePath = TEMPLATES.find((value) => value.id === 'index.html')!.file(projectRoot);\n }\n return fs.promises.readFile(filePath, 'utf8');\n}\n\n/** Return an `index.html` string with template values added. */\nexport async function createTemplateHtmlAsync(\n projectRoot: string,\n {\n scripts,\n description,\n langIsoCode,\n title,\n themeColor,\n }: {\n scripts: string[];\n description?: string;\n langIsoCode: string;\n title: string;\n themeColor?: string;\n }\n): Promise<string> {\n // Resolve the best possible index.html template file.\n let contents = await getTemplateIndexHtmlAsync(projectRoot);\n\n contents = contents.replace('%LANG_ISO_CODE%', langIsoCode);\n contents = contents.replace('%WEB_TITLE%', title);\n contents = contents.replace(\n '</body>',\n scripts.map((url) => `<script src=\"${url}\"></script>`).join('') + '</body>'\n );\n\n if (themeColor) {\n contents = addMeta(contents, `name=\"theme-color\" content=\"${themeColor}\"`);\n }\n\n if (description) {\n contents = addMeta(contents, `name=\"description\" content=\"${description}\"`);\n }\n\n return contents;\n}\n\n/** Add a `<meta />` tag to the `<head />` element. */\nfunction addMeta(contents: string, meta: string): string {\n return contents.replace('</head>', `<meta ${meta}>\\n</head>`);\n}\n"],"names":["createTemplateHtmlFromExpoConfigAsync","createTemplateHtmlAsync","projectRoot","scripts","exp","getConfig","skipSDKVersionRequirement","getNameFromConfig","langIsoCode","web","lang","title","webName","description","themeColor","getFileFromLocalPublicFolder","publicFolder","filePath","localFilePath","path","resolve","fs","existsSync","getTemplateIndexHtmlAsync","env","EXPO_PUBLIC_FOLDER","TEMPLATES","find","value","id","file","promises","readFile","contents","replace","map","url","join","addMeta","meta"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/start/server/webTemplate.ts"],"sourcesContent":["import { ExpoConfig, getConfig, getNameFromConfig } from '@expo/config';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { TEMPLATES } from '../../customize/templates';\nimport { appendLinkToHtml, appendScriptsToHtml } from '../../export/html';\nimport { env } from '../../utils/env';\n\n/**\n * Create a static HTML for SPA styled websites.\n * This method attempts to reuse the same patterns as `@expo/webpack-config`.\n */\nexport async function createTemplateHtmlFromExpoConfigAsync(\n projectRoot: string,\n {\n scripts,\n cssLinks,\n exp = getConfig(projectRoot, { skipSDKVersionRequirement: true }).exp,\n }: {\n scripts: string[];\n cssLinks?: string[];\n exp?: ExpoConfig;\n }\n) {\n return createTemplateHtmlAsync(projectRoot, {\n langIsoCode: exp.web?.lang ?? 'en',\n scripts,\n cssLinks,\n title: getNameFromConfig(exp).webName ?? 'Expo App',\n description: exp.web?.description,\n themeColor: exp.web?.themeColor,\n });\n}\n\nfunction getFileFromLocalPublicFolder(\n projectRoot: string,\n { publicFolder, filePath }: { publicFolder: string; filePath: string }\n): string | null {\n const localFilePath = path.resolve(projectRoot, publicFolder, filePath);\n if (!fs.existsSync(localFilePath)) {\n return null;\n }\n return localFilePath;\n}\n\n/** Attempt to read the `index.html` from the local project before falling back on the template `index.html`. */\nasync function getTemplateIndexHtmlAsync(projectRoot: string): Promise<string> {\n let filePath = getFileFromLocalPublicFolder(projectRoot, {\n // TODO: Maybe use the app.json override.\n publicFolder: env.EXPO_PUBLIC_FOLDER,\n filePath: 'index.html',\n });\n if (!filePath) {\n filePath = TEMPLATES.find((value) => value.id === 'index.html')!.file(projectRoot);\n }\n return fs.promises.readFile(filePath, 'utf8');\n}\n\n/** Return an `index.html` string with template values added. */\nexport async function createTemplateHtmlAsync(\n projectRoot: string,\n {\n scripts,\n cssLinks,\n description,\n langIsoCode,\n title,\n themeColor,\n }: {\n scripts: string[];\n cssLinks?: string[];\n description?: string;\n langIsoCode: string;\n title: string;\n themeColor?: string;\n }\n): Promise<string> {\n // Resolve the best possible index.html template file.\n let contents = await getTemplateIndexHtmlAsync(projectRoot);\n\n contents = contents.replace('%LANG_ISO_CODE%', langIsoCode);\n contents = contents.replace('%WEB_TITLE%', title);\n\n contents = appendScriptsToHtml(contents, scripts);\n\n if (cssLinks) {\n contents = appendLinkToHtml(\n contents,\n cssLinks\n .map((href) => [\n // NOTE: We probably don't have to preload the CSS files for SPA-styled websites.\n {\n as: 'style',\n rel: 'preload',\n href,\n },\n {\n rel: 'stylesheet',\n href,\n },\n ])\n .flat()\n );\n }\n\n if (themeColor) {\n contents = addMeta(contents, `name=\"theme-color\" content=\"${themeColor}\"`);\n }\n\n if (description) {\n contents = addMeta(contents, `name=\"description\" content=\"${description}\"`);\n }\n\n return contents;\n}\n\n/** Add a `<meta />` tag to the `<head />` element. */\nfunction addMeta(contents: string, meta: string): string {\n return contents.replace('</head>', `<meta ${meta}>\\n</head>`);\n}\n"],"names":["createTemplateHtmlFromExpoConfigAsync","createTemplateHtmlAsync","projectRoot","scripts","cssLinks","exp","getConfig","skipSDKVersionRequirement","getNameFromConfig","langIsoCode","web","lang","title","webName","description","themeColor","getFileFromLocalPublicFolder","publicFolder","filePath","localFilePath","path","resolve","fs","existsSync","getTemplateIndexHtmlAsync","env","EXPO_PUBLIC_FOLDER","TEMPLATES","find","value","id","file","promises","readFile","contents","replace","appendScriptsToHtml","appendLinkToHtml","map","href","as","rel","flat","addMeta","meta"],"mappings":"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"}
@@ -11,6 +11,7 @@ var Log = _interopRequireWildcard(require("../../../log"));
11
11
  var _env = require("../../../utils/env");
12
12
  var _errors = require("../../../utils/errors");
13
13
  var _ip = require("../../../utils/ip");
14
+ var _nodeEnv = require("../../../utils/nodeEnv");
14
15
  var _port = require("../../../utils/port");
15
16
  var _progress = require("../../../utils/progress");
16
17
  var _dotExpo = require("../../project/dotExpo");
@@ -117,7 +118,7 @@ class WebpackBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
117
118
  // Add manifest middleware to the other middleware.
118
119
  // TODO: Move this in to expo/dev-server.
119
120
  const middleware = await this.getManifestMiddlewareAsync(options);
120
- nativeMiddleware.middleware.use(middleware);
121
+ nativeMiddleware.middleware.use(middleware.getHandler());
121
122
  return nativeMiddleware;
122
123
  }
123
124
  async getAvailablePortAsync(options) {
@@ -283,7 +284,8 @@ class WebpackBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
283
284
  https: options.https
284
285
  };
285
286
  var _mode;
286
- setMode((_mode = env.mode) != null ? _mode : "development");
287
+ (0, _nodeEnv).setNodeEnv((_mode = env.mode) != null ? _mode : "development");
288
+ require("@expo/env").load(env.projectRoot);
287
289
  // Check if the project has a webpack.config.js in the root.
288
290
  const projectWebpackConfig = this.getProjectConfigFilePath();
289
291
  let config;
@@ -322,10 +324,6 @@ class WebpackBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
322
324
  }
323
325
  }
324
326
  exports.WebpackBundlerDevServer = WebpackBundlerDevServer;
325
- function setMode(mode) {
326
- process.env.BABEL_ENV = mode;
327
- process.env.NODE_ENV = mode;
328
- }
329
327
  function getProjectWebpackConfigFilePath(projectRoot) {
330
328
  return _resolveFrom.default.silent(projectRoot, "./webpack.config.js");
331
329
  }