@expo/cli 0.10.7 → 0.10.8

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 (32) hide show
  1. package/build/bin/cli +2 -2
  2. package/build/src/start/server/metro/inspector-proxy/device.js +21 -2
  3. package/build/src/start/server/metro/inspector-proxy/device.js.map +1 -1
  4. package/build/src/start/server/metro/inspector-proxy/handlers/DebuggerScriptSource.js.map +1 -1
  5. package/build/src/start/server/metro/inspector-proxy/handlers/NetworkResponse.js.map +1 -1
  6. package/build/src/start/server/metro/inspector-proxy/handlers/PageReload.js.map +1 -1
  7. package/build/src/start/server/metro/inspector-proxy/handlers/VscodeDebuggerGetPossibleBreakpoints.js +22 -0
  8. package/build/src/start/server/metro/inspector-proxy/handlers/VscodeDebuggerGetPossibleBreakpoints.js.map +1 -0
  9. package/build/src/start/server/metro/inspector-proxy/handlers/VscodeDebuggerScriptParsed.js +55 -0
  10. package/build/src/start/server/metro/inspector-proxy/handlers/VscodeDebuggerScriptParsed.js.map +1 -0
  11. package/build/src/start/server/metro/inspector-proxy/handlers/VscodeDebuggerSetBreakpointByUrl.js +17 -0
  12. package/build/src/start/server/metro/inspector-proxy/handlers/VscodeDebuggerSetBreakpointByUrl.js.map +1 -0
  13. package/build/src/start/server/metro/inspector-proxy/handlers/VscodeRuntimeGetProperties.js +39 -0
  14. package/build/src/start/server/metro/inspector-proxy/handlers/VscodeRuntimeGetProperties.js.map +1 -0
  15. package/build/src/start/server/metro/inspector-proxy/handlers/types.js.map +1 -1
  16. package/build/src/start/server/metro/inspector-proxy/proxy.js +14 -6
  17. package/build/src/start/server/metro/inspector-proxy/proxy.js.map +1 -1
  18. package/build/src/start/server/metro/withMetroMultiPlatform.js +2 -1
  19. package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
  20. package/build/src/start/server/middleware/ClassicManifestMiddleware.js +1 -1
  21. package/build/src/start/server/type-generation/__typetests__/fixtures/basic.js +38 -0
  22. package/build/src/start/server/type-generation/__typetests__/fixtures/basic.js.map +1 -0
  23. package/build/src/start/server/type-generation/__typetests__/generateFixtures.js +38 -0
  24. package/build/src/start/server/type-generation/__typetests__/generateFixtures.js.map +1 -0
  25. package/build/src/start/server/type-generation/__typetests__/route.test.js +165 -0
  26. package/build/src/start/server/type-generation/__typetests__/route.test.js.map +1 -0
  27. package/build/src/start/server/type-generation/routes.js +175 -62
  28. package/build/src/start/server/type-generation/routes.js.map +1 -1
  29. package/build/src/utils/analytics/rudderstackClient.js +2 -2
  30. package/package.json +10 -8
  31. package/build/src/start/server/metro/inspector-proxy/handlers/VscodeCompat.js +0 -63
  32. package/build/src/start/server/metro/inspector-proxy/handlers/VscodeCompat.js.map +0 -1
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
5
  exports.setupTypedRoutes = setupTypedRoutes;
6
+ exports.getTemplateString = getTemplateString;
6
7
  exports.getTypedRoutesUtils = getTypedRoutesUtils;
7
8
  exports.extrapolateGroupRoutes = extrapolateGroupRoutes;
8
9
  exports.setToUnionType = exports.CAPTURE_GROUP_REGEX = exports.ARRAY_GROUP_REGEX = exports.SLUG = exports.CATCH_ALL = exports.CAPTURE_DYNAMIC_PARAMS = void 0;
@@ -77,20 +78,38 @@ async function setupTypedRoutes({ server , metro , typesDirectory , projectRoot
77
78
  * Generate a router.d.ts file that contains all of the routes in the project.
78
79
  * Should be debounced as its very common for developers to make changes to multiple files at once (eg Save All)
79
80
  */ const regenerateRouterDotTS = (0, _lodash).debounce((typesDir, staticRoutes, dynamicRoutes, dynamicRouteTemplates)=>{
80
- _promises.default.writeFile(_path.default.resolve(typesDir, "./router.d.ts"), routerDotTSTemplate({
81
+ _promises.default.writeFile(_path.default.resolve(typesDir, "./router.d.ts"), getTemplateString(staticRoutes, dynamicRoutes, dynamicRouteTemplates));
82
+ }, 100);
83
+ function getTemplateString(staticRoutes, dynamicRoutes, dynamicRouteTemplates) {
84
+ return routerDotTSTemplate({
81
85
  staticRoutes: setToUnionType(staticRoutes),
82
86
  dynamicRoutes: setToUnionType(dynamicRoutes),
83
87
  dynamicRouteParams: setToUnionType(dynamicRouteTemplates)
84
- }));
85
- }, 100);
88
+ });
89
+ }
86
90
  function getTypedRoutesUtils(appRoot) {
87
- const staticRoutes = new Map([
91
+ /*
92
+ * staticRoutes are a map where the key if the route without groups and the value
93
+ * is another set of all group versions of the route. e.g,
94
+ * Map([
95
+ * ["/", ["/(app)/(notes)", "/(app)/(profile)"]
96
+ * ])
97
+ */ const staticRoutes = new Map([
88
98
  [
89
99
  "/",
90
100
  new Set("/")
91
101
  ]
92
102
  ]);
93
- const dynamicRoutes = new Map();
103
+ /*
104
+ * dynamicRoutes are the same as staticRoutes (key if the resolved route,
105
+ * and the value is a set of possible routes). e.g:
106
+ *
107
+ * /[...fruits] -> /${CatchAllRoutePart<T>}
108
+ * /color/[color] -> /color/${SingleRoutePart<T>}
109
+ *
110
+ * The keys of this map are also important, as they can be used as "static" types
111
+ * <Link href={{ pathname: "/[...fruits]",params: { fruits: ["apple"] } }} />
112
+ */ const dynamicRoutes = new Map();
94
113
  const filePathToRoute = (filePath)=>{
95
114
  return filePath.replace(appRoot, "").replace(/index.[jt]sx?/, "").replace(/\.[jt]sx?$/, "");
96
115
  };
@@ -115,7 +134,7 @@ function getTypedRoutesUtils(appRoot) {
115
134
  set = new Set();
116
135
  dynamicRoutes.set(originalRoute, set);
117
136
  }
118
- set.add(route.replaceAll(CATCH_ALL, "${CatchAllSlug<T>}").replaceAll(SLUG, "${SafeSlug<T>}"));
137
+ set.add(route.replaceAll(CATCH_ALL, "${CatchAllRoutePart<T>}").replaceAll(SLUG, "${SingleRoutePart<T>}"));
119
138
  } else {
120
139
  let set = staticRoutes.get(originalRoute);
121
140
  if (!set) {
@@ -187,104 +206,198 @@ function extrapolateGroupRoutes(route, routes = new Set()) {
187
206
  * NOTE: This code refers to a specific version of `expo-router` and is therefore unsafe to
188
207
  * mix with arbitrary versions.
189
208
  * TODO: Version this code with `expo-router` or version expo-router with `@expo/cli`.
190
- */ const routerDotTSTemplate = _template.unsafeTemplate`declare module "expo-router" {
191
- import type { LinkProps as OriginalLinkProps } from "expo-router/build/link/Link";
192
- export * from "expo-router/build";
209
+ */ const routerDotTSTemplate = _template.unsafeTemplate`/* eslint-disable @typescript-eslint/no-unused-vars */
210
+ /* eslint-disable import/export */
211
+ /* eslint-disable @typescript-eslint/ban-types */
212
+ declare module "expo-router" {
213
+ import type { LinkProps as OriginalLinkProps } from 'expo-router/build/link/Link';
214
+ export * from 'expo-router/build';
193
215
 
194
- type StaticRoutes = ${"staticRoutes"}
195
- type DynamicRoutes<T extends string> = ${"dynamicRoutes"}
196
- type DynamicRouteTemplate = ${"dynamicRouteParams"}
197
-
198
- type SearchOrHash = \`?\${string}\` | \`#\${string}\`;
216
+ // prettier-ignore
217
+ type StaticRoutes = ${"staticRoutes"};
218
+ // prettier-ignore
219
+ type DynamicRoutes<T extends string> = ${"dynamicRoutes"};
220
+ // prettier-ignore
221
+ type DynamicRouteTemplate = ${"dynamicRouteParams"};
199
222
 
200
223
  type RelativePathString = \`./\${string}\` | \`../\${string}\` | '..';
224
+ type AbsoluteRoute = DynamicRouteTemplate | StaticRoutes;
225
+ type ExternalPathString = \`http\${string}\`;
226
+ type ExpoRouterRoutes = DynamicRouteTemplate | StaticRoutes | RelativePathString;
227
+ type AllRoutes = ExpoRouterRoutes | ExternalPathString;
228
+
229
+ /****************
230
+ * Route Utils *
231
+ ****************/
201
232
 
202
- type Suffix = "" | SearchOrHash;
233
+ type SearchOrHash = \`?\${string}\` | \`#\${string}\`;
203
234
 
204
- type SafeSlug<S extends string> = S extends \`\${string}/\${string}\`
235
+ /**
236
+ * Return only the RoutePart of a string. If the string has multiple parts return never
237
+ *
238
+ * string | type
239
+ * ---------|------
240
+ * 123 | 123
241
+ * /123/abc | never
242
+ * 123?abc | never
243
+ * ./123 | never
244
+ * /123 | never
245
+ * 123/../ | never
246
+ */
247
+ type SingleRoutePart<S extends string> = S extends \`\${string}/\${string}\`
205
248
  ? never
206
249
  : S extends \`\${string}\${SearchOrHash}\`
207
250
  ? never
208
- : S extends ""
251
+ : S extends ''
209
252
  ? never
210
253
  : S;
211
254
 
212
- type CatchAllSlug<S extends string> = S extends \`\${string}\${SearchOrHash}\`
255
+ /**
256
+ * Return only the CatchAll router part. If the string has search parameters or a hash return never
257
+ */
258
+ type CatchAllRoutePart<S extends string> = S extends \`\${string}\${SearchOrHash}\`
213
259
  ? never
214
- : S extends ""
260
+ : S extends ''
215
261
  ? never
216
262
  : S;
217
263
 
218
- type InvaildPartialSlug = | \`\${string | never}\${'[' | ']'}\${string | never}\`
264
+ // type OptionalCatchAllRoutePart<S extends string> = S extends \`\${string}\${SearchOrHash}\` ? never : S
219
265
 
220
- type IsParameter<Part> = Part extends \`[\${infer ParamName}]\`
221
- ? ParamName
222
- : never;
266
+ /**
267
+ * Return the name of a route parameter
268
+ * '[test]' -> 'test'
269
+ * 'test' -> never
270
+ * '[...test]' -> '...test'
271
+ */
272
+ type IsParameter<Part> = Part extends \`[\${infer ParamName}]\` ? ParamName : never;
223
273
 
224
- type FilteredParts<Path> = Path extends \`\${infer PartA}/\${infer PartB}\`
225
- ? IsParameter<PartA> | FilteredParts<PartB>
274
+ /**
275
+ * Return a union of all parameter names. If there are no names return never
276
+ *
277
+ * /[test] -> 'test'
278
+ * /[abc]/[...def] -> 'abc'|'...def'
279
+ */
280
+ type ParameterNames<Path> = Path extends \`\${infer PartA}/\${infer PartB}\`
281
+ ? IsParameter<PartA> | ParameterNames<PartB>
226
282
  : IsParameter<Path>;
227
283
 
284
+ /**
285
+ * Returns all segements of a route.
286
+ *
287
+ * /(group)/123/abc/[id]/[...rest] -> ['(group)', '123', 'abc', '[id]', '[...rest]'
288
+ */
289
+ type RouteSegments<Path> = Path extends \`\${infer PartA}/\${infer PartB}\`
290
+ ? PartA extends '' | '.'
291
+ ? [...RouteSegments<PartB>]
292
+ : [PartA, ...RouteSegments<PartB>]
293
+ : Path extends ''
294
+ ? []
295
+ : [Path];
296
+
297
+ /**
298
+ * Returns a Record of the routes parameters as strings and CatchAll parameters as string[]
299
+ *
300
+ * /[id]/[...rest] -> { id: string, rest: string[] }
301
+ * /no-params -> {}
302
+ */
228
303
  type RouteParams<Path> = {
229
- [Key in FilteredParts<Path> as Key extends \`...\${infer Name}\` ? Name : Key]:
230
- Key extends \`...\${string}\` ? string[] : string;
304
+ [Key in ParameterNames<Path> as Key extends \`...\${infer Name}\`
305
+ ? Name
306
+ : Key]: Key extends \`...\${string}\` ? string[] : string;
231
307
  };
232
308
 
233
- type Route<T> = T extends DynamicRouteTemplate
309
+ /**
310
+ * Returns the search parameters for a route
311
+ */
312
+ export type SearchParams<T extends AllRoutes> = T extends DynamicRouteTemplate
313
+ ? RouteParams<T>
314
+ : T extends StaticRoutes
315
+ ? never
316
+ : Record<string, string>;
317
+
318
+ /**
319
+ * Route is mostly used as part of Href to ensure that a valid route is provided
320
+ *
321
+ * Given a dynamic route, this will return never. This is helpful for conditional logic
322
+ *
323
+ * /test -> /test, /test2, etc
324
+ * /test/[abc] -> never
325
+ * /test/resolve -> /test, /test2, etc
326
+ *
327
+ * Note that if we provide a value for [abc] then the route is allowed
328
+ *
329
+ * This is named Route to prevent confusion, as users they will often see it in tooltips
330
+ */
331
+ export type Route<T> = T extends DynamicRouteTemplate
234
332
  ? never
235
333
  :
236
334
  | StaticRoutes
237
335
  | RelativePathString
238
- | \`\${StaticRoutes}\${Suffix}\`
239
- | (T extends \`\${DynamicRoutes<infer P>}\${Suffix}\`
240
- ? P extends InvaildPartialSlug
241
- ? never
242
- : T
243
- : never);
336
+ | ExternalPathString
337
+ | (T extends DynamicRoutes<infer _> ? T : never);
244
338
 
245
- export type Href<T> = Route<T> | HrefObject<T> | DynamicRouteTemplate
339
+ /*********
340
+ * Href *
341
+ *********/
246
342
 
247
- export type HrefObject<T> = {
248
- pathname: Route<T> | DynamicRouteTemplate
249
- } & HrefObjectParams<T>;
343
+ export type Href<T extends string> = Route<T> | HrefObject<T>;
250
344
 
251
- type HrefObjectParams<T> = T extends RelativePathString
252
- ? { params?: Record<string, string> }
253
- : T extends { pathname: DynamicRouteTemplate }
254
- ? { params: RouteParams<InferPathName<T>> }
255
- : unknown;
345
+ export type HrefObject<T = AllRoutes> = T extends DynamicRouteTemplate
346
+ ? { pathname: T; params: RouteParams<T> }
347
+ : T extends Route<T>
348
+ ? { pathname: Route<T>; params?: never }
349
+ : never;
256
350
 
257
- /** Returns the search parameters for a route **/
258
- export type SearchParams<T extends DynamicRouteTemplate | StaticRoutes | RelativePathString> =
259
- T extends DynamicRouteTemplate ? RouteParams<T> : {};
351
+ /***********************
352
+ * Expo Router Exports *
353
+ ***********************/
260
354
 
261
- type InferPathName<T> = T extends { pathname: infer P } ? P : never;
355
+ export type Router = {
356
+ /** Navigate to the provided href. */
357
+ push: <T extends string>(href: Href<T>) => void;
358
+ /** Navigate to route without appending to the history. */
359
+ replace: <T extends string>(href: Href<T>) => void;
360
+ /** Go back in the history. */
361
+ back: () => void;
362
+ /** Update the current route query params. */
363
+ setParams: <T extends string = ''>(
364
+ params?: T extends '' ? Record<string, string> : RouteParams<T>
365
+ ) => void;
366
+ };
262
367
 
263
- export interface LinkProps<T> extends OriginalLinkProps {
368
+ /************
369
+ * <Link /> *
370
+ ************/
371
+ export interface LinkProps<T extends string> extends OriginalLinkProps {
264
372
  href: T extends DynamicRouteTemplate ? HrefObject<T> : Href<T>;
265
373
  }
266
374
 
267
375
  export interface LinkComponent {
268
- <T>(props: React.PropsWithChildren<LinkProps<T>>): JSX.Element;
376
+ <T extends string>(props: React.PropsWithChildren<LinkProps<T>>): JSX.Element;
269
377
  /** Helper method to resolve an Href object into a string. */
270
- resolveHref: <T>(href: Href<T>) => string;
378
+ resolveHref: <T extends string>(href: Href<T>) => string;
271
379
  }
272
380
 
273
381
  export const Link: LinkComponent;
274
382
 
275
- export type Router = {
276
- /** Navigate to the provided href. */
277
- push: <T>(href: Href<T>) => void;
278
- /** Navigate to route without appending to the history. */
279
- replace: <T>(href: Href<T>) => void;
280
- /** Go back in the history. */
281
- back: () => void;
282
- /** Update the current route query params. */
283
- setParams: <T extends string = ''>(params?: T extends '' ? Record<string, string> : RouteParams<T>) => void;
284
- };
383
+ /************
384
+ * Hooks *
385
+ ************/
386
+ export function useRouter(): Router;
387
+ export function useLocalSearchParams<
388
+ T extends DynamicRouteTemplate | StaticRoutes | RelativePathString
389
+ >(): SearchParams<T>;
390
+ export function useSearchParams<
391
+ T extends AllRoutes | SearchParams<DynamicRouteTemplate>
392
+ >(): T extends AllRoutes ? SearchParams<T> : T;
393
+
394
+ export function useGlobalSearchParams<
395
+ T extends AllRoutes | SearchParams<DynamicRouteTemplate>
396
+ >(): T extends AllRoutes ? SearchParams<T> : T;
285
397
 
286
- export function useRouter<T>(): Router<T>
287
- export function useLocalSearchParams<T extends DynamicRouteTemplate | StaticRoutes | RelativePathString>(): SearchParams<T>
398
+ export function useSegments<
399
+ T extends AbsoluteRoute | RouteSegments<AbsoluteRoute> | RelativePathString
400
+ >(): T extends AbsoluteRoute ? RouteSegments<T> : T extends string ? string[] : T;
288
401
  }
289
402
  `;
290
403
 
@@ -1 +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';\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 routerDirectory: string;\n}\n\nexport async function setupTypedRoutes({\n server,\n metro,\n typesDirectory,\n projectRoot,\n routerDirectory,\n}: SetupTypedRoutesOptions) {\n const appRoot = path.join(projectRoot, routerDirectory);\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","routerDirectory","appRoot","path","join","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","resolve","routerDotTSTemplate","setToUnionType","dynamicRouteParams","Map","replace","match","has","dynamicParams","matchAll","map","isDynamic","size","addRoute","originalRoute","set","get","add","replaceAll","includes","routeWithoutGroups","routeWithSingleGroup","s","directory","files","readdir","file","p","stat","isDirectory","normalizedPath","sep","routes","groupsMatch","group","unsafeTemplate"],"mappings":"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"}
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';\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 routerDirectory: string;\n}\n\nexport async function setupTypedRoutes({\n server,\n metro,\n typesDirectory,\n projectRoot,\n routerDirectory,\n}: SetupTypedRoutesOptions) {\n const appRoot = path.join(projectRoot, routerDirectory);\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 getTemplateString(staticRoutes, dynamicRoutes, dynamicRouteTemplates)\n );\n },\n 100\n);\n\n/*\n * This is exported for testing purposes\n */\nexport function getTemplateString(\n staticRoutes: Set<string>,\n dynamicRoutes: Set<string>,\n dynamicRouteTemplates: Set<string>\n) {\n return routerDotTSTemplate({\n staticRoutes: setToUnionType(staticRoutes),\n dynamicRoutes: setToUnionType(dynamicRoutes),\n dynamicRouteParams: setToUnionType(dynamicRouteTemplates),\n });\n}\n\n/**\n * Utility functions for typed routes\n *\n * These are extracted for easier testing\n */\nexport function getTypedRoutesUtils(appRoot: string) {\n /*\n * staticRoutes are a map where the key if the route without groups and the value\n * is another set of all group versions of the route. e.g,\n * Map([\n * [\"/\", [\"/(app)/(notes)\", \"/(app)/(profile)\"]\n * ])\n */\n const staticRoutes = new Map<string, Set<string>>([['/', new Set('/')]]);\n /*\n * dynamicRoutes are the same as staticRoutes (key if the resolved route,\n * and the value is a set of possible routes). e.g:\n *\n * /[...fruits] -> /${CatchAllRoutePart<T>}\n * /color/[color] -> /color/${SingleRoutePart<T>}\n *\n * The keys of this map are also important, as they can be used as \"static\" types\n * <Link href={{ pathname: \"/[...fruits]\",params: { fruits: [\"apple\"] } }} />\n */\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\n .replaceAll(CATCH_ALL, '${CatchAllRoutePart<T>}')\n .replaceAll(SLUG, '${SingleRoutePart<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`/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable import/export */\n/* eslint-disable @typescript-eslint/ban-types */\ndeclare module \"expo-router\" {\n import type { LinkProps as OriginalLinkProps } from 'expo-router/build/link/Link';\n export * from 'expo-router/build';\n\n // prettier-ignore\n type StaticRoutes = ${'staticRoutes'};\n // prettier-ignore\n type DynamicRoutes<T extends string> = ${'dynamicRoutes'};\n // prettier-ignore\n type DynamicRouteTemplate = ${'dynamicRouteParams'};\n\n type RelativePathString = \\`./\\${string}\\` | \\`../\\${string}\\` | '..';\n type AbsoluteRoute = DynamicRouteTemplate | StaticRoutes;\n type ExternalPathString = \\`http\\${string}\\`;\n type ExpoRouterRoutes = DynamicRouteTemplate | StaticRoutes | RelativePathString;\n type AllRoutes = ExpoRouterRoutes | ExternalPathString;\n\n /****************\n * Route Utils *\n ****************/\n\n type SearchOrHash = \\`?\\${string}\\` | \\`#\\${string}\\`;\n\n /**\n * Return only the RoutePart of a string. If the string has multiple parts return never\n *\n * string | type\n * ---------|------\n * 123 | 123\n * /123/abc | never\n * 123?abc | never\n * ./123 | never\n * /123 | never\n * 123/../ | never\n */\n type SingleRoutePart<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 /**\n * Return only the CatchAll router part. If the string has search parameters or a hash return never\n */\n type CatchAllRoutePart<S extends string> = S extends \\`\\${string}\\${SearchOrHash}\\`\n ? never\n : S extends ''\n ? never\n : S;\n\n // type OptionalCatchAllRoutePart<S extends string> = S extends \\`\\${string}\\${SearchOrHash}\\` ? never : S\n\n /**\n * Return the name of a route parameter\n * '[test]' -> 'test'\n * 'test' -> never\n * '[...test]' -> '...test'\n */\n type IsParameter<Part> = Part extends \\`[\\${infer ParamName}]\\` ? ParamName : never;\n\n /**\n * Return a union of all parameter names. If there are no names return never\n *\n * /[test] -> 'test'\n * /[abc]/[...def] -> 'abc'|'...def'\n */\n type ParameterNames<Path> = Path extends \\`\\${infer PartA}/\\${infer PartB}\\`\n ? IsParameter<PartA> | ParameterNames<PartB>\n : IsParameter<Path>;\n\n /**\n * Returns all segements of a route.\n *\n * /(group)/123/abc/[id]/[...rest] -> ['(group)', '123', 'abc', '[id]', '[...rest]'\n */\n type RouteSegments<Path> = Path extends \\`\\${infer PartA}/\\${infer PartB}\\`\n ? PartA extends '' | '.'\n ? [...RouteSegments<PartB>]\n : [PartA, ...RouteSegments<PartB>]\n : Path extends ''\n ? []\n : [Path];\n\n /**\n * Returns a Record of the routes parameters as strings and CatchAll parameters as string[]\n *\n * /[id]/[...rest] -> { id: string, rest: string[] }\n * /no-params -> {}\n */\n type RouteParams<Path> = {\n [Key in ParameterNames<Path> as Key extends \\`...\\${infer Name}\\`\n ? Name\n : Key]: Key extends \\`...\\${string}\\` ? string[] : string;\n };\n\n /**\n * Returns the search parameters for a route\n */\n export type SearchParams<T extends AllRoutes> = T extends DynamicRouteTemplate\n ? RouteParams<T>\n : T extends StaticRoutes\n ? never\n : Record<string, string>;\n\n /**\n * Route is mostly used as part of Href to ensure that a valid route is provided\n *\n * Given a dynamic route, this will return never. This is helpful for conditional logic\n *\n * /test -> /test, /test2, etc\n * /test/[abc] -> never\n * /test/resolve -> /test, /test2, etc\n *\n * Note that if we provide a value for [abc] then the route is allowed\n *\n * This is named Route to prevent confusion, as users they will often see it in tooltips\n */\n export type Route<T> = T extends DynamicRouteTemplate\n ? never\n :\n | StaticRoutes\n | RelativePathString\n | ExternalPathString\n | (T extends DynamicRoutes<infer _> ? T : never);\n\n /*********\n * Href *\n *********/\n\n export type Href<T extends string> = Route<T> | HrefObject<T>;\n\n export type HrefObject<T = AllRoutes> = T extends DynamicRouteTemplate\n ? { pathname: T; params: RouteParams<T> }\n : T extends Route<T>\n ? { pathname: Route<T>; params?: never }\n : never;\n\n /***********************\n * Expo Router Exports *\n ***********************/\n\n export type Router = {\n /** Navigate to the provided href. */\n push: <T extends string>(href: Href<T>) => void;\n /** Navigate to route without appending to the history. */\n replace: <T extends string>(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 = ''>(\n params?: T extends '' ? Record<string, string> : RouteParams<T>\n ) => void;\n };\n\n /************\n * <Link /> *\n ************/\n export interface LinkProps<T extends string> extends OriginalLinkProps {\n href: T extends DynamicRouteTemplate ? HrefObject<T> : Href<T>;\n }\n\n export interface LinkComponent {\n <T extends string>(props: React.PropsWithChildren<LinkProps<T>>): JSX.Element;\n /** Helper method to resolve an Href object into a string. */\n resolveHref: <T extends string>(href: Href<T>) => string;\n }\n\n export const Link: LinkComponent;\n\n /************\n * Hooks *\n ************/\n export function useRouter(): Router;\n export function useLocalSearchParams<\n T extends DynamicRouteTemplate | StaticRoutes | RelativePathString\n >(): SearchParams<T>;\n export function useSearchParams<\n T extends AllRoutes | SearchParams<DynamicRouteTemplate>\n >(): T extends AllRoutes ? SearchParams<T> : T;\n\n export function useGlobalSearchParams<\n T extends AllRoutes | SearchParams<DynamicRouteTemplate>\n >(): T extends AllRoutes ? SearchParams<T> : T;\n\n export function useSegments<\n T extends AbsoluteRoute | RouteSegments<AbsoluteRoute> | RelativePathString\n >(): T extends AbsoluteRoute ? RouteSegments<T> : T extends string ? string[] : T;\n}\n`;\n"],"names":["setupTypedRoutes","getTemplateString","getTypedRoutesUtils","extrapolateGroupRoutes","CAPTURE_DYNAMIC_PARAMS","CATCH_ALL","SLUG","ARRAY_GROUP_REGEX","CAPTURE_GROUP_REGEX","server","metro","typesDirectory","projectRoot","routerDirectory","appRoot","path","join","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","resolve","routerDotTSTemplate","setToUnionType","dynamicRouteParams","Map","replace","match","has","dynamicParams","matchAll","map","isDynamic","size","addRoute","originalRoute","set","get","add","replaceAll","includes","routeWithoutGroups","routeWithSingleGroup","s","directory","files","readdir","file","p","stat","isDirectory","normalizedPath","sep","routes","groupsMatch","group","unsafeTemplate"],"mappings":"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"}
@@ -94,7 +94,7 @@ async function logEventAsync(event, properties = {}) {
94
94
  }
95
95
  const { userId , deviceId } = identifyData;
96
96
  const commonEventProperties = {
97
- source_version: "0.10.7",
97
+ source_version: "0.10.8",
98
98
  source: "expo"
99
99
  };
100
100
  const identity = {
@@ -135,7 +135,7 @@ function getContext() {
135
135
  },
136
136
  app: {
137
137
  name: "expo",
138
- version: "0.10.7"
138
+ version: "0.10.8"
139
139
  },
140
140
  ci: ciInfo.isCI ? {
141
141
  name: ciInfo.name,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/cli",
3
- "version": "0.10.7",
3
+ "version": "0.10.8",
4
4
  "description": "The Expo CLI",
5
5
  "main": "build/bin/cli",
6
6
  "bin": {
@@ -40,16 +40,16 @@
40
40
  "@babel/runtime": "^7.20.0",
41
41
  "@expo/code-signing-certificates": "0.0.5",
42
42
  "@expo/config": "~8.1.0",
43
- "@expo/env": "0.0.5",
44
43
  "@expo/config-plugins": "~7.2.0",
45
44
  "@expo/dev-server": "0.5.3",
46
45
  "@expo/devcert": "^1.0.0",
46
+ "@expo/env": "0.0.5",
47
47
  "@expo/json-file": "^8.2.37",
48
48
  "@expo/metro-config": "~0.10.0",
49
49
  "@expo/osascript": "^2.0.31",
50
50
  "@expo/package-manager": "~1.0.0",
51
51
  "@expo/plist": "^0.0.20",
52
- "@expo/prebuild-config": "6.2.5",
52
+ "@expo/prebuild-config": "6.2.6",
53
53
  "@expo/rudder-sdk-node": "1.1.1",
54
54
  "@expo/spawn-async": "1.5.0",
55
55
  "@expo/xcpretty": "^4.2.1",
@@ -107,12 +107,12 @@
107
107
  ]
108
108
  },
109
109
  "devDependencies": {
110
- "@graphql-codegen/cli": "2.16.3",
111
- "@graphql-codegen/typescript": "2.8.7",
112
- "@graphql-codegen/typescript-operations": "2.5.12",
113
110
  "@expo/multipart-body-parser": "^1.0.0",
114
111
  "@expo/ngrok": "4.1.0",
115
112
  "@expo/webpack-config": "^0.17.4",
113
+ "@graphql-codegen/cli": "2.16.3",
114
+ "@graphql-codegen/typescript": "2.8.7",
115
+ "@graphql-codegen/typescript-operations": "2.5.12",
116
116
  "@swc/core": "^1.2.126",
117
117
  "@taskr/clear": "1.1.0",
118
118
  "@taskr/esnext": "1.1.0",
@@ -146,7 +146,9 @@
146
146
  "nullthrows": "^1.1.1",
147
147
  "structured-headers": "^0.4.1",
148
148
  "taskr": "1.1.0",
149
- "tree-kill": "^1.2.2"
149
+ "tree-kill": "^1.2.2",
150
+ "jest-runner-tsd": "^6.0.0",
151
+ "tsd": "^0.28.1"
150
152
  },
151
- "gitHead": "554e8b88a1a5d7f54c67cdb66e928a0adfb8731d"
153
+ "gitHead": "cf90d5c30c2a08a6493ebfa8aa3791aa70666759"
152
154
  }
@@ -1,63 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- class VscodeCompatHandler {
6
- /** Keep track of `Runtime.getProperties` responses to intercept, by request id */ interceptGetProperties = new Set();
7
- onDebuggerMessage(message, { socket }) {
8
- // Hermes doesn't seem to handle this request, but `locations` have to be returned.
9
- // Respond with an empty location to make it "spec compliant" with Chrome DevTools.
10
- if (message.method === "Debugger.getPossibleBreakpoints") {
11
- const response = {
12
- id: message.id,
13
- result: {
14
- locations: []
15
- }
16
- };
17
- socket.send(JSON.stringify(response));
18
- return true;
19
- }
20
- // Vscode doesn't seem to work nicely with missing `description` fields on `RemoteObject` instances.
21
- // See: https://github.com/microsoft/vscode-js-debug/issues/1583
22
- if (message.method === "Runtime.getProperties") {
23
- this.interceptGetProperties.add(message.id);
24
- }
25
- // Hermes and vscode have trouble setting breakpoints by `urlRegex` through `Debugger.setBreakpointByUrl`.
26
- // Vscode adds `file://` to a URL containing `http://`, which confuses Hermes and sets it to the wrong location.
27
- // Hermes needs to create the breakpoint to get the proper ID, but it must be unbounded.
28
- // Once the sourcemap is loaded, vscode will rebind the unbounded breakpoint to the correct location (using `Debugger.setBreakpoint`).
29
- if (message.method === "Debugger.setBreakpointByUrl" && message.params.urlRegex) {
30
- // Explicitly force the breakpoint to be unbounded
31
- message.params.url = "file://__invalid_url__";
32
- delete message.params.urlRegex;
33
- }
34
- return false;
35
- }
36
- onDeviceMessage(message) {
37
- // Vscode doesn't seem to work nicely with missing `description` fields on `RemoteObject` instances.
38
- // See: https://github.com/microsoft/vscode-js-debug/issues/1583
39
- if ("id" in message && this.interceptGetProperties.has(message.id)) {
40
- this.interceptGetProperties.delete(message.id);
41
- var _result;
42
- for (const item of (_result = message.result.result) != null ? _result : []){
43
- var ref;
44
- // Force-fully format the properties description to be an empty string
45
- // See: https://github.com/facebook/hermes/issues/114
46
- if (item.value) {
47
- var _description;
48
- item.value.description = (_description = item.value.description) != null ? _description : "";
49
- }
50
- // Avoid passing the `objectId` for symbol types.
51
- // When collapsing in vscode, it will fetch information about the symbol using the `objectId`.
52
- // The `Runtime.getProperties` request of the symbol hard-crashes Hermes.
53
- if (((ref = item.value) == null ? void 0 : ref.type) === "symbol" && item.value.objectId) {
54
- delete item.value.objectId;
55
- }
56
- }
57
- }
58
- return false;
59
- }
60
- }
61
- exports.VscodeCompatHandler = VscodeCompatHandler;
62
-
63
- //# sourceMappingURL=VscodeCompat.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../../../../../src/start/server/metro/inspector-proxy/handlers/VscodeCompat.ts"],"sourcesContent":["import type { Protocol } from 'devtools-protocol';\nimport type { DebuggerInfo } from 'metro-inspector-proxy';\n\nimport { CdpMessage, DebuggerRequest, DeviceResponse, InspectorHandler } from './types';\n\nexport class VscodeCompatHandler implements InspectorHandler {\n /** Keep track of `Runtime.getProperties` responses to intercept, by request id */\n interceptGetProperties = new Set<number>();\n\n onDebuggerMessage(\n message:\n | DebuggerRequest<DebuggerGetPossibleBreakpoints>\n | DebuggerRequest<DebuggerSetBreakpointByUrl>\n | DebuggerRequest<RuntimeGetProperties>,\n { socket }: Pick<DebuggerInfo, 'socket'>\n ) {\n // Hermes doesn't seem to handle this request, but `locations` have to be returned.\n // Respond with an empty location to make it \"spec compliant\" with Chrome DevTools.\n if (message.method === 'Debugger.getPossibleBreakpoints') {\n const response: DeviceResponse<DebuggerGetPossibleBreakpoints> = {\n id: message.id,\n result: { locations: [] },\n };\n socket.send(JSON.stringify(response));\n return true;\n }\n\n // Vscode doesn't seem to work nicely with missing `description` fields on `RemoteObject` instances.\n // See: https://github.com/microsoft/vscode-js-debug/issues/1583\n if (message.method === 'Runtime.getProperties') {\n this.interceptGetProperties.add(message.id);\n }\n\n // Hermes and vscode have trouble setting breakpoints by `urlRegex` through `Debugger.setBreakpointByUrl`.\n // Vscode adds `file://` to a URL containing `http://`, which confuses Hermes and sets it to the wrong location.\n // Hermes needs to create the breakpoint to get the proper ID, but it must be unbounded.\n // Once the sourcemap is loaded, vscode will rebind the unbounded breakpoint to the correct location (using `Debugger.setBreakpoint`).\n if (message.method === 'Debugger.setBreakpointByUrl' && message.params.urlRegex) {\n // Explicitly force the breakpoint to be unbounded\n message.params.url = 'file://__invalid_url__';\n delete message.params.urlRegex;\n }\n\n return false;\n }\n\n onDeviceMessage(message: DeviceResponse<RuntimeGetProperties>) {\n // Vscode doesn't seem to work nicely with missing `description` fields on `RemoteObject` instances.\n // See: https://github.com/microsoft/vscode-js-debug/issues/1583\n if ('id' in message && this.interceptGetProperties.has(message.id)) {\n this.interceptGetProperties.delete(message.id);\n\n for (const item of message.result.result ?? []) {\n // Force-fully format the properties description to be an empty string\n // See: https://github.com/facebook/hermes/issues/114\n if (item.value) {\n item.value.description = item.value.description ?? '';\n }\n\n // Avoid passing the `objectId` for symbol types.\n // When collapsing in vscode, it will fetch information about the symbol using the `objectId`.\n // The `Runtime.getProperties` request of the symbol hard-crashes Hermes.\n if (item.value?.type === 'symbol' && item.value.objectId) {\n delete item.value.objectId;\n }\n }\n }\n\n return false;\n }\n}\n\n/** @see https://chromedevtools.github.io/devtools-protocol/v8/Debugger/#method-getPossibleBreakpoints */\nexport type DebuggerGetPossibleBreakpoints = CdpMessage<\n 'Debugger.getPossibleBreakpoints',\n Protocol.Debugger.GetPossibleBreakpointsRequest,\n Protocol.Debugger.GetPossibleBreakpointsResponse\n>;\n\n/** @see https://chromedevtools.github.io/devtools-protocol/v8/Debugger/#method-setBreakpointByUrl */\nexport type DebuggerSetBreakpointByUrl = CdpMessage<\n 'Debugger.setBreakpointByUrl',\n Protocol.Debugger.SetBreakpointByUrlRequest,\n Protocol.Debugger.SetBreakpointByUrlResponse\n>;\n\n/** @see https://chromedevtools.github.io/devtools-protocol/v8/Runtime/#method-getProperties */\nexport type RuntimeGetProperties = CdpMessage<\n 'Runtime.getProperties',\n Protocol.Runtime.GetPropertiesRequest,\n Protocol.Runtime.GetPropertiesResponse\n>;\n"],"names":["VscodeCompatHandler","interceptGetProperties","Set","onDebuggerMessage","message","socket","method","response","id","result","locations","send","JSON","stringify","add","params","urlRegex","url","onDeviceMessage","has","delete","item","value","description","type","objectId"],"mappings":"AAAA;;;;AAKO,MAAMA,mBAAmB;IAC9B,kFAAkF,CAClFC,sBAAsB,GAAG,IAAIC,GAAG,EAAU,CAAC;IAE3CC,iBAAiB,CACfC,OAGyC,EACzC,EAAEC,MAAM,CAAA,EAAgC,EACxC;QACA,mFAAmF;QACnF,mFAAmF;QACnF,IAAID,OAAO,CAACE,MAAM,KAAK,iCAAiC,EAAE;YACxD,MAAMC,QAAQ,GAAmD;gBAC/DC,EAAE,EAAEJ,OAAO,CAACI,EAAE;gBACdC,MAAM,EAAE;oBAAEC,SAAS,EAAE,EAAE;iBAAE;aAC1B,AAAC;YACFL,MAAM,CAACM,IAAI,CAACC,IAAI,CAACC,SAAS,CAACN,QAAQ,CAAC,CAAC,CAAC;YACtC,OAAO,IAAI,CAAC;SACb;QAED,oGAAoG;QACpG,gEAAgE;QAChE,IAAIH,OAAO,CAACE,MAAM,KAAK,uBAAuB,EAAE;YAC9C,IAAI,CAACL,sBAAsB,CAACa,GAAG,CAACV,OAAO,CAACI,EAAE,CAAC,CAAC;SAC7C;QAED,0GAA0G;QAC1G,gHAAgH;QAChH,wFAAwF;QACxF,sIAAsI;QACtI,IAAIJ,OAAO,CAACE,MAAM,KAAK,6BAA6B,IAAIF,OAAO,CAACW,MAAM,CAACC,QAAQ,EAAE;YAC/E,kDAAkD;YAClDZ,OAAO,CAACW,MAAM,CAACE,GAAG,GAAG,wBAAwB,CAAC;YAC9C,OAAOb,OAAO,CAACW,MAAM,CAACC,QAAQ,CAAC;SAChC;QAED,OAAO,KAAK,CAAC;KACd;IAEDE,eAAe,CAACd,OAA6C,EAAE;QAC7D,oGAAoG;QACpG,gEAAgE;QAChE,IAAI,IAAI,IAAIA,OAAO,IAAI,IAAI,CAACH,sBAAsB,CAACkB,GAAG,CAACf,OAAO,CAACI,EAAE,CAAC,EAAE;YAClE,IAAI,CAACP,sBAAsB,CAACmB,MAAM,CAAChB,OAAO,CAACI,EAAE,CAAC,CAAC;gBAE5BJ,OAAqB;YAAxC,KAAK,MAAMiB,IAAI,IAAIjB,CAAAA,OAAqB,GAArBA,OAAO,CAACK,MAAM,CAACA,MAAM,YAArBL,OAAqB,GAAI,EAAE,CAAE;oBAU1CiB,GAAU;gBATd,sEAAsE;gBACtE,qDAAqD;gBACrD,IAAIA,IAAI,CAACC,KAAK,EAAE;wBACWD,YAAsB;oBAA/CA,IAAI,CAACC,KAAK,CAACC,WAAW,GAAGF,CAAAA,YAAsB,GAAtBA,IAAI,CAACC,KAAK,CAACC,WAAW,YAAtBF,YAAsB,GAAI,EAAE,CAAC;iBACvD;gBAED,iDAAiD;gBACjD,8FAA8F;gBAC9F,yEAAyE;gBACzE,IAAIA,CAAAA,CAAAA,GAAU,GAAVA,IAAI,CAACC,KAAK,SAAM,GAAhBD,KAAAA,CAAgB,GAAhBA,GAAU,CAAEG,IAAI,CAAA,KAAK,QAAQ,IAAIH,IAAI,CAACC,KAAK,CAACG,QAAQ,EAAE;oBACxD,OAAOJ,IAAI,CAACC,KAAK,CAACG,QAAQ,CAAC;iBAC5B;aACF;SACF;QAED,OAAO,KAAK,CAAC;KACd;CACF;QAjEYzB,mBAAmB,GAAnBA,mBAAmB"}