@expo/cli 0.10.11 → 0.11.1

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 (34) hide show
  1. package/build/bin/cli +2 -2
  2. package/build/src/api/endpoint.js +10 -0
  3. package/build/src/api/endpoint.js.map +1 -1
  4. package/build/src/api/graphql/queries/UserQuery.js +2 -1
  5. package/build/src/api/graphql/queries/UserQuery.js.map +1 -1
  6. package/build/src/api/user/UserSettings.js.map +1 -1
  7. package/build/src/api/user/actions.js +6 -1
  8. package/build/src/api/user/actions.js.map +1 -1
  9. package/build/src/api/user/expoSsoLauncher.js +127 -0
  10. package/build/src/api/user/expoSsoLauncher.js.map +1 -0
  11. package/build/src/api/user/user.js +46 -18
  12. package/build/src/api/user/user.js.map +1 -1
  13. package/build/src/graphql/generated.js +25 -1
  14. package/build/src/graphql/generated.js.map +1 -1
  15. package/build/src/login/index.js +7 -2
  16. package/build/src/login/index.js.map +1 -1
  17. package/build/src/start/server/metro/MetroBundlerDevServer.js +4 -2
  18. package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
  19. package/build/src/start/server/metro/MetroTerminalReporter.js +9 -1
  20. package/build/src/start/server/metro/MetroTerminalReporter.js.map +1 -1
  21. package/build/src/start/server/metro/withMetroMultiPlatform.js +32 -6
  22. package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
  23. package/build/src/start/server/metro/withMetroResolvers.js +164 -22
  24. package/build/src/start/server/metro/withMetroResolvers.js.map +1 -1
  25. package/build/src/start/server/middleware/ClassicManifestMiddleware.js +1 -1
  26. package/build/src/start/server/middleware/ManifestMiddleware.js +23 -12
  27. package/build/src/start/server/middleware/ManifestMiddleware.js.map +1 -1
  28. package/build/src/start/server/type-generation/routes.js +3 -0
  29. package/build/src/start/server/type-generation/routes.js.map +1 -1
  30. package/build/src/utils/analytics/rudderstackClient.js +2 -2
  31. package/build/src/utils/env.js +3 -0
  32. package/build/src/utils/env.js.map +1 -1
  33. package/package.json +8 -8
  34. package/static/react-devtools-page/index.html +1 -1
package/build/bin/cli CHANGED
@@ -132,7 +132,7 @@ const args = (0, _arg).default({
132
132
  });
133
133
  if (args["--version"]) {
134
134
  // Version is added in the build script.
135
- console.log("0.10.11");
135
+ console.log("0.11.1");
136
136
  process.exit(0);
137
137
  }
138
138
  if (args["--non-interactive"]) {
@@ -262,7 +262,7 @@ commands[command]().then((exec)=>{
262
262
  logEventAsync("action", {
263
263
  action: `expo ${command}`,
264
264
  source: "expo/cli",
265
- source_version: "0.10.11"
265
+ source_version: "0.11.1"
266
266
  });
267
267
  });
268
268
 
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
5
  exports.getExpoApiBaseUrl = getExpoApiBaseUrl;
6
+ exports.getExpoWebsiteBaseUrl = getExpoWebsiteBaseUrl;
6
7
  var _env = require("../utils/env");
7
8
  function getExpoApiBaseUrl() {
8
9
  if (_env.env.EXPO_STAGING) {
@@ -13,5 +14,14 @@ function getExpoApiBaseUrl() {
13
14
  return `https://api.expo.dev`;
14
15
  }
15
16
  }
17
+ function getExpoWebsiteBaseUrl() {
18
+ if (_env.env.EXPO_STAGING) {
19
+ return `https://staging.expo.dev`;
20
+ } else if (_env.env.EXPO_LOCAL) {
21
+ return `http://127.0.0.1:3001`;
22
+ } else {
23
+ return `https://expo.dev`;
24
+ }
25
+ }
16
26
 
17
27
  //# sourceMappingURL=endpoint.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/api/endpoint.ts"],"sourcesContent":["import { env } from '../utils/env';\n\n/** Get the URL for the expo.dev API. */\nexport function getExpoApiBaseUrl(): string {\n if (env.EXPO_STAGING) {\n return `https://staging-api.expo.dev`;\n } else if (env.EXPO_LOCAL) {\n return `http://127.0.0.1:3000`;\n } else {\n return `https://api.expo.dev`;\n }\n}\n"],"names":["getExpoApiBaseUrl","env","EXPO_STAGING","EXPO_LOCAL"],"mappings":"AAAA;;;;QAGgBA,iBAAiB,GAAjBA,iBAAiB;AAHb,IAAA,IAAc,WAAd,cAAc,CAAA;AAG3B,SAASA,iBAAiB,GAAW;IAC1C,IAAIC,IAAG,IAAA,CAACC,YAAY,EAAE;QACpB,OAAO,CAAC,4BAA4B,CAAC,CAAC;KACvC,MAAM,IAAID,IAAG,IAAA,CAACE,UAAU,EAAE;QACzB,OAAO,CAAC,qBAAqB,CAAC,CAAC;KAChC,MAAM;QACL,OAAO,CAAC,oBAAoB,CAAC,CAAC;KAC/B;CACF"}
1
+ {"version":3,"sources":["../../../src/api/endpoint.ts"],"sourcesContent":["import { env } from '../utils/env';\n\n/** Get the URL for the expo.dev API. */\nexport function getExpoApiBaseUrl(): string {\n if (env.EXPO_STAGING) {\n return `https://staging-api.expo.dev`;\n } else if (env.EXPO_LOCAL) {\n return `http://127.0.0.1:3000`;\n } else {\n return `https://api.expo.dev`;\n }\n}\n\n/** Get the URL for the expo.dev website. */\nexport function getExpoWebsiteBaseUrl(): string {\n if (env.EXPO_STAGING) {\n return `https://staging.expo.dev`;\n } else if (env.EXPO_LOCAL) {\n return `http://127.0.0.1:3001`;\n } else {\n return `https://expo.dev`;\n }\n}\n"],"names":["getExpoApiBaseUrl","getExpoWebsiteBaseUrl","env","EXPO_STAGING","EXPO_LOCAL"],"mappings":"AAAA;;;;QAGgBA,iBAAiB,GAAjBA,iBAAiB;QAWjBC,qBAAqB,GAArBA,qBAAqB;AAdjB,IAAA,IAAc,WAAd,cAAc,CAAA;AAG3B,SAASD,iBAAiB,GAAW;IAC1C,IAAIE,IAAG,IAAA,CAACC,YAAY,EAAE;QACpB,OAAO,CAAC,4BAA4B,CAAC,CAAC;KACvC,MAAM,IAAID,IAAG,IAAA,CAACE,UAAU,EAAE;QACzB,OAAO,CAAC,qBAAqB,CAAC,CAAC;KAChC,MAAM;QACL,OAAO,CAAC,oBAAoB,CAAC,CAAC;KAC/B;CACF;AAGM,SAASH,qBAAqB,GAAW;IAC9C,IAAIC,IAAG,IAAA,CAACC,YAAY,EAAE;QACpB,OAAO,CAAC,wBAAwB,CAAC,CAAC;KACnC,MAAM,IAAID,IAAG,IAAA,CAACE,UAAU,EAAE;QACzB,OAAO,CAAC,qBAAqB,CAAC,CAAC;KAChC,MAAM;QACL,OAAO,CAAC,gBAAgB,CAAC,CAAC;KAC3B;CACF"}
@@ -39,7 +39,8 @@ const UserQuery = {
39
39
  }
40
40
  `, /* variables */ undefined, {
41
41
  additionalTypenames: [
42
- "User"
42
+ "User",
43
+ "SSOUser"
43
44
  ]
44
45
  }).toPromise());
45
46
  return data.meActor;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/api/graphql/queries/UserQuery.ts"],"sourcesContent":["import gql from 'graphql-tag';\n\nimport { CurrentUserQuery } from '../../../graphql/generated';\nimport { graphqlClient, withErrorHandlingAsync } from '../client';\n\nexport const UserQuery = {\n async currentUserAsync(): Promise<CurrentUserQuery['meActor']> {\n const data = await withErrorHandlingAsync(\n graphqlClient\n .query<CurrentUserQuery>(\n gql`\n query CurrentUser {\n meActor {\n __typename\n id\n ... on UserActor {\n primaryAccount {\n id\n }\n username\n }\n ... on Robot {\n firstName\n }\n accounts {\n id\n users {\n actor {\n id\n }\n permissions\n }\n }\n }\n }\n `,\n /* variables */ undefined,\n {\n additionalTypenames: ['User'],\n }\n )\n .toPromise()\n );\n\n return data.meActor;\n },\n};\n"],"names":["UserQuery","currentUserAsync","data","withErrorHandlingAsync","graphqlClient","query","gql","undefined","additionalTypenames","toPromise","meActor"],"mappings":"AAAA;;;;;AAAgB,IAAA,WAAa,kCAAb,aAAa,EAAA;AAGyB,IAAA,OAAW,WAAX,WAAW,CAAA;;;;;;AAE1D,MAAMA,SAAS,GAAG;IACvB,MAAMC,gBAAgB,IAAyC;QAC7D,MAAMC,IAAI,GAAG,MAAMC,CAAAA,GAAAA,OAAsB,AAmCxC,CAAA,uBAnCwC,CACvCC,OAAa,cAAA,CACVC,KAAK,CACJC,WAAG,QAAA,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;UAyBJ,CAAC,EACD,eAAe,CAACC,SAAS,EACzB;YACEC,mBAAmB,EAAE;gBAAC,MAAM;aAAC;SAC9B,CACF,CACAC,SAAS,EAAE,CACf,AAAC;QAEF,OAAOP,IAAI,CAACQ,OAAO,CAAC;KACrB;CACF,AAAC;QAzCWV,SAAS,GAATA,SAAS"}
1
+ {"version":3,"sources":["../../../../../src/api/graphql/queries/UserQuery.ts"],"sourcesContent":["import gql from 'graphql-tag';\n\nimport { CurrentUserQuery } from '../../../graphql/generated';\nimport { graphqlClient, withErrorHandlingAsync } from '../client';\n\nexport const UserQuery = {\n async currentUserAsync(): Promise<CurrentUserQuery['meActor']> {\n const data = await withErrorHandlingAsync(\n graphqlClient\n .query<CurrentUserQuery>(\n gql`\n query CurrentUser {\n meActor {\n __typename\n id\n ... on UserActor {\n primaryAccount {\n id\n }\n username\n }\n ... on Robot {\n firstName\n }\n accounts {\n id\n users {\n actor {\n id\n }\n permissions\n }\n }\n }\n }\n `,\n /* variables */ undefined,\n {\n additionalTypenames: ['User', 'SSOUser'],\n }\n )\n .toPromise()\n );\n\n return data.meActor;\n },\n};\n"],"names":["UserQuery","currentUserAsync","data","withErrorHandlingAsync","graphqlClient","query","gql","undefined","additionalTypenames","toPromise","meActor"],"mappings":"AAAA;;;;;AAAgB,IAAA,WAAa,kCAAb,aAAa,EAAA;AAGyB,IAAA,OAAW,WAAX,WAAW,CAAA;;;;;;AAE1D,MAAMA,SAAS,GAAG;IACvB,MAAMC,gBAAgB,IAAyC;QAC7D,MAAMC,IAAI,GAAG,MAAMC,CAAAA,GAAAA,OAAsB,AAmCxC,CAAA,uBAnCwC,CACvCC,OAAa,cAAA,CACVC,KAAK,CACJC,WAAG,QAAA,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;UAyBJ,CAAC,EACD,eAAe,CAACC,SAAS,EACzB;YACEC,mBAAmB,EAAE;gBAAC,MAAM;gBAAE,SAAS;aAAC;SACzC,CACF,CACAC,SAAS,EAAE,CACf,AAAC;QAEF,OAAOP,IAAI,CAACQ,OAAO,CAAC;KACrB;CACF,AAAC;QAzCWV,SAAS,GAATA,SAAS"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/api/user/UserSettings.ts"],"sourcesContent":["import { getExpoHomeDirectory, getUserStatePath } from '@expo/config/build/getUserState';\nimport JsonFile from '@expo/json-file';\nimport crypto from 'crypto';\n\ntype SessionData = {\n sessionSecret: string;\n // These fields are potentially used by Expo CLI.\n userId: string;\n username: string;\n currentConnection: 'Username-Password-Authentication';\n};\n\nexport type UserSettingsData = {\n auth?: SessionData | null;\n ignoreBundledBinaries?: string[];\n PATH?: string;\n /** Last development code signing ID used for `npx expo run:ios`. */\n developmentCodeSigningId?: string;\n /** Unique user ID which is generated anonymously and can be cleared locally. */\n uuid?: string;\n};\n\n/** Return the user cache directory. */\nfunction getDirectory() {\n return getExpoHomeDirectory();\n}\n\nfunction getFilePath(): string {\n return getUserStatePath();\n}\n\nfunction userSettingsJsonFile(): JsonFile<UserSettingsData> {\n return new JsonFile<UserSettingsData>(getFilePath(), {\n ensureDir: true,\n jsonParseErrorDefault: {},\n cantReadFileDefault: {},\n });\n}\n\nasync function setSessionAsync(sessionData?: SessionData): Promise<void> {\n await UserSettings.setAsync('auth', sessionData, {\n default: {},\n ensureDir: true,\n });\n}\n\nfunction getSession(): SessionData | null {\n try {\n return JsonFile.read<UserSettingsData>(getUserStatePath())?.auth ?? null;\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n return null;\n }\n throw error;\n }\n}\n\nfunction getAccessToken(): string | null {\n return process.env.EXPO_TOKEN ?? null;\n}\n\n// returns an anonymous, unique identifier for a user on the current computer\nasync function getAnonymousIdentifierAsync(): Promise<string> {\n const settings = await userSettingsJsonFile();\n let id = await settings.getAsync('uuid', null);\n\n if (!id) {\n id = crypto.randomUUID();\n await settings.setAsync('uuid', id);\n }\n\n return id;\n}\n\nconst UserSettings = Object.assign(userSettingsJsonFile(), {\n getSession,\n setSessionAsync,\n getAccessToken,\n getDirectory,\n getFilePath,\n userSettingsJsonFile,\n getAnonymousIdentifierAsync,\n});\n\nexport default UserSettings;\n"],"names":["getDirectory","getExpoHomeDirectory","getFilePath","getUserStatePath","userSettingsJsonFile","JsonFile","ensureDir","jsonParseErrorDefault","cantReadFileDefault","setSessionAsync","sessionData","UserSettings","setAsync","default","getSession","read","auth","error","code","getAccessToken","process","env","EXPO_TOKEN","getAnonymousIdentifierAsync","settings","id","getAsync","crypto","randomUUID","Object","assign"],"mappings":"AAAA;;;;;AAAuD,IAAA,aAAiC,WAAjC,iCAAiC,CAAA;AACnE,IAAA,SAAiB,kCAAjB,iBAAiB,EAAA;AACnB,IAAA,OAAQ,kCAAR,QAAQ,EAAA;;;;;;AAoB3B,uCAAuC,CACvC,SAASA,YAAY,GAAG;IACtB,OAAOC,CAAAA,GAAAA,aAAoB,AAAE,CAAA,qBAAF,EAAE,CAAC;CAC/B;AAED,SAASC,WAAW,GAAW;IAC7B,OAAOC,CAAAA,GAAAA,aAAgB,AAAE,CAAA,iBAAF,EAAE,CAAC;CAC3B;AAED,SAASC,oBAAoB,GAA+B;IAC1D,OAAO,IAAIC,SAAQ,QAAA,CAAmBH,WAAW,EAAE,EAAE;QACnDI,SAAS,EAAE,IAAI;QACfC,qBAAqB,EAAE,EAAE;QACzBC,mBAAmB,EAAE,EAAE;KACxB,CAAC,CAAC;CACJ;AAED,eAAeC,eAAe,CAACC,WAAyB,EAAiB;IACvE,MAAMC,YAAY,CAACC,QAAQ,CAAC,MAAM,EAAEF,WAAW,EAAE;QAC/CG,OAAO,EAAE,EAAE;QACXP,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;CACJ;AAED,SAASQ,UAAU,GAAuB;IACxC,IAAI;YACKT,GAAmD;YAAnDA,IAAyD;QAAhE,OAAOA,CAAAA,IAAyD,GAAzDA,CAAAA,GAAmD,GAAnDA,SAAQ,QAAA,CAACU,IAAI,CAAmBZ,CAAAA,GAAAA,aAAgB,AAAE,CAAA,iBAAF,EAAE,CAAC,SAAM,GAAzDE,KAAAA,CAAyD,GAAzDA,GAAmD,CAAEW,IAAI,YAAzDX,IAAyD,GAAI,IAAI,CAAC;KAC1E,CAAC,OAAOY,KAAK,EAAO;QACnB,IAAIA,KAAK,CAACC,IAAI,KAAK,QAAQ,EAAE;YAC3B,OAAO,IAAI,CAAC;SACb;QACD,MAAMD,KAAK,CAAC;KACb;CACF;AAED,SAASE,cAAc,GAAkB;QAChCC,WAAsB;IAA7B,OAAOA,CAAAA,WAAsB,GAAtBA,OAAO,CAACC,GAAG,CAACC,UAAU,YAAtBF,WAAsB,GAAI,IAAI,CAAC;CACvC;AAED,6EAA6E;AAC7E,eAAeG,2BAA2B,GAAoB;IAC5D,MAAMC,QAAQ,GAAG,MAAMpB,oBAAoB,EAAE,AAAC;IAC9C,IAAIqB,EAAE,GAAG,MAAMD,QAAQ,CAACE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,AAAC;IAE/C,IAAI,CAACD,EAAE,EAAE;QACPA,EAAE,GAAGE,OAAM,QAAA,CAACC,UAAU,EAAE,CAAC;QACzB,MAAMJ,QAAQ,CAACZ,QAAQ,CAAC,MAAM,EAAEa,EAAE,CAAC,CAAC;KACrC;IAED,OAAOA,EAAE,CAAC;CACX;AAED,MAAMd,YAAY,GAAGkB,MAAM,CAACC,MAAM,CAAC1B,oBAAoB,EAAE,EAAE;IACzDU,UAAU;IACVL,eAAe;IACfU,cAAc;IACdnB,YAAY;IACZE,WAAW;IACXE,oBAAoB;IACpBmB,2BAA2B;CAC5B,CAAC,AAAC;eAEYZ,YAAY"}
1
+ {"version":3,"sources":["../../../../src/api/user/UserSettings.ts"],"sourcesContent":["import { getExpoHomeDirectory, getUserStatePath } from '@expo/config/build/getUserState';\nimport JsonFile from '@expo/json-file';\nimport crypto from 'crypto';\n\ntype SessionData = {\n sessionSecret: string;\n // These fields are potentially used by Expo CLI.\n userId: string;\n username: string;\n currentConnection: 'Username-Password-Authentication' | 'Browser-Flow-Authentication';\n};\n\nexport type UserSettingsData = {\n auth?: SessionData | null;\n ignoreBundledBinaries?: string[];\n PATH?: string;\n /** Last development code signing ID used for `npx expo run:ios`. */\n developmentCodeSigningId?: string;\n /** Unique user ID which is generated anonymously and can be cleared locally. */\n uuid?: string;\n};\n\n/** Return the user cache directory. */\nfunction getDirectory() {\n return getExpoHomeDirectory();\n}\n\nfunction getFilePath(): string {\n return getUserStatePath();\n}\n\nfunction userSettingsJsonFile(): JsonFile<UserSettingsData> {\n return new JsonFile<UserSettingsData>(getFilePath(), {\n ensureDir: true,\n jsonParseErrorDefault: {},\n cantReadFileDefault: {},\n });\n}\n\nasync function setSessionAsync(sessionData?: SessionData): Promise<void> {\n await UserSettings.setAsync('auth', sessionData, {\n default: {},\n ensureDir: true,\n });\n}\n\nfunction getSession(): SessionData | null {\n try {\n return JsonFile.read<UserSettingsData>(getUserStatePath())?.auth ?? null;\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n return null;\n }\n throw error;\n }\n}\n\nfunction getAccessToken(): string | null {\n return process.env.EXPO_TOKEN ?? null;\n}\n\n// returns an anonymous, unique identifier for a user on the current computer\nasync function getAnonymousIdentifierAsync(): Promise<string> {\n const settings = await userSettingsJsonFile();\n let id = await settings.getAsync('uuid', null);\n\n if (!id) {\n id = crypto.randomUUID();\n await settings.setAsync('uuid', id);\n }\n\n return id;\n}\n\nconst UserSettings = Object.assign(userSettingsJsonFile(), {\n getSession,\n setSessionAsync,\n getAccessToken,\n getDirectory,\n getFilePath,\n userSettingsJsonFile,\n getAnonymousIdentifierAsync,\n});\n\nexport default UserSettings;\n"],"names":["getDirectory","getExpoHomeDirectory","getFilePath","getUserStatePath","userSettingsJsonFile","JsonFile","ensureDir","jsonParseErrorDefault","cantReadFileDefault","setSessionAsync","sessionData","UserSettings","setAsync","default","getSession","read","auth","error","code","getAccessToken","process","env","EXPO_TOKEN","getAnonymousIdentifierAsync","settings","id","getAsync","crypto","randomUUID","Object","assign"],"mappings":"AAAA;;;;;AAAuD,IAAA,aAAiC,WAAjC,iCAAiC,CAAA;AACnE,IAAA,SAAiB,kCAAjB,iBAAiB,EAAA;AACnB,IAAA,OAAQ,kCAAR,QAAQ,EAAA;;;;;;AAoB3B,uCAAuC,CACvC,SAASA,YAAY,GAAG;IACtB,OAAOC,CAAAA,GAAAA,aAAoB,AAAE,CAAA,qBAAF,EAAE,CAAC;CAC/B;AAED,SAASC,WAAW,GAAW;IAC7B,OAAOC,CAAAA,GAAAA,aAAgB,AAAE,CAAA,iBAAF,EAAE,CAAC;CAC3B;AAED,SAASC,oBAAoB,GAA+B;IAC1D,OAAO,IAAIC,SAAQ,QAAA,CAAmBH,WAAW,EAAE,EAAE;QACnDI,SAAS,EAAE,IAAI;QACfC,qBAAqB,EAAE,EAAE;QACzBC,mBAAmB,EAAE,EAAE;KACxB,CAAC,CAAC;CACJ;AAED,eAAeC,eAAe,CAACC,WAAyB,EAAiB;IACvE,MAAMC,YAAY,CAACC,QAAQ,CAAC,MAAM,EAAEF,WAAW,EAAE;QAC/CG,OAAO,EAAE,EAAE;QACXP,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;CACJ;AAED,SAASQ,UAAU,GAAuB;IACxC,IAAI;YACKT,GAAmD;YAAnDA,IAAyD;QAAhE,OAAOA,CAAAA,IAAyD,GAAzDA,CAAAA,GAAmD,GAAnDA,SAAQ,QAAA,CAACU,IAAI,CAAmBZ,CAAAA,GAAAA,aAAgB,AAAE,CAAA,iBAAF,EAAE,CAAC,SAAM,GAAzDE,KAAAA,CAAyD,GAAzDA,GAAmD,CAAEW,IAAI,YAAzDX,IAAyD,GAAI,IAAI,CAAC;KAC1E,CAAC,OAAOY,KAAK,EAAO;QACnB,IAAIA,KAAK,CAACC,IAAI,KAAK,QAAQ,EAAE;YAC3B,OAAO,IAAI,CAAC;SACb;QACD,MAAMD,KAAK,CAAC;KACb;CACF;AAED,SAASE,cAAc,GAAkB;QAChCC,WAAsB;IAA7B,OAAOA,CAAAA,WAAsB,GAAtBA,OAAO,CAACC,GAAG,CAACC,UAAU,YAAtBF,WAAsB,GAAI,IAAI,CAAC;CACvC;AAED,6EAA6E;AAC7E,eAAeG,2BAA2B,GAAoB;IAC5D,MAAMC,QAAQ,GAAG,MAAMpB,oBAAoB,EAAE,AAAC;IAC9C,IAAIqB,EAAE,GAAG,MAAMD,QAAQ,CAACE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,AAAC;IAE/C,IAAI,CAACD,EAAE,EAAE;QACPA,EAAE,GAAGE,OAAM,QAAA,CAACC,UAAU,EAAE,CAAC;QACzB,MAAMJ,QAAQ,CAACZ,QAAQ,CAAC,MAAM,EAAEa,EAAE,CAAC,CAAC;KACrC;IAED,OAAOA,EAAE,CAAC;CACX;AAED,MAAMd,YAAY,GAAGkB,MAAM,CAACC,MAAM,CAAC1B,oBAAoB,EAAE,EAAE;IACzDU,UAAU;IACVL,eAAe;IACfU,cAAc;IACdnB,YAAY;IACZE,WAAW;IACXE,oBAAoB;IACpBmB,2BAA2B;CAC5B,CAAC,AAAC;eAEYZ,YAAY"}
@@ -45,10 +45,15 @@ async function showLoginPromptAsync({ printNewLine =false , otp , ...options } =
45
45
  throw new _errors.CommandError("OFFLINE", "Cannot authenticate in offline-mode");
46
46
  }
47
47
  const hasCredentials = options.username && options.password;
48
+ const sso = options.sso;
48
49
  if (printNewLine) {
49
50
  Log.log();
50
51
  }
51
- Log.log(hasCredentials ? "Logging in to EAS" : "Log in to EAS");
52
+ if (sso) {
53
+ await (0, _user).ssoLoginAsync();
54
+ return;
55
+ }
56
+ Log.log(hasCredentials ? `Logging in to EAS with email or username (exit and run 'eas login' for other options)` : `Log in to EAS with email or username (exit and run 'eas login' for other options)`);
52
57
  let username = options.username;
53
58
  let password = options.password;
54
59
  if (!hasCredentials) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/api/user/actions.ts"],"sourcesContent":["import assert from 'assert';\nimport chalk from 'chalk';\n\nimport * as Log from '../../log';\nimport { env } from '../../utils/env';\nimport { CommandError } from '../../utils/errors';\nimport { learnMore } from '../../utils/link';\nimport promptAsync, { Question } from '../../utils/prompts';\nimport { ApiV2Error } from '../rest/client';\nimport { retryUsernamePasswordAuthWithOTPAsync } from './otp';\nimport { Actor, getUserAsync, loginAsync } from './user';\n\n/** Show login prompt while prompting for missing credentials. */\nexport async function showLoginPromptAsync({\n printNewLine = false,\n otp,\n ...options\n}: {\n printNewLine?: boolean;\n username?: string;\n password?: string;\n otp?: string;\n} = {}): Promise<void> {\n if (env.EXPO_OFFLINE) {\n throw new CommandError('OFFLINE', 'Cannot authenticate in offline-mode');\n }\n const hasCredentials = options.username && options.password;\n\n if (printNewLine) {\n Log.log();\n }\n\n Log.log(hasCredentials ? 'Logging in to EAS' : 'Log in to EAS');\n\n let username = options.username;\n let password = options.password;\n\n if (!hasCredentials) {\n const resolved = await promptAsync(\n [\n !options.username && {\n type: 'text',\n name: 'username',\n message: 'Email or username',\n },\n !options.password && {\n type: 'password',\n name: 'password',\n message: 'Password',\n },\n ].filter(Boolean) as Question<string>[],\n {\n nonInteractiveHelp: `Use the EXPO_TOKEN environment variable to authenticate in CI (${learnMore(\n 'https://docs.expo.dev/accounts/programmatic-access/'\n )})`,\n }\n );\n username ??= resolved.username;\n password ??= resolved.password;\n }\n // This is just for the types.\n assert(username && password);\n\n try {\n await loginAsync({\n username,\n password,\n otp,\n });\n } catch (e) {\n if (e instanceof ApiV2Error && e.expoApiV2ErrorCode === 'ONE_TIME_PASSWORD_REQUIRED') {\n await retryUsernamePasswordAuthWithOTPAsync(\n username,\n password,\n e.expoApiV2ErrorMetadata as any\n );\n } else {\n throw e;\n }\n }\n}\n\n/** Ensure the user is logged in, if not, prompt to login. */\nexport async function ensureLoggedInAsync(): Promise<Actor> {\n let user = await getUserAsync().catch(() => null);\n\n if (!user) {\n Log.warn(chalk.yellow`An Expo user account is required to proceed.`);\n await showLoginPromptAsync({ printNewLine: true });\n user = await getUserAsync();\n }\n\n assert(user, 'User should be logged in');\n return user;\n}\n"],"names":["showLoginPromptAsync","ensureLoggedInAsync","Log","printNewLine","otp","options","env","EXPO_OFFLINE","CommandError","hasCredentials","username","password","log","resolved","promptAsync","type","name","message","filter","Boolean","nonInteractiveHelp","learnMore","assert","loginAsync","e","ApiV2Error","expoApiV2ErrorCode","retryUsernamePasswordAuthWithOTPAsync","expoApiV2ErrorMetadata","user","getUserAsync","catch","warn","chalk","yellow"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/api/user/actions.ts"],"sourcesContent":["import assert from 'assert';\nimport chalk from 'chalk';\n\nimport * as Log from '../../log';\nimport { env } from '../../utils/env';\nimport { CommandError } from '../../utils/errors';\nimport { learnMore } from '../../utils/link';\nimport promptAsync, { Question } from '../../utils/prompts';\nimport { ApiV2Error } from '../rest/client';\nimport { retryUsernamePasswordAuthWithOTPAsync } from './otp';\nimport { Actor, getUserAsync, loginAsync, ssoLoginAsync } from './user';\n\n/** Show login prompt while prompting for missing credentials. */\nexport async function showLoginPromptAsync({\n printNewLine = false,\n otp,\n ...options\n}: {\n printNewLine?: boolean;\n username?: string;\n password?: string;\n otp?: string;\n sso?: boolean | undefined;\n} = {}): Promise<void> {\n if (env.EXPO_OFFLINE) {\n throw new CommandError('OFFLINE', 'Cannot authenticate in offline-mode');\n }\n const hasCredentials = options.username && options.password;\n const sso = options.sso;\n\n if (printNewLine) {\n Log.log();\n }\n\n if (sso) {\n await ssoLoginAsync();\n return;\n }\n\n Log.log(\n hasCredentials\n ? `Logging in to EAS with email or username (exit and run 'eas login' for other options)`\n : `Log in to EAS with email or username (exit and run 'eas login' for other options)`\n );\n\n let username = options.username;\n let password = options.password;\n\n if (!hasCredentials) {\n const resolved = await promptAsync(\n [\n !options.username && {\n type: 'text',\n name: 'username',\n message: 'Email or username',\n },\n !options.password && {\n type: 'password',\n name: 'password',\n message: 'Password',\n },\n ].filter(Boolean) as Question<string>[],\n {\n nonInteractiveHelp: `Use the EXPO_TOKEN environment variable to authenticate in CI (${learnMore(\n 'https://docs.expo.dev/accounts/programmatic-access/'\n )})`,\n }\n );\n username ??= resolved.username;\n password ??= resolved.password;\n }\n // This is just for the types.\n assert(username && password);\n\n try {\n await loginAsync({\n username,\n password,\n otp,\n });\n } catch (e) {\n if (e instanceof ApiV2Error && e.expoApiV2ErrorCode === 'ONE_TIME_PASSWORD_REQUIRED') {\n await retryUsernamePasswordAuthWithOTPAsync(\n username,\n password,\n e.expoApiV2ErrorMetadata as any\n );\n } else {\n throw e;\n }\n }\n}\n\n/** Ensure the user is logged in, if not, prompt to login. */\nexport async function ensureLoggedInAsync(): Promise<Actor> {\n let user = await getUserAsync().catch(() => null);\n\n if (!user) {\n Log.warn(chalk.yellow`An Expo user account is required to proceed.`);\n await showLoginPromptAsync({ printNewLine: true });\n user = await getUserAsync();\n }\n\n assert(user, 'User should be logged in');\n return user;\n}\n"],"names":["showLoginPromptAsync","ensureLoggedInAsync","Log","printNewLine","otp","options","env","EXPO_OFFLINE","CommandError","hasCredentials","username","password","sso","log","ssoLoginAsync","resolved","promptAsync","type","name","message","filter","Boolean","nonInteractiveHelp","learnMore","assert","loginAsync","e","ApiV2Error","expoApiV2ErrorCode","retryUsernamePasswordAuthWithOTPAsync","expoApiV2ErrorMetadata","user","getUserAsync","catch","warn","chalk","yellow"],"mappings":"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"}
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ exports.getSessionUsingBrowserAuthFlowAsync = getSessionUsingBrowserAuthFlowAsync;
6
+ var _assert = _interopRequireDefault(require("assert"));
7
+ var _betterOpn = _interopRequireDefault(require("better-opn"));
8
+ var _http = _interopRequireDefault(require("http"));
9
+ var _querystring = _interopRequireDefault(require("querystring"));
10
+ var Log = _interopRequireWildcard(require("../../log"));
11
+ function _interopRequireDefault(obj) {
12
+ return obj && obj.__esModule ? obj : {
13
+ default: obj
14
+ };
15
+ }
16
+ function _interopRequireWildcard(obj) {
17
+ if (obj && obj.__esModule) {
18
+ return obj;
19
+ } else {
20
+ var newObj = {};
21
+ if (obj != null) {
22
+ for(var key in obj){
23
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
24
+ var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};
25
+ if (desc.get || desc.set) {
26
+ Object.defineProperty(newObj, key, desc);
27
+ } else {
28
+ newObj[key] = obj[key];
29
+ }
30
+ }
31
+ }
32
+ }
33
+ newObj.default = obj;
34
+ return newObj;
35
+ }
36
+ }
37
+ const successBody = `
38
+ <!DOCTYPE html>
39
+ <html lang="en">
40
+ <head>
41
+ <title>Expo SSO Login</title>
42
+ <meta charset="utf-8">
43
+ <style type="text/css">
44
+ html {
45
+ margin: 0;
46
+ padding: 0
47
+ }
48
+
49
+ body {
50
+ background-color: #fff;
51
+ font-family: Tahoma,Verdana;
52
+ font-size: 16px;
53
+ color: #000;
54
+ max-width: 100%;
55
+ box-sizing: border-box;
56
+ padding: .5rem;
57
+ margin: 1em;
58
+ overflow-wrap: break-word
59
+ }
60
+ </style>
61
+ </head>
62
+ <body>
63
+ SSO login complete. You may now close this tab and return to the command prompt.
64
+ </body>
65
+ </html>`;
66
+ async function getSessionUsingBrowserAuthFlowAsync({ expoWebsiteUrl }) {
67
+ const scheme = "http";
68
+ const hostname = "localhost";
69
+ const path = "/auth/callback";
70
+ const buildExpoSsoLoginUrl = (port)=>{
71
+ const data = {
72
+ app_redirect_uri: `${scheme}://${hostname}:${port}${path}`
73
+ };
74
+ const params = _querystring.default.stringify(data);
75
+ return `${expoWebsiteUrl}/sso-login?${params}`;
76
+ };
77
+ // Start server and begin auth flow
78
+ const executeAuthFlow = ()=>{
79
+ return new Promise(async (resolve, reject)=>{
80
+ const connections = new Set();
81
+ const server = _http.default.createServer((request, response)=>{
82
+ try {
83
+ var ref;
84
+ if (!(request.method === "GET" && ((ref = request.url) == null ? void 0 : ref.includes(path)))) {
85
+ throw new Error("Unexpected SSO login response.");
86
+ }
87
+ const url = new URL(request.url, `http:${request.headers.host}`);
88
+ const sessionSecret = url.searchParams.get("session_secret");
89
+ if (!sessionSecret) {
90
+ throw new Error("Request missing session_secret search parameter.");
91
+ }
92
+ resolve(sessionSecret);
93
+ response.writeHead(200, {
94
+ "Content-Type": "text/html"
95
+ });
96
+ response.write(successBody);
97
+ response.end();
98
+ } catch (error) {
99
+ reject(error);
100
+ } finally{
101
+ server.close();
102
+ // Ensure that the server shuts down
103
+ for (const connection of connections){
104
+ connection.destroy();
105
+ }
106
+ }
107
+ });
108
+ server.listen(0, hostname, ()=>{
109
+ Log.log("Waiting for browser login...");
110
+ const address = server.address();
111
+ (0, _assert).default(address !== null && typeof address === "object", "Server address and port should be set after listening has begun");
112
+ const port = address.port;
113
+ const authorizeUrl = buildExpoSsoLoginUrl(port);
114
+ (0, _betterOpn).default(authorizeUrl);
115
+ });
116
+ server.on("connection", (connection)=>{
117
+ connections.add(connection);
118
+ connection.on("close", ()=>{
119
+ connections.delete(connection);
120
+ });
121
+ });
122
+ });
123
+ };
124
+ return await executeAuthFlow();
125
+ }
126
+
127
+ //# sourceMappingURL=expoSsoLauncher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/api/user/expoSsoLauncher.ts"],"sourcesContent":["import assert from 'assert';\nimport openBrowserAsync from 'better-opn';\nimport http from 'http';\nimport { Socket } from 'node:net';\nimport querystring from 'querystring';\n\nimport * as Log from '../../log';\n\nconst successBody = `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <title>Expo SSO Login</title>\n <meta charset=\"utf-8\">\n <style type=\"text/css\">\n html {\n margin: 0;\n padding: 0\n }\n\n body {\n background-color: #fff;\n font-family: Tahoma,Verdana;\n font-size: 16px;\n color: #000;\n max-width: 100%;\n box-sizing: border-box;\n padding: .5rem;\n margin: 1em;\n overflow-wrap: break-word\n }\n </style>\n</head>\n<body>\n SSO login complete. You may now close this tab and return to the command prompt.\n</body>\n</html>`;\n\nexport async function getSessionUsingBrowserAuthFlowAsync({\n expoWebsiteUrl,\n}: {\n expoWebsiteUrl: string;\n}): Promise<string> {\n const scheme = 'http';\n const hostname = 'localhost';\n const path = '/auth/callback';\n\n const buildExpoSsoLoginUrl = (port: number): string => {\n const data = {\n app_redirect_uri: `${scheme}://${hostname}:${port}${path}`,\n };\n const params = querystring.stringify(data);\n return `${expoWebsiteUrl}/sso-login?${params}`;\n };\n\n // Start server and begin auth flow\n const executeAuthFlow = (): Promise<string> => {\n return new Promise<string>(async (resolve, reject) => {\n const connections = new Set<Socket>();\n\n const server = http.createServer(\n (request: http.IncomingMessage, response: http.ServerResponse) => {\n try {\n if (!(request.method === 'GET' && request.url?.includes(path))) {\n throw new Error('Unexpected SSO login response.');\n }\n const url = new URL(request.url, `http:${request.headers.host}`);\n const sessionSecret = url.searchParams.get('session_secret');\n\n if (!sessionSecret) {\n throw new Error('Request missing session_secret search parameter.');\n }\n resolve(sessionSecret);\n response.writeHead(200, { 'Content-Type': 'text/html' });\n response.write(successBody);\n response.end();\n } catch (error) {\n reject(error);\n } finally {\n server.close();\n // Ensure that the server shuts down\n for (const connection of connections) {\n connection.destroy();\n }\n }\n }\n );\n\n server.listen(0, hostname, () => {\n Log.log('Waiting for browser login...');\n\n const address = server.address();\n assert(\n address !== null && typeof address === 'object',\n 'Server address and port should be set after listening has begun'\n );\n const port = address.port;\n const authorizeUrl = buildExpoSsoLoginUrl(port);\n openBrowserAsync(authorizeUrl);\n });\n\n server.on('connection', (connection) => {\n connections.add(connection);\n\n connection.on('close', () => {\n connections.delete(connection);\n });\n });\n });\n };\n\n return await executeAuthFlow();\n}\n"],"names":["getSessionUsingBrowserAuthFlowAsync","Log","successBody","expoWebsiteUrl","scheme","hostname","path","buildExpoSsoLoginUrl","port","data","app_redirect_uri","params","querystring","stringify","executeAuthFlow","Promise","resolve","reject","connections","Set","server","http","createServer","request","response","method","url","includes","Error","URL","headers","host","sessionSecret","searchParams","get","writeHead","write","end","error","close","connection","destroy","listen","log","address","assert","authorizeUrl","openBrowserAsync","on","add","delete"],"mappings":"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"}
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  exports.getActorDisplayName = getActorDisplayName;
6
6
  exports.getUserAsync = getUserAsync;
7
7
  exports.loginAsync = loginAsync;
8
+ exports.ssoLoginAsync = ssoLoginAsync;
8
9
  exports.logoutAsync = logoutAsync;
9
10
  exports.ANONYMOUS_USERNAME = void 0;
10
11
  var _fs = require("fs");
@@ -13,10 +14,12 @@ var Log = _interopRequireWildcard(require("../../log"));
13
14
  var Analytics = _interopRequireWildcard(require("../../utils/analytics/rudderstackClient"));
14
15
  var _codesigning = require("../../utils/codesigning");
15
16
  var _env = require("../../utils/env");
17
+ var _endpoint = require("../endpoint");
16
18
  var _client = require("../graphql/client");
17
19
  var _userQuery = require("../graphql/queries/UserQuery");
18
20
  var _client1 = require("../rest/client");
19
21
  var _userSettings = _interopRequireDefault(require("./UserSettings"));
22
+ var _expoSsoLauncher = require("./expoSsoLauncher");
20
23
  function _interopRequireDefault(obj) {
21
24
  return obj && obj.__esModule ? obj : {
22
25
  default: obj
@@ -50,6 +53,8 @@ function getActorDisplayName(user) {
50
53
  switch(user == null ? void 0 : user.__typename){
51
54
  case "User":
52
55
  return user.username;
56
+ case "SSOUser":
57
+ return user.username;
53
58
  case "Robot":
54
59
  return user.firstName ? `${user.firstName} (robot)` : "robot";
55
60
  default:
@@ -78,29 +83,30 @@ async function loginAsync(json) {
78
83
  body: JSON.stringify(json)
79
84
  });
80
85
  const { data: { sessionSecret } , } = await res.json();
81
- const result = await _client.graphqlClient.query(_graphqlTag.default`
82
- query UserQuery {
83
- viewer {
84
- id
85
- username
86
- }
87
- }
88
- `, {}, {
89
- fetchOptions: {
90
- headers: {
91
- "expo-session": sessionSecret
92
- }
93
- },
94
- additionalTypenames: []
95
- }).toPromise();
96
- const { data: { viewer } , } = result;
86
+ const userData = await fetchUserAsync({
87
+ sessionSecret
88
+ });
97
89
  await _userSettings.default.setSessionAsync({
98
90
  sessionSecret,
99
- userId: viewer.id,
100
- username: viewer.username,
91
+ userId: userData.id,
92
+ username: userData.username,
101
93
  currentConnection: "Username-Password-Authentication"
102
94
  });
103
95
  }
96
+ async function ssoLoginAsync() {
97
+ const sessionSecret = await (0, _expoSsoLauncher).getSessionUsingBrowserAuthFlowAsync({
98
+ expoWebsiteUrl: (0, _endpoint).getExpoWebsiteBaseUrl()
99
+ });
100
+ const userData = await fetchUserAsync({
101
+ sessionSecret
102
+ });
103
+ await _userSettings.default.setSessionAsync({
104
+ sessionSecret,
105
+ userId: userData.id,
106
+ username: userData.username,
107
+ currentConnection: "Browser-Flow-Authentication"
108
+ });
109
+ }
104
110
  async function logoutAsync() {
105
111
  currentUser = undefined;
106
112
  await Promise.all([
@@ -112,5 +118,27 @@ async function logoutAsync() {
112
118
  ]);
113
119
  Log.log("Logged out");
114
120
  }
121
+ async function fetchUserAsync({ sessionSecret }) {
122
+ const result = await _client.graphqlClient.query(_graphqlTag.default`
123
+ query UserQuery {
124
+ meUserActor {
125
+ id
126
+ username
127
+ }
128
+ }
129
+ `, {}, {
130
+ fetchOptions: {
131
+ headers: {
132
+ "expo-session": sessionSecret
133
+ }
134
+ },
135
+ additionalTypenames: []
136
+ }).toPromise();
137
+ const { data } = result;
138
+ return {
139
+ id: data.meUserActor.id,
140
+ username: data.meUserActor.username
141
+ };
142
+ }
115
143
 
116
144
  //# sourceMappingURL=user.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/api/user/user.ts"],"sourcesContent":["import { promises as fs } from 'fs';\nimport gql from 'graphql-tag';\n\nimport { CurrentUserQuery } from '../../graphql/generated';\nimport * as Log from '../../log';\nimport * as Analytics from '../../utils/analytics/rudderstackClient';\nimport { getDevelopmentCodeSigningDirectory } from '../../utils/codesigning';\nimport { env } from '../../utils/env';\nimport { graphqlClient } from '../graphql/client';\nimport { UserQuery } from '../graphql/queries/UserQuery';\nimport { fetchAsync } from '../rest/client';\nimport UserSettings from './UserSettings';\n\nexport type Actor = NonNullable<CurrentUserQuery['meActor']>;\n\nlet currentUser: Actor | undefined;\n\nexport const ANONYMOUS_USERNAME = 'anonymous';\n\n/**\n * Resolve the name of the actor, either normal user or robot user.\n * This should be used whenever the \"current user\" needs to be displayed.\n * The display name CANNOT be used as project owner.\n */\nexport function getActorDisplayName(user?: Actor): string {\n switch (user?.__typename) {\n case 'User':\n return user.username;\n case 'Robot':\n return user.firstName ? `${user.firstName} (robot)` : 'robot';\n default:\n return ANONYMOUS_USERNAME;\n }\n}\n\nexport async function getUserAsync(): Promise<Actor | undefined> {\n const hasCredentials = UserSettings.getAccessToken() || UserSettings.getSession()?.sessionSecret;\n if (!env.EXPO_OFFLINE && !currentUser && hasCredentials) {\n const user = await UserQuery.currentUserAsync();\n currentUser = user ?? undefined;\n if (user) {\n await Analytics.setUserDataAsync(user.id, {\n username: getActorDisplayName(user),\n user_id: user.id,\n user_type: user.__typename,\n });\n }\n }\n return currentUser;\n}\n\nexport async function loginAsync(json: {\n username: string;\n password: string;\n otp?: string;\n}): Promise<void> {\n const res = await fetchAsync('auth/loginAsync', {\n method: 'POST',\n body: JSON.stringify(json),\n });\n const {\n data: { sessionSecret },\n } = await res.json();\n const result = await graphqlClient\n .query(\n gql`\n query UserQuery {\n viewer {\n id\n username\n }\n }\n `,\n {},\n {\n fetchOptions: {\n headers: {\n 'expo-session': sessionSecret,\n },\n },\n additionalTypenames: [] /* UserQuery has immutable fields */,\n }\n )\n .toPromise();\n const {\n data: { viewer },\n } = result;\n await UserSettings.setSessionAsync({\n sessionSecret,\n userId: viewer.id,\n username: viewer.username,\n currentConnection: 'Username-Password-Authentication',\n });\n}\n\nexport async function logoutAsync(): Promise<void> {\n currentUser = undefined;\n await Promise.all([\n fs.rm(getDevelopmentCodeSigningDirectory(), { recursive: true, force: true }),\n UserSettings.setSessionAsync(undefined),\n ]);\n Log.log('Logged out');\n}\n"],"names":["getActorDisplayName","getUserAsync","loginAsync","logoutAsync","Log","Analytics","currentUser","ANONYMOUS_USERNAME","user","__typename","username","firstName","UserSettings","hasCredentials","getAccessToken","getSession","sessionSecret","env","EXPO_OFFLINE","UserQuery","currentUserAsync","undefined","setUserDataAsync","id","user_id","user_type","json","res","fetchAsync","method","body","JSON","stringify","data","result","graphqlClient","query","gql","fetchOptions","headers","additionalTypenames","toPromise","viewer","setSessionAsync","userId","currentConnection","Promise","all","fs","rm","getDevelopmentCodeSigningDirectory","recursive","force","log"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/api/user/user.ts"],"sourcesContent":["import { promises as fs } from 'fs';\nimport gql from 'graphql-tag';\n\nimport { CurrentUserQuery } from '../../graphql/generated';\nimport * as Log from '../../log';\nimport * as Analytics from '../../utils/analytics/rudderstackClient';\nimport { getDevelopmentCodeSigningDirectory } from '../../utils/codesigning';\nimport { env } from '../../utils/env';\nimport { getExpoWebsiteBaseUrl } from '../endpoint';\nimport { graphqlClient } from '../graphql/client';\nimport { UserQuery } from '../graphql/queries/UserQuery';\nimport { fetchAsync } from '../rest/client';\nimport UserSettings from './UserSettings';\nimport { getSessionUsingBrowserAuthFlowAsync } from './expoSsoLauncher';\n\nexport type Actor = NonNullable<CurrentUserQuery['meActor']>;\n\nlet currentUser: Actor | undefined;\n\nexport const ANONYMOUS_USERNAME = 'anonymous';\n\n/**\n * Resolve the name of the actor, either normal user or robot user.\n * This should be used whenever the \"current user\" needs to be displayed.\n * The display name CANNOT be used as project owner.\n */\nexport function getActorDisplayName(user?: Actor): string {\n switch (user?.__typename) {\n case 'User':\n return user.username;\n case 'SSOUser':\n return user.username;\n case 'Robot':\n return user.firstName ? `${user.firstName} (robot)` : 'robot';\n default:\n return ANONYMOUS_USERNAME;\n }\n}\n\nexport async function getUserAsync(): Promise<Actor | undefined> {\n const hasCredentials = UserSettings.getAccessToken() || UserSettings.getSession()?.sessionSecret;\n if (!env.EXPO_OFFLINE && !currentUser && hasCredentials) {\n const user = await UserQuery.currentUserAsync();\n currentUser = user ?? undefined;\n if (user) {\n await Analytics.setUserDataAsync(user.id, {\n username: getActorDisplayName(user),\n user_id: user.id,\n user_type: user.__typename,\n });\n }\n }\n return currentUser;\n}\n\nexport async function loginAsync(json: {\n username: string;\n password: string;\n otp?: string;\n}): Promise<void> {\n const res = await fetchAsync('auth/loginAsync', {\n method: 'POST',\n body: JSON.stringify(json),\n });\n const {\n data: { sessionSecret },\n } = await res.json();\n\n const userData = await fetchUserAsync({ sessionSecret });\n\n await UserSettings.setSessionAsync({\n sessionSecret,\n userId: userData.id,\n username: userData.username,\n currentConnection: 'Username-Password-Authentication',\n });\n}\n\nexport async function ssoLoginAsync(): Promise<void> {\n const sessionSecret = await getSessionUsingBrowserAuthFlowAsync({\n expoWebsiteUrl: getExpoWebsiteBaseUrl(),\n });\n const userData = await fetchUserAsync({ sessionSecret });\n\n await UserSettings.setSessionAsync({\n sessionSecret,\n userId: userData.id,\n username: userData.username,\n currentConnection: 'Browser-Flow-Authentication',\n });\n}\n\nexport async function logoutAsync(): Promise<void> {\n currentUser = undefined;\n await Promise.all([\n fs.rm(getDevelopmentCodeSigningDirectory(), { recursive: true, force: true }),\n UserSettings.setSessionAsync(undefined),\n ]);\n Log.log('Logged out');\n}\n\nasync function fetchUserAsync({\n sessionSecret,\n}: {\n sessionSecret: string;\n}): Promise<{ id: string; username: string }> {\n const result = await graphqlClient\n .query(\n gql`\n query UserQuery {\n meUserActor {\n id\n username\n }\n }\n `,\n {},\n {\n fetchOptions: {\n headers: {\n 'expo-session': sessionSecret,\n },\n },\n additionalTypenames: [] /* UserQuery has immutable fields */,\n }\n )\n .toPromise();\n const { data } = result;\n return {\n id: data.meUserActor.id,\n username: data.meUserActor.username,\n };\n}\n"],"names":["getActorDisplayName","getUserAsync","loginAsync","ssoLoginAsync","logoutAsync","Log","Analytics","currentUser","ANONYMOUS_USERNAME","user","__typename","username","firstName","UserSettings","hasCredentials","getAccessToken","getSession","sessionSecret","env","EXPO_OFFLINE","UserQuery","currentUserAsync","undefined","setUserDataAsync","id","user_id","user_type","json","res","fetchAsync","method","body","JSON","stringify","data","userData","fetchUserAsync","setSessionAsync","userId","currentConnection","getSessionUsingBrowserAuthFlowAsync","expoWebsiteUrl","getExpoWebsiteBaseUrl","Promise","all","fs","rm","getDevelopmentCodeSigningDirectory","recursive","force","log","result","graphqlClient","query","gql","fetchOptions","headers","additionalTypenames","toPromise","meUserActor"],"mappings":"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"}
@@ -2,7 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- exports.WebhookType = exports.UsageMetricsGranularity = exports.UsageMetricType = exports.UploadSessionType = exports.SubmissionStatus = exports.SubmissionArchiveSourceType = exports.SubmissionAndroidTrack = exports.SubmissionAndroidReleaseStatus = exports.SubmissionAndroidArchiveType = exports.StatuspageServiceStatus = exports.StatuspageServiceName = exports.StatuspageIncidentStatus = exports.StatuspageIncidentImpact = exports.StandardOffer = exports.SecondFactorMethod = exports.Role = exports.ProjectArchiveSourceType = exports.Permission = exports.Order = exports.OfferType = exports.NotificationType = exports.NotificationEvent = exports.MailchimpTag = exports.MailchimpAudience = exports.IosSchemeBuildConfiguration = exports.IosManagedBuildType = exports.IosDistributionType = exports.IosBuildType = exports.InvoiceDiscountType = exports.GitHubAppInstallationStatus = exports.GitHubAppEnvironment = exports.Feature = exports.EnvironmentSecretType = exports.EasTotalPlanEnablementUnit = exports.EasServiceMetric = exports.EasService = exports.EasBuildDeprecationInfoType = exports.DistributionType = exports.BuildWorkflow = exports.BuildTrigger = exports.BuildStatus = exports.BuildResourceClass = exports.BuildPriority = exports.BuildMode = exports.BuildJobStatus = exports.BuildJobLogsFormat = exports.BuildIosEnterpriseProvisioning = exports.BuildCredentialsSource = exports.AuthProtocolType = exports.AssetMetadataStatus = exports.AppsFilter = exports.AppleDeviceClass = exports.AppStoreConnectUserRole = exports.AppSort = exports.AppPrivacy = exports.AppPlatform = exports.AndroidKeystoreType = exports.AndroidFcmVersion = exports.AndroidBuildType = exports.ActivityTimelineProjectActivityType = void 0;
5
+ exports.WebhookType = exports.UsageMetricsGranularity = exports.UsageMetricType = exports.UploadSessionType = exports.SubmissionStatus = exports.SubmissionArchiveSourceType = exports.SubmissionAndroidTrack = exports.SubmissionAndroidReleaseStatus = exports.SubmissionAndroidArchiveType = exports.StatuspageServiceStatus = exports.StatuspageServiceName = exports.StatuspageIncidentStatus = exports.StatuspageIncidentImpact = exports.StandardOffer = exports.SecondFactorMethod = exports.Role = exports.ProjectArchiveSourceType = exports.Permission = exports.Order = exports.OfferType = exports.NotificationType = exports.NotificationEvent = exports.MailchimpTag = exports.MailchimpAudience = exports.IosSchemeBuildConfiguration = exports.IosManagedBuildType = exports.IosDistributionType = exports.IosBuildType = exports.InvoiceDiscountType = exports.GitHubAppInstallationStatus = exports.GitHubAppEnvironment = exports.Feature = exports.EnvironmentSecretType = exports.EasTotalPlanEnablementUnit = exports.EasServiceMetric = exports.EasService = exports.EasBuildDeprecationInfoType = exports.EasBuildBillingResourceClass = exports.DistributionType = exports.BuildWorkflow = exports.BuildTrigger = exports.BuildStatus = exports.BuildRetryDisabledReason = exports.BuildResourceClass = exports.BuildPriority = exports.BuildMode = exports.BuildJobStatus = exports.BuildJobLogsFormat = exports.BuildIosEnterpriseProvisioning = exports.BuildCredentialsSource = exports.AuthProtocolType = exports.AssetMetadataStatus = exports.AppsFilter = exports.AppleDeviceClass = exports.AppStoreConnectUserRole = exports.AppSort = exports.AppPrivacy = exports.AppPlatform = exports.AndroidKeystoreType = exports.AndroidFcmVersion = exports.AndroidBuildType = exports.ActivityTimelineProjectActivityType = exports.AccountAppsSortByField = void 0;
6
+ var AccountAppsSortByField;
7
+ exports.AccountAppsSortByField = AccountAppsSortByField;
8
+ (function(AccountAppsSortByField) {
9
+ AccountAppsSortByField["LatestActivityTime"] = "LATEST_ACTIVITY_TIME";
10
+ AccountAppsSortByField[/**
11
+ * Name prefers the display name but falls back to full_name with @account/
12
+ * part stripped.
13
+ */ "Name"] = "NAME";
14
+ })(AccountAppsSortByField || (exports.AccountAppsSortByField = AccountAppsSortByField = {}));
6
15
  var ActivityTimelineProjectActivityType;
7
16
  exports.ActivityTimelineProjectActivityType = ActivityTimelineProjectActivityType;
8
17
  (function(ActivityTimelineProjectActivityType) {
@@ -152,6 +161,15 @@ exports.BuildResourceClass = BuildResourceClass;
152
161
  BuildResourceClass["IosMMedium"] = "IOS_M_MEDIUM";
153
162
  BuildResourceClass["Legacy"] = "LEGACY";
154
163
  })(BuildResourceClass || (exports.BuildResourceClass = BuildResourceClass = {}));
164
+ var BuildRetryDisabledReason;
165
+ exports.BuildRetryDisabledReason = BuildRetryDisabledReason;
166
+ (function(BuildRetryDisabledReason) {
167
+ BuildRetryDisabledReason["AlreadyRetried"] = "ALREADY_RETRIED";
168
+ BuildRetryDisabledReason["InvalidStatus"] = "INVALID_STATUS";
169
+ BuildRetryDisabledReason["IsGithubBuild"] = "IS_GITHUB_BUILD";
170
+ BuildRetryDisabledReason["NotCompletedYet"] = "NOT_COMPLETED_YET";
171
+ BuildRetryDisabledReason["TooMuchTimeElapsed"] = "TOO_MUCH_TIME_ELAPSED";
172
+ })(BuildRetryDisabledReason || (exports.BuildRetryDisabledReason = BuildRetryDisabledReason = {}));
155
173
  var BuildStatus;
156
174
  exports.BuildStatus = BuildStatus;
157
175
  (function(BuildStatus) {
@@ -182,6 +200,12 @@ exports.DistributionType = DistributionType;
182
200
  DistributionType["Simulator"] = "SIMULATOR";
183
201
  DistributionType["Store"] = "STORE";
184
202
  })(DistributionType || (exports.DistributionType = DistributionType = {}));
203
+ var EasBuildBillingResourceClass;
204
+ exports.EasBuildBillingResourceClass = EasBuildBillingResourceClass;
205
+ (function(EasBuildBillingResourceClass) {
206
+ EasBuildBillingResourceClass["Large"] = "LARGE";
207
+ EasBuildBillingResourceClass["Medium"] = "MEDIUM";
208
+ })(EasBuildBillingResourceClass || (exports.EasBuildBillingResourceClass = EasBuildBillingResourceClass = {}));
185
209
  var EasBuildDeprecationInfoType;
186
210
  exports.EasBuildDeprecationInfoType = EasBuildDeprecationInfoType;
187
211
  (function(EasBuildDeprecationInfoType) {