@slicemachine/manager 0.25.2-beta.1 → 0.25.2-beta.10

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 (27) hide show
  1. package/dist/auth/PrismicAuthManager.cjs +1 -1
  2. package/dist/auth/PrismicAuthManager.cjs.map +1 -1
  3. package/dist/auth/PrismicAuthManager.js +1 -1
  4. package/dist/auth/PrismicAuthManager.js.map +1 -1
  5. package/dist/lib/fetchGitHubReleaseBodyForRelease.cjs +10 -6
  6. package/dist/lib/fetchGitHubReleaseBodyForRelease.cjs.map +1 -1
  7. package/dist/lib/fetchGitHubReleaseBodyForRelease.js +10 -6
  8. package/dist/lib/fetchGitHubReleaseBodyForRelease.js.map +1 -1
  9. package/dist/managers/SliceMachineManager.cjs +4 -3
  10. package/dist/managers/SliceMachineManager.cjs.map +1 -1
  11. package/dist/managers/SliceMachineManager.js +4 -3
  12. package/dist/managers/SliceMachineManager.js.map +1 -1
  13. package/dist/managers/project/ProjectManager.cjs +6 -3
  14. package/dist/managers/project/ProjectManager.cjs.map +1 -1
  15. package/dist/managers/project/ProjectManager.d.ts +5 -0
  16. package/dist/managers/project/ProjectManager.js +6 -3
  17. package/dist/managers/project/ProjectManager.js.map +1 -1
  18. package/dist/managers/telemetry/TelemetryManager.cjs +6 -2
  19. package/dist/managers/telemetry/TelemetryManager.cjs.map +1 -1
  20. package/dist/managers/telemetry/TelemetryManager.js +6 -2
  21. package/dist/managers/telemetry/TelemetryManager.js.map +1 -1
  22. package/package.json +2 -2
  23. package/src/auth/PrismicAuthManager.ts +1 -1
  24. package/src/lib/fetchGitHubReleaseBodyForRelease.ts +11 -6
  25. package/src/managers/SliceMachineManager.ts +4 -2
  26. package/src/managers/project/ProjectManager.ts +9 -6
  27. package/src/managers/telemetry/TelemetryManager.ts +7 -2
@@ -142,7 +142,7 @@ class PrismicAuthManager {
142
142
  server.once("listening", () => {
143
143
  resolve2();
144
144
  });
145
- server.listen(args.port);
145
+ server.listen(args.port, "127.0.0.1");
146
146
  });
147
147
  if (args.onListenCallback) {
148
148
  args.onListenCallback();
@@ -1 +1 @@
1
- {"version":3,"file":"PrismicAuthManager.cjs","sources":["../../../src/auth/PrismicAuthManager.ts"],"sourcesContent":["import * as t from \"io-ts\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport * as http from \"node:http\";\n\nimport * as h3 from \"h3\";\nimport fetch from \"../lib/fetch\";\nimport cookie from \"cookie\";\nimport cors from \"cors\";\nimport getPort from \"get-port\";\n\nimport { decode } from \"../lib/decode\";\nimport { serializeCookies } from \"../lib/serializeCookies\";\n\nimport { API_ENDPOINTS } from \"../constants/API_ENDPOINTS\";\nimport { SLICE_MACHINE_USER_AGENT } from \"../constants/SLICE_MACHINE_USER_AGENT\";\nimport { createPrismicAuthManagerMiddleware } from \"./createPrismicAuthManagerMiddleware\";\nimport {\n\tInternalError,\n\tUnauthenticatedError,\n\tUnexpectedDataError,\n} from \"../errors\";\n\nconst COOKIE_SEPARATOR = \"; \";\nconst AUTH_COOKIE_KEY = \"prismic-auth\";\nconst SESSION_COOKIE_KEY = \"SESSION\";\n\nconst PERSISTED_AUTH_STATE_FILE_NAME = \".prismic\";\nconst DEFAULT_PERSISTED_AUTH_STATE: PrismicAuthState = {\n\tbase: \"https://prismic.io\",\n\tcookies: {},\n};\n\nconst PrismicAuthState = t.intersection([\n\tt.type({\n\t\tbase: t.string,\n\t\tcookies: t.intersection([\n\t\t\tt.partial({\n\t\t\t\t[AUTH_COOKIE_KEY]: t.string,\n\t\t\t\tSESSION: t.string,\n\t\t\t}),\n\t\t\tt.record(t.string, t.string),\n\t\t]),\n\t}),\n\tt.partial({\n\t\tshortId: t.string,\n\t\tintercomHash: t.string,\n\t\toauthAccessToken: t.string,\n\t\tauthUrl: t.string,\n\t}),\n]);\nexport type PrismicAuthState = t.TypeOf<typeof PrismicAuthState>;\n\nconst PrismicUserProfile = t.exact(\n\tt.type({\n\t\tuserId: t.string,\n\t\tshortId: t.string,\n\t\tintercomHash: t.string,\n\t\temail: t.string,\n\t\tfirstName: t.string,\n\t\tlastName: t.string,\n\t}),\n);\nexport type PrismicUserProfile = t.TypeOf<typeof PrismicUserProfile>;\n\ntype PrismicAuthManagerConstructorArgs = {\n\tscopedDirectory?: string;\n};\n\ntype PrismicAuthManagerLoginArgs = {\n\temail: string;\n\tcookies: string[];\n};\n\ntype PrismicAuthManagerGetLoginSessionInfoReturnType = {\n\tport: number;\n\turl: string;\n};\n\ntype PrismicAuthManagerNodeLoginSessionArgs = {\n\tport: number;\n\tonListenCallback?: () => void;\n};\n\ntype GetProfileForAuthenticationTokenArgs = {\n\tauthenticationToken: string;\n};\n\nconst checkHasAuthenticationToken = (\n\tauthState: PrismicAuthState,\n): authState is PrismicAuthState & {\n\tcookies: Required<\n\t\tPick<\n\t\t\tPrismicAuthState[\"cookies\"],\n\t\t\ttypeof AUTH_COOKIE_KEY | typeof SESSION_COOKIE_KEY\n\t\t>\n\t>;\n} => {\n\treturn Boolean(\n\t\tauthState.cookies[AUTH_COOKIE_KEY] && authState.cookies[SESSION_COOKIE_KEY],\n\t);\n};\n\nconst parseCookies = (cookies: string): Record<string, string> => {\n\treturn cookie.parse(cookies, {\n\t\t// Don't escape any values.\n\t\tdecode: (value) => value,\n\t});\n};\n\nexport class PrismicAuthManager {\n\t// TODO: Automatically scope the manager to the current Slice Machine\n\t// project? If not, this internal state can be removed.\n\tscopedDirectory: string;\n\n\tconstructor({\n\t\tscopedDirectory = os.homedir(),\n\t}: PrismicAuthManagerConstructorArgs = {}) {\n\t\tthis.scopedDirectory = scopedDirectory;\n\t}\n\n\t// TODO: Make the `cookies` argument more explicit. What are these\n\t// mysterious cookies?\n\tasync login(args: PrismicAuthManagerLoginArgs): Promise<void> {\n\t\tconst authState = await this._readPersistedAuthState();\n\n\t\t// Set the auth's URL base to the current base at runtime.\n\t\tauthState.base = API_ENDPOINTS.PrismicWroom;\n\t\tauthState.cookies = {\n\t\t\t...authState.cookies,\n\t\t\t...parseCookies(args.cookies.join(COOKIE_SEPARATOR)),\n\t\t};\n\n\t\tif (checkHasAuthenticationToken(authState)) {\n\t\t\tconst authenticationToken = authState.cookies[AUTH_COOKIE_KEY];\n\t\t\tconst profile = await this._getProfileForAuthenticationToken({\n\t\t\t\tauthenticationToken,\n\t\t\t});\n\n\t\t\tauthState.shortId = profile.shortId;\n\t\t\tauthState.intercomHash = profile.intercomHash;\n\t\t}\n\n\t\tawait this._writePersistedAuthState(authState);\n\t}\n\n\tasync getLoginSessionInfo(): Promise<PrismicAuthManagerGetLoginSessionInfoReturnType> {\n\t\t// Pick a random port, with a preference for historic `5555`\n\t\tconst port = await getPort({ port: 5555 });\n\n\t\tconst url = new URL(\n\t\t\t`./dashboard/cli/login?source=slice-machine&port=${port}`,\n\t\t\tAPI_ENDPOINTS.PrismicWroom,\n\t\t).toString();\n\n\t\treturn {\n\t\t\tport,\n\t\t\turl,\n\t\t};\n\t}\n\n\tasync nodeLoginSession(\n\t\targs: PrismicAuthManagerNodeLoginSessionArgs,\n\t): Promise<void> {\n\t\treturn new Promise<void>(async (resolve) => {\n\t\t\t// Timeout attempt after 3 minutes\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tserver.close();\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Login timeout, server did not receive a response within a 3-minute delay\",\n\t\t\t\t);\n\t\t\t}, 180_000);\n\n\t\t\tconst app = h3.createApp();\n\t\t\tapp.use(h3.fromNodeMiddleware(cors()));\n\t\t\tapp.use(\n\t\t\t\th3.fromNodeMiddleware(\n\t\t\t\t\tcreatePrismicAuthManagerMiddleware({\n\t\t\t\t\t\tprismicAuthManager: this,\n\t\t\t\t\t\tonLoginCallback() {\n\t\t\t\t\t\t\t// Cleanup process and resolve\n\t\t\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\t\t\tserver.close();\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\t// Start server\n\t\t\tconst server = http.createServer(h3.toNodeListener(app));\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tserver.once(\"listening\", () => {\n\t\t\t\t\tresolve();\n\t\t\t\t});\n\t\t\t\tserver.listen(args.port);\n\t\t\t});\n\n\t\t\tif (args.onListenCallback) {\n\t\t\t\targs.onListenCallback();\n\t\t\t}\n\t\t});\n\t}\n\n\tasync logout(): Promise<void> {\n\t\tconst authState = await this._readPersistedAuthState();\n\n\t\t// Remove all Prismic cookies, short ID, and Intercom hash\n\t\t// associated with the currently logged in user.\n\t\tauthState.cookies = {};\n\t\tauthState.shortId = undefined;\n\t\tauthState.intercomHash = undefined;\n\n\t\tawait this._writePersistedAuthState(authState);\n\t}\n\n\tasync checkIsLoggedIn(): Promise<boolean> {\n\t\tconst authState = await this._readPersistedAuthState();\n\n\t\tif (checkHasAuthenticationToken(authState)) {\n\t\t\tconst url = new URL(\"./validate\", API_ENDPOINTS.PrismicAuthentication);\n\t\t\turl.searchParams.set(\"token\", authState.cookies[AUTH_COOKIE_KEY]);\n\n\t\t\tlet res;\n\t\t\ttry {\n\t\t\t\tres = await fetch(url.toString(), {\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\t// Noop, we return if `res` is not defined.\n\t\t\t}\n\n\t\t\tif (!res || !res.ok) {\n\t\t\t\tawait this.logout();\n\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync getAuthenticationCookies(): Promise<\n\t\tPrismicAuthState[\"cookies\"] &\n\t\t\tRequired<\n\t\t\t\tPick<\n\t\t\t\t\tPrismicAuthState[\"cookies\"],\n\t\t\t\t\ttypeof AUTH_COOKIE_KEY | typeof SESSION_COOKIE_KEY\n\t\t\t\t>\n\t\t\t>\n\t> {\n\t\tconst isLoggedIn = await this.checkIsLoggedIn();\n\n\t\tif (isLoggedIn) {\n\t\t\tconst authState = await this._readPersistedAuthState();\n\n\t\t\tif (checkHasAuthenticationToken(authState)) {\n\t\t\t\treturn authState.cookies;\n\t\t\t}\n\t\t}\n\n\t\tthrow new UnauthenticatedError();\n\t}\n\n\tasync getAuthenticationToken(): Promise<string> {\n\t\tconst cookies = await this.getAuthenticationCookies();\n\n\t\treturn cookies[AUTH_COOKIE_KEY];\n\t}\n\n\tasync refreshAuthenticationToken(): Promise<void> {\n\t\tconst authState = await this._readPersistedAuthState();\n\n\t\tif (checkHasAuthenticationToken(authState)) {\n\t\t\tconst url = new URL(\n\t\t\t\t\"./refreshtoken\",\n\t\t\t\tAPI_ENDPOINTS.PrismicAuthentication,\n\t\t\t);\n\t\t\turl.searchParams.set(\"token\", authState.cookies[AUTH_COOKIE_KEY]);\n\n\t\t\tconst res = await fetch(url.toString(), {\n\t\t\t\theaders: {\n\t\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst text = await res.text();\n\n\t\t\tif (res.ok) {\n\t\t\t\tauthState.cookies[AUTH_COOKIE_KEY] = text;\n\n\t\t\t\tawait this._writePersistedAuthState(authState);\n\t\t\t} else {\n\t\t\t\tthrow new InternalError(\"Failed to refresh authentication token.\", {\n\t\t\t\t\tcause: text,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new UnauthenticatedError();\n\t\t}\n\t}\n\n\tasync getProfile(): Promise<PrismicUserProfile> {\n\t\tconst authenticationToken = await this.getAuthenticationToken();\n\n\t\treturn await this._getProfileForAuthenticationToken({\n\t\t\tauthenticationToken,\n\t\t});\n\t}\n\n\tprivate async _getProfileForAuthenticationToken(\n\t\targs: GetProfileForAuthenticationTokenArgs,\n\t): Promise<PrismicUserProfile> {\n\t\tconst url = new URL(\"./profile\", API_ENDPOINTS.PrismicUser);\n\t\tconst res = await fetch(url.toString(), {\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${args.authenticationToken}`,\n\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t},\n\t\t});\n\n\t\tif (res.ok) {\n\t\t\tconst json = await res.json();\n\t\t\tconst { value: profile, error } = decode(PrismicUserProfile, json);\n\n\t\t\tif (error) {\n\t\t\t\tthrow new UnexpectedDataError(\n\t\t\t\t\t\"Received invalid data from the Prismic user service.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn profile;\n\t\t} else {\n\t\t\tconst text = await res.text();\n\t\t\tthrow new InternalError(\n\t\t\t\t\"Failed to retrieve profile from the Prismic user service.\",\n\t\t\t\t{\n\t\t\t\t\tcause: text,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate async _readPersistedAuthState(): Promise<PrismicAuthState> {\n\t\tconst authStateFilePath = this._getPersistedAuthStateFilePath();\n\n\t\tlet authStateFileContents: string = JSON.stringify({});\n\t\tlet rawAuthState: Record<string, unknown> = {};\n\n\t\ttry {\n\t\t\tauthStateFileContents = await fs.readFile(authStateFilePath, \"utf8\");\n\t\t\trawAuthState = JSON.parse(authStateFileContents);\n\t\t} catch {\n\t\t\t// Write a default persisted state if it doesn't already exist.\n\n\t\t\trawAuthState = {\n\t\t\t\t...DEFAULT_PERSISTED_AUTH_STATE,\n\t\t\t\tcookies: serializeCookies(DEFAULT_PERSISTED_AUTH_STATE.cookies),\n\t\t\t};\n\t\t\tauthStateFileContents = JSON.stringify(rawAuthState, null, \"\\t\");\n\n\t\t\tawait fs.mkdir(path.dirname(authStateFilePath), { recursive: true });\n\t\t\tawait fs.writeFile(authStateFilePath, authStateFileContents);\n\t\t}\n\n\t\t// Decode cookies into a record for convenience.\n\t\tif (typeof rawAuthState.cookies === \"string\") {\n\t\t\trawAuthState.cookies = parseCookies(rawAuthState.cookies);\n\t\t}\n\n\t\tconst { value: authState, error } = decode(PrismicAuthState, rawAuthState);\n\n\t\tif (error) {\n\t\t\tthrow new UnexpectedDataError(\"Prismic authentication state is invalid.\");\n\t\t}\n\n\t\treturn authState;\n\t}\n\n\tprivate async _writePersistedAuthState(\n\t\tauthState: PrismicAuthState,\n\t): Promise<void> {\n\t\tconst authStateFilePath = this._getPersistedAuthStateFilePath();\n\n\t\tconst preparedAuthState = {\n\t\t\t...authState,\n\t\t\tcookies: serializeCookies(authState.cookies),\n\t\t};\n\n\t\ttry {\n\t\t\tawait fs.writeFile(\n\t\t\t\tauthStateFilePath,\n\t\t\t\tJSON.stringify(preparedAuthState, null, 2),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthrow new InternalError(\n\t\t\t\t\"Failed to write Prismic authentication state to the file system.\",\n\t\t\t\t{\n\t\t\t\t\tcause: error,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate _getPersistedAuthStateFilePath(): string {\n\t\treturn path.resolve(this.scopedDirectory, PERSISTED_AUTH_STATE_FILE_NAME);\n\t}\n}\n"],"names":["t","os","API_ENDPOINTS","getPort","h3","createPrismicAuthManagerMiddleware","http","resolve","fetch","SLICE_MACHINE_USER_AGENT","UnauthenticatedError","InternalError","decode","UnexpectedDataError","fs","serializeCookies","path"],"mappings":"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"}
1
+ {"version":3,"file":"PrismicAuthManager.cjs","sources":["../../../src/auth/PrismicAuthManager.ts"],"sourcesContent":["import * as t from \"io-ts\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport * as http from \"node:http\";\n\nimport * as h3 from \"h3\";\nimport fetch from \"../lib/fetch\";\nimport cookie from \"cookie\";\nimport cors from \"cors\";\nimport getPort from \"get-port\";\n\nimport { decode } from \"../lib/decode\";\nimport { serializeCookies } from \"../lib/serializeCookies\";\n\nimport { API_ENDPOINTS } from \"../constants/API_ENDPOINTS\";\nimport { SLICE_MACHINE_USER_AGENT } from \"../constants/SLICE_MACHINE_USER_AGENT\";\nimport { createPrismicAuthManagerMiddleware } from \"./createPrismicAuthManagerMiddleware\";\nimport {\n\tInternalError,\n\tUnauthenticatedError,\n\tUnexpectedDataError,\n} from \"../errors\";\n\nconst COOKIE_SEPARATOR = \"; \";\nconst AUTH_COOKIE_KEY = \"prismic-auth\";\nconst SESSION_COOKIE_KEY = \"SESSION\";\n\nconst PERSISTED_AUTH_STATE_FILE_NAME = \".prismic\";\nconst DEFAULT_PERSISTED_AUTH_STATE: PrismicAuthState = {\n\tbase: \"https://prismic.io\",\n\tcookies: {},\n};\n\nconst PrismicAuthState = t.intersection([\n\tt.type({\n\t\tbase: t.string,\n\t\tcookies: t.intersection([\n\t\t\tt.partial({\n\t\t\t\t[AUTH_COOKIE_KEY]: t.string,\n\t\t\t\tSESSION: t.string,\n\t\t\t}),\n\t\t\tt.record(t.string, t.string),\n\t\t]),\n\t}),\n\tt.partial({\n\t\tshortId: t.string,\n\t\tintercomHash: t.string,\n\t\toauthAccessToken: t.string,\n\t\tauthUrl: t.string,\n\t}),\n]);\nexport type PrismicAuthState = t.TypeOf<typeof PrismicAuthState>;\n\nconst PrismicUserProfile = t.exact(\n\tt.type({\n\t\tuserId: t.string,\n\t\tshortId: t.string,\n\t\tintercomHash: t.string,\n\t\temail: t.string,\n\t\tfirstName: t.string,\n\t\tlastName: t.string,\n\t}),\n);\nexport type PrismicUserProfile = t.TypeOf<typeof PrismicUserProfile>;\n\ntype PrismicAuthManagerConstructorArgs = {\n\tscopedDirectory?: string;\n};\n\ntype PrismicAuthManagerLoginArgs = {\n\temail: string;\n\tcookies: string[];\n};\n\ntype PrismicAuthManagerGetLoginSessionInfoReturnType = {\n\tport: number;\n\turl: string;\n};\n\ntype PrismicAuthManagerNodeLoginSessionArgs = {\n\tport: number;\n\tonListenCallback?: () => void;\n};\n\ntype GetProfileForAuthenticationTokenArgs = {\n\tauthenticationToken: string;\n};\n\nconst checkHasAuthenticationToken = (\n\tauthState: PrismicAuthState,\n): authState is PrismicAuthState & {\n\tcookies: Required<\n\t\tPick<\n\t\t\tPrismicAuthState[\"cookies\"],\n\t\t\ttypeof AUTH_COOKIE_KEY | typeof SESSION_COOKIE_KEY\n\t\t>\n\t>;\n} => {\n\treturn Boolean(\n\t\tauthState.cookies[AUTH_COOKIE_KEY] && authState.cookies[SESSION_COOKIE_KEY],\n\t);\n};\n\nconst parseCookies = (cookies: string): Record<string, string> => {\n\treturn cookie.parse(cookies, {\n\t\t// Don't escape any values.\n\t\tdecode: (value) => value,\n\t});\n};\n\nexport class PrismicAuthManager {\n\t// TODO: Automatically scope the manager to the current Slice Machine\n\t// project? If not, this internal state can be removed.\n\tscopedDirectory: string;\n\n\tconstructor({\n\t\tscopedDirectory = os.homedir(),\n\t}: PrismicAuthManagerConstructorArgs = {}) {\n\t\tthis.scopedDirectory = scopedDirectory;\n\t}\n\n\t// TODO: Make the `cookies` argument more explicit. What are these\n\t// mysterious cookies?\n\tasync login(args: PrismicAuthManagerLoginArgs): Promise<void> {\n\t\tconst authState = await this._readPersistedAuthState();\n\n\t\t// Set the auth's URL base to the current base at runtime.\n\t\tauthState.base = API_ENDPOINTS.PrismicWroom;\n\t\tauthState.cookies = {\n\t\t\t...authState.cookies,\n\t\t\t...parseCookies(args.cookies.join(COOKIE_SEPARATOR)),\n\t\t};\n\n\t\tif (checkHasAuthenticationToken(authState)) {\n\t\t\tconst authenticationToken = authState.cookies[AUTH_COOKIE_KEY];\n\t\t\tconst profile = await this._getProfileForAuthenticationToken({\n\t\t\t\tauthenticationToken,\n\t\t\t});\n\n\t\t\tauthState.shortId = profile.shortId;\n\t\t\tauthState.intercomHash = profile.intercomHash;\n\t\t}\n\n\t\tawait this._writePersistedAuthState(authState);\n\t}\n\n\tasync getLoginSessionInfo(): Promise<PrismicAuthManagerGetLoginSessionInfoReturnType> {\n\t\t// Pick a random port, with a preference for historic `5555`\n\t\tconst port = await getPort({ port: 5555 });\n\n\t\tconst url = new URL(\n\t\t\t`./dashboard/cli/login?source=slice-machine&port=${port}`,\n\t\t\tAPI_ENDPOINTS.PrismicWroom,\n\t\t).toString();\n\n\t\treturn {\n\t\t\tport,\n\t\t\turl,\n\t\t};\n\t}\n\n\tasync nodeLoginSession(\n\t\targs: PrismicAuthManagerNodeLoginSessionArgs,\n\t): Promise<void> {\n\t\treturn new Promise<void>(async (resolve) => {\n\t\t\t// Timeout attempt after 3 minutes\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tserver.close();\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Login timeout, server did not receive a response within a 3-minute delay\",\n\t\t\t\t);\n\t\t\t}, 180_000);\n\n\t\t\tconst app = h3.createApp();\n\t\t\tapp.use(h3.fromNodeMiddleware(cors()));\n\t\t\tapp.use(\n\t\t\t\th3.fromNodeMiddleware(\n\t\t\t\t\tcreatePrismicAuthManagerMiddleware({\n\t\t\t\t\t\tprismicAuthManager: this,\n\t\t\t\t\t\tonLoginCallback() {\n\t\t\t\t\t\t\t// Cleanup process and resolve\n\t\t\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\t\t\tserver.close();\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\t// Start server\n\t\t\tconst server = http.createServer(h3.toNodeListener(app));\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tserver.once(\"listening\", () => {\n\t\t\t\t\tresolve();\n\t\t\t\t});\n\t\t\t\tserver.listen(args.port, \"127.0.0.1\");\n\t\t\t});\n\n\t\t\tif (args.onListenCallback) {\n\t\t\t\targs.onListenCallback();\n\t\t\t}\n\t\t});\n\t}\n\n\tasync logout(): Promise<void> {\n\t\tconst authState = await this._readPersistedAuthState();\n\n\t\t// Remove all Prismic cookies, short ID, and Intercom hash\n\t\t// associated with the currently logged in user.\n\t\tauthState.cookies = {};\n\t\tauthState.shortId = undefined;\n\t\tauthState.intercomHash = undefined;\n\n\t\tawait this._writePersistedAuthState(authState);\n\t}\n\n\tasync checkIsLoggedIn(): Promise<boolean> {\n\t\tconst authState = await this._readPersistedAuthState();\n\n\t\tif (checkHasAuthenticationToken(authState)) {\n\t\t\tconst url = new URL(\"./validate\", API_ENDPOINTS.PrismicAuthentication);\n\t\t\turl.searchParams.set(\"token\", authState.cookies[AUTH_COOKIE_KEY]);\n\n\t\t\tlet res;\n\t\t\ttry {\n\t\t\t\tres = await fetch(url.toString(), {\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\t// Noop, we return if `res` is not defined.\n\t\t\t}\n\n\t\t\tif (!res || !res.ok) {\n\t\t\t\tawait this.logout();\n\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync getAuthenticationCookies(): Promise<\n\t\tPrismicAuthState[\"cookies\"] &\n\t\t\tRequired<\n\t\t\t\tPick<\n\t\t\t\t\tPrismicAuthState[\"cookies\"],\n\t\t\t\t\ttypeof AUTH_COOKIE_KEY | typeof SESSION_COOKIE_KEY\n\t\t\t\t>\n\t\t\t>\n\t> {\n\t\tconst isLoggedIn = await this.checkIsLoggedIn();\n\n\t\tif (isLoggedIn) {\n\t\t\tconst authState = await this._readPersistedAuthState();\n\n\t\t\tif (checkHasAuthenticationToken(authState)) {\n\t\t\t\treturn authState.cookies;\n\t\t\t}\n\t\t}\n\n\t\tthrow new UnauthenticatedError();\n\t}\n\n\tasync getAuthenticationToken(): Promise<string> {\n\t\tconst cookies = await this.getAuthenticationCookies();\n\n\t\treturn cookies[AUTH_COOKIE_KEY];\n\t}\n\n\tasync refreshAuthenticationToken(): Promise<void> {\n\t\tconst authState = await this._readPersistedAuthState();\n\n\t\tif (checkHasAuthenticationToken(authState)) {\n\t\t\tconst url = new URL(\n\t\t\t\t\"./refreshtoken\",\n\t\t\t\tAPI_ENDPOINTS.PrismicAuthentication,\n\t\t\t);\n\t\t\turl.searchParams.set(\"token\", authState.cookies[AUTH_COOKIE_KEY]);\n\n\t\t\tconst res = await fetch(url.toString(), {\n\t\t\t\theaders: {\n\t\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst text = await res.text();\n\n\t\t\tif (res.ok) {\n\t\t\t\tauthState.cookies[AUTH_COOKIE_KEY] = text;\n\n\t\t\t\tawait this._writePersistedAuthState(authState);\n\t\t\t} else {\n\t\t\t\tthrow new InternalError(\"Failed to refresh authentication token.\", {\n\t\t\t\t\tcause: text,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new UnauthenticatedError();\n\t\t}\n\t}\n\n\tasync getProfile(): Promise<PrismicUserProfile> {\n\t\tconst authenticationToken = await this.getAuthenticationToken();\n\n\t\treturn await this._getProfileForAuthenticationToken({\n\t\t\tauthenticationToken,\n\t\t});\n\t}\n\n\tprivate async _getProfileForAuthenticationToken(\n\t\targs: GetProfileForAuthenticationTokenArgs,\n\t): Promise<PrismicUserProfile> {\n\t\tconst url = new URL(\"./profile\", API_ENDPOINTS.PrismicUser);\n\t\tconst res = await fetch(url.toString(), {\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${args.authenticationToken}`,\n\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t},\n\t\t});\n\n\t\tif (res.ok) {\n\t\t\tconst json = await res.json();\n\t\t\tconst { value: profile, error } = decode(PrismicUserProfile, json);\n\n\t\t\tif (error) {\n\t\t\t\tthrow new UnexpectedDataError(\n\t\t\t\t\t\"Received invalid data from the Prismic user service.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn profile;\n\t\t} else {\n\t\t\tconst text = await res.text();\n\t\t\tthrow new InternalError(\n\t\t\t\t\"Failed to retrieve profile from the Prismic user service.\",\n\t\t\t\t{\n\t\t\t\t\tcause: text,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate async _readPersistedAuthState(): Promise<PrismicAuthState> {\n\t\tconst authStateFilePath = this._getPersistedAuthStateFilePath();\n\n\t\tlet authStateFileContents: string = JSON.stringify({});\n\t\tlet rawAuthState: Record<string, unknown> = {};\n\n\t\ttry {\n\t\t\tauthStateFileContents = await fs.readFile(authStateFilePath, \"utf8\");\n\t\t\trawAuthState = JSON.parse(authStateFileContents);\n\t\t} catch {\n\t\t\t// Write a default persisted state if it doesn't already exist.\n\n\t\t\trawAuthState = {\n\t\t\t\t...DEFAULT_PERSISTED_AUTH_STATE,\n\t\t\t\tcookies: serializeCookies(DEFAULT_PERSISTED_AUTH_STATE.cookies),\n\t\t\t};\n\t\t\tauthStateFileContents = JSON.stringify(rawAuthState, null, \"\\t\");\n\n\t\t\tawait fs.mkdir(path.dirname(authStateFilePath), { recursive: true });\n\t\t\tawait fs.writeFile(authStateFilePath, authStateFileContents);\n\t\t}\n\n\t\t// Decode cookies into a record for convenience.\n\t\tif (typeof rawAuthState.cookies === \"string\") {\n\t\t\trawAuthState.cookies = parseCookies(rawAuthState.cookies);\n\t\t}\n\n\t\tconst { value: authState, error } = decode(PrismicAuthState, rawAuthState);\n\n\t\tif (error) {\n\t\t\tthrow new UnexpectedDataError(\"Prismic authentication state is invalid.\");\n\t\t}\n\n\t\treturn authState;\n\t}\n\n\tprivate async _writePersistedAuthState(\n\t\tauthState: PrismicAuthState,\n\t): Promise<void> {\n\t\tconst authStateFilePath = this._getPersistedAuthStateFilePath();\n\n\t\tconst preparedAuthState = {\n\t\t\t...authState,\n\t\t\tcookies: serializeCookies(authState.cookies),\n\t\t};\n\n\t\ttry {\n\t\t\tawait fs.writeFile(\n\t\t\t\tauthStateFilePath,\n\t\t\t\tJSON.stringify(preparedAuthState, null, 2),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthrow new InternalError(\n\t\t\t\t\"Failed to write Prismic authentication state to the file system.\",\n\t\t\t\t{\n\t\t\t\t\tcause: error,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate _getPersistedAuthStateFilePath(): string {\n\t\treturn path.resolve(this.scopedDirectory, PERSISTED_AUTH_STATE_FILE_NAME);\n\t}\n}\n"],"names":["t","os","API_ENDPOINTS","getPort","h3","createPrismicAuthManagerMiddleware","http","resolve","fetch","SLICE_MACHINE_USER_AGENT","UnauthenticatedError","InternalError","decode","UnexpectedDataError","fs","serializeCookies","path"],"mappings":"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"}
@@ -118,7 +118,7 @@ class PrismicAuthManager {
118
118
  server.once("listening", () => {
119
119
  resolve2();
120
120
  });
121
- server.listen(args.port);
121
+ server.listen(args.port, "127.0.0.1");
122
122
  });
123
123
  if (args.onListenCallback) {
124
124
  args.onListenCallback();
@@ -1 +1 @@
1
- {"version":3,"file":"PrismicAuthManager.js","sources":["../../../src/auth/PrismicAuthManager.ts"],"sourcesContent":["import * as t from \"io-ts\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport * as http from \"node:http\";\n\nimport * as h3 from \"h3\";\nimport fetch from \"../lib/fetch\";\nimport cookie from \"cookie\";\nimport cors from \"cors\";\nimport getPort from \"get-port\";\n\nimport { decode } from \"../lib/decode\";\nimport { serializeCookies } from \"../lib/serializeCookies\";\n\nimport { API_ENDPOINTS } from \"../constants/API_ENDPOINTS\";\nimport { SLICE_MACHINE_USER_AGENT } from \"../constants/SLICE_MACHINE_USER_AGENT\";\nimport { createPrismicAuthManagerMiddleware } from \"./createPrismicAuthManagerMiddleware\";\nimport {\n\tInternalError,\n\tUnauthenticatedError,\n\tUnexpectedDataError,\n} from \"../errors\";\n\nconst COOKIE_SEPARATOR = \"; \";\nconst AUTH_COOKIE_KEY = \"prismic-auth\";\nconst SESSION_COOKIE_KEY = \"SESSION\";\n\nconst PERSISTED_AUTH_STATE_FILE_NAME = \".prismic\";\nconst DEFAULT_PERSISTED_AUTH_STATE: PrismicAuthState = {\n\tbase: \"https://prismic.io\",\n\tcookies: {},\n};\n\nconst PrismicAuthState = t.intersection([\n\tt.type({\n\t\tbase: t.string,\n\t\tcookies: t.intersection([\n\t\t\tt.partial({\n\t\t\t\t[AUTH_COOKIE_KEY]: t.string,\n\t\t\t\tSESSION: t.string,\n\t\t\t}),\n\t\t\tt.record(t.string, t.string),\n\t\t]),\n\t}),\n\tt.partial({\n\t\tshortId: t.string,\n\t\tintercomHash: t.string,\n\t\toauthAccessToken: t.string,\n\t\tauthUrl: t.string,\n\t}),\n]);\nexport type PrismicAuthState = t.TypeOf<typeof PrismicAuthState>;\n\nconst PrismicUserProfile = t.exact(\n\tt.type({\n\t\tuserId: t.string,\n\t\tshortId: t.string,\n\t\tintercomHash: t.string,\n\t\temail: t.string,\n\t\tfirstName: t.string,\n\t\tlastName: t.string,\n\t}),\n);\nexport type PrismicUserProfile = t.TypeOf<typeof PrismicUserProfile>;\n\ntype PrismicAuthManagerConstructorArgs = {\n\tscopedDirectory?: string;\n};\n\ntype PrismicAuthManagerLoginArgs = {\n\temail: string;\n\tcookies: string[];\n};\n\ntype PrismicAuthManagerGetLoginSessionInfoReturnType = {\n\tport: number;\n\turl: string;\n};\n\ntype PrismicAuthManagerNodeLoginSessionArgs = {\n\tport: number;\n\tonListenCallback?: () => void;\n};\n\ntype GetProfileForAuthenticationTokenArgs = {\n\tauthenticationToken: string;\n};\n\nconst checkHasAuthenticationToken = (\n\tauthState: PrismicAuthState,\n): authState is PrismicAuthState & {\n\tcookies: Required<\n\t\tPick<\n\t\t\tPrismicAuthState[\"cookies\"],\n\t\t\ttypeof AUTH_COOKIE_KEY | typeof SESSION_COOKIE_KEY\n\t\t>\n\t>;\n} => {\n\treturn Boolean(\n\t\tauthState.cookies[AUTH_COOKIE_KEY] && authState.cookies[SESSION_COOKIE_KEY],\n\t);\n};\n\nconst parseCookies = (cookies: string): Record<string, string> => {\n\treturn cookie.parse(cookies, {\n\t\t// Don't escape any values.\n\t\tdecode: (value) => value,\n\t});\n};\n\nexport class PrismicAuthManager {\n\t// TODO: Automatically scope the manager to the current Slice Machine\n\t// project? If not, this internal state can be removed.\n\tscopedDirectory: string;\n\n\tconstructor({\n\t\tscopedDirectory = os.homedir(),\n\t}: PrismicAuthManagerConstructorArgs = {}) {\n\t\tthis.scopedDirectory = scopedDirectory;\n\t}\n\n\t// TODO: Make the `cookies` argument more explicit. What are these\n\t// mysterious cookies?\n\tasync login(args: PrismicAuthManagerLoginArgs): Promise<void> {\n\t\tconst authState = await this._readPersistedAuthState();\n\n\t\t// Set the auth's URL base to the current base at runtime.\n\t\tauthState.base = API_ENDPOINTS.PrismicWroom;\n\t\tauthState.cookies = {\n\t\t\t...authState.cookies,\n\t\t\t...parseCookies(args.cookies.join(COOKIE_SEPARATOR)),\n\t\t};\n\n\t\tif (checkHasAuthenticationToken(authState)) {\n\t\t\tconst authenticationToken = authState.cookies[AUTH_COOKIE_KEY];\n\t\t\tconst profile = await this._getProfileForAuthenticationToken({\n\t\t\t\tauthenticationToken,\n\t\t\t});\n\n\t\t\tauthState.shortId = profile.shortId;\n\t\t\tauthState.intercomHash = profile.intercomHash;\n\t\t}\n\n\t\tawait this._writePersistedAuthState(authState);\n\t}\n\n\tasync getLoginSessionInfo(): Promise<PrismicAuthManagerGetLoginSessionInfoReturnType> {\n\t\t// Pick a random port, with a preference for historic `5555`\n\t\tconst port = await getPort({ port: 5555 });\n\n\t\tconst url = new URL(\n\t\t\t`./dashboard/cli/login?source=slice-machine&port=${port}`,\n\t\t\tAPI_ENDPOINTS.PrismicWroom,\n\t\t).toString();\n\n\t\treturn {\n\t\t\tport,\n\t\t\turl,\n\t\t};\n\t}\n\n\tasync nodeLoginSession(\n\t\targs: PrismicAuthManagerNodeLoginSessionArgs,\n\t): Promise<void> {\n\t\treturn new Promise<void>(async (resolve) => {\n\t\t\t// Timeout attempt after 3 minutes\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tserver.close();\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Login timeout, server did not receive a response within a 3-minute delay\",\n\t\t\t\t);\n\t\t\t}, 180_000);\n\n\t\t\tconst app = h3.createApp();\n\t\t\tapp.use(h3.fromNodeMiddleware(cors()));\n\t\t\tapp.use(\n\t\t\t\th3.fromNodeMiddleware(\n\t\t\t\t\tcreatePrismicAuthManagerMiddleware({\n\t\t\t\t\t\tprismicAuthManager: this,\n\t\t\t\t\t\tonLoginCallback() {\n\t\t\t\t\t\t\t// Cleanup process and resolve\n\t\t\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\t\t\tserver.close();\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\t// Start server\n\t\t\tconst server = http.createServer(h3.toNodeListener(app));\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tserver.once(\"listening\", () => {\n\t\t\t\t\tresolve();\n\t\t\t\t});\n\t\t\t\tserver.listen(args.port);\n\t\t\t});\n\n\t\t\tif (args.onListenCallback) {\n\t\t\t\targs.onListenCallback();\n\t\t\t}\n\t\t});\n\t}\n\n\tasync logout(): Promise<void> {\n\t\tconst authState = await this._readPersistedAuthState();\n\n\t\t// Remove all Prismic cookies, short ID, and Intercom hash\n\t\t// associated with the currently logged in user.\n\t\tauthState.cookies = {};\n\t\tauthState.shortId = undefined;\n\t\tauthState.intercomHash = undefined;\n\n\t\tawait this._writePersistedAuthState(authState);\n\t}\n\n\tasync checkIsLoggedIn(): Promise<boolean> {\n\t\tconst authState = await this._readPersistedAuthState();\n\n\t\tif (checkHasAuthenticationToken(authState)) {\n\t\t\tconst url = new URL(\"./validate\", API_ENDPOINTS.PrismicAuthentication);\n\t\t\turl.searchParams.set(\"token\", authState.cookies[AUTH_COOKIE_KEY]);\n\n\t\t\tlet res;\n\t\t\ttry {\n\t\t\t\tres = await fetch(url.toString(), {\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\t// Noop, we return if `res` is not defined.\n\t\t\t}\n\n\t\t\tif (!res || !res.ok) {\n\t\t\t\tawait this.logout();\n\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync getAuthenticationCookies(): Promise<\n\t\tPrismicAuthState[\"cookies\"] &\n\t\t\tRequired<\n\t\t\t\tPick<\n\t\t\t\t\tPrismicAuthState[\"cookies\"],\n\t\t\t\t\ttypeof AUTH_COOKIE_KEY | typeof SESSION_COOKIE_KEY\n\t\t\t\t>\n\t\t\t>\n\t> {\n\t\tconst isLoggedIn = await this.checkIsLoggedIn();\n\n\t\tif (isLoggedIn) {\n\t\t\tconst authState = await this._readPersistedAuthState();\n\n\t\t\tif (checkHasAuthenticationToken(authState)) {\n\t\t\t\treturn authState.cookies;\n\t\t\t}\n\t\t}\n\n\t\tthrow new UnauthenticatedError();\n\t}\n\n\tasync getAuthenticationToken(): Promise<string> {\n\t\tconst cookies = await this.getAuthenticationCookies();\n\n\t\treturn cookies[AUTH_COOKIE_KEY];\n\t}\n\n\tasync refreshAuthenticationToken(): Promise<void> {\n\t\tconst authState = await this._readPersistedAuthState();\n\n\t\tif (checkHasAuthenticationToken(authState)) {\n\t\t\tconst url = new URL(\n\t\t\t\t\"./refreshtoken\",\n\t\t\t\tAPI_ENDPOINTS.PrismicAuthentication,\n\t\t\t);\n\t\t\turl.searchParams.set(\"token\", authState.cookies[AUTH_COOKIE_KEY]);\n\n\t\t\tconst res = await fetch(url.toString(), {\n\t\t\t\theaders: {\n\t\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst text = await res.text();\n\n\t\t\tif (res.ok) {\n\t\t\t\tauthState.cookies[AUTH_COOKIE_KEY] = text;\n\n\t\t\t\tawait this._writePersistedAuthState(authState);\n\t\t\t} else {\n\t\t\t\tthrow new InternalError(\"Failed to refresh authentication token.\", {\n\t\t\t\t\tcause: text,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new UnauthenticatedError();\n\t\t}\n\t}\n\n\tasync getProfile(): Promise<PrismicUserProfile> {\n\t\tconst authenticationToken = await this.getAuthenticationToken();\n\n\t\treturn await this._getProfileForAuthenticationToken({\n\t\t\tauthenticationToken,\n\t\t});\n\t}\n\n\tprivate async _getProfileForAuthenticationToken(\n\t\targs: GetProfileForAuthenticationTokenArgs,\n\t): Promise<PrismicUserProfile> {\n\t\tconst url = new URL(\"./profile\", API_ENDPOINTS.PrismicUser);\n\t\tconst res = await fetch(url.toString(), {\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${args.authenticationToken}`,\n\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t},\n\t\t});\n\n\t\tif (res.ok) {\n\t\t\tconst json = await res.json();\n\t\t\tconst { value: profile, error } = decode(PrismicUserProfile, json);\n\n\t\t\tif (error) {\n\t\t\t\tthrow new UnexpectedDataError(\n\t\t\t\t\t\"Received invalid data from the Prismic user service.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn profile;\n\t\t} else {\n\t\t\tconst text = await res.text();\n\t\t\tthrow new InternalError(\n\t\t\t\t\"Failed to retrieve profile from the Prismic user service.\",\n\t\t\t\t{\n\t\t\t\t\tcause: text,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate async _readPersistedAuthState(): Promise<PrismicAuthState> {\n\t\tconst authStateFilePath = this._getPersistedAuthStateFilePath();\n\n\t\tlet authStateFileContents: string = JSON.stringify({});\n\t\tlet rawAuthState: Record<string, unknown> = {};\n\n\t\ttry {\n\t\t\tauthStateFileContents = await fs.readFile(authStateFilePath, \"utf8\");\n\t\t\trawAuthState = JSON.parse(authStateFileContents);\n\t\t} catch {\n\t\t\t// Write a default persisted state if it doesn't already exist.\n\n\t\t\trawAuthState = {\n\t\t\t\t...DEFAULT_PERSISTED_AUTH_STATE,\n\t\t\t\tcookies: serializeCookies(DEFAULT_PERSISTED_AUTH_STATE.cookies),\n\t\t\t};\n\t\t\tauthStateFileContents = JSON.stringify(rawAuthState, null, \"\\t\");\n\n\t\t\tawait fs.mkdir(path.dirname(authStateFilePath), { recursive: true });\n\t\t\tawait fs.writeFile(authStateFilePath, authStateFileContents);\n\t\t}\n\n\t\t// Decode cookies into a record for convenience.\n\t\tif (typeof rawAuthState.cookies === \"string\") {\n\t\t\trawAuthState.cookies = parseCookies(rawAuthState.cookies);\n\t\t}\n\n\t\tconst { value: authState, error } = decode(PrismicAuthState, rawAuthState);\n\n\t\tif (error) {\n\t\t\tthrow new UnexpectedDataError(\"Prismic authentication state is invalid.\");\n\t\t}\n\n\t\treturn authState;\n\t}\n\n\tprivate async _writePersistedAuthState(\n\t\tauthState: PrismicAuthState,\n\t): Promise<void> {\n\t\tconst authStateFilePath = this._getPersistedAuthStateFilePath();\n\n\t\tconst preparedAuthState = {\n\t\t\t...authState,\n\t\t\tcookies: serializeCookies(authState.cookies),\n\t\t};\n\n\t\ttry {\n\t\t\tawait fs.writeFile(\n\t\t\t\tauthStateFilePath,\n\t\t\t\tJSON.stringify(preparedAuthState, null, 2),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthrow new InternalError(\n\t\t\t\t\"Failed to write Prismic authentication state to the file system.\",\n\t\t\t\t{\n\t\t\t\t\tcause: error,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate _getPersistedAuthStateFilePath(): string {\n\t\treturn path.resolve(this.scopedDirectory, PERSISTED_AUTH_STATE_FILE_NAME);\n\t}\n}\n"],"names":["getPort","resolve"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAM,mBAAmB;AACzB,MAAM,kBAAkB;AACxB,MAAM,qBAAqB;AAE3B,MAAM,iCAAiC;AACvC,MAAM,+BAAiD;AAAA,EACtD,MAAM;AAAA,EACN,SAAS,CAAE;;AAGZ,MAAM,mBAAmB,EAAE,aAAa;AAAA,EACvC,EAAE,KAAK;AAAA,IACN,MAAM,EAAE;AAAA,IACR,SAAS,EAAE,aAAa;AAAA,MACvB,EAAE,QAAQ;AAAA,QACT,CAAC,eAAe,GAAG,EAAE;AAAA,QACrB,SAAS,EAAE;AAAA,MAAA,CACX;AAAA,MACD,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM;AAAA,IAAA,CAC3B;AAAA,EAAA,CACD;AAAA,EACD,EAAE,QAAQ;AAAA,IACT,SAAS,EAAE;AAAA,IACX,cAAc,EAAE;AAAA,IAChB,kBAAkB,EAAE;AAAA,IACpB,SAAS,EAAE;AAAA,EAAA,CACX;AACD,CAAA;AAGD,MAAM,qBAAqB,EAAE,MAC5B,EAAE,KAAK;AAAA,EACN,QAAQ,EAAE;AAAA,EACV,SAAS,EAAE;AAAA,EACX,cAAc,EAAE;AAAA,EAChB,OAAO,EAAE;AAAA,EACT,WAAW,EAAE;AAAA,EACb,UAAU,EAAE;AACZ,CAAA,CAAC;AA2BH,MAAM,8BAA8B,CACnC,cAQG;AACI,SAAA,QACN,UAAU,QAAQ,eAAe,KAAK,UAAU,QAAQ,kBAAkB,CAAC;AAE7E;AAEA,MAAM,eAAe,CAAC,YAA2C;AACzD,SAAA,OAAO,MAAM,SAAS;AAAA;AAAA,IAE5B,QAAQ,CAAC,UAAU;AAAA,EAAA,CACnB;AACF;MAEa,mBAAkB;AAAA,EAK9B,YAAY,EACX,kBAAkB,GAAG,cACiB,CAAA,GAAE;AAJzC;AAAA;AAAA;AAKC,SAAK,kBAAkB;AAAA,EACxB;AAAA;AAAA;AAAA,EAIA,MAAM,MAAM,MAAiC;AACtC,UAAA,YAAY,MAAM,KAAK;AAG7B,cAAU,OAAO,cAAc;AAC/B,cAAU,UAAU;AAAA,MACnB,GAAG,UAAU;AAAA,MACb,GAAG,aAAa,KAAK,QAAQ,KAAK,gBAAgB,CAAC;AAAA,IAAA;AAGhD,QAAA,4BAA4B,SAAS,GAAG;AACrC,YAAA,sBAAsB,UAAU,QAAQ,eAAe;AACvD,YAAA,UAAU,MAAM,KAAK,kCAAkC;AAAA,QAC5D;AAAA,MAAA,CACA;AAED,gBAAU,UAAU,QAAQ;AAC5B,gBAAU,eAAe,QAAQ;AAAA,IAClC;AAEM,UAAA,KAAK,yBAAyB,SAAS;AAAA,EAC9C;AAAA,EAEA,MAAM,sBAAmB;AAExB,UAAM,OAAO,MAAMA,SAAQ,EAAE,MAAM,KAAM,CAAA;AAEnC,UAAA,MAAM,IAAI,IACf,mDAAmD,IAAI,IACvD,cAAc,YAAY,EACzB;AAEK,WAAA;AAAA,MACN;AAAA,MACA;AAAA,IAAA;AAAA,EAEF;AAAA,EAEA,MAAM,iBACL,MAA4C;AAErC,WAAA,IAAI,QAAc,OAAO,YAAW;AAEpC,YAAA,UAAU,WAAW,MAAK;AAC/B,eAAO,MAAK;AACN,cAAA,IAAI,MACT,0EAA0E;AAAA,SAEzE,IAAO;AAEJ,YAAA,MAAM,GAAG;AACf,UAAI,IAAI,GAAG,mBAAmB,KAAA,CAAM,CAAC;AACjC,UAAA,IACH,GAAG,mBACF,mCAAmC;AAAA,QAClC,oBAAoB;AAAA,QACpB,kBAAe;AAEd,uBAAa,OAAO;AACpB,iBAAO,MAAK;;QAEb;AAAA,MACA,CAAA,CAAC,CACF;AAIF,YAAM,SAAS,KAAK,aAAa,GAAG,eAAe,GAAG,CAAC;AACjD,YAAA,IAAI,QAAc,CAACC,aAAW;AAC5B,eAAA,KAAK,aAAa,MAAK;AAC7BA;SACA;AACM,eAAA,OAAO,KAAK,IAAI;AAAA,MAAA,CACvB;AAED,UAAI,KAAK,kBAAkB;AAC1B,aAAK,iBAAgB;AAAA,MACtB;AAAA,IAAA,CACA;AAAA,EACF;AAAA,EAEA,MAAM,SAAM;AACL,UAAA,YAAY,MAAM,KAAK;AAI7B,cAAU,UAAU;AACpB,cAAU,UAAU;AACpB,cAAU,eAAe;AAEnB,UAAA,KAAK,yBAAyB,SAAS;AAAA,EAC9C;AAAA,EAEA,MAAM,kBAAe;AACd,UAAA,YAAY,MAAM,KAAK;AAEzB,QAAA,4BAA4B,SAAS,GAAG;AAC3C,YAAM,MAAM,IAAI,IAAI,cAAc,cAAc,qBAAqB;AACrE,UAAI,aAAa,IAAI,SAAS,UAAU,QAAQ,eAAe,CAAC;AAE5D,UAAA;AACA,UAAA;AACH,cAAM,MAAM,MAAM,IAAI,SAAA,GAAY;AAAA,UACjC,SAAS;AAAA,YACR,cAAc;AAAA,UACd;AAAA,QAAA,CACD;AAAA,eACO,OAAO;AAAA,MAEhB;AAEA,UAAI,CAAC,OAAO,CAAC,IAAI,IAAI;AACpB,cAAM,KAAK;AAEJ,eAAA;AAAA,MACR;AAEO,aAAA;AAAA,IAAA,OACD;AACC,aAAA;AAAA,IACR;AAAA,EACD;AAAA,EAEA,MAAM,2BAAwB;AASvB,UAAA,aAAa,MAAM,KAAK;AAE9B,QAAI,YAAY;AACT,YAAA,YAAY,MAAM,KAAK;AAEzB,UAAA,4BAA4B,SAAS,GAAG;AAC3C,eAAO,UAAU;AAAA,MAClB;AAAA,IACD;AAEA,UAAM,IAAI,qBAAoB;AAAA,EAC/B;AAAA,EAEA,MAAM,yBAAsB;AACrB,UAAA,UAAU,MAAM,KAAK;AAE3B,WAAO,QAAQ,eAAe;AAAA,EAC/B;AAAA,EAEA,MAAM,6BAA0B;AACzB,UAAA,YAAY,MAAM,KAAK;AAEzB,QAAA,4BAA4B,SAAS,GAAG;AAC3C,YAAM,MAAM,IAAI,IACf,kBACA,cAAc,qBAAqB;AAEpC,UAAI,aAAa,IAAI,SAAS,UAAU,QAAQ,eAAe,CAAC;AAEhE,YAAM,MAAM,MAAM,MAAM,IAAI,YAAY;AAAA,QACvC,SAAS;AAAA,UACR,cAAc;AAAA,QACd;AAAA,MAAA,CACD;AACK,YAAA,OAAO,MAAM,IAAI;AAEvB,UAAI,IAAI,IAAI;AACD,kBAAA,QAAQ,eAAe,IAAI;AAE/B,cAAA,KAAK,yBAAyB,SAAS;AAAA,MAAA,OACvC;AACA,cAAA,IAAI,cAAc,2CAA2C;AAAA,UAClE,OAAO;AAAA,QAAA,CACP;AAAA,MACF;AAAA,IAAA,OACM;AACN,YAAM,IAAI,qBAAoB;AAAA,IAC/B;AAAA,EACD;AAAA,EAEA,MAAM,aAAU;AACT,UAAA,sBAAsB,MAAM,KAAK;AAEhC,WAAA,MAAM,KAAK,kCAAkC;AAAA,MACnD;AAAA,IAAA,CACA;AAAA,EACF;AAAA,EAEQ,MAAM,kCACb,MAA0C;AAE1C,UAAM,MAAM,IAAI,IAAI,aAAa,cAAc,WAAW;AAC1D,UAAM,MAAM,MAAM,MAAM,IAAI,YAAY;AAAA,MACvC,SAAS;AAAA,QACR,eAAe,UAAU,KAAK,mBAAmB;AAAA,QACjD,cAAc;AAAA,MACd;AAAA,IAAA,CACD;AAED,QAAI,IAAI,IAAI;AACL,YAAA,OAAO,MAAM,IAAI;AACvB,YAAM,EAAE,OAAO,SAAS,MAAU,IAAA,OAAO,oBAAoB,IAAI;AAEjE,UAAI,OAAO;AACJ,cAAA,IAAI,oBACT,sDAAsD;AAAA,MAExD;AAEO,aAAA;AAAA,IAAA,OACD;AACA,YAAA,OAAO,MAAM,IAAI;AACjB,YAAA,IAAI,cACT,6DACA;AAAA,QACC,OAAO;AAAA,MAAA,CACP;AAAA,IAEH;AAAA,EACD;AAAA,EAEQ,MAAM,0BAAuB;AAC9B,UAAA,oBAAoB,KAAK;AAE/B,QAAI,wBAAgC,KAAK,UAAU,CAAE,CAAA;AACrD,QAAI,eAAwC,CAAA;AAExC,QAAA;AACH,8BAAwB,MAAM,GAAG,SAAS,mBAAmB,MAAM;AACpD,qBAAA,KAAK,MAAM,qBAAqB;AAAA,IAAA,QACxC;AAGQ,qBAAA;AAAA,QACd,GAAG;AAAA,QACH,SAAS,iBAAiB,6BAA6B,OAAO;AAAA,MAAA;AAE/D,8BAAwB,KAAK,UAAU,cAAc,MAAM,GAAI;AAEzD,YAAA,GAAG,MAAM,KAAK,QAAQ,iBAAiB,GAAG,EAAE,WAAW,KAAA,CAAM;AAC7D,YAAA,GAAG,UAAU,mBAAmB,qBAAqB;AAAA,IAC5D;AAGI,QAAA,OAAO,aAAa,YAAY,UAAU;AAChC,mBAAA,UAAU,aAAa,aAAa,OAAO;AAAA,IACzD;AAEA,UAAM,EAAE,OAAO,WAAW,MAAU,IAAA,OAAO,kBAAkB,YAAY;AAEzE,QAAI,OAAO;AACJ,YAAA,IAAI,oBAAoB,0CAA0C;AAAA,IACzE;AAEO,WAAA;AAAA,EACR;AAAA,EAEQ,MAAM,yBACb,WAA2B;AAErB,UAAA,oBAAoB,KAAK;AAE/B,UAAM,oBAAoB;AAAA,MACzB,GAAG;AAAA,MACH,SAAS,iBAAiB,UAAU,OAAO;AAAA,IAAA;AAGxC,QAAA;AACG,YAAA,GAAG,UACR,mBACA,KAAK,UAAU,mBAAmB,MAAM,CAAC,CAAC;AAAA,aAEnC,OAAO;AACT,YAAA,IAAI,cACT,oEACA;AAAA,QACC,OAAO;AAAA,MAAA,CACP;AAAA,IAEH;AAAA,EACD;AAAA,EAEQ,iCAA8B;AACrC,WAAO,KAAK,QAAQ,KAAK,iBAAiB,8BAA8B;AAAA,EACzE;AACA;"}
1
+ {"version":3,"file":"PrismicAuthManager.js","sources":["../../../src/auth/PrismicAuthManager.ts"],"sourcesContent":["import * as t from \"io-ts\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport * as http from \"node:http\";\n\nimport * as h3 from \"h3\";\nimport fetch from \"../lib/fetch\";\nimport cookie from \"cookie\";\nimport cors from \"cors\";\nimport getPort from \"get-port\";\n\nimport { decode } from \"../lib/decode\";\nimport { serializeCookies } from \"../lib/serializeCookies\";\n\nimport { API_ENDPOINTS } from \"../constants/API_ENDPOINTS\";\nimport { SLICE_MACHINE_USER_AGENT } from \"../constants/SLICE_MACHINE_USER_AGENT\";\nimport { createPrismicAuthManagerMiddleware } from \"./createPrismicAuthManagerMiddleware\";\nimport {\n\tInternalError,\n\tUnauthenticatedError,\n\tUnexpectedDataError,\n} from \"../errors\";\n\nconst COOKIE_SEPARATOR = \"; \";\nconst AUTH_COOKIE_KEY = \"prismic-auth\";\nconst SESSION_COOKIE_KEY = \"SESSION\";\n\nconst PERSISTED_AUTH_STATE_FILE_NAME = \".prismic\";\nconst DEFAULT_PERSISTED_AUTH_STATE: PrismicAuthState = {\n\tbase: \"https://prismic.io\",\n\tcookies: {},\n};\n\nconst PrismicAuthState = t.intersection([\n\tt.type({\n\t\tbase: t.string,\n\t\tcookies: t.intersection([\n\t\t\tt.partial({\n\t\t\t\t[AUTH_COOKIE_KEY]: t.string,\n\t\t\t\tSESSION: t.string,\n\t\t\t}),\n\t\t\tt.record(t.string, t.string),\n\t\t]),\n\t}),\n\tt.partial({\n\t\tshortId: t.string,\n\t\tintercomHash: t.string,\n\t\toauthAccessToken: t.string,\n\t\tauthUrl: t.string,\n\t}),\n]);\nexport type PrismicAuthState = t.TypeOf<typeof PrismicAuthState>;\n\nconst PrismicUserProfile = t.exact(\n\tt.type({\n\t\tuserId: t.string,\n\t\tshortId: t.string,\n\t\tintercomHash: t.string,\n\t\temail: t.string,\n\t\tfirstName: t.string,\n\t\tlastName: t.string,\n\t}),\n);\nexport type PrismicUserProfile = t.TypeOf<typeof PrismicUserProfile>;\n\ntype PrismicAuthManagerConstructorArgs = {\n\tscopedDirectory?: string;\n};\n\ntype PrismicAuthManagerLoginArgs = {\n\temail: string;\n\tcookies: string[];\n};\n\ntype PrismicAuthManagerGetLoginSessionInfoReturnType = {\n\tport: number;\n\turl: string;\n};\n\ntype PrismicAuthManagerNodeLoginSessionArgs = {\n\tport: number;\n\tonListenCallback?: () => void;\n};\n\ntype GetProfileForAuthenticationTokenArgs = {\n\tauthenticationToken: string;\n};\n\nconst checkHasAuthenticationToken = (\n\tauthState: PrismicAuthState,\n): authState is PrismicAuthState & {\n\tcookies: Required<\n\t\tPick<\n\t\t\tPrismicAuthState[\"cookies\"],\n\t\t\ttypeof AUTH_COOKIE_KEY | typeof SESSION_COOKIE_KEY\n\t\t>\n\t>;\n} => {\n\treturn Boolean(\n\t\tauthState.cookies[AUTH_COOKIE_KEY] && authState.cookies[SESSION_COOKIE_KEY],\n\t);\n};\n\nconst parseCookies = (cookies: string): Record<string, string> => {\n\treturn cookie.parse(cookies, {\n\t\t// Don't escape any values.\n\t\tdecode: (value) => value,\n\t});\n};\n\nexport class PrismicAuthManager {\n\t// TODO: Automatically scope the manager to the current Slice Machine\n\t// project? If not, this internal state can be removed.\n\tscopedDirectory: string;\n\n\tconstructor({\n\t\tscopedDirectory = os.homedir(),\n\t}: PrismicAuthManagerConstructorArgs = {}) {\n\t\tthis.scopedDirectory = scopedDirectory;\n\t}\n\n\t// TODO: Make the `cookies` argument more explicit. What are these\n\t// mysterious cookies?\n\tasync login(args: PrismicAuthManagerLoginArgs): Promise<void> {\n\t\tconst authState = await this._readPersistedAuthState();\n\n\t\t// Set the auth's URL base to the current base at runtime.\n\t\tauthState.base = API_ENDPOINTS.PrismicWroom;\n\t\tauthState.cookies = {\n\t\t\t...authState.cookies,\n\t\t\t...parseCookies(args.cookies.join(COOKIE_SEPARATOR)),\n\t\t};\n\n\t\tif (checkHasAuthenticationToken(authState)) {\n\t\t\tconst authenticationToken = authState.cookies[AUTH_COOKIE_KEY];\n\t\t\tconst profile = await this._getProfileForAuthenticationToken({\n\t\t\t\tauthenticationToken,\n\t\t\t});\n\n\t\t\tauthState.shortId = profile.shortId;\n\t\t\tauthState.intercomHash = profile.intercomHash;\n\t\t}\n\n\t\tawait this._writePersistedAuthState(authState);\n\t}\n\n\tasync getLoginSessionInfo(): Promise<PrismicAuthManagerGetLoginSessionInfoReturnType> {\n\t\t// Pick a random port, with a preference for historic `5555`\n\t\tconst port = await getPort({ port: 5555 });\n\n\t\tconst url = new URL(\n\t\t\t`./dashboard/cli/login?source=slice-machine&port=${port}`,\n\t\t\tAPI_ENDPOINTS.PrismicWroom,\n\t\t).toString();\n\n\t\treturn {\n\t\t\tport,\n\t\t\turl,\n\t\t};\n\t}\n\n\tasync nodeLoginSession(\n\t\targs: PrismicAuthManagerNodeLoginSessionArgs,\n\t): Promise<void> {\n\t\treturn new Promise<void>(async (resolve) => {\n\t\t\t// Timeout attempt after 3 minutes\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tserver.close();\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Login timeout, server did not receive a response within a 3-minute delay\",\n\t\t\t\t);\n\t\t\t}, 180_000);\n\n\t\t\tconst app = h3.createApp();\n\t\t\tapp.use(h3.fromNodeMiddleware(cors()));\n\t\t\tapp.use(\n\t\t\t\th3.fromNodeMiddleware(\n\t\t\t\t\tcreatePrismicAuthManagerMiddleware({\n\t\t\t\t\t\tprismicAuthManager: this,\n\t\t\t\t\t\tonLoginCallback() {\n\t\t\t\t\t\t\t// Cleanup process and resolve\n\t\t\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\t\t\tserver.close();\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\t// Start server\n\t\t\tconst server = http.createServer(h3.toNodeListener(app));\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tserver.once(\"listening\", () => {\n\t\t\t\t\tresolve();\n\t\t\t\t});\n\t\t\t\tserver.listen(args.port, \"127.0.0.1\");\n\t\t\t});\n\n\t\t\tif (args.onListenCallback) {\n\t\t\t\targs.onListenCallback();\n\t\t\t}\n\t\t});\n\t}\n\n\tasync logout(): Promise<void> {\n\t\tconst authState = await this._readPersistedAuthState();\n\n\t\t// Remove all Prismic cookies, short ID, and Intercom hash\n\t\t// associated with the currently logged in user.\n\t\tauthState.cookies = {};\n\t\tauthState.shortId = undefined;\n\t\tauthState.intercomHash = undefined;\n\n\t\tawait this._writePersistedAuthState(authState);\n\t}\n\n\tasync checkIsLoggedIn(): Promise<boolean> {\n\t\tconst authState = await this._readPersistedAuthState();\n\n\t\tif (checkHasAuthenticationToken(authState)) {\n\t\t\tconst url = new URL(\"./validate\", API_ENDPOINTS.PrismicAuthentication);\n\t\t\turl.searchParams.set(\"token\", authState.cookies[AUTH_COOKIE_KEY]);\n\n\t\t\tlet res;\n\t\t\ttry {\n\t\t\t\tres = await fetch(url.toString(), {\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\t// Noop, we return if `res` is not defined.\n\t\t\t}\n\n\t\t\tif (!res || !res.ok) {\n\t\t\t\tawait this.logout();\n\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync getAuthenticationCookies(): Promise<\n\t\tPrismicAuthState[\"cookies\"] &\n\t\t\tRequired<\n\t\t\t\tPick<\n\t\t\t\t\tPrismicAuthState[\"cookies\"],\n\t\t\t\t\ttypeof AUTH_COOKIE_KEY | typeof SESSION_COOKIE_KEY\n\t\t\t\t>\n\t\t\t>\n\t> {\n\t\tconst isLoggedIn = await this.checkIsLoggedIn();\n\n\t\tif (isLoggedIn) {\n\t\t\tconst authState = await this._readPersistedAuthState();\n\n\t\t\tif (checkHasAuthenticationToken(authState)) {\n\t\t\t\treturn authState.cookies;\n\t\t\t}\n\t\t}\n\n\t\tthrow new UnauthenticatedError();\n\t}\n\n\tasync getAuthenticationToken(): Promise<string> {\n\t\tconst cookies = await this.getAuthenticationCookies();\n\n\t\treturn cookies[AUTH_COOKIE_KEY];\n\t}\n\n\tasync refreshAuthenticationToken(): Promise<void> {\n\t\tconst authState = await this._readPersistedAuthState();\n\n\t\tif (checkHasAuthenticationToken(authState)) {\n\t\t\tconst url = new URL(\n\t\t\t\t\"./refreshtoken\",\n\t\t\t\tAPI_ENDPOINTS.PrismicAuthentication,\n\t\t\t);\n\t\t\turl.searchParams.set(\"token\", authState.cookies[AUTH_COOKIE_KEY]);\n\n\t\t\tconst res = await fetch(url.toString(), {\n\t\t\t\theaders: {\n\t\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst text = await res.text();\n\n\t\t\tif (res.ok) {\n\t\t\t\tauthState.cookies[AUTH_COOKIE_KEY] = text;\n\n\t\t\t\tawait this._writePersistedAuthState(authState);\n\t\t\t} else {\n\t\t\t\tthrow new InternalError(\"Failed to refresh authentication token.\", {\n\t\t\t\t\tcause: text,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new UnauthenticatedError();\n\t\t}\n\t}\n\n\tasync getProfile(): Promise<PrismicUserProfile> {\n\t\tconst authenticationToken = await this.getAuthenticationToken();\n\n\t\treturn await this._getProfileForAuthenticationToken({\n\t\t\tauthenticationToken,\n\t\t});\n\t}\n\n\tprivate async _getProfileForAuthenticationToken(\n\t\targs: GetProfileForAuthenticationTokenArgs,\n\t): Promise<PrismicUserProfile> {\n\t\tconst url = new URL(\"./profile\", API_ENDPOINTS.PrismicUser);\n\t\tconst res = await fetch(url.toString(), {\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${args.authenticationToken}`,\n\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t},\n\t\t});\n\n\t\tif (res.ok) {\n\t\t\tconst json = await res.json();\n\t\t\tconst { value: profile, error } = decode(PrismicUserProfile, json);\n\n\t\t\tif (error) {\n\t\t\t\tthrow new UnexpectedDataError(\n\t\t\t\t\t\"Received invalid data from the Prismic user service.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn profile;\n\t\t} else {\n\t\t\tconst text = await res.text();\n\t\t\tthrow new InternalError(\n\t\t\t\t\"Failed to retrieve profile from the Prismic user service.\",\n\t\t\t\t{\n\t\t\t\t\tcause: text,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate async _readPersistedAuthState(): Promise<PrismicAuthState> {\n\t\tconst authStateFilePath = this._getPersistedAuthStateFilePath();\n\n\t\tlet authStateFileContents: string = JSON.stringify({});\n\t\tlet rawAuthState: Record<string, unknown> = {};\n\n\t\ttry {\n\t\t\tauthStateFileContents = await fs.readFile(authStateFilePath, \"utf8\");\n\t\t\trawAuthState = JSON.parse(authStateFileContents);\n\t\t} catch {\n\t\t\t// Write a default persisted state if it doesn't already exist.\n\n\t\t\trawAuthState = {\n\t\t\t\t...DEFAULT_PERSISTED_AUTH_STATE,\n\t\t\t\tcookies: serializeCookies(DEFAULT_PERSISTED_AUTH_STATE.cookies),\n\t\t\t};\n\t\t\tauthStateFileContents = JSON.stringify(rawAuthState, null, \"\\t\");\n\n\t\t\tawait fs.mkdir(path.dirname(authStateFilePath), { recursive: true });\n\t\t\tawait fs.writeFile(authStateFilePath, authStateFileContents);\n\t\t}\n\n\t\t// Decode cookies into a record for convenience.\n\t\tif (typeof rawAuthState.cookies === \"string\") {\n\t\t\trawAuthState.cookies = parseCookies(rawAuthState.cookies);\n\t\t}\n\n\t\tconst { value: authState, error } = decode(PrismicAuthState, rawAuthState);\n\n\t\tif (error) {\n\t\t\tthrow new UnexpectedDataError(\"Prismic authentication state is invalid.\");\n\t\t}\n\n\t\treturn authState;\n\t}\n\n\tprivate async _writePersistedAuthState(\n\t\tauthState: PrismicAuthState,\n\t): Promise<void> {\n\t\tconst authStateFilePath = this._getPersistedAuthStateFilePath();\n\n\t\tconst preparedAuthState = {\n\t\t\t...authState,\n\t\t\tcookies: serializeCookies(authState.cookies),\n\t\t};\n\n\t\ttry {\n\t\t\tawait fs.writeFile(\n\t\t\t\tauthStateFilePath,\n\t\t\t\tJSON.stringify(preparedAuthState, null, 2),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthrow new InternalError(\n\t\t\t\t\"Failed to write Prismic authentication state to the file system.\",\n\t\t\t\t{\n\t\t\t\t\tcause: error,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate _getPersistedAuthStateFilePath(): string {\n\t\treturn path.resolve(this.scopedDirectory, PERSISTED_AUTH_STATE_FILE_NAME);\n\t}\n}\n"],"names":["getPort","resolve"],"mappings":"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"}
@@ -70,12 +70,16 @@ const fetchGitHubReleaseByVersion = async (args) => {
70
70
  const _fetchGitHubReleaseBodyForRelease = async (args) => {
71
71
  const cache = args.cache || {};
72
72
  if (Object.keys(cache).length < 1) {
73
- const releases = await fetchAllGitHubReleases({
74
- repositoryOwner: args.repositoryOwner,
75
- repositoryName: args.repositoryName
76
- });
77
- for (const release of releases) {
78
- cache[release.name] = release;
73
+ try {
74
+ const releases = await fetchAllGitHubReleases({
75
+ repositoryOwner: args.repositoryOwner,
76
+ repositoryName: args.repositoryName
77
+ });
78
+ for (const release of releases) {
79
+ cache[release.name] = release;
80
+ }
81
+ } catch (error) {
82
+ return void 0;
79
83
  }
80
84
  }
81
85
  if (args.version in cache) {
@@ -1 +1 @@
1
- {"version":3,"file":"fetchGitHubReleaseBodyForRelease.cjs","sources":["../../../src/lib/fetchGitHubReleaseBodyForRelease.ts"],"sourcesContent":["import * as t from \"io-ts\";\nimport fetch from \"./fetch\";\nimport pLimit from \"p-limit\";\n\nimport { decode } from \"./decode\";\n\nconst GITHUB_JSON_ACCEPT_HEADER = \"application/vnd.github+json\";\n\n/**\n * A minimally defined codec for GitHub release metadata.\n *\n * @see https://docs.github.com/en/rest/releases/releases#get-a-release-by-tag-name\n */\nconst GitHubReleaseMetadata = t.type({\n\tname: t.string,\n\tbody: t.union([t.null, t.string]),\n});\nexport type GitHubReleaseMetadata = t.TypeOf<typeof GitHubReleaseMetadata>;\n\ntype FetchAllGitHubReleasesArgs = {\n\trepositoryOwner: string;\n\trepositoryName: string;\n};\n\nconst fetchAllGitHubReleases = async (\n\targs: FetchAllGitHubReleasesArgs,\n): Promise<GitHubReleaseMetadata[]> => {\n\tconst res = await fetch(\n\t\t`https://api.github.com/repos/${args.repositoryOwner}/${args.repositoryName}/releases`,\n\t\t{\n\t\t\theaders: {\n\t\t\t\tAccept: GITHUB_JSON_ACCEPT_HEADER,\n\t\t\t},\n\t\t},\n\t);\n\n\tif (res.ok) {\n\t\tconst json = await res.json();\n\n\t\tconst { value, error } = decode(t.array(GitHubReleaseMetadata), json);\n\n\t\tif (error) {\n\t\t\tthrow new Error(`Invalid GitHub Release response.`, { cause: error });\n\t\t}\n\n\t\treturn value;\n\t} else {\n\t\tconst text = await res.text();\n\t\tthrow new Error(`Invalid GitHub Release response.`, {\n\t\t\tcause: text,\n\t\t});\n\t}\n};\n\ntype FetchGitHubReleaseByVersionArgs = {\n\trepositoryOwner: string;\n\trepositoryName: string;\n\tpackageName?: string;\n\tversion: string;\n};\n\nconst fetchGitHubReleaseByVersion = async (\n\targs: FetchGitHubReleaseByVersionArgs,\n): Promise<GitHubReleaseMetadata | undefined> => {\n\tlet url: string;\n\n\tif (args.packageName) {\n\t\turl = `https://api.github.com/repos/${args.repositoryOwner}/${args.repositoryName}/releases/tags/${args.packageName}@${args.version}`;\n\t} else {\n\t\turl = `https://api.github.com/repos/${args.repositoryOwner}/${args.repositoryName}/releases/tags/${args.version}`;\n\t}\n\n\tconst res = await fetch(url, {\n\t\theaders: {\n\t\t\tAccept: GITHUB_JSON_ACCEPT_HEADER,\n\t\t},\n\t});\n\n\tif (res.ok) {\n\t\tconst json = await res.json();\n\n\t\tconst { value, error } = decode(GitHubReleaseMetadata, json);\n\n\t\tif (error) {\n\t\t\tthrow new Error(`Invalid GitHub Release response.`, { cause: error });\n\t\t}\n\n\t\treturn value;\n\t}\n};\n\ntype FetchGitHubReleaseBodyForReleaseArgs = {\n\trepositoryOwner: string;\n\trepositoryName: string;\n\tpackageName?: string;\n\tversion: string;\n\tcache?: Record<string, GitHubReleaseMetadata | undefined>;\n};\n\nconst _fetchGitHubReleaseBodyForRelease = async (\n\targs: FetchGitHubReleaseBodyForReleaseArgs,\n): Promise<string | undefined> => {\n\tconst cache = args.cache || {};\n\n\tif (Object.keys(cache).length < 1) {\n\t\tconst releases = await fetchAllGitHubReleases({\n\t\t\trepositoryOwner: args.repositoryOwner,\n\t\t\trepositoryName: args.repositoryName,\n\t\t});\n\n\t\tfor (const release of releases) {\n\t\t\tcache[release.name] = release;\n\t\t}\n\t}\n\n\tif (args.version in cache) {\n\t\tconst release = cache[args.version];\n\n\t\treturn release?.body ?? undefined;\n\t} else {\n\t\ttry {\n\t\t\tconst version = await fetchGitHubReleaseByVersion({\n\t\t\t\trepositoryOwner: args.repositoryOwner,\n\t\t\t\trepositoryName: args.repositoryName,\n\t\t\t\tpackageName: args.packageName,\n\t\t\t\tversion: args.version,\n\t\t\t});\n\n\t\t\tcache[args.version] = version;\n\n\t\t\treturn version?.body ?? undefined;\n\t\t} catch {\n\t\t\tcache[args.version] = undefined;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n};\n\nconst limit = pLimit(1);\n\nexport const fetchGitHubReleaseBodyForRelease = async (\n\t...args: Parameters<typeof _fetchGitHubReleaseBodyForRelease>\n): ReturnType<typeof _fetchGitHubReleaseBodyForRelease> => {\n\treturn await limit(() => _fetchGitHubReleaseBodyForRelease(...args));\n};\n"],"names":["t","fetch","decode","pLimit"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAMA,MAAM,4BAA4B;AAOlC,MAAM,wBAAwBA,aAAE,KAAK;AAAA,EACpC,MAAMA,aAAE;AAAA,EACR,MAAMA,aAAE,MAAM,CAACA,aAAE,MAAMA,aAAE,MAAM,CAAC;AAChC,CAAA;AAQD,MAAM,yBAAyB,OAC9B,SACqC;AAC/B,QAAA,MAAM,MAAMC,cACjB,gCAAgC,KAAK,eAAe,IAAI,KAAK,cAAc,aAC3E;AAAA,IACC,SAAS;AAAA,MACR,QAAQ;AAAA,IACR;AAAA,EAAA,CACD;AAGF,MAAI,IAAI,IAAI;AACL,UAAA,OAAO,MAAM,IAAI;AAEjB,UAAA,EAAE,OAAO,MAAK,IAAKC,cAAOF,aAAE,MAAM,qBAAqB,GAAG,IAAI;AAEpE,QAAI,OAAO;AACV,YAAM,IAAI,MAAM,oCAAoC,EAAE,OAAO,OAAO;AAAA,IACrE;AAEO,WAAA;AAAA,EAAA,OACD;AACA,UAAA,OAAO,MAAM,IAAI;AACjB,UAAA,IAAI,MAAM,oCAAoC;AAAA,MACnD,OAAO;AAAA,IAAA,CACP;AAAA,EACF;AACD;AASA,MAAM,8BAA8B,OACnC,SAC+C;AAC3C,MAAA;AAEJ,MAAI,KAAK,aAAa;AACf,UAAA,gCAAgC,KAAK,eAAe,IAAI,KAAK,cAAc,kBAAkB,KAAK,WAAW,IAAI,KAAK,OAAO;AAAA,EAAA,OAC7H;AACA,UAAA,gCAAgC,KAAK,eAAe,IAAI,KAAK,cAAc,kBAAkB,KAAK,OAAO;AAAA,EAChH;AAEM,QAAA,MAAM,MAAMC,MAAA,QAAM,KAAK;AAAA,IAC5B,SAAS;AAAA,MACR,QAAQ;AAAA,IACR;AAAA,EAAA,CACD;AAED,MAAI,IAAI,IAAI;AACL,UAAA,OAAO,MAAM,IAAI;AAEvB,UAAM,EAAE,OAAO,MAAA,IAAUC,OAAAA,OAAO,uBAAuB,IAAI;AAE3D,QAAI,OAAO;AACV,YAAM,IAAI,MAAM,oCAAoC,EAAE,OAAO,OAAO;AAAA,IACrE;AAEO,WAAA;AAAA,EACR;AACD;AAUA,MAAM,oCAAoC,OACzC,SACgC;AAC1B,QAAA,QAAQ,KAAK,SAAS;AAE5B,MAAI,OAAO,KAAK,KAAK,EAAE,SAAS,GAAG;AAC5B,UAAA,WAAW,MAAM,uBAAuB;AAAA,MAC7C,iBAAiB,KAAK;AAAA,MACtB,gBAAgB,KAAK;AAAA,IAAA,CACrB;AAED,eAAW,WAAW,UAAU;AACzB,YAAA,QAAQ,IAAI,IAAI;AAAA,IACvB;AAAA,EACD;AAEI,MAAA,KAAK,WAAW,OAAO;AACpB,UAAA,UAAU,MAAM,KAAK,OAAO;AAElC,YAAO,mCAAS,SAAQ;AAAA,EAAA,OAClB;AACF,QAAA;AACG,YAAA,UAAU,MAAM,4BAA4B;AAAA,QACjD,iBAAiB,KAAK;AAAA,QACtB,gBAAgB,KAAK;AAAA,QACrB,aAAa,KAAK;AAAA,QAClB,SAAS,KAAK;AAAA,MAAA,CACd;AAEK,YAAA,KAAK,OAAO,IAAI;AAEtB,cAAO,mCAAS,SAAQ;AAAA,IAAA,QACjB;AACD,YAAA,KAAK,OAAO,IAAI;AAEf,aAAA;AAAA,IACR;AAAA,EACD;AACD;AAEA,MAAM,QAAQC,MAAO,CAAC;AAET,MAAA,mCAAmC,UAC5C,SACsD;AACzD,SAAO,MAAM,MAAM,MAAM,kCAAkC,GAAG,IAAI,CAAC;AACpE;;"}
1
+ {"version":3,"file":"fetchGitHubReleaseBodyForRelease.cjs","sources":["../../../src/lib/fetchGitHubReleaseBodyForRelease.ts"],"sourcesContent":["import * as t from \"io-ts\";\nimport fetch from \"./fetch\";\nimport pLimit from \"p-limit\";\n\nimport { decode } from \"./decode\";\n\nconst GITHUB_JSON_ACCEPT_HEADER = \"application/vnd.github+json\";\n\n/**\n * A minimally defined codec for GitHub release metadata.\n *\n * @see https://docs.github.com/en/rest/releases/releases#get-a-release-by-tag-name\n */\nconst GitHubReleaseMetadata = t.type({\n\tname: t.string,\n\tbody: t.union([t.null, t.string]),\n});\nexport type GitHubReleaseMetadata = t.TypeOf<typeof GitHubReleaseMetadata>;\n\ntype FetchAllGitHubReleasesArgs = {\n\trepositoryOwner: string;\n\trepositoryName: string;\n};\n\nconst fetchAllGitHubReleases = async (\n\targs: FetchAllGitHubReleasesArgs,\n): Promise<GitHubReleaseMetadata[]> => {\n\tconst res = await fetch(\n\t\t`https://api.github.com/repos/${args.repositoryOwner}/${args.repositoryName}/releases`,\n\t\t{\n\t\t\theaders: {\n\t\t\t\tAccept: GITHUB_JSON_ACCEPT_HEADER,\n\t\t\t},\n\t\t},\n\t);\n\n\tif (res.ok) {\n\t\tconst json = await res.json();\n\n\t\tconst { value, error } = decode(t.array(GitHubReleaseMetadata), json);\n\n\t\tif (error) {\n\t\t\tthrow new Error(`Invalid GitHub Release response.`, { cause: error });\n\t\t}\n\n\t\treturn value;\n\t} else {\n\t\tconst text = await res.text();\n\t\tthrow new Error(`Invalid GitHub Release response.`, {\n\t\t\tcause: text,\n\t\t});\n\t}\n};\n\ntype FetchGitHubReleaseByVersionArgs = {\n\trepositoryOwner: string;\n\trepositoryName: string;\n\tpackageName?: string;\n\tversion: string;\n};\n\nconst fetchGitHubReleaseByVersion = async (\n\targs: FetchGitHubReleaseByVersionArgs,\n): Promise<GitHubReleaseMetadata | undefined> => {\n\tlet url: string;\n\n\tif (args.packageName) {\n\t\turl = `https://api.github.com/repos/${args.repositoryOwner}/${args.repositoryName}/releases/tags/${args.packageName}@${args.version}`;\n\t} else {\n\t\turl = `https://api.github.com/repos/${args.repositoryOwner}/${args.repositoryName}/releases/tags/${args.version}`;\n\t}\n\n\tconst res = await fetch(url, {\n\t\theaders: {\n\t\t\tAccept: GITHUB_JSON_ACCEPT_HEADER,\n\t\t},\n\t});\n\n\tif (res.ok) {\n\t\tconst json = await res.json();\n\n\t\tconst { value, error } = decode(GitHubReleaseMetadata, json);\n\n\t\tif (error) {\n\t\t\tthrow new Error(`Invalid GitHub Release response.`, { cause: error });\n\t\t}\n\n\t\treturn value;\n\t}\n};\n\ntype FetchGitHubReleaseBodyForReleaseArgs = {\n\trepositoryOwner: string;\n\trepositoryName: string;\n\tpackageName?: string;\n\tversion: string;\n\tcache?: Record<string, GitHubReleaseMetadata | undefined>;\n};\n\nconst _fetchGitHubReleaseBodyForRelease = async (\n\targs: FetchGitHubReleaseBodyForReleaseArgs,\n): Promise<string | undefined> => {\n\tconst cache = args.cache || {};\n\n\tif (Object.keys(cache).length < 1) {\n\t\ttry {\n\t\t\tconst releases = await fetchAllGitHubReleases({\n\t\t\t\trepositoryOwner: args.repositoryOwner,\n\t\t\t\trepositoryName: args.repositoryName,\n\t\t\t});\n\n\t\t\tfor (const release of releases) {\n\t\t\t\tcache[release.name] = release;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// noop - Fetch all releases failed, no need to track this error in Sentry.\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tif (args.version in cache) {\n\t\tconst release = cache[args.version];\n\n\t\treturn release?.body ?? undefined;\n\t} else {\n\t\ttry {\n\t\t\tconst version = await fetchGitHubReleaseByVersion({\n\t\t\t\trepositoryOwner: args.repositoryOwner,\n\t\t\t\trepositoryName: args.repositoryName,\n\t\t\t\tpackageName: args.packageName,\n\t\t\t\tversion: args.version,\n\t\t\t});\n\n\t\t\tcache[args.version] = version;\n\n\t\t\treturn version?.body ?? undefined;\n\t\t} catch {\n\t\t\tcache[args.version] = undefined;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n};\n\nconst limit = pLimit(1);\n\nexport const fetchGitHubReleaseBodyForRelease = async (\n\t...args: Parameters<typeof _fetchGitHubReleaseBodyForRelease>\n): ReturnType<typeof _fetchGitHubReleaseBodyForRelease> => {\n\treturn await limit(() => _fetchGitHubReleaseBodyForRelease(...args));\n};\n"],"names":["t","fetch","decode","pLimit"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAMA,MAAM,4BAA4B;AAOlC,MAAM,wBAAwBA,aAAE,KAAK;AAAA,EACpC,MAAMA,aAAE;AAAA,EACR,MAAMA,aAAE,MAAM,CAACA,aAAE,MAAMA,aAAE,MAAM,CAAC;AAChC,CAAA;AAQD,MAAM,yBAAyB,OAC9B,SACqC;AAC/B,QAAA,MAAM,MAAMC,cACjB,gCAAgC,KAAK,eAAe,IAAI,KAAK,cAAc,aAC3E;AAAA,IACC,SAAS;AAAA,MACR,QAAQ;AAAA,IACR;AAAA,EAAA,CACD;AAGF,MAAI,IAAI,IAAI;AACL,UAAA,OAAO,MAAM,IAAI;AAEjB,UAAA,EAAE,OAAO,MAAK,IAAKC,cAAOF,aAAE,MAAM,qBAAqB,GAAG,IAAI;AAEpE,QAAI,OAAO;AACV,YAAM,IAAI,MAAM,oCAAoC,EAAE,OAAO,OAAO;AAAA,IACrE;AAEO,WAAA;AAAA,EAAA,OACD;AACA,UAAA,OAAO,MAAM,IAAI;AACjB,UAAA,IAAI,MAAM,oCAAoC;AAAA,MACnD,OAAO;AAAA,IAAA,CACP;AAAA,EACF;AACD;AASA,MAAM,8BAA8B,OACnC,SAC+C;AAC3C,MAAA;AAEJ,MAAI,KAAK,aAAa;AACf,UAAA,gCAAgC,KAAK,eAAe,IAAI,KAAK,cAAc,kBAAkB,KAAK,WAAW,IAAI,KAAK,OAAO;AAAA,EAAA,OAC7H;AACA,UAAA,gCAAgC,KAAK,eAAe,IAAI,KAAK,cAAc,kBAAkB,KAAK,OAAO;AAAA,EAChH;AAEM,QAAA,MAAM,MAAMC,MAAA,QAAM,KAAK;AAAA,IAC5B,SAAS;AAAA,MACR,QAAQ;AAAA,IACR;AAAA,EAAA,CACD;AAED,MAAI,IAAI,IAAI;AACL,UAAA,OAAO,MAAM,IAAI;AAEvB,UAAM,EAAE,OAAO,MAAA,IAAUC,OAAAA,OAAO,uBAAuB,IAAI;AAE3D,QAAI,OAAO;AACV,YAAM,IAAI,MAAM,oCAAoC,EAAE,OAAO,OAAO;AAAA,IACrE;AAEO,WAAA;AAAA,EACR;AACD;AAUA,MAAM,oCAAoC,OACzC,SACgC;AAC1B,QAAA,QAAQ,KAAK,SAAS;AAE5B,MAAI,OAAO,KAAK,KAAK,EAAE,SAAS,GAAG;AAC9B,QAAA;AACG,YAAA,WAAW,MAAM,uBAAuB;AAAA,QAC7C,iBAAiB,KAAK;AAAA,QACtB,gBAAgB,KAAK;AAAA,MAAA,CACrB;AAED,iBAAW,WAAW,UAAU;AACzB,cAAA,QAAQ,IAAI,IAAI;AAAA,MACvB;AAAA,aACQ,OAAO;AAER,aAAA;AAAA,IACR;AAAA,EACD;AAEI,MAAA,KAAK,WAAW,OAAO;AACpB,UAAA,UAAU,MAAM,KAAK,OAAO;AAElC,YAAO,mCAAS,SAAQ;AAAA,EAAA,OAClB;AACF,QAAA;AACG,YAAA,UAAU,MAAM,4BAA4B;AAAA,QACjD,iBAAiB,KAAK;AAAA,QACtB,gBAAgB,KAAK;AAAA,QACrB,aAAa,KAAK;AAAA,QAClB,SAAS,KAAK;AAAA,MAAA,CACd;AAEK,YAAA,KAAK,OAAO,IAAI;AAEtB,cAAO,mCAAS,SAAQ;AAAA,IAAA,QACjB;AACD,YAAA,KAAK,OAAO,IAAI;AAEf,aAAA;AAAA,IACR;AAAA,EACD;AACD;AAEA,MAAM,QAAQC,MAAO,CAAC;AAET,MAAA,mCAAmC,UAC5C,SACsD;AACzD,SAAO,MAAM,MAAM,MAAM,kCAAkC,GAAG,IAAI,CAAC;AACpE;;"}
@@ -51,12 +51,16 @@ const fetchGitHubReleaseByVersion = async (args) => {
51
51
  const _fetchGitHubReleaseBodyForRelease = async (args) => {
52
52
  const cache = args.cache || {};
53
53
  if (Object.keys(cache).length < 1) {
54
- const releases = await fetchAllGitHubReleases({
55
- repositoryOwner: args.repositoryOwner,
56
- repositoryName: args.repositoryName
57
- });
58
- for (const release of releases) {
59
- cache[release.name] = release;
54
+ try {
55
+ const releases = await fetchAllGitHubReleases({
56
+ repositoryOwner: args.repositoryOwner,
57
+ repositoryName: args.repositoryName
58
+ });
59
+ for (const release of releases) {
60
+ cache[release.name] = release;
61
+ }
62
+ } catch (error) {
63
+ return void 0;
60
64
  }
61
65
  }
62
66
  if (args.version in cache) {
@@ -1 +1 @@
1
- {"version":3,"file":"fetchGitHubReleaseBodyForRelease.js","sources":["../../../src/lib/fetchGitHubReleaseBodyForRelease.ts"],"sourcesContent":["import * as t from \"io-ts\";\nimport fetch from \"./fetch\";\nimport pLimit from \"p-limit\";\n\nimport { decode } from \"./decode\";\n\nconst GITHUB_JSON_ACCEPT_HEADER = \"application/vnd.github+json\";\n\n/**\n * A minimally defined codec for GitHub release metadata.\n *\n * @see https://docs.github.com/en/rest/releases/releases#get-a-release-by-tag-name\n */\nconst GitHubReleaseMetadata = t.type({\n\tname: t.string,\n\tbody: t.union([t.null, t.string]),\n});\nexport type GitHubReleaseMetadata = t.TypeOf<typeof GitHubReleaseMetadata>;\n\ntype FetchAllGitHubReleasesArgs = {\n\trepositoryOwner: string;\n\trepositoryName: string;\n};\n\nconst fetchAllGitHubReleases = async (\n\targs: FetchAllGitHubReleasesArgs,\n): Promise<GitHubReleaseMetadata[]> => {\n\tconst res = await fetch(\n\t\t`https://api.github.com/repos/${args.repositoryOwner}/${args.repositoryName}/releases`,\n\t\t{\n\t\t\theaders: {\n\t\t\t\tAccept: GITHUB_JSON_ACCEPT_HEADER,\n\t\t\t},\n\t\t},\n\t);\n\n\tif (res.ok) {\n\t\tconst json = await res.json();\n\n\t\tconst { value, error } = decode(t.array(GitHubReleaseMetadata), json);\n\n\t\tif (error) {\n\t\t\tthrow new Error(`Invalid GitHub Release response.`, { cause: error });\n\t\t}\n\n\t\treturn value;\n\t} else {\n\t\tconst text = await res.text();\n\t\tthrow new Error(`Invalid GitHub Release response.`, {\n\t\t\tcause: text,\n\t\t});\n\t}\n};\n\ntype FetchGitHubReleaseByVersionArgs = {\n\trepositoryOwner: string;\n\trepositoryName: string;\n\tpackageName?: string;\n\tversion: string;\n};\n\nconst fetchGitHubReleaseByVersion = async (\n\targs: FetchGitHubReleaseByVersionArgs,\n): Promise<GitHubReleaseMetadata | undefined> => {\n\tlet url: string;\n\n\tif (args.packageName) {\n\t\turl = `https://api.github.com/repos/${args.repositoryOwner}/${args.repositoryName}/releases/tags/${args.packageName}@${args.version}`;\n\t} else {\n\t\turl = `https://api.github.com/repos/${args.repositoryOwner}/${args.repositoryName}/releases/tags/${args.version}`;\n\t}\n\n\tconst res = await fetch(url, {\n\t\theaders: {\n\t\t\tAccept: GITHUB_JSON_ACCEPT_HEADER,\n\t\t},\n\t});\n\n\tif (res.ok) {\n\t\tconst json = await res.json();\n\n\t\tconst { value, error } = decode(GitHubReleaseMetadata, json);\n\n\t\tif (error) {\n\t\t\tthrow new Error(`Invalid GitHub Release response.`, { cause: error });\n\t\t}\n\n\t\treturn value;\n\t}\n};\n\ntype FetchGitHubReleaseBodyForReleaseArgs = {\n\trepositoryOwner: string;\n\trepositoryName: string;\n\tpackageName?: string;\n\tversion: string;\n\tcache?: Record<string, GitHubReleaseMetadata | undefined>;\n};\n\nconst _fetchGitHubReleaseBodyForRelease = async (\n\targs: FetchGitHubReleaseBodyForReleaseArgs,\n): Promise<string | undefined> => {\n\tconst cache = args.cache || {};\n\n\tif (Object.keys(cache).length < 1) {\n\t\tconst releases = await fetchAllGitHubReleases({\n\t\t\trepositoryOwner: args.repositoryOwner,\n\t\t\trepositoryName: args.repositoryName,\n\t\t});\n\n\t\tfor (const release of releases) {\n\t\t\tcache[release.name] = release;\n\t\t}\n\t}\n\n\tif (args.version in cache) {\n\t\tconst release = cache[args.version];\n\n\t\treturn release?.body ?? undefined;\n\t} else {\n\t\ttry {\n\t\t\tconst version = await fetchGitHubReleaseByVersion({\n\t\t\t\trepositoryOwner: args.repositoryOwner,\n\t\t\t\trepositoryName: args.repositoryName,\n\t\t\t\tpackageName: args.packageName,\n\t\t\t\tversion: args.version,\n\t\t\t});\n\n\t\t\tcache[args.version] = version;\n\n\t\t\treturn version?.body ?? undefined;\n\t\t} catch {\n\t\t\tcache[args.version] = undefined;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n};\n\nconst limit = pLimit(1);\n\nexport const fetchGitHubReleaseBodyForRelease = async (\n\t...args: Parameters<typeof _fetchGitHubReleaseBodyForRelease>\n): ReturnType<typeof _fetchGitHubReleaseBodyForRelease> => {\n\treturn await limit(() => _fetchGitHubReleaseBodyForRelease(...args));\n};\n"],"names":[],"mappings":";;;;AAMA,MAAM,4BAA4B;AAOlC,MAAM,wBAAwB,EAAE,KAAK;AAAA,EACpC,MAAM,EAAE;AAAA,EACR,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC;AAChC,CAAA;AAQD,MAAM,yBAAyB,OAC9B,SACqC;AAC/B,QAAA,MAAM,MAAM,MACjB,gCAAgC,KAAK,eAAe,IAAI,KAAK,cAAc,aAC3E;AAAA,IACC,SAAS;AAAA,MACR,QAAQ;AAAA,IACR;AAAA,EAAA,CACD;AAGF,MAAI,IAAI,IAAI;AACL,UAAA,OAAO,MAAM,IAAI;AAEjB,UAAA,EAAE,OAAO,MAAK,IAAK,OAAO,EAAE,MAAM,qBAAqB,GAAG,IAAI;AAEpE,QAAI,OAAO;AACV,YAAM,IAAI,MAAM,oCAAoC,EAAE,OAAO,OAAO;AAAA,IACrE;AAEO,WAAA;AAAA,EAAA,OACD;AACA,UAAA,OAAO,MAAM,IAAI;AACjB,UAAA,IAAI,MAAM,oCAAoC;AAAA,MACnD,OAAO;AAAA,IAAA,CACP;AAAA,EACF;AACD;AASA,MAAM,8BAA8B,OACnC,SAC+C;AAC3C,MAAA;AAEJ,MAAI,KAAK,aAAa;AACf,UAAA,gCAAgC,KAAK,eAAe,IAAI,KAAK,cAAc,kBAAkB,KAAK,WAAW,IAAI,KAAK,OAAO;AAAA,EAAA,OAC7H;AACA,UAAA,gCAAgC,KAAK,eAAe,IAAI,KAAK,cAAc,kBAAkB,KAAK,OAAO;AAAA,EAChH;AAEM,QAAA,MAAM,MAAM,MAAM,KAAK;AAAA,IAC5B,SAAS;AAAA,MACR,QAAQ;AAAA,IACR;AAAA,EAAA,CACD;AAED,MAAI,IAAI,IAAI;AACL,UAAA,OAAO,MAAM,IAAI;AAEvB,UAAM,EAAE,OAAO,MAAA,IAAU,OAAO,uBAAuB,IAAI;AAE3D,QAAI,OAAO;AACV,YAAM,IAAI,MAAM,oCAAoC,EAAE,OAAO,OAAO;AAAA,IACrE;AAEO,WAAA;AAAA,EACR;AACD;AAUA,MAAM,oCAAoC,OACzC,SACgC;AAC1B,QAAA,QAAQ,KAAK,SAAS;AAE5B,MAAI,OAAO,KAAK,KAAK,EAAE,SAAS,GAAG;AAC5B,UAAA,WAAW,MAAM,uBAAuB;AAAA,MAC7C,iBAAiB,KAAK;AAAA,MACtB,gBAAgB,KAAK;AAAA,IAAA,CACrB;AAED,eAAW,WAAW,UAAU;AACzB,YAAA,QAAQ,IAAI,IAAI;AAAA,IACvB;AAAA,EACD;AAEI,MAAA,KAAK,WAAW,OAAO;AACpB,UAAA,UAAU,MAAM,KAAK,OAAO;AAElC,YAAO,mCAAS,SAAQ;AAAA,EAAA,OAClB;AACF,QAAA;AACG,YAAA,UAAU,MAAM,4BAA4B;AAAA,QACjD,iBAAiB,KAAK;AAAA,QACtB,gBAAgB,KAAK;AAAA,QACrB,aAAa,KAAK;AAAA,QAClB,SAAS,KAAK;AAAA,MAAA,CACd;AAEK,YAAA,KAAK,OAAO,IAAI;AAEtB,cAAO,mCAAS,SAAQ;AAAA,IAAA,QACjB;AACD,YAAA,KAAK,OAAO,IAAI;AAEf,aAAA;AAAA,IACR;AAAA,EACD;AACD;AAEA,MAAM,QAAQ,OAAO,CAAC;AAET,MAAA,mCAAmC,UAC5C,SACsD;AACzD,SAAO,MAAM,MAAM,MAAM,kCAAkC,GAAG,IAAI,CAAC;AACpE;"}
1
+ {"version":3,"file":"fetchGitHubReleaseBodyForRelease.js","sources":["../../../src/lib/fetchGitHubReleaseBodyForRelease.ts"],"sourcesContent":["import * as t from \"io-ts\";\nimport fetch from \"./fetch\";\nimport pLimit from \"p-limit\";\n\nimport { decode } from \"./decode\";\n\nconst GITHUB_JSON_ACCEPT_HEADER = \"application/vnd.github+json\";\n\n/**\n * A minimally defined codec for GitHub release metadata.\n *\n * @see https://docs.github.com/en/rest/releases/releases#get-a-release-by-tag-name\n */\nconst GitHubReleaseMetadata = t.type({\n\tname: t.string,\n\tbody: t.union([t.null, t.string]),\n});\nexport type GitHubReleaseMetadata = t.TypeOf<typeof GitHubReleaseMetadata>;\n\ntype FetchAllGitHubReleasesArgs = {\n\trepositoryOwner: string;\n\trepositoryName: string;\n};\n\nconst fetchAllGitHubReleases = async (\n\targs: FetchAllGitHubReleasesArgs,\n): Promise<GitHubReleaseMetadata[]> => {\n\tconst res = await fetch(\n\t\t`https://api.github.com/repos/${args.repositoryOwner}/${args.repositoryName}/releases`,\n\t\t{\n\t\t\theaders: {\n\t\t\t\tAccept: GITHUB_JSON_ACCEPT_HEADER,\n\t\t\t},\n\t\t},\n\t);\n\n\tif (res.ok) {\n\t\tconst json = await res.json();\n\n\t\tconst { value, error } = decode(t.array(GitHubReleaseMetadata), json);\n\n\t\tif (error) {\n\t\t\tthrow new Error(`Invalid GitHub Release response.`, { cause: error });\n\t\t}\n\n\t\treturn value;\n\t} else {\n\t\tconst text = await res.text();\n\t\tthrow new Error(`Invalid GitHub Release response.`, {\n\t\t\tcause: text,\n\t\t});\n\t}\n};\n\ntype FetchGitHubReleaseByVersionArgs = {\n\trepositoryOwner: string;\n\trepositoryName: string;\n\tpackageName?: string;\n\tversion: string;\n};\n\nconst fetchGitHubReleaseByVersion = async (\n\targs: FetchGitHubReleaseByVersionArgs,\n): Promise<GitHubReleaseMetadata | undefined> => {\n\tlet url: string;\n\n\tif (args.packageName) {\n\t\turl = `https://api.github.com/repos/${args.repositoryOwner}/${args.repositoryName}/releases/tags/${args.packageName}@${args.version}`;\n\t} else {\n\t\turl = `https://api.github.com/repos/${args.repositoryOwner}/${args.repositoryName}/releases/tags/${args.version}`;\n\t}\n\n\tconst res = await fetch(url, {\n\t\theaders: {\n\t\t\tAccept: GITHUB_JSON_ACCEPT_HEADER,\n\t\t},\n\t});\n\n\tif (res.ok) {\n\t\tconst json = await res.json();\n\n\t\tconst { value, error } = decode(GitHubReleaseMetadata, json);\n\n\t\tif (error) {\n\t\t\tthrow new Error(`Invalid GitHub Release response.`, { cause: error });\n\t\t}\n\n\t\treturn value;\n\t}\n};\n\ntype FetchGitHubReleaseBodyForReleaseArgs = {\n\trepositoryOwner: string;\n\trepositoryName: string;\n\tpackageName?: string;\n\tversion: string;\n\tcache?: Record<string, GitHubReleaseMetadata | undefined>;\n};\n\nconst _fetchGitHubReleaseBodyForRelease = async (\n\targs: FetchGitHubReleaseBodyForReleaseArgs,\n): Promise<string | undefined> => {\n\tconst cache = args.cache || {};\n\n\tif (Object.keys(cache).length < 1) {\n\t\ttry {\n\t\t\tconst releases = await fetchAllGitHubReleases({\n\t\t\t\trepositoryOwner: args.repositoryOwner,\n\t\t\t\trepositoryName: args.repositoryName,\n\t\t\t});\n\n\t\t\tfor (const release of releases) {\n\t\t\t\tcache[release.name] = release;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// noop - Fetch all releases failed, no need to track this error in Sentry.\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tif (args.version in cache) {\n\t\tconst release = cache[args.version];\n\n\t\treturn release?.body ?? undefined;\n\t} else {\n\t\ttry {\n\t\t\tconst version = await fetchGitHubReleaseByVersion({\n\t\t\t\trepositoryOwner: args.repositoryOwner,\n\t\t\t\trepositoryName: args.repositoryName,\n\t\t\t\tpackageName: args.packageName,\n\t\t\t\tversion: args.version,\n\t\t\t});\n\n\t\t\tcache[args.version] = version;\n\n\t\t\treturn version?.body ?? undefined;\n\t\t} catch {\n\t\t\tcache[args.version] = undefined;\n\n\t\t\treturn undefined;\n\t\t}\n\t}\n};\n\nconst limit = pLimit(1);\n\nexport const fetchGitHubReleaseBodyForRelease = async (\n\t...args: Parameters<typeof _fetchGitHubReleaseBodyForRelease>\n): ReturnType<typeof _fetchGitHubReleaseBodyForRelease> => {\n\treturn await limit(() => _fetchGitHubReleaseBodyForRelease(...args));\n};\n"],"names":[],"mappings":";;;;AAMA,MAAM,4BAA4B;AAOlC,MAAM,wBAAwB,EAAE,KAAK;AAAA,EACpC,MAAM,EAAE;AAAA,EACR,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC;AAChC,CAAA;AAQD,MAAM,yBAAyB,OAC9B,SACqC;AAC/B,QAAA,MAAM,MAAM,MACjB,gCAAgC,KAAK,eAAe,IAAI,KAAK,cAAc,aAC3E;AAAA,IACC,SAAS;AAAA,MACR,QAAQ;AAAA,IACR;AAAA,EAAA,CACD;AAGF,MAAI,IAAI,IAAI;AACL,UAAA,OAAO,MAAM,IAAI;AAEjB,UAAA,EAAE,OAAO,MAAK,IAAK,OAAO,EAAE,MAAM,qBAAqB,GAAG,IAAI;AAEpE,QAAI,OAAO;AACV,YAAM,IAAI,MAAM,oCAAoC,EAAE,OAAO,OAAO;AAAA,IACrE;AAEO,WAAA;AAAA,EAAA,OACD;AACA,UAAA,OAAO,MAAM,IAAI;AACjB,UAAA,IAAI,MAAM,oCAAoC;AAAA,MACnD,OAAO;AAAA,IAAA,CACP;AAAA,EACF;AACD;AASA,MAAM,8BAA8B,OACnC,SAC+C;AAC3C,MAAA;AAEJ,MAAI,KAAK,aAAa;AACf,UAAA,gCAAgC,KAAK,eAAe,IAAI,KAAK,cAAc,kBAAkB,KAAK,WAAW,IAAI,KAAK,OAAO;AAAA,EAAA,OAC7H;AACA,UAAA,gCAAgC,KAAK,eAAe,IAAI,KAAK,cAAc,kBAAkB,KAAK,OAAO;AAAA,EAChH;AAEM,QAAA,MAAM,MAAM,MAAM,KAAK;AAAA,IAC5B,SAAS;AAAA,MACR,QAAQ;AAAA,IACR;AAAA,EAAA,CACD;AAED,MAAI,IAAI,IAAI;AACL,UAAA,OAAO,MAAM,IAAI;AAEvB,UAAM,EAAE,OAAO,MAAA,IAAU,OAAO,uBAAuB,IAAI;AAE3D,QAAI,OAAO;AACV,YAAM,IAAI,MAAM,oCAAoC,EAAE,OAAO,OAAO;AAAA,IACrE;AAEO,WAAA;AAAA,EACR;AACD;AAUA,MAAM,oCAAoC,OACzC,SACgC;AAC1B,QAAA,QAAQ,KAAK,SAAS;AAE5B,MAAI,OAAO,KAAK,KAAK,EAAE,SAAS,GAAG;AAC9B,QAAA;AACG,YAAA,WAAW,MAAM,uBAAuB;AAAA,QAC7C,iBAAiB,KAAK;AAAA,QACtB,gBAAgB,KAAK;AAAA,MAAA,CACrB;AAED,iBAAW,WAAW,UAAU;AACzB,cAAA,QAAQ,IAAI,IAAI;AAAA,MACvB;AAAA,aACQ,OAAO;AAER,aAAA;AAAA,IACR;AAAA,EACD;AAEI,MAAA,KAAK,WAAW,OAAO;AACpB,UAAA,UAAU,MAAM,KAAK,OAAO;AAElC,YAAO,mCAAS,SAAQ;AAAA,EAAA,OAClB;AACF,QAAA;AACG,YAAA,UAAU,MAAM,4BAA4B;AAAA,QACjD,iBAAiB,KAAK;AAAA,QACtB,gBAAgB,KAAK;AAAA,QACrB,aAAa,KAAK;AAAA,QAClB,SAAS,KAAK;AAAA,MAAA,CACd;AAEK,YAAA,KAAK,OAAO,IAAI;AAEtB,cAAO,mCAAS,SAAQ;AAAA,IAAA,QACjB;AACD,YAAA,KAAK,OAAO,IAAI;AAEf,aAAA;AAAA,IACR;AAAA,EACD;AACD;AAEA,MAAM,QAAQ,OAAO,CAAC;AAET,MAAA,mCAAmC,UAC5C,SACsD;AACzD,SAAO,MAAM,MAAM,MAAM,kCAAkC,GAAG,IAAI,CAAC;AACpE;"}
@@ -9,6 +9,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
9
9
  const prismicCustomTypesClient = require("@prismicio/custom-types-client");
10
10
  const createContentDigest = require("../lib/createContentDigest.cjs");
11
11
  const createPrismicAuthManager = require("../auth/createPrismicAuthManager.cjs");
12
+ const errors = require("../errors.cjs");
12
13
  const API_ENDPOINTS = require("../constants/API_ENDPOINTS.cjs");
13
14
  const UserManager = require("./user/UserManager.cjs");
14
15
  const PrismicRepositoryManager = require("./prismicRepository/PrismicRepositoryManager.cjs");
@@ -128,14 +129,14 @@ class SliceMachineManager {
128
129
  name: "__stub__",
129
130
  message: "__stub__",
130
131
  reason: "__stub__",
131
- status: 401
132
+ status: 403
132
133
  };
133
- } else if (error instanceof prismicCustomTypesClient__namespace.UnauthorizedError) {
134
+ } else if (error instanceof errors.UnauthenticatedError || error instanceof prismicCustomTypesClient__namespace.UnauthorizedError) {
134
135
  authError2 = {
135
136
  name: "__stub__",
136
137
  message: "__stub__",
137
138
  reason: "__stub__",
138
- status: 403
139
+ status: 401
139
140
  };
140
141
  } else {
141
142
  throw error;
@@ -1 +1 @@
1
- {"version":3,"file":"SliceMachineManager.cjs","sources":["../../../src/managers/SliceMachineManager.ts"],"sourcesContent":["import {\n\tSharedSlice,\n\tCustomType,\n} from \"@prismicio/types-internal/lib/customtypes\";\nimport { SharedSliceContent } from \"@prismicio/types-internal/lib/content\";\nimport * as prismicCustomTypesClient from \"@prismicio/custom-types-client\";\nimport {\n\tSliceMachinePlugin,\n\tSliceMachinePluginRunner,\n} from \"@slicemachine/plugin-kit\";\n\nimport { createContentDigest } from \"../lib/createContentDigest\";\n\nimport { PackageManager, SliceMachineConfig } from \"../types\";\nimport {\n\tPrismicAuthManager,\n\tPrismicUserProfile,\n} from \"../auth/PrismicAuthManager\";\nimport { createPrismicAuthManager } from \"../auth/createPrismicAuthManager\";\n\nimport { API_ENDPOINTS, APIEndpoints } from \"../constants/API_ENDPOINTS\";\n\nimport { UserManager } from \"./user/UserManager\";\nimport { PrismicRepositoryManager } from \"./prismicRepository/PrismicRepositoryManager\";\n\nimport { PluginsManager } from \"./plugins/PluginsManager\";\n\nimport { ProjectManager } from \"./project/ProjectManager\";\nimport { CustomTypesManager } from \"./customTypes/CustomTypesManager\";\nimport { SlicesManager } from \"./slices/SlicesManager\";\nimport { SnippetsManager } from \"./snippets/SnippetsManager\";\nimport { ScreenshotsManager } from \"./screenshots/ScreenshotsManager\";\nimport { SimulatorManager } from \"./simulator/SimulatorManager\";\n\nimport { VersionsManager } from \"./versions/VersionsManager\";\n\nimport { TelemetryManager } from \"./telemetry/TelemetryManager\";\nimport { buildPrismicRepositoryAPIEndpoint } from \"../lib/buildPrismicRepositoryAPIEndpoint\";\nimport { DocumentationManager } from \"./documentation/DocumentationManager\";\nimport { SliceTemplateLibraryManager } from \"./sliceTemplateLibrary/SliceTemplateLibraryManager\";\nimport { GitManager } from \"./git/GitManager\";\n\ntype SliceMachineManagerGetStateReturnType = {\n\tenv: {\n\t\tshortId?: string;\n\t\tintercomHash?: string;\n\t\tmanifest: {\n\t\t\tapiEndpoint: string;\n\t\t\tlocalSliceSimulatorURL?: string;\n\t\t};\n\t\trepo: string;\n\t\tpackageManager: PackageManager;\n\t\tendpoints: APIEndpoints;\n\t};\n\tlibraries: {\n\t\tname: string;\n\t\tpath: string;\n\t\tisLocal: boolean;\n\t\tcomponents: {\n\t\t\tfrom: string;\n\t\t\thref: string;\n\t\t\tpathToSlice: string;\n\t\t\tfileName: string | null;\n\t\t\textension: string | null;\n\t\t\tmodel: SharedSlice;\n\t\t\tscreenshots: Record<\n\t\t\t\tstring,\n\t\t\t\t{\n\t\t\t\t\thash: string;\n\t\t\t\t\tdata: Buffer;\n\t\t\t\t}\n\t\t\t>;\n\t\t\tmocks?: SharedSliceContent[];\n\t\t}[];\n\t\tmeta: {\n\t\t\tname?: string;\n\t\t\tversion?: string;\n\t\t\tisNodeModule: boolean;\n\t\t\tisDownloaded: boolean;\n\t\t\tisManual: boolean;\n\t\t};\n\t}[];\n\tcustomTypes: CustomType[];\n\tremoteCustomTypes: CustomType[];\n\tremoteSlices: SharedSlice[];\n\tclientError?: {\n\t\tname: string;\n\t\tmessage: string;\n\t\tstatus: number;\n\t\treason: string;\n\t};\n};\n\ntype SliceMachineManagerConstructorArgs = {\n\tcwd?: string;\n\tnativePlugins?: Record<string, SliceMachinePlugin>;\n};\n\nexport class SliceMachineManager {\n\tprivate _sliceMachinePluginRunner: SliceMachinePluginRunner | undefined =\n\t\tundefined;\n\tprivate _prismicAuthManager: PrismicAuthManager;\n\n\tcwd: string;\n\n\tcustomTypes: CustomTypesManager;\n\tplugins: PluginsManager;\n\tprismicRepository: PrismicRepositoryManager;\n\tproject: ProjectManager;\n\tscreenshots: ScreenshotsManager;\n\tsimulator: SimulatorManager;\n\tslices: SlicesManager;\n\tsnippets: SnippetsManager;\n\tdocumentation: DocumentationManager;\n\tsliceTemplateLibrary: SliceTemplateLibraryManager;\n\ttelemetry: TelemetryManager;\n\tuser: UserManager;\n\tversions: VersionsManager;\n\tgit: GitManager;\n\n\tconstructor(args?: SliceMachineManagerConstructorArgs) {\n\t\t// _prismicAuthManager must be set at least before UserManager\n\t\t// is instantiated. It depends on the PrismicAuthManager for\n\t\t// authentication-related methods.\n\t\tthis._prismicAuthManager = createPrismicAuthManager();\n\n\t\tthis.user = new UserManager(this);\n\t\tthis.prismicRepository = new PrismicRepositoryManager(this);\n\n\t\tthis.plugins = new PluginsManager(this, {\n\t\t\tnativePlugins: args?.nativePlugins,\n\t\t});\n\n\t\tthis.project = new ProjectManager(this);\n\t\tthis.customTypes = new CustomTypesManager(this);\n\t\tthis.slices = new SlicesManager(this);\n\t\tthis.snippets = new SnippetsManager(this);\n\t\tthis.screenshots = new ScreenshotsManager(this);\n\t\tthis.simulator = new SimulatorManager(this);\n\t\tthis.documentation = new DocumentationManager(this);\n\t\tthis.sliceTemplateLibrary = new SliceTemplateLibraryManager(this);\n\n\t\tthis.versions = new VersionsManager(this);\n\n\t\tthis.telemetry = new TelemetryManager(this);\n\n\t\tthis.git = new GitManager(this);\n\n\t\tthis.cwd = args?.cwd ?? process.cwd();\n\t}\n\n\t// The `_sliceMachinePluginRunner` property is hidden behind a function to\n\t// discourage access. Using a function deliberatly breaks the pattern\n\t// of other child managers that are accessible as properties, like\n\t// `project`, `plugins`, etc. We do not treat SliceMachinePluginRunner\n\t// as a child manager.\n\tgetSliceMachinePluginRunner(): SliceMachinePluginRunner | undefined {\n\t\treturn this._sliceMachinePluginRunner;\n\t}\n\n\t// The `_prismicAuthManager` property is hidden behind a function to\n\t// discourage access. Using a function deliberatly breaks the pattern\n\t// of other child managers that are accessible as properties, like\n\t// `project`, `plugins`, etc. We do not treat PrismicAuthManager as a\n\t// child manager.\n\tgetPrismicAuthManager(): PrismicAuthManager {\n\t\treturn this._prismicAuthManager;\n\t}\n\n\tgetAPIEndpoints(): APIEndpoints {\n\t\treturn API_ENDPOINTS;\n\t}\n\n\t// TODO: Remove this global-state method. It is expensive and a\n\t// potential source of bugs due to data inconsistency. SM UI relies on\n\t// it heavily, so removal will require significant effort.\n\tasync getState(): Promise<SliceMachineManagerGetStateReturnType> {\n\t\tconst [\n\t\t\t{ sliceMachineConfig, libraries },\n\t\t\t{ profile, remoteCustomTypes, remoteSlices, authError },\n\t\t\tcustomTypes,\n\t\t\tpackageManager,\n\t\t] = await Promise.all([\n\t\t\tthis.project.getSliceMachineConfig().then(async (sliceMachineConfig) => {\n\t\t\t\tconst libraries = await this._getLibraries(sliceMachineConfig);\n\n\t\t\t\treturn { sliceMachineConfig, libraries };\n\t\t\t}),\n\t\t\tthis._getProfile().then(async (profile) => {\n\t\t\t\tlet authError;\n\t\t\t\tif (profile) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst [remoteCustomTypes, remoteSlices] = await Promise.all([\n\t\t\t\t\t\t\tthis.customTypes.fetchRemoteCustomTypes(),\n\t\t\t\t\t\t\tthis.slices.fetchRemoteSlices(),\n\t\t\t\t\t\t]);\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tprofile,\n\t\t\t\t\t\t\tremoteCustomTypes,\n\t\t\t\t\t\t\tremoteSlices,\n\t\t\t\t\t\t\tauthError,\n\t\t\t\t\t\t};\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (error instanceof prismicCustomTypesClient.ForbiddenError) {\n\t\t\t\t\t\t\tauthError = {\n\t\t\t\t\t\t\t\tname: \"__stub__\",\n\t\t\t\t\t\t\t\tmessage: \"__stub__\",\n\t\t\t\t\t\t\t\treason: \"__stub__\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\terror instanceof prismicCustomTypesClient.UnauthorizedError\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tauthError = {\n\t\t\t\t\t\t\t\tname: \"__stub__\",\n\t\t\t\t\t\t\t\tmessage: \"__stub__\",\n\t\t\t\t\t\t\t\treason: \"__stub__\",\n\t\t\t\t\t\t\t\tstatus: 403,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tprofile,\n\t\t\t\t\tremoteCustomTypes: [],\n\t\t\t\t\tremoteSlices: [],\n\t\t\t\t\tauthError,\n\t\t\t\t};\n\t\t\t}),\n\t\t\tthis._getCustomTypes(),\n\t\t\tthis.project.detectPackageManager(),\n\t\t]);\n\n\t\t// SM UI detects if a user is logged out by looking at\n\t\t// `clientError`. Here, we simulate what the old core does by\n\t\t// returning an `ErrorWithStatus`-like object if the user does\n\t\t// not have access to the repository or is not logged in.\n\t\tconst clientError: SliceMachineManagerGetStateReturnType[\"clientError\"] =\n\t\t\tauthError ||\n\t\t\t(profile\n\t\t\t\t? undefined\n\t\t\t\t: {\n\t\t\t\t\t\tname: \"__stub__\",\n\t\t\t\t\t\tmessage: \"__stub__\",\n\t\t\t\t\t\treason: \"__stub__\",\n\t\t\t\t\t\tstatus: 401, // Needed to trigger the unauthorized flow.\n\t\t\t\t });\n\n\t\treturn {\n\t\t\tenv: {\n\t\t\t\tmanifest: {\n\t\t\t\t\tapiEndpoint:\n\t\t\t\t\t\tsliceMachineConfig.apiEndpoint ||\n\t\t\t\t\t\tbuildPrismicRepositoryAPIEndpoint(\n\t\t\t\t\t\t\tsliceMachineConfig.repositoryName,\n\t\t\t\t\t\t),\n\t\t\t\t\tlocalSliceSimulatorURL: sliceMachineConfig.localSliceSimulatorURL,\n\t\t\t\t},\n\t\t\t\tpackageManager,\n\t\t\t\trepo: sliceMachineConfig.repositoryName,\n\t\t\t\tintercomHash: profile?.intercomHash,\n\t\t\t\tshortId: profile?.shortId,\n\t\t\t\tendpoints: this.getAPIEndpoints(),\n\t\t\t},\n\t\t\tlibraries,\n\t\t\tcustomTypes,\n\t\t\tremoteCustomTypes,\n\t\t\tremoteSlices,\n\t\t\tclientError,\n\t\t};\n\t}\n\n\tprivate async _getProfile(): Promise<PrismicUserProfile | undefined> {\n\t\tlet profile: PrismicUserProfile | undefined;\n\n\t\tconst isLoggedIn = await this.user.checkIsLoggedIn();\n\n\t\tif (isLoggedIn) {\n\t\t\tprofile = await this.user.getProfile();\n\t\t\tawait this.user.refreshAuthenticationToken();\n\t\t}\n\n\t\treturn profile;\n\t}\n\n\tprivate async _getLibraries(\n\t\tsliceMachineConfig: SliceMachineConfig,\n\t): Promise<SliceMachineManagerGetStateReturnType[\"libraries\"]> {\n\t\tconst libraries: SliceMachineManagerGetStateReturnType[\"libraries\"] = [];\n\n\t\tif (sliceMachineConfig.libraries) {\n\t\t\tawait Promise.all(\n\t\t\t\tsliceMachineConfig.libraries.map(async (libraryID) => {\n\t\t\t\t\tconst { sliceIDs } = await this.slices.readSliceLibrary({\n\t\t\t\t\t\tlibraryID,\n\t\t\t\t\t});\n\n\t\t\t\t\tif (sliceIDs) {\n\t\t\t\t\t\tconst components: SliceMachineManagerGetStateReturnType[\"libraries\"][number][\"components\"] =\n\t\t\t\t\t\t\t[];\n\n\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\tsliceIDs.map(async (sliceID) => {\n\t\t\t\t\t\t\t\tconst [{ model }, { mocks }] = await Promise.all([\n\t\t\t\t\t\t\t\t\tthis.slices.readSlice({ libraryID, sliceID }),\n\t\t\t\t\t\t\t\t\tthis.slices.readSliceMocks({ libraryID, sliceID }),\n\t\t\t\t\t\t\t\t]);\n\n\t\t\t\t\t\t\t\tif (model) {\n\t\t\t\t\t\t\t\t\tconst screenshots: (typeof components)[number][\"screenshots\"] =\n\t\t\t\t\t\t\t\t\t\t{};\n\t\t\t\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\t\t\t\tmodel.variations.map(async (variation) => {\n\t\t\t\t\t\t\t\t\t\t\tconst screenshot = await this.slices.readSliceScreenshot({\n\t\t\t\t\t\t\t\t\t\t\t\tlibraryID,\n\t\t\t\t\t\t\t\t\t\t\t\tsliceID,\n\t\t\t\t\t\t\t\t\t\t\t\tvariationID: variation.id,\n\t\t\t\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\t\t\t\tif (screenshot.data) {\n\t\t\t\t\t\t\t\t\t\t\t\tscreenshots[variation.id] = {\n\t\t\t\t\t\t\t\t\t\t\t\t\thash: createContentDigest(screenshot.data),\n\t\t\t\t\t\t\t\t\t\t\t\t\tdata: screenshot.data,\n\t\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\tcomponents.push({\n\t\t\t\t\t\t\t\t\t\tfrom: libraryID,\n\t\t\t\t\t\t\t\t\t\thref: libraryID.replace(/\\//g, \"--\"),\n\t\t\t\t\t\t\t\t\t\tpathToSlice: \"pathToSlice\",\n\t\t\t\t\t\t\t\t\t\tfileName: \"fileName\",\n\t\t\t\t\t\t\t\t\t\textension: \"extension\",\n\t\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t\t\tscreenshots,\n\t\t\t\t\t\t\t\t\t\tmocks,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tlibraries.push({\n\t\t\t\t\t\t\tname: libraryID,\n\t\t\t\t\t\t\tpath: libraryID,\n\t\t\t\t\t\t\tisLocal: true, // TODO: Do we still support node_modules-based libraries?\n\t\t\t\t\t\t\tcomponents,\n\t\t\t\t\t\t\tmeta: {\n\t\t\t\t\t\t\t\t// TODO: Do we still support node_modules-based libraries?\n\t\t\t\t\t\t\t\tisNodeModule: false,\n\t\t\t\t\t\t\t\tisDownloaded: false,\n\t\t\t\t\t\t\t\tisManual: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\t// Preserve library order from config file\n\t\treturn libraries.sort((library1, library2) => {\n\t\t\tconst libraryIndex1 =\n\t\t\t\tsliceMachineConfig.libraries?.indexOf(library1.name) || 0;\n\t\t\tconst libraryIndex2 =\n\t\t\t\tsliceMachineConfig.libraries?.indexOf(library2.name) || 0;\n\n\t\t\treturn Math.sign(libraryIndex1 - libraryIndex2);\n\t\t});\n\t}\n\n\tprivate async _getCustomTypes(): Promise<\n\t\tSliceMachineManagerGetStateReturnType[\"customTypes\"]\n\t> {\n\t\tconst customTypes: SliceMachineManagerGetStateReturnType[\"customTypes\"] =\n\t\t\t[];\n\n\t\tconst { ids: customTypeIDs } =\n\t\t\tawait this.customTypes.readCustomTypeLibrary();\n\n\t\tif (customTypeIDs) {\n\t\t\tawait Promise.all(\n\t\t\t\tcustomTypeIDs.map(async (customTypeID) => {\n\t\t\t\t\tconst { model } = await this.customTypes.readCustomType({\n\t\t\t\t\t\tid: customTypeID,\n\t\t\t\t\t});\n\n\t\t\t\t\tif (model) {\n\t\t\t\t\t\tcustomTypes.push(model);\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\treturn customTypes;\n\t}\n}\n"],"names":["createPrismicAuthManager","UserManager","PrismicRepositoryManager","PluginsManager","ProjectManager","CustomTypesManager","SlicesManager","SnippetsManager","ScreenshotsManager","SimulatorManager","DocumentationManager","SliceTemplateLibraryManager","VersionsManager","TelemetryManager","GitManager","API_ENDPOINTS","sliceMachineConfig","libraries","profile","authError","remoteCustomTypes","remoteSlices","prismicCustomTypesClient","buildPrismicRepositoryAPIEndpoint","createContentDigest"],"mappings":"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"}
1
+ {"version":3,"file":"SliceMachineManager.cjs","sources":["../../../src/managers/SliceMachineManager.ts"],"sourcesContent":["import {\n\tSharedSlice,\n\tCustomType,\n} from \"@prismicio/types-internal/lib/customtypes\";\nimport { SharedSliceContent } from \"@prismicio/types-internal/lib/content\";\nimport * as prismicCustomTypesClient from \"@prismicio/custom-types-client\";\nimport {\n\tSliceMachinePlugin,\n\tSliceMachinePluginRunner,\n} from \"@slicemachine/plugin-kit\";\n\nimport { createContentDigest } from \"../lib/createContentDigest\";\n\nimport { PackageManager, SliceMachineConfig } from \"../types\";\nimport {\n\tPrismicAuthManager,\n\tPrismicUserProfile,\n} from \"../auth/PrismicAuthManager\";\nimport { createPrismicAuthManager } from \"../auth/createPrismicAuthManager\";\nimport { UnauthenticatedError } from \"../errors\";\n\nimport { API_ENDPOINTS, APIEndpoints } from \"../constants/API_ENDPOINTS\";\n\nimport { UserManager } from \"./user/UserManager\";\nimport { PrismicRepositoryManager } from \"./prismicRepository/PrismicRepositoryManager\";\n\nimport { PluginsManager } from \"./plugins/PluginsManager\";\n\nimport { ProjectManager } from \"./project/ProjectManager\";\nimport { CustomTypesManager } from \"./customTypes/CustomTypesManager\";\nimport { SlicesManager } from \"./slices/SlicesManager\";\nimport { SnippetsManager } from \"./snippets/SnippetsManager\";\nimport { ScreenshotsManager } from \"./screenshots/ScreenshotsManager\";\nimport { SimulatorManager } from \"./simulator/SimulatorManager\";\n\nimport { VersionsManager } from \"./versions/VersionsManager\";\n\nimport { TelemetryManager } from \"./telemetry/TelemetryManager\";\nimport { buildPrismicRepositoryAPIEndpoint } from \"../lib/buildPrismicRepositoryAPIEndpoint\";\nimport { DocumentationManager } from \"./documentation/DocumentationManager\";\nimport { SliceTemplateLibraryManager } from \"./sliceTemplateLibrary/SliceTemplateLibraryManager\";\nimport { GitManager } from \"./git/GitManager\";\n\ntype SliceMachineManagerGetStateReturnType = {\n\tenv: {\n\t\tshortId?: string;\n\t\tintercomHash?: string;\n\t\tmanifest: {\n\t\t\tapiEndpoint: string;\n\t\t\tlocalSliceSimulatorURL?: string;\n\t\t};\n\t\trepo: string;\n\t\tpackageManager: PackageManager;\n\t\tendpoints: APIEndpoints;\n\t};\n\tlibraries: {\n\t\tname: string;\n\t\tpath: string;\n\t\tisLocal: boolean;\n\t\tcomponents: {\n\t\t\tfrom: string;\n\t\t\thref: string;\n\t\t\tpathToSlice: string;\n\t\t\tfileName: string | null;\n\t\t\textension: string | null;\n\t\t\tmodel: SharedSlice;\n\t\t\tscreenshots: Record<\n\t\t\t\tstring,\n\t\t\t\t{\n\t\t\t\t\thash: string;\n\t\t\t\t\tdata: Buffer;\n\t\t\t\t}\n\t\t\t>;\n\t\t\tmocks?: SharedSliceContent[];\n\t\t}[];\n\t\tmeta: {\n\t\t\tname?: string;\n\t\t\tversion?: string;\n\t\t\tisNodeModule: boolean;\n\t\t\tisDownloaded: boolean;\n\t\t\tisManual: boolean;\n\t\t};\n\t}[];\n\tcustomTypes: CustomType[];\n\tremoteCustomTypes: CustomType[];\n\tremoteSlices: SharedSlice[];\n\tclientError?: {\n\t\tname: string;\n\t\tmessage: string;\n\t\tstatus: number;\n\t\treason: string;\n\t};\n};\n\ntype SliceMachineManagerConstructorArgs = {\n\tcwd?: string;\n\tnativePlugins?: Record<string, SliceMachinePlugin>;\n};\n\nexport class SliceMachineManager {\n\tprivate _sliceMachinePluginRunner: SliceMachinePluginRunner | undefined =\n\t\tundefined;\n\tprivate _prismicAuthManager: PrismicAuthManager;\n\n\tcwd: string;\n\n\tcustomTypes: CustomTypesManager;\n\tplugins: PluginsManager;\n\tprismicRepository: PrismicRepositoryManager;\n\tproject: ProjectManager;\n\tscreenshots: ScreenshotsManager;\n\tsimulator: SimulatorManager;\n\tslices: SlicesManager;\n\tsnippets: SnippetsManager;\n\tdocumentation: DocumentationManager;\n\tsliceTemplateLibrary: SliceTemplateLibraryManager;\n\ttelemetry: TelemetryManager;\n\tuser: UserManager;\n\tversions: VersionsManager;\n\tgit: GitManager;\n\n\tconstructor(args?: SliceMachineManagerConstructorArgs) {\n\t\t// _prismicAuthManager must be set at least before UserManager\n\t\t// is instantiated. It depends on the PrismicAuthManager for\n\t\t// authentication-related methods.\n\t\tthis._prismicAuthManager = createPrismicAuthManager();\n\n\t\tthis.user = new UserManager(this);\n\t\tthis.prismicRepository = new PrismicRepositoryManager(this);\n\n\t\tthis.plugins = new PluginsManager(this, {\n\t\t\tnativePlugins: args?.nativePlugins,\n\t\t});\n\n\t\tthis.project = new ProjectManager(this);\n\t\tthis.customTypes = new CustomTypesManager(this);\n\t\tthis.slices = new SlicesManager(this);\n\t\tthis.snippets = new SnippetsManager(this);\n\t\tthis.screenshots = new ScreenshotsManager(this);\n\t\tthis.simulator = new SimulatorManager(this);\n\t\tthis.documentation = new DocumentationManager(this);\n\t\tthis.sliceTemplateLibrary = new SliceTemplateLibraryManager(this);\n\n\t\tthis.versions = new VersionsManager(this);\n\n\t\tthis.telemetry = new TelemetryManager(this);\n\n\t\tthis.git = new GitManager(this);\n\n\t\tthis.cwd = args?.cwd ?? process.cwd();\n\t}\n\n\t// The `_sliceMachinePluginRunner` property is hidden behind a function to\n\t// discourage access. Using a function deliberatly breaks the pattern\n\t// of other child managers that are accessible as properties, like\n\t// `project`, `plugins`, etc. We do not treat SliceMachinePluginRunner\n\t// as a child manager.\n\tgetSliceMachinePluginRunner(): SliceMachinePluginRunner | undefined {\n\t\treturn this._sliceMachinePluginRunner;\n\t}\n\n\t// The `_prismicAuthManager` property is hidden behind a function to\n\t// discourage access. Using a function deliberatly breaks the pattern\n\t// of other child managers that are accessible as properties, like\n\t// `project`, `plugins`, etc. We do not treat PrismicAuthManager as a\n\t// child manager.\n\tgetPrismicAuthManager(): PrismicAuthManager {\n\t\treturn this._prismicAuthManager;\n\t}\n\n\tgetAPIEndpoints(): APIEndpoints {\n\t\treturn API_ENDPOINTS;\n\t}\n\n\t// TODO: Remove this global-state method. It is expensive and a\n\t// potential source of bugs due to data inconsistency. SM UI relies on\n\t// it heavily, so removal will require significant effort.\n\tasync getState(): Promise<SliceMachineManagerGetStateReturnType> {\n\t\tconst [\n\t\t\t{ sliceMachineConfig, libraries },\n\t\t\t{ profile, remoteCustomTypes, remoteSlices, authError },\n\t\t\tcustomTypes,\n\t\t\tpackageManager,\n\t\t] = await Promise.all([\n\t\t\tthis.project.getSliceMachineConfig().then(async (sliceMachineConfig) => {\n\t\t\t\tconst libraries = await this._getLibraries(sliceMachineConfig);\n\n\t\t\t\treturn { sliceMachineConfig, libraries };\n\t\t\t}),\n\t\t\tthis._getProfile().then(async (profile) => {\n\t\t\t\tlet authError;\n\t\t\t\tif (profile) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst [remoteCustomTypes, remoteSlices] = await Promise.all([\n\t\t\t\t\t\t\tthis.customTypes.fetchRemoteCustomTypes(),\n\t\t\t\t\t\t\tthis.slices.fetchRemoteSlices(),\n\t\t\t\t\t\t]);\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tprofile,\n\t\t\t\t\t\t\tremoteCustomTypes,\n\t\t\t\t\t\t\tremoteSlices,\n\t\t\t\t\t\t\tauthError,\n\t\t\t\t\t\t};\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (error instanceof prismicCustomTypesClient.ForbiddenError) {\n\t\t\t\t\t\t\tauthError = {\n\t\t\t\t\t\t\t\tname: \"__stub__\",\n\t\t\t\t\t\t\t\tmessage: \"__stub__\",\n\t\t\t\t\t\t\t\treason: \"__stub__\",\n\t\t\t\t\t\t\t\tstatus: 403,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\terror instanceof UnauthenticatedError ||\n\t\t\t\t\t\t\terror instanceof prismicCustomTypesClient.UnauthorizedError\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tauthError = {\n\t\t\t\t\t\t\t\tname: \"__stub__\",\n\t\t\t\t\t\t\t\tmessage: \"__stub__\",\n\t\t\t\t\t\t\t\treason: \"__stub__\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tprofile,\n\t\t\t\t\tremoteCustomTypes: [],\n\t\t\t\t\tremoteSlices: [],\n\t\t\t\t\tauthError,\n\t\t\t\t};\n\t\t\t}),\n\t\t\tthis._getCustomTypes(),\n\t\t\tthis.project.detectPackageManager(),\n\t\t]);\n\n\t\t// SM UI detects if a user is logged out by looking at\n\t\t// `clientError`. Here, we simulate what the old core does by\n\t\t// returning an `ErrorWithStatus`-like object if the user does\n\t\t// not have access to the repository or is not logged in.\n\t\tconst clientError: SliceMachineManagerGetStateReturnType[\"clientError\"] =\n\t\t\tauthError ||\n\t\t\t(profile\n\t\t\t\t? undefined\n\t\t\t\t: {\n\t\t\t\t\t\tname: \"__stub__\",\n\t\t\t\t\t\tmessage: \"__stub__\",\n\t\t\t\t\t\treason: \"__stub__\",\n\t\t\t\t\t\tstatus: 401, // Needed to trigger the unauthorized flow.\n\t\t\t\t });\n\n\t\treturn {\n\t\t\tenv: {\n\t\t\t\tmanifest: {\n\t\t\t\t\tapiEndpoint:\n\t\t\t\t\t\tsliceMachineConfig.apiEndpoint ||\n\t\t\t\t\t\tbuildPrismicRepositoryAPIEndpoint(\n\t\t\t\t\t\t\tsliceMachineConfig.repositoryName,\n\t\t\t\t\t\t),\n\t\t\t\t\tlocalSliceSimulatorURL: sliceMachineConfig.localSliceSimulatorURL,\n\t\t\t\t},\n\t\t\t\tpackageManager,\n\t\t\t\trepo: sliceMachineConfig.repositoryName,\n\t\t\t\tintercomHash: profile?.intercomHash,\n\t\t\t\tshortId: profile?.shortId,\n\t\t\t\tendpoints: this.getAPIEndpoints(),\n\t\t\t},\n\t\t\tlibraries,\n\t\t\tcustomTypes,\n\t\t\tremoteCustomTypes,\n\t\t\tremoteSlices,\n\t\t\tclientError,\n\t\t};\n\t}\n\n\tprivate async _getProfile(): Promise<PrismicUserProfile | undefined> {\n\t\tlet profile: PrismicUserProfile | undefined;\n\n\t\tconst isLoggedIn = await this.user.checkIsLoggedIn();\n\n\t\tif (isLoggedIn) {\n\t\t\tprofile = await this.user.getProfile();\n\t\t\tawait this.user.refreshAuthenticationToken();\n\t\t}\n\n\t\treturn profile;\n\t}\n\n\tprivate async _getLibraries(\n\t\tsliceMachineConfig: SliceMachineConfig,\n\t): Promise<SliceMachineManagerGetStateReturnType[\"libraries\"]> {\n\t\tconst libraries: SliceMachineManagerGetStateReturnType[\"libraries\"] = [];\n\n\t\tif (sliceMachineConfig.libraries) {\n\t\t\tawait Promise.all(\n\t\t\t\tsliceMachineConfig.libraries.map(async (libraryID) => {\n\t\t\t\t\tconst { sliceIDs } = await this.slices.readSliceLibrary({\n\t\t\t\t\t\tlibraryID,\n\t\t\t\t\t});\n\n\t\t\t\t\tif (sliceIDs) {\n\t\t\t\t\t\tconst components: SliceMachineManagerGetStateReturnType[\"libraries\"][number][\"components\"] =\n\t\t\t\t\t\t\t[];\n\n\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\tsliceIDs.map(async (sliceID) => {\n\t\t\t\t\t\t\t\tconst [{ model }, { mocks }] = await Promise.all([\n\t\t\t\t\t\t\t\t\tthis.slices.readSlice({ libraryID, sliceID }),\n\t\t\t\t\t\t\t\t\tthis.slices.readSliceMocks({ libraryID, sliceID }),\n\t\t\t\t\t\t\t\t]);\n\n\t\t\t\t\t\t\t\tif (model) {\n\t\t\t\t\t\t\t\t\tconst screenshots: (typeof components)[number][\"screenshots\"] =\n\t\t\t\t\t\t\t\t\t\t{};\n\t\t\t\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\t\t\t\tmodel.variations.map(async (variation) => {\n\t\t\t\t\t\t\t\t\t\t\tconst screenshot = await this.slices.readSliceScreenshot({\n\t\t\t\t\t\t\t\t\t\t\t\tlibraryID,\n\t\t\t\t\t\t\t\t\t\t\t\tsliceID,\n\t\t\t\t\t\t\t\t\t\t\t\tvariationID: variation.id,\n\t\t\t\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\t\t\t\tif (screenshot.data) {\n\t\t\t\t\t\t\t\t\t\t\t\tscreenshots[variation.id] = {\n\t\t\t\t\t\t\t\t\t\t\t\t\thash: createContentDigest(screenshot.data),\n\t\t\t\t\t\t\t\t\t\t\t\t\tdata: screenshot.data,\n\t\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\tcomponents.push({\n\t\t\t\t\t\t\t\t\t\tfrom: libraryID,\n\t\t\t\t\t\t\t\t\t\thref: libraryID.replace(/\\//g, \"--\"),\n\t\t\t\t\t\t\t\t\t\tpathToSlice: \"pathToSlice\",\n\t\t\t\t\t\t\t\t\t\tfileName: \"fileName\",\n\t\t\t\t\t\t\t\t\t\textension: \"extension\",\n\t\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t\t\tscreenshots,\n\t\t\t\t\t\t\t\t\t\tmocks,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tlibraries.push({\n\t\t\t\t\t\t\tname: libraryID,\n\t\t\t\t\t\t\tpath: libraryID,\n\t\t\t\t\t\t\tisLocal: true, // TODO: Do we still support node_modules-based libraries?\n\t\t\t\t\t\t\tcomponents,\n\t\t\t\t\t\t\tmeta: {\n\t\t\t\t\t\t\t\t// TODO: Do we still support node_modules-based libraries?\n\t\t\t\t\t\t\t\tisNodeModule: false,\n\t\t\t\t\t\t\t\tisDownloaded: false,\n\t\t\t\t\t\t\t\tisManual: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\t// Preserve library order from config file\n\t\treturn libraries.sort((library1, library2) => {\n\t\t\tconst libraryIndex1 =\n\t\t\t\tsliceMachineConfig.libraries?.indexOf(library1.name) || 0;\n\t\t\tconst libraryIndex2 =\n\t\t\t\tsliceMachineConfig.libraries?.indexOf(library2.name) || 0;\n\n\t\t\treturn Math.sign(libraryIndex1 - libraryIndex2);\n\t\t});\n\t}\n\n\tprivate async _getCustomTypes(): Promise<\n\t\tSliceMachineManagerGetStateReturnType[\"customTypes\"]\n\t> {\n\t\tconst customTypes: SliceMachineManagerGetStateReturnType[\"customTypes\"] =\n\t\t\t[];\n\n\t\tconst { ids: customTypeIDs } =\n\t\t\tawait this.customTypes.readCustomTypeLibrary();\n\n\t\tif (customTypeIDs) {\n\t\t\tawait Promise.all(\n\t\t\t\tcustomTypeIDs.map(async (customTypeID) => {\n\t\t\t\t\tconst { model } = await this.customTypes.readCustomType({\n\t\t\t\t\t\tid: customTypeID,\n\t\t\t\t\t});\n\n\t\t\t\t\tif (model) {\n\t\t\t\t\t\tcustomTypes.push(model);\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\treturn customTypes;\n\t}\n}\n"],"names":["createPrismicAuthManager","UserManager","PrismicRepositoryManager","PluginsManager","ProjectManager","CustomTypesManager","SlicesManager","SnippetsManager","ScreenshotsManager","SimulatorManager","DocumentationManager","SliceTemplateLibraryManager","VersionsManager","TelemetryManager","GitManager","API_ENDPOINTS","sliceMachineConfig","libraries","profile","authError","remoteCustomTypes","remoteSlices","prismicCustomTypesClient","UnauthenticatedError","buildPrismicRepositoryAPIEndpoint","createContentDigest"],"mappings":"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"}
@@ -7,6 +7,7 @@ var __publicField = (obj, key, value) => {
7
7
  import * as prismicCustomTypesClient from "@prismicio/custom-types-client";
8
8
  import { createContentDigest } from "../lib/createContentDigest.js";
9
9
  import { createPrismicAuthManager } from "../auth/createPrismicAuthManager.js";
10
+ import { UnauthenticatedError } from "../errors.js";
10
11
  import { API_ENDPOINTS } from "../constants/API_ENDPOINTS.js";
11
12
  import { UserManager } from "./user/UserManager.js";
12
13
  import { PrismicRepositoryManager } from "./prismicRepository/PrismicRepositoryManager.js";
@@ -109,14 +110,14 @@ class SliceMachineManager {
109
110
  name: "__stub__",
110
111
  message: "__stub__",
111
112
  reason: "__stub__",
112
- status: 401
113
+ status: 403
113
114
  };
114
- } else if (error instanceof prismicCustomTypesClient.UnauthorizedError) {
115
+ } else if (error instanceof UnauthenticatedError || error instanceof prismicCustomTypesClient.UnauthorizedError) {
115
116
  authError2 = {
116
117
  name: "__stub__",
117
118
  message: "__stub__",
118
119
  reason: "__stub__",
119
- status: 403
120
+ status: 401
120
121
  };
121
122
  } else {
122
123
  throw error;
@@ -1 +1 @@
1
- {"version":3,"file":"SliceMachineManager.js","sources":["../../../src/managers/SliceMachineManager.ts"],"sourcesContent":["import {\n\tSharedSlice,\n\tCustomType,\n} from \"@prismicio/types-internal/lib/customtypes\";\nimport { SharedSliceContent } from \"@prismicio/types-internal/lib/content\";\nimport * as prismicCustomTypesClient from \"@prismicio/custom-types-client\";\nimport {\n\tSliceMachinePlugin,\n\tSliceMachinePluginRunner,\n} from \"@slicemachine/plugin-kit\";\n\nimport { createContentDigest } from \"../lib/createContentDigest\";\n\nimport { PackageManager, SliceMachineConfig } from \"../types\";\nimport {\n\tPrismicAuthManager,\n\tPrismicUserProfile,\n} from \"../auth/PrismicAuthManager\";\nimport { createPrismicAuthManager } from \"../auth/createPrismicAuthManager\";\n\nimport { API_ENDPOINTS, APIEndpoints } from \"../constants/API_ENDPOINTS\";\n\nimport { UserManager } from \"./user/UserManager\";\nimport { PrismicRepositoryManager } from \"./prismicRepository/PrismicRepositoryManager\";\n\nimport { PluginsManager } from \"./plugins/PluginsManager\";\n\nimport { ProjectManager } from \"./project/ProjectManager\";\nimport { CustomTypesManager } from \"./customTypes/CustomTypesManager\";\nimport { SlicesManager } from \"./slices/SlicesManager\";\nimport { SnippetsManager } from \"./snippets/SnippetsManager\";\nimport { ScreenshotsManager } from \"./screenshots/ScreenshotsManager\";\nimport { SimulatorManager } from \"./simulator/SimulatorManager\";\n\nimport { VersionsManager } from \"./versions/VersionsManager\";\n\nimport { TelemetryManager } from \"./telemetry/TelemetryManager\";\nimport { buildPrismicRepositoryAPIEndpoint } from \"../lib/buildPrismicRepositoryAPIEndpoint\";\nimport { DocumentationManager } from \"./documentation/DocumentationManager\";\nimport { SliceTemplateLibraryManager } from \"./sliceTemplateLibrary/SliceTemplateLibraryManager\";\nimport { GitManager } from \"./git/GitManager\";\n\ntype SliceMachineManagerGetStateReturnType = {\n\tenv: {\n\t\tshortId?: string;\n\t\tintercomHash?: string;\n\t\tmanifest: {\n\t\t\tapiEndpoint: string;\n\t\t\tlocalSliceSimulatorURL?: string;\n\t\t};\n\t\trepo: string;\n\t\tpackageManager: PackageManager;\n\t\tendpoints: APIEndpoints;\n\t};\n\tlibraries: {\n\t\tname: string;\n\t\tpath: string;\n\t\tisLocal: boolean;\n\t\tcomponents: {\n\t\t\tfrom: string;\n\t\t\thref: string;\n\t\t\tpathToSlice: string;\n\t\t\tfileName: string | null;\n\t\t\textension: string | null;\n\t\t\tmodel: SharedSlice;\n\t\t\tscreenshots: Record<\n\t\t\t\tstring,\n\t\t\t\t{\n\t\t\t\t\thash: string;\n\t\t\t\t\tdata: Buffer;\n\t\t\t\t}\n\t\t\t>;\n\t\t\tmocks?: SharedSliceContent[];\n\t\t}[];\n\t\tmeta: {\n\t\t\tname?: string;\n\t\t\tversion?: string;\n\t\t\tisNodeModule: boolean;\n\t\t\tisDownloaded: boolean;\n\t\t\tisManual: boolean;\n\t\t};\n\t}[];\n\tcustomTypes: CustomType[];\n\tremoteCustomTypes: CustomType[];\n\tremoteSlices: SharedSlice[];\n\tclientError?: {\n\t\tname: string;\n\t\tmessage: string;\n\t\tstatus: number;\n\t\treason: string;\n\t};\n};\n\ntype SliceMachineManagerConstructorArgs = {\n\tcwd?: string;\n\tnativePlugins?: Record<string, SliceMachinePlugin>;\n};\n\nexport class SliceMachineManager {\n\tprivate _sliceMachinePluginRunner: SliceMachinePluginRunner | undefined =\n\t\tundefined;\n\tprivate _prismicAuthManager: PrismicAuthManager;\n\n\tcwd: string;\n\n\tcustomTypes: CustomTypesManager;\n\tplugins: PluginsManager;\n\tprismicRepository: PrismicRepositoryManager;\n\tproject: ProjectManager;\n\tscreenshots: ScreenshotsManager;\n\tsimulator: SimulatorManager;\n\tslices: SlicesManager;\n\tsnippets: SnippetsManager;\n\tdocumentation: DocumentationManager;\n\tsliceTemplateLibrary: SliceTemplateLibraryManager;\n\ttelemetry: TelemetryManager;\n\tuser: UserManager;\n\tversions: VersionsManager;\n\tgit: GitManager;\n\n\tconstructor(args?: SliceMachineManagerConstructorArgs) {\n\t\t// _prismicAuthManager must be set at least before UserManager\n\t\t// is instantiated. It depends on the PrismicAuthManager for\n\t\t// authentication-related methods.\n\t\tthis._prismicAuthManager = createPrismicAuthManager();\n\n\t\tthis.user = new UserManager(this);\n\t\tthis.prismicRepository = new PrismicRepositoryManager(this);\n\n\t\tthis.plugins = new PluginsManager(this, {\n\t\t\tnativePlugins: args?.nativePlugins,\n\t\t});\n\n\t\tthis.project = new ProjectManager(this);\n\t\tthis.customTypes = new CustomTypesManager(this);\n\t\tthis.slices = new SlicesManager(this);\n\t\tthis.snippets = new SnippetsManager(this);\n\t\tthis.screenshots = new ScreenshotsManager(this);\n\t\tthis.simulator = new SimulatorManager(this);\n\t\tthis.documentation = new DocumentationManager(this);\n\t\tthis.sliceTemplateLibrary = new SliceTemplateLibraryManager(this);\n\n\t\tthis.versions = new VersionsManager(this);\n\n\t\tthis.telemetry = new TelemetryManager(this);\n\n\t\tthis.git = new GitManager(this);\n\n\t\tthis.cwd = args?.cwd ?? process.cwd();\n\t}\n\n\t// The `_sliceMachinePluginRunner` property is hidden behind a function to\n\t// discourage access. Using a function deliberatly breaks the pattern\n\t// of other child managers that are accessible as properties, like\n\t// `project`, `plugins`, etc. We do not treat SliceMachinePluginRunner\n\t// as a child manager.\n\tgetSliceMachinePluginRunner(): SliceMachinePluginRunner | undefined {\n\t\treturn this._sliceMachinePluginRunner;\n\t}\n\n\t// The `_prismicAuthManager` property is hidden behind a function to\n\t// discourage access. Using a function deliberatly breaks the pattern\n\t// of other child managers that are accessible as properties, like\n\t// `project`, `plugins`, etc. We do not treat PrismicAuthManager as a\n\t// child manager.\n\tgetPrismicAuthManager(): PrismicAuthManager {\n\t\treturn this._prismicAuthManager;\n\t}\n\n\tgetAPIEndpoints(): APIEndpoints {\n\t\treturn API_ENDPOINTS;\n\t}\n\n\t// TODO: Remove this global-state method. It is expensive and a\n\t// potential source of bugs due to data inconsistency. SM UI relies on\n\t// it heavily, so removal will require significant effort.\n\tasync getState(): Promise<SliceMachineManagerGetStateReturnType> {\n\t\tconst [\n\t\t\t{ sliceMachineConfig, libraries },\n\t\t\t{ profile, remoteCustomTypes, remoteSlices, authError },\n\t\t\tcustomTypes,\n\t\t\tpackageManager,\n\t\t] = await Promise.all([\n\t\t\tthis.project.getSliceMachineConfig().then(async (sliceMachineConfig) => {\n\t\t\t\tconst libraries = await this._getLibraries(sliceMachineConfig);\n\n\t\t\t\treturn { sliceMachineConfig, libraries };\n\t\t\t}),\n\t\t\tthis._getProfile().then(async (profile) => {\n\t\t\t\tlet authError;\n\t\t\t\tif (profile) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst [remoteCustomTypes, remoteSlices] = await Promise.all([\n\t\t\t\t\t\t\tthis.customTypes.fetchRemoteCustomTypes(),\n\t\t\t\t\t\t\tthis.slices.fetchRemoteSlices(),\n\t\t\t\t\t\t]);\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tprofile,\n\t\t\t\t\t\t\tremoteCustomTypes,\n\t\t\t\t\t\t\tremoteSlices,\n\t\t\t\t\t\t\tauthError,\n\t\t\t\t\t\t};\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (error instanceof prismicCustomTypesClient.ForbiddenError) {\n\t\t\t\t\t\t\tauthError = {\n\t\t\t\t\t\t\t\tname: \"__stub__\",\n\t\t\t\t\t\t\t\tmessage: \"__stub__\",\n\t\t\t\t\t\t\t\treason: \"__stub__\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\terror instanceof prismicCustomTypesClient.UnauthorizedError\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tauthError = {\n\t\t\t\t\t\t\t\tname: \"__stub__\",\n\t\t\t\t\t\t\t\tmessage: \"__stub__\",\n\t\t\t\t\t\t\t\treason: \"__stub__\",\n\t\t\t\t\t\t\t\tstatus: 403,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tprofile,\n\t\t\t\t\tremoteCustomTypes: [],\n\t\t\t\t\tremoteSlices: [],\n\t\t\t\t\tauthError,\n\t\t\t\t};\n\t\t\t}),\n\t\t\tthis._getCustomTypes(),\n\t\t\tthis.project.detectPackageManager(),\n\t\t]);\n\n\t\t// SM UI detects if a user is logged out by looking at\n\t\t// `clientError`. Here, we simulate what the old core does by\n\t\t// returning an `ErrorWithStatus`-like object if the user does\n\t\t// not have access to the repository or is not logged in.\n\t\tconst clientError: SliceMachineManagerGetStateReturnType[\"clientError\"] =\n\t\t\tauthError ||\n\t\t\t(profile\n\t\t\t\t? undefined\n\t\t\t\t: {\n\t\t\t\t\t\tname: \"__stub__\",\n\t\t\t\t\t\tmessage: \"__stub__\",\n\t\t\t\t\t\treason: \"__stub__\",\n\t\t\t\t\t\tstatus: 401, // Needed to trigger the unauthorized flow.\n\t\t\t\t });\n\n\t\treturn {\n\t\t\tenv: {\n\t\t\t\tmanifest: {\n\t\t\t\t\tapiEndpoint:\n\t\t\t\t\t\tsliceMachineConfig.apiEndpoint ||\n\t\t\t\t\t\tbuildPrismicRepositoryAPIEndpoint(\n\t\t\t\t\t\t\tsliceMachineConfig.repositoryName,\n\t\t\t\t\t\t),\n\t\t\t\t\tlocalSliceSimulatorURL: sliceMachineConfig.localSliceSimulatorURL,\n\t\t\t\t},\n\t\t\t\tpackageManager,\n\t\t\t\trepo: sliceMachineConfig.repositoryName,\n\t\t\t\tintercomHash: profile?.intercomHash,\n\t\t\t\tshortId: profile?.shortId,\n\t\t\t\tendpoints: this.getAPIEndpoints(),\n\t\t\t},\n\t\t\tlibraries,\n\t\t\tcustomTypes,\n\t\t\tremoteCustomTypes,\n\t\t\tremoteSlices,\n\t\t\tclientError,\n\t\t};\n\t}\n\n\tprivate async _getProfile(): Promise<PrismicUserProfile | undefined> {\n\t\tlet profile: PrismicUserProfile | undefined;\n\n\t\tconst isLoggedIn = await this.user.checkIsLoggedIn();\n\n\t\tif (isLoggedIn) {\n\t\t\tprofile = await this.user.getProfile();\n\t\t\tawait this.user.refreshAuthenticationToken();\n\t\t}\n\n\t\treturn profile;\n\t}\n\n\tprivate async _getLibraries(\n\t\tsliceMachineConfig: SliceMachineConfig,\n\t): Promise<SliceMachineManagerGetStateReturnType[\"libraries\"]> {\n\t\tconst libraries: SliceMachineManagerGetStateReturnType[\"libraries\"] = [];\n\n\t\tif (sliceMachineConfig.libraries) {\n\t\t\tawait Promise.all(\n\t\t\t\tsliceMachineConfig.libraries.map(async (libraryID) => {\n\t\t\t\t\tconst { sliceIDs } = await this.slices.readSliceLibrary({\n\t\t\t\t\t\tlibraryID,\n\t\t\t\t\t});\n\n\t\t\t\t\tif (sliceIDs) {\n\t\t\t\t\t\tconst components: SliceMachineManagerGetStateReturnType[\"libraries\"][number][\"components\"] =\n\t\t\t\t\t\t\t[];\n\n\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\tsliceIDs.map(async (sliceID) => {\n\t\t\t\t\t\t\t\tconst [{ model }, { mocks }] = await Promise.all([\n\t\t\t\t\t\t\t\t\tthis.slices.readSlice({ libraryID, sliceID }),\n\t\t\t\t\t\t\t\t\tthis.slices.readSliceMocks({ libraryID, sliceID }),\n\t\t\t\t\t\t\t\t]);\n\n\t\t\t\t\t\t\t\tif (model) {\n\t\t\t\t\t\t\t\t\tconst screenshots: (typeof components)[number][\"screenshots\"] =\n\t\t\t\t\t\t\t\t\t\t{};\n\t\t\t\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\t\t\t\tmodel.variations.map(async (variation) => {\n\t\t\t\t\t\t\t\t\t\t\tconst screenshot = await this.slices.readSliceScreenshot({\n\t\t\t\t\t\t\t\t\t\t\t\tlibraryID,\n\t\t\t\t\t\t\t\t\t\t\t\tsliceID,\n\t\t\t\t\t\t\t\t\t\t\t\tvariationID: variation.id,\n\t\t\t\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\t\t\t\tif (screenshot.data) {\n\t\t\t\t\t\t\t\t\t\t\t\tscreenshots[variation.id] = {\n\t\t\t\t\t\t\t\t\t\t\t\t\thash: createContentDigest(screenshot.data),\n\t\t\t\t\t\t\t\t\t\t\t\t\tdata: screenshot.data,\n\t\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\tcomponents.push({\n\t\t\t\t\t\t\t\t\t\tfrom: libraryID,\n\t\t\t\t\t\t\t\t\t\thref: libraryID.replace(/\\//g, \"--\"),\n\t\t\t\t\t\t\t\t\t\tpathToSlice: \"pathToSlice\",\n\t\t\t\t\t\t\t\t\t\tfileName: \"fileName\",\n\t\t\t\t\t\t\t\t\t\textension: \"extension\",\n\t\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t\t\tscreenshots,\n\t\t\t\t\t\t\t\t\t\tmocks,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tlibraries.push({\n\t\t\t\t\t\t\tname: libraryID,\n\t\t\t\t\t\t\tpath: libraryID,\n\t\t\t\t\t\t\tisLocal: true, // TODO: Do we still support node_modules-based libraries?\n\t\t\t\t\t\t\tcomponents,\n\t\t\t\t\t\t\tmeta: {\n\t\t\t\t\t\t\t\t// TODO: Do we still support node_modules-based libraries?\n\t\t\t\t\t\t\t\tisNodeModule: false,\n\t\t\t\t\t\t\t\tisDownloaded: false,\n\t\t\t\t\t\t\t\tisManual: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\t// Preserve library order from config file\n\t\treturn libraries.sort((library1, library2) => {\n\t\t\tconst libraryIndex1 =\n\t\t\t\tsliceMachineConfig.libraries?.indexOf(library1.name) || 0;\n\t\t\tconst libraryIndex2 =\n\t\t\t\tsliceMachineConfig.libraries?.indexOf(library2.name) || 0;\n\n\t\t\treturn Math.sign(libraryIndex1 - libraryIndex2);\n\t\t});\n\t}\n\n\tprivate async _getCustomTypes(): Promise<\n\t\tSliceMachineManagerGetStateReturnType[\"customTypes\"]\n\t> {\n\t\tconst customTypes: SliceMachineManagerGetStateReturnType[\"customTypes\"] =\n\t\t\t[];\n\n\t\tconst { ids: customTypeIDs } =\n\t\t\tawait this.customTypes.readCustomTypeLibrary();\n\n\t\tif (customTypeIDs) {\n\t\t\tawait Promise.all(\n\t\t\t\tcustomTypeIDs.map(async (customTypeID) => {\n\t\t\t\t\tconst { model } = await this.customTypes.readCustomType({\n\t\t\t\t\t\tid: customTypeID,\n\t\t\t\t\t});\n\n\t\t\t\t\tif (model) {\n\t\t\t\t\t\tcustomTypes.push(model);\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\treturn customTypes;\n\t}\n}\n"],"names":["sliceMachineConfig","libraries","profile","authError","remoteCustomTypes","remoteSlices"],"mappings":"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"}
1
+ {"version":3,"file":"SliceMachineManager.js","sources":["../../../src/managers/SliceMachineManager.ts"],"sourcesContent":["import {\n\tSharedSlice,\n\tCustomType,\n} from \"@prismicio/types-internal/lib/customtypes\";\nimport { SharedSliceContent } from \"@prismicio/types-internal/lib/content\";\nimport * as prismicCustomTypesClient from \"@prismicio/custom-types-client\";\nimport {\n\tSliceMachinePlugin,\n\tSliceMachinePluginRunner,\n} from \"@slicemachine/plugin-kit\";\n\nimport { createContentDigest } from \"../lib/createContentDigest\";\n\nimport { PackageManager, SliceMachineConfig } from \"../types\";\nimport {\n\tPrismicAuthManager,\n\tPrismicUserProfile,\n} from \"../auth/PrismicAuthManager\";\nimport { createPrismicAuthManager } from \"../auth/createPrismicAuthManager\";\nimport { UnauthenticatedError } from \"../errors\";\n\nimport { API_ENDPOINTS, APIEndpoints } from \"../constants/API_ENDPOINTS\";\n\nimport { UserManager } from \"./user/UserManager\";\nimport { PrismicRepositoryManager } from \"./prismicRepository/PrismicRepositoryManager\";\n\nimport { PluginsManager } from \"./plugins/PluginsManager\";\n\nimport { ProjectManager } from \"./project/ProjectManager\";\nimport { CustomTypesManager } from \"./customTypes/CustomTypesManager\";\nimport { SlicesManager } from \"./slices/SlicesManager\";\nimport { SnippetsManager } from \"./snippets/SnippetsManager\";\nimport { ScreenshotsManager } from \"./screenshots/ScreenshotsManager\";\nimport { SimulatorManager } from \"./simulator/SimulatorManager\";\n\nimport { VersionsManager } from \"./versions/VersionsManager\";\n\nimport { TelemetryManager } from \"./telemetry/TelemetryManager\";\nimport { buildPrismicRepositoryAPIEndpoint } from \"../lib/buildPrismicRepositoryAPIEndpoint\";\nimport { DocumentationManager } from \"./documentation/DocumentationManager\";\nimport { SliceTemplateLibraryManager } from \"./sliceTemplateLibrary/SliceTemplateLibraryManager\";\nimport { GitManager } from \"./git/GitManager\";\n\ntype SliceMachineManagerGetStateReturnType = {\n\tenv: {\n\t\tshortId?: string;\n\t\tintercomHash?: string;\n\t\tmanifest: {\n\t\t\tapiEndpoint: string;\n\t\t\tlocalSliceSimulatorURL?: string;\n\t\t};\n\t\trepo: string;\n\t\tpackageManager: PackageManager;\n\t\tendpoints: APIEndpoints;\n\t};\n\tlibraries: {\n\t\tname: string;\n\t\tpath: string;\n\t\tisLocal: boolean;\n\t\tcomponents: {\n\t\t\tfrom: string;\n\t\t\thref: string;\n\t\t\tpathToSlice: string;\n\t\t\tfileName: string | null;\n\t\t\textension: string | null;\n\t\t\tmodel: SharedSlice;\n\t\t\tscreenshots: Record<\n\t\t\t\tstring,\n\t\t\t\t{\n\t\t\t\t\thash: string;\n\t\t\t\t\tdata: Buffer;\n\t\t\t\t}\n\t\t\t>;\n\t\t\tmocks?: SharedSliceContent[];\n\t\t}[];\n\t\tmeta: {\n\t\t\tname?: string;\n\t\t\tversion?: string;\n\t\t\tisNodeModule: boolean;\n\t\t\tisDownloaded: boolean;\n\t\t\tisManual: boolean;\n\t\t};\n\t}[];\n\tcustomTypes: CustomType[];\n\tremoteCustomTypes: CustomType[];\n\tremoteSlices: SharedSlice[];\n\tclientError?: {\n\t\tname: string;\n\t\tmessage: string;\n\t\tstatus: number;\n\t\treason: string;\n\t};\n};\n\ntype SliceMachineManagerConstructorArgs = {\n\tcwd?: string;\n\tnativePlugins?: Record<string, SliceMachinePlugin>;\n};\n\nexport class SliceMachineManager {\n\tprivate _sliceMachinePluginRunner: SliceMachinePluginRunner | undefined =\n\t\tundefined;\n\tprivate _prismicAuthManager: PrismicAuthManager;\n\n\tcwd: string;\n\n\tcustomTypes: CustomTypesManager;\n\tplugins: PluginsManager;\n\tprismicRepository: PrismicRepositoryManager;\n\tproject: ProjectManager;\n\tscreenshots: ScreenshotsManager;\n\tsimulator: SimulatorManager;\n\tslices: SlicesManager;\n\tsnippets: SnippetsManager;\n\tdocumentation: DocumentationManager;\n\tsliceTemplateLibrary: SliceTemplateLibraryManager;\n\ttelemetry: TelemetryManager;\n\tuser: UserManager;\n\tversions: VersionsManager;\n\tgit: GitManager;\n\n\tconstructor(args?: SliceMachineManagerConstructorArgs) {\n\t\t// _prismicAuthManager must be set at least before UserManager\n\t\t// is instantiated. It depends on the PrismicAuthManager for\n\t\t// authentication-related methods.\n\t\tthis._prismicAuthManager = createPrismicAuthManager();\n\n\t\tthis.user = new UserManager(this);\n\t\tthis.prismicRepository = new PrismicRepositoryManager(this);\n\n\t\tthis.plugins = new PluginsManager(this, {\n\t\t\tnativePlugins: args?.nativePlugins,\n\t\t});\n\n\t\tthis.project = new ProjectManager(this);\n\t\tthis.customTypes = new CustomTypesManager(this);\n\t\tthis.slices = new SlicesManager(this);\n\t\tthis.snippets = new SnippetsManager(this);\n\t\tthis.screenshots = new ScreenshotsManager(this);\n\t\tthis.simulator = new SimulatorManager(this);\n\t\tthis.documentation = new DocumentationManager(this);\n\t\tthis.sliceTemplateLibrary = new SliceTemplateLibraryManager(this);\n\n\t\tthis.versions = new VersionsManager(this);\n\n\t\tthis.telemetry = new TelemetryManager(this);\n\n\t\tthis.git = new GitManager(this);\n\n\t\tthis.cwd = args?.cwd ?? process.cwd();\n\t}\n\n\t// The `_sliceMachinePluginRunner` property is hidden behind a function to\n\t// discourage access. Using a function deliberatly breaks the pattern\n\t// of other child managers that are accessible as properties, like\n\t// `project`, `plugins`, etc. We do not treat SliceMachinePluginRunner\n\t// as a child manager.\n\tgetSliceMachinePluginRunner(): SliceMachinePluginRunner | undefined {\n\t\treturn this._sliceMachinePluginRunner;\n\t}\n\n\t// The `_prismicAuthManager` property is hidden behind a function to\n\t// discourage access. Using a function deliberatly breaks the pattern\n\t// of other child managers that are accessible as properties, like\n\t// `project`, `plugins`, etc. We do not treat PrismicAuthManager as a\n\t// child manager.\n\tgetPrismicAuthManager(): PrismicAuthManager {\n\t\treturn this._prismicAuthManager;\n\t}\n\n\tgetAPIEndpoints(): APIEndpoints {\n\t\treturn API_ENDPOINTS;\n\t}\n\n\t// TODO: Remove this global-state method. It is expensive and a\n\t// potential source of bugs due to data inconsistency. SM UI relies on\n\t// it heavily, so removal will require significant effort.\n\tasync getState(): Promise<SliceMachineManagerGetStateReturnType> {\n\t\tconst [\n\t\t\t{ sliceMachineConfig, libraries },\n\t\t\t{ profile, remoteCustomTypes, remoteSlices, authError },\n\t\t\tcustomTypes,\n\t\t\tpackageManager,\n\t\t] = await Promise.all([\n\t\t\tthis.project.getSliceMachineConfig().then(async (sliceMachineConfig) => {\n\t\t\t\tconst libraries = await this._getLibraries(sliceMachineConfig);\n\n\t\t\t\treturn { sliceMachineConfig, libraries };\n\t\t\t}),\n\t\t\tthis._getProfile().then(async (profile) => {\n\t\t\t\tlet authError;\n\t\t\t\tif (profile) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst [remoteCustomTypes, remoteSlices] = await Promise.all([\n\t\t\t\t\t\t\tthis.customTypes.fetchRemoteCustomTypes(),\n\t\t\t\t\t\t\tthis.slices.fetchRemoteSlices(),\n\t\t\t\t\t\t]);\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tprofile,\n\t\t\t\t\t\t\tremoteCustomTypes,\n\t\t\t\t\t\t\tremoteSlices,\n\t\t\t\t\t\t\tauthError,\n\t\t\t\t\t\t};\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (error instanceof prismicCustomTypesClient.ForbiddenError) {\n\t\t\t\t\t\t\tauthError = {\n\t\t\t\t\t\t\t\tname: \"__stub__\",\n\t\t\t\t\t\t\t\tmessage: \"__stub__\",\n\t\t\t\t\t\t\t\treason: \"__stub__\",\n\t\t\t\t\t\t\t\tstatus: 403,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\terror instanceof UnauthenticatedError ||\n\t\t\t\t\t\t\terror instanceof prismicCustomTypesClient.UnauthorizedError\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tauthError = {\n\t\t\t\t\t\t\t\tname: \"__stub__\",\n\t\t\t\t\t\t\t\tmessage: \"__stub__\",\n\t\t\t\t\t\t\t\treason: \"__stub__\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tprofile,\n\t\t\t\t\tremoteCustomTypes: [],\n\t\t\t\t\tremoteSlices: [],\n\t\t\t\t\tauthError,\n\t\t\t\t};\n\t\t\t}),\n\t\t\tthis._getCustomTypes(),\n\t\t\tthis.project.detectPackageManager(),\n\t\t]);\n\n\t\t// SM UI detects if a user is logged out by looking at\n\t\t// `clientError`. Here, we simulate what the old core does by\n\t\t// returning an `ErrorWithStatus`-like object if the user does\n\t\t// not have access to the repository or is not logged in.\n\t\tconst clientError: SliceMachineManagerGetStateReturnType[\"clientError\"] =\n\t\t\tauthError ||\n\t\t\t(profile\n\t\t\t\t? undefined\n\t\t\t\t: {\n\t\t\t\t\t\tname: \"__stub__\",\n\t\t\t\t\t\tmessage: \"__stub__\",\n\t\t\t\t\t\treason: \"__stub__\",\n\t\t\t\t\t\tstatus: 401, // Needed to trigger the unauthorized flow.\n\t\t\t\t });\n\n\t\treturn {\n\t\t\tenv: {\n\t\t\t\tmanifest: {\n\t\t\t\t\tapiEndpoint:\n\t\t\t\t\t\tsliceMachineConfig.apiEndpoint ||\n\t\t\t\t\t\tbuildPrismicRepositoryAPIEndpoint(\n\t\t\t\t\t\t\tsliceMachineConfig.repositoryName,\n\t\t\t\t\t\t),\n\t\t\t\t\tlocalSliceSimulatorURL: sliceMachineConfig.localSliceSimulatorURL,\n\t\t\t\t},\n\t\t\t\tpackageManager,\n\t\t\t\trepo: sliceMachineConfig.repositoryName,\n\t\t\t\tintercomHash: profile?.intercomHash,\n\t\t\t\tshortId: profile?.shortId,\n\t\t\t\tendpoints: this.getAPIEndpoints(),\n\t\t\t},\n\t\t\tlibraries,\n\t\t\tcustomTypes,\n\t\t\tremoteCustomTypes,\n\t\t\tremoteSlices,\n\t\t\tclientError,\n\t\t};\n\t}\n\n\tprivate async _getProfile(): Promise<PrismicUserProfile | undefined> {\n\t\tlet profile: PrismicUserProfile | undefined;\n\n\t\tconst isLoggedIn = await this.user.checkIsLoggedIn();\n\n\t\tif (isLoggedIn) {\n\t\t\tprofile = await this.user.getProfile();\n\t\t\tawait this.user.refreshAuthenticationToken();\n\t\t}\n\n\t\treturn profile;\n\t}\n\n\tprivate async _getLibraries(\n\t\tsliceMachineConfig: SliceMachineConfig,\n\t): Promise<SliceMachineManagerGetStateReturnType[\"libraries\"]> {\n\t\tconst libraries: SliceMachineManagerGetStateReturnType[\"libraries\"] = [];\n\n\t\tif (sliceMachineConfig.libraries) {\n\t\t\tawait Promise.all(\n\t\t\t\tsliceMachineConfig.libraries.map(async (libraryID) => {\n\t\t\t\t\tconst { sliceIDs } = await this.slices.readSliceLibrary({\n\t\t\t\t\t\tlibraryID,\n\t\t\t\t\t});\n\n\t\t\t\t\tif (sliceIDs) {\n\t\t\t\t\t\tconst components: SliceMachineManagerGetStateReturnType[\"libraries\"][number][\"components\"] =\n\t\t\t\t\t\t\t[];\n\n\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\tsliceIDs.map(async (sliceID) => {\n\t\t\t\t\t\t\t\tconst [{ model }, { mocks }] = await Promise.all([\n\t\t\t\t\t\t\t\t\tthis.slices.readSlice({ libraryID, sliceID }),\n\t\t\t\t\t\t\t\t\tthis.slices.readSliceMocks({ libraryID, sliceID }),\n\t\t\t\t\t\t\t\t]);\n\n\t\t\t\t\t\t\t\tif (model) {\n\t\t\t\t\t\t\t\t\tconst screenshots: (typeof components)[number][\"screenshots\"] =\n\t\t\t\t\t\t\t\t\t\t{};\n\t\t\t\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\t\t\t\tmodel.variations.map(async (variation) => {\n\t\t\t\t\t\t\t\t\t\t\tconst screenshot = await this.slices.readSliceScreenshot({\n\t\t\t\t\t\t\t\t\t\t\t\tlibraryID,\n\t\t\t\t\t\t\t\t\t\t\t\tsliceID,\n\t\t\t\t\t\t\t\t\t\t\t\tvariationID: variation.id,\n\t\t\t\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\t\t\t\tif (screenshot.data) {\n\t\t\t\t\t\t\t\t\t\t\t\tscreenshots[variation.id] = {\n\t\t\t\t\t\t\t\t\t\t\t\t\thash: createContentDigest(screenshot.data),\n\t\t\t\t\t\t\t\t\t\t\t\t\tdata: screenshot.data,\n\t\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\tcomponents.push({\n\t\t\t\t\t\t\t\t\t\tfrom: libraryID,\n\t\t\t\t\t\t\t\t\t\thref: libraryID.replace(/\\//g, \"--\"),\n\t\t\t\t\t\t\t\t\t\tpathToSlice: \"pathToSlice\",\n\t\t\t\t\t\t\t\t\t\tfileName: \"fileName\",\n\t\t\t\t\t\t\t\t\t\textension: \"extension\",\n\t\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t\t\tscreenshots,\n\t\t\t\t\t\t\t\t\t\tmocks,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tlibraries.push({\n\t\t\t\t\t\t\tname: libraryID,\n\t\t\t\t\t\t\tpath: libraryID,\n\t\t\t\t\t\t\tisLocal: true, // TODO: Do we still support node_modules-based libraries?\n\t\t\t\t\t\t\tcomponents,\n\t\t\t\t\t\t\tmeta: {\n\t\t\t\t\t\t\t\t// TODO: Do we still support node_modules-based libraries?\n\t\t\t\t\t\t\t\tisNodeModule: false,\n\t\t\t\t\t\t\t\tisDownloaded: false,\n\t\t\t\t\t\t\t\tisManual: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\t// Preserve library order from config file\n\t\treturn libraries.sort((library1, library2) => {\n\t\t\tconst libraryIndex1 =\n\t\t\t\tsliceMachineConfig.libraries?.indexOf(library1.name) || 0;\n\t\t\tconst libraryIndex2 =\n\t\t\t\tsliceMachineConfig.libraries?.indexOf(library2.name) || 0;\n\n\t\t\treturn Math.sign(libraryIndex1 - libraryIndex2);\n\t\t});\n\t}\n\n\tprivate async _getCustomTypes(): Promise<\n\t\tSliceMachineManagerGetStateReturnType[\"customTypes\"]\n\t> {\n\t\tconst customTypes: SliceMachineManagerGetStateReturnType[\"customTypes\"] =\n\t\t\t[];\n\n\t\tconst { ids: customTypeIDs } =\n\t\t\tawait this.customTypes.readCustomTypeLibrary();\n\n\t\tif (customTypeIDs) {\n\t\t\tawait Promise.all(\n\t\t\t\tcustomTypeIDs.map(async (customTypeID) => {\n\t\t\t\t\tconst { model } = await this.customTypes.readCustomType({\n\t\t\t\t\t\tid: customTypeID,\n\t\t\t\t\t});\n\n\t\t\t\t\tif (model) {\n\t\t\t\t\t\tcustomTypes.push(model);\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\treturn customTypes;\n\t}\n}\n"],"names":["sliceMachineConfig","libraries","profile","authError","remoteCustomTypes","remoteSlices"],"mappings":"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"}
@@ -264,7 +264,7 @@ Error Message: ${error2.message}`);
264
264
  const { environment: activeEnvironmentDomain } = await this.readEnvironment();
265
265
  const cachedActiveEnvironment = findEnvironment.findEnvironment(activeEnvironmentDomain, this._cachedEnvironments || []);
266
266
  if (cachedActiveEnvironment) {
267
- return { activeEnvironment: cachedActiveEnvironment };
267
+ return { type: "ok", activeEnvironment: cachedActiveEnvironment };
268
268
  }
269
269
  const { environments } = await this.prismicRepository.fetchEnvironments();
270
270
  if (environments) {
@@ -272,9 +272,12 @@ Error Message: ${error2.message}`);
272
272
  }
273
273
  const activeEnvironment = findEnvironment.findEnvironment(activeEnvironmentDomain, this._cachedEnvironments || []);
274
274
  if (!activeEnvironment) {
275
- throw new errors.InvalidActiveEnvironmentError();
275
+ return {
276
+ type: "error",
277
+ error: new errors.InvalidActiveEnvironmentError()
278
+ };
276
279
  }
277
- return { activeEnvironment };
280
+ return { type: "ok", activeEnvironment };
278
281
  }
279
282
  async detectVersionControlSystem() {
280
283
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectManager.cjs","sources":["../../../../src/managers/project/ProjectManager.ts"],"sourcesContent":["import * as fs from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport { detect as niDetect } from \"@antfu/ni\";\nimport { ExecaChildProcess } from \"execa\";\nimport {\n\tHookError,\n\tCallHookReturnType,\n\tProjectEnvironmentUpdateHook,\n} from \"@slicemachine/plugin-kit\";\nimport * as t from \"io-ts\";\n\nimport { DecodeError } from \"../../lib/DecodeError\";\nimport { assertPluginsInitialized } from \"../../lib/assertPluginsInitialized\";\nimport { decodeHookResult } from \"../../lib/decodeHookResult\";\nimport { decodeSliceMachineConfig } from \"../../lib/decodeSliceMachineConfig\";\nimport { findEnvironment } from \"../../lib/findEnvironment\";\nimport { format } from \"../../lib/format\";\nimport { installDependencies } from \"../../lib/installDependencies\";\nimport { locateFileUpward } from \"../../lib/locateFileUpward\";\nimport { requireResolve } from \"../../lib/requireResolve\";\n\nimport {\n\tPackageManager,\n\tSliceMachineConfig,\n\tOnlyHookErrors,\n} from \"../../types\";\n\nimport {\n\tSliceMachineError,\n\tInternalError,\n\tPluginError,\n\tInvalidActiveEnvironmentError,\n} from \"../../errors\";\n\nimport { SLICE_MACHINE_CONFIG_FILENAME } from \"../../constants/SLICE_MACHINE_CONFIG_FILENAME\";\nimport { TS_CONFIG_FILENAME } from \"../../constants/TS_CONFIG_FILENAME\";\nimport { SLICE_MACHINE_NPM_PACKAGE_NAME } from \"../../constants/SLICE_MACHINE_NPM_PACKAGE_NAME\";\n\nimport { BaseManager } from \"../BaseManager\";\nimport { Environment } from \"../prismicRepository/types\";\n\ntype ProjectManagerGetSliceMachineConfigPathArgs = {\n\tignoreCache?: boolean;\n};\n\ntype ProjectManagerGetRootArgs = {\n\tignoreCache?: boolean;\n};\n\ntype ProjectManagerCheckIsTypeScriptArgs = {\n\trootOverride?: string;\n};\n\ntype ProjectManagerWriteSliceMachineConfigArgs = {\n\tconfig: SliceMachineConfig;\n\tpath?: string;\n};\n\ntype ProjectManagerInitProjectArgs = {\n\tlog?: (message: string) => void;\n};\n\ntype ProjectManagerDetectPackageManager = {\n\troot?: string;\n};\n\ntype ProjectManagerInstallDependenciesArgs = {\n\tdependencies: Record<string, string>;\n\tdev?: boolean;\n\tpackageManager?: PackageManager;\n\tlog?: (message: string) => void;\n};\n\ntype ProjectManagerInstallDependenciesReturnType = {\n\texecaProcess: ExecaChildProcess;\n};\n\ntype ProjectManagerReadEnvironmentReturnType = {\n\tenvironment: string | undefined;\n\terrors: (DecodeError | HookError)[];\n};\n\ntype ProjectManagerUpdateEnvironmentArgs = {\n\tenvironment: string | undefined;\n};\n\ntype ProjectManagerFetchActiveEnvironmentReturnType = {\n\tactiveEnvironment: Environment;\n};\n\nexport class ProjectManager extends BaseManager {\n\tprivate _cachedRoot: string | undefined;\n\tprivate _cachedSliceMachineConfigPath: string | undefined;\n\tprivate _cachedSliceMachineConfig: SliceMachineConfig | undefined;\n\tprivate _cachedEnvironments: Environment[] | undefined;\n\n\tasync getSliceMachineConfigPath(\n\t\targs?: ProjectManagerGetSliceMachineConfigPathArgs,\n\t): Promise<string> {\n\t\tif (this._cachedSliceMachineConfigPath && !args?.ignoreCache) {\n\t\t\treturn this._cachedSliceMachineConfigPath;\n\t\t}\n\n\t\ttry {\n\t\t\tthis._cachedSliceMachineConfigPath = await locateFileUpward(\n\t\t\t\tSLICE_MACHINE_CONFIG_FILENAME,\n\t\t\t\t{ startDir: this.cwd },\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Could not find a ${SLICE_MACHINE_CONFIG_FILENAME} file. Please create a config file at the root of your project.`,\n\t\t\t);\n\t\t}\n\n\t\treturn this._cachedSliceMachineConfigPath;\n\t}\n\n\tasync getRoot(args?: ProjectManagerGetRootArgs): Promise<string> {\n\t\tif (this._cachedRoot && !args?.ignoreCache) {\n\t\t\treturn this._cachedRoot;\n\t\t}\n\n\t\tconst sliceMachineConfigFilePath = await this.getSliceMachineConfigPath({\n\t\t\tignoreCache: args?.ignoreCache,\n\t\t});\n\n\t\tthis._cachedRoot = path.dirname(sliceMachineConfigFilePath);\n\n\t\treturn this._cachedRoot;\n\t}\n\n\tasync suggestRoot(): Promise<string> {\n\t\tconst suggestedRootPackageJSON = await locateFileUpward(\"package.json\", {\n\t\t\tstartDir: this.cwd,\n\t\t});\n\n\t\treturn path.dirname(suggestedRootPackageJSON);\n\t}\n\n\tasync suggestSliceMachineConfigPath(): Promise<string> {\n\t\tconst suggestedRoot = await this.suggestRoot();\n\n\t\treturn path.resolve(suggestedRoot, SLICE_MACHINE_CONFIG_FILENAME);\n\t}\n\n\tasync checkIsTypeScript(\n\t\targs?: ProjectManagerCheckIsTypeScriptArgs,\n\t): Promise<boolean> {\n\t\tconst root = args?.rootOverride || (await this.getRoot());\n\t\tconst rootTSConfigPath = path.resolve(root, TS_CONFIG_FILENAME);\n\n\t\t// We just care if the file exists, we don't need access to it\n\t\treturn existsSync(rootTSConfigPath);\n\t}\n\n\tasync getSliceMachineConfig(): Promise<SliceMachineConfig> {\n\t\tif (this._cachedSliceMachineConfig) {\n\t\t\treturn this._cachedSliceMachineConfig;\n\t\t} else {\n\t\t\treturn await this.loadSliceMachineConfig();\n\t\t}\n\t}\n\n\tasync writeSliceMachineConfig(\n\t\targs: ProjectManagerWriteSliceMachineConfigArgs,\n\t): Promise<void> {\n\t\tconst configFilePath =\n\t\t\targs.path || (await this.getSliceMachineConfigPath());\n\n\t\tconst config = await format(\n\t\t\tJSON.stringify(args.config, null, 2),\n\t\t\tconfigFilePath,\n\t\t);\n\n\t\tawait fs.writeFile(configFilePath, config, \"utf-8\");\n\t\tdelete this._cachedSliceMachineConfig; // Clear config cache\n\t}\n\n\tasync loadSliceMachineConfig(): Promise<SliceMachineConfig> {\n\t\t// TODO: Reload plugins with a fresh plugin runner. Plugins may\n\t\t// have been added or removed.\n\t\tconst configFilePath = await this.getSliceMachineConfigPath();\n\n\t\tlet rawConfig: unknown | undefined;\n\t\ttry {\n\t\t\tconst contents = await fs.readFile(configFilePath, \"utf8\");\n\t\t\trawConfig = JSON.parse(contents);\n\t\t} catch (error) {\n\t\t\tif (error instanceof SyntaxError) {\n\t\t\t\tthrow new SliceMachineError(\n\t\t\t\t\t`Could not parse config file at ${configFilePath}.\\n\\nError Message: ${error.message}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Noop, more specific error is thrown after\n\t\t}\n\n\t\tif (!rawConfig) {\n\t\t\t// TODO: Write a more friendly and useful message.\n\t\t\tthrow new Error(\"No config found.\");\n\t\t}\n\n\t\tconst { value: sliceMachineConfig, error } =\n\t\t\tdecodeSliceMachineConfig(rawConfig);\n\n\t\tif (error) {\n\t\t\t// TODO: Write a more friendly and useful message.\n\t\t\tthrow new Error(`Invalid config. ${error.errors.join(\", \")}`, {\n\t\t\t\tcause: { rawConfig },\n\t\t\t});\n\t\t}\n\n\t\t// Allow cached config reading using `SliceMachineManager.prototype.getProjectConfig()`.\n\t\tthis._cachedSliceMachineConfig = sliceMachineConfig;\n\n\t\treturn sliceMachineConfig;\n\t}\n\n\tasync locateSliceMachineUIDir(): Promise<string> {\n\t\tconst projectRoot = await this.getRoot();\n\n\t\tconst sliceMachinePackageJSONPath = requireResolve(\n\t\t\t`${SLICE_MACHINE_NPM_PACKAGE_NAME}/package.json`,\n\t\t\tpath.join(projectRoot, \"index.js\"),\n\t\t);\n\n\t\treturn path.dirname(sliceMachinePackageJSONPath);\n\t}\n\n\t/**\n\t * Returns the project's repository name (i.e. the production environment). It\n\t * ignores the currently selected environment.\n\t *\n\t * Use this method to retrieve the production environment domain.\n\t *\n\t * @returns The project's repository name.\n\t */\n\tasync getRepositoryName(): Promise<string> {\n\t\tconst sliceMachineConfig = await this.getSliceMachineConfig();\n\n\t\treturn sliceMachineConfig.repositoryName;\n\t}\n\n\t/**\n\t * Returns the currently selected environment domain if set. If an environment\n\t * is not set, it returns the project's repository name (the production\n\t * environment).\n\t *\n\t * Use this method to retrieve the repository name to be sent with Prismic API\n\t * requests.\n\t *\n\t * @returns The resolved repository name.\n\t */\n\tasync getResolvedRepositoryName(): Promise<string> {\n\t\tconst repositoryName = await this.getRepositoryName();\n\n\t\tconst supportsEnvironments = this.project.checkSupportsEnvironments();\n\t\tif (!supportsEnvironments) {\n\t\t\treturn repositoryName;\n\t\t}\n\n\t\tconst { environment } = await this.project.readEnvironment();\n\n\t\treturn environment ?? repositoryName;\n\t}\n\n\tasync getAdapterName(): Promise<string> {\n\t\tconst sliceMachineConfig = await this.getSliceMachineConfig();\n\t\tconst adapterName =\n\t\t\ttypeof sliceMachineConfig.adapter === \"string\"\n\t\t\t\t? sliceMachineConfig.adapter\n\t\t\t\t: sliceMachineConfig.adapter.resolve;\n\n\t\treturn adapterName;\n\t}\n\n\tasync locateAdapterDir(): Promise<string> {\n\t\tconst projectRoot = await this.getRoot();\n\t\tconst adapterName = await this.getAdapterName();\n\t\tconst adapterPackageJSONPath = requireResolve(\n\t\t\t`${adapterName}/package.json`,\n\t\t\tpath.join(projectRoot, \"index.js\"),\n\t\t);\n\n\t\treturn path.dirname(adapterPackageJSONPath);\n\t}\n\n\tasync initProject(args?: ProjectManagerInitProjectArgs): Promise<void> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\t// eslint-disable-next-line no-console\n\t\tconst log = args?.log || console.log.bind(this);\n\n\t\tconst { errors } = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"project:init\",\n\t\t\t{\n\t\t\t\tlog,\n\t\t\t\tinstallDependencies: async (args) => {\n\t\t\t\t\tconst { execaProcess } = await this.installDependencies({\n\t\t\t\t\t\tdependencies: args.dependencies,\n\t\t\t\t\t\tdev: args.dev,\n\t\t\t\t\t\tlog,\n\t\t\t\t\t});\n\n\t\t\t\t\tawait execaProcess;\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\tif (errors.length > 0) {\n\t\t\t// TODO: Provide better error message.\n\t\t\tthrow new SliceMachineError(\n\t\t\t\t`Failed to initialize project: ${errors.join(\", \")}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync detectPackageManager(\n\t\targs?: ProjectManagerDetectPackageManager,\n\t): Promise<PackageManager> {\n\t\tconst projectRoot = args?.root || (await this.getRoot());\n\n\t\tconst packageManager = await niDetect({\n\t\t\tautoInstall: true,\n\t\t\tcwd: projectRoot,\n\t\t});\n\n\t\treturn packageManager || \"npm\";\n\t}\n\n\tasync installDependencies(\n\t\targs: ProjectManagerInstallDependenciesArgs,\n\t): Promise<ProjectManagerInstallDependenciesReturnType> {\n\t\tconst packageManager =\n\t\t\targs.packageManager || (await this.detectPackageManager());\n\n\t\t// eslint-disable-next-line no-console\n\t\tconst log = args.log || console.log.bind(this);\n\n\t\tconst wrappedLogger = (data: Buffer | string | null) => {\n\t\t\tif (data instanceof Buffer) {\n\t\t\t\tlog(data.toString());\n\t\t\t} else if (typeof data === \"string\") {\n\t\t\t\tlog(data);\n\t\t\t}\n\t\t};\n\n\t\ttry {\n\t\t\tconst { execaProcess } = await installDependencies({\n\t\t\t\tpackageManager,\n\t\t\t\tdependencies: args.dependencies,\n\t\t\t\tdev: args.dev,\n\t\t\t});\n\n\t\t\t// Don't clutter console with logs when process is non TTY (CI, etc.)\n\t\t\tif (process.stdout.isTTY || process.env.NODE_ENV === \"test\") {\n\t\t\t\texecaProcess.stdout?.on(\"data\", wrappedLogger);\n\t\t\t}\n\t\t\texecaProcess.stderr?.on(\"data\", wrappedLogger);\n\n\t\t\treturn {\n\t\t\t\texecaProcess,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tif (\n\t\t\t\terror instanceof Error &&\n\t\t\t\t\"shortMessage\" in error &&\n\t\t\t\t\"stderr\" in error\n\t\t\t) {\n\t\t\t\tthrow new InternalError(\"Package installation failed\", {\n\t\t\t\t\tcause: error,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tcheckSupportsEnvironments(): boolean {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\treturn (\n\t\t\tthis.sliceMachinePluginRunner.hooksForType(\"project:environment:read\")\n\t\t\t\t.length > 0 &&\n\t\t\tthis.sliceMachinePluginRunner.hooksForType(\"project:environment:update\")\n\t\t\t\t.length > 0\n\t\t);\n\t}\n\n\tasync readEnvironment(): Promise<ProjectManagerReadEnvironmentReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tawait this._assertAdapterSupportsEnvironments();\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"project:environment:read\",\n\t\t\tundefined,\n\t\t);\n\t\tconst { data, errors } = decodeHookResult(\n\t\t\tt.type({\n\t\t\t\tenvironment: t.union([t.undefined, t.string]),\n\t\t\t}),\n\t\t\thookResult,\n\t\t);\n\n\t\t// An undefined value is equivalent to the production environment.\n\t\t// We cast to undefined.\n\t\tconst repositoryName = await this.project.getRepositoryName();\n\t\tconst environmentDomain =\n\t\t\tdata[0]?.environment === repositoryName\n\t\t\t\t? undefined\n\t\t\t\t: data[0]?.environment;\n\n\t\treturn {\n\t\t\tenvironment: environmentDomain,\n\t\t\terrors,\n\t\t};\n\t}\n\n\tasync updateEnvironment(\n\t\targs: ProjectManagerUpdateEnvironmentArgs,\n\t): Promise<OnlyHookErrors<CallHookReturnType<ProjectEnvironmentUpdateHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tawait this._assertAdapterSupportsEnvironments();\n\n\t\tconst repositoryName = await this.project.getRepositoryName();\n\t\tconst environment =\n\t\t\targs.environment === repositoryName ? undefined : args.environment;\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"project:environment:update\",\n\t\t\t{ environment },\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync fetchActiveEnvironment(): Promise<ProjectManagerFetchActiveEnvironmentReturnType> {\n\t\tconst { environment: activeEnvironmentDomain } =\n\t\t\tawait this.readEnvironment();\n\n\t\t// We can assume an environment cannot change its kind. If the\n\t\t// environment exists in the cached list, we are confident it\n\t\t// will not change.\n\t\tconst cachedActiveEnvironment = findEnvironment(\n\t\t\tactiveEnvironmentDomain,\n\t\t\tthis._cachedEnvironments || [],\n\t\t);\n\t\tif (cachedActiveEnvironment) {\n\t\t\treturn { activeEnvironment: cachedActiveEnvironment };\n\t\t}\n\n\t\t// If the environment is not in the cached environments list, we\n\t\t// must fetch a fresh list and set the cache.\n\t\tconst { environments } = await this.prismicRepository.fetchEnvironments();\n\t\t// TODO: Remove the wrapping if statement when\n\t\t// `this.prismicRepository.fetchEnvironments()` is able to throw\n\t\t// normally. The method returns an object with an `error`\n\t\t// property at the time of this writing, which means we need to\n\t\t// check if the `environments` property exists.\n\t\tif (environments) {\n\t\t\tthis._cachedEnvironments = environments;\n\t\t}\n\n\t\tconst activeEnvironment = findEnvironment(\n\t\t\tactiveEnvironmentDomain,\n\t\t\tthis._cachedEnvironments || [],\n\t\t);\n\n\t\tif (!activeEnvironment) {\n\t\t\tthrow new InvalidActiveEnvironmentError();\n\t\t}\n\n\t\treturn { activeEnvironment };\n\t}\n\n\tasync detectVersionControlSystem(): Promise<string | \"_unknown\"> {\n\t\ttry {\n\t\t\tconst projectRoot = await this.getRoot();\n\n\t\t\tif (existsSync(path.join(projectRoot, \".git\"))) {\n\t\t\t\treturn \"Git\";\n\t\t\t}\n\n\t\t\tif (existsSync(path.join(projectRoot, \".svn\"))) {\n\t\t\t\treturn \"SVN\";\n\t\t\t}\n\n\t\t\tif (existsSync(path.join(projectRoot, \".hg\"))) {\n\t\t\t\treturn \"Mercurial\";\n\t\t\t}\n\n\t\t\tif (existsSync(path.join(projectRoot, \"CVS\"))) {\n\t\t\t\treturn \"CVS\";\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (import.meta.env.DEV) {\n\t\t\t\tconsole.error(\"Failed to detect Version Control System:\", error);\n\t\t\t}\n\t\t}\n\n\t\treturn \"_unknown\";\n\t}\n\n\tprivate async _assertAdapterSupportsEnvironments(): Promise<void> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst supportsEnvironments = this.checkSupportsEnvironments();\n\n\t\tif (!supportsEnvironments) {\n\t\t\tconst adapterName = await this.project.getAdapterName();\n\n\t\t\tthrow new PluginError(\n\t\t\t\t`${adapterName} does not support environments. Use an adapter that implements the \\`project:environment:read\\` and \\`project:environment:update\\` hooks to use environments.`,\n\t\t\t);\n\t\t}\n\t}\n}\n"],"names":["BaseManager","locateFileUpward","SLICE_MACHINE_CONFIG_FILENAME","path","TS_CONFIG_FILENAME","existsSync","format","fs","error","SliceMachineError","decodeSliceMachineConfig","requireResolve","SLICE_MACHINE_NPM_PACKAGE_NAME","assertPluginsInitialized","errors","args","niDetect","installDependencies","InternalError","decodeHookResult","t","findEnvironment","InvalidActiveEnvironmentError","PluginError"],"mappings":"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"}
1
+ {"version":3,"file":"ProjectManager.cjs","sources":["../../../../src/managers/project/ProjectManager.ts"],"sourcesContent":["import * as fs from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport { detect as niDetect } from \"@antfu/ni\";\nimport { ExecaChildProcess } from \"execa\";\nimport {\n\tHookError,\n\tCallHookReturnType,\n\tProjectEnvironmentUpdateHook,\n} from \"@slicemachine/plugin-kit\";\nimport * as t from \"io-ts\";\n\nimport { DecodeError } from \"../../lib/DecodeError\";\nimport { assertPluginsInitialized } from \"../../lib/assertPluginsInitialized\";\nimport { decodeHookResult } from \"../../lib/decodeHookResult\";\nimport { decodeSliceMachineConfig } from \"../../lib/decodeSliceMachineConfig\";\nimport { findEnvironment } from \"../../lib/findEnvironment\";\nimport { format } from \"../../lib/format\";\nimport { installDependencies } from \"../../lib/installDependencies\";\nimport { locateFileUpward } from \"../../lib/locateFileUpward\";\nimport { requireResolve } from \"../../lib/requireResolve\";\n\nimport {\n\tPackageManager,\n\tSliceMachineConfig,\n\tOnlyHookErrors,\n} from \"../../types\";\n\nimport {\n\tSliceMachineError,\n\tInternalError,\n\tPluginError,\n\tInvalidActiveEnvironmentError,\n} from \"../../errors\";\n\nimport { SLICE_MACHINE_CONFIG_FILENAME } from \"../../constants/SLICE_MACHINE_CONFIG_FILENAME\";\nimport { TS_CONFIG_FILENAME } from \"../../constants/TS_CONFIG_FILENAME\";\nimport { SLICE_MACHINE_NPM_PACKAGE_NAME } from \"../../constants/SLICE_MACHINE_NPM_PACKAGE_NAME\";\n\nimport { BaseManager } from \"../BaseManager\";\nimport { Environment } from \"../prismicRepository/types\";\n\ntype ProjectManagerGetSliceMachineConfigPathArgs = {\n\tignoreCache?: boolean;\n};\n\ntype ProjectManagerGetRootArgs = {\n\tignoreCache?: boolean;\n};\n\ntype ProjectManagerCheckIsTypeScriptArgs = {\n\trootOverride?: string;\n};\n\ntype ProjectManagerWriteSliceMachineConfigArgs = {\n\tconfig: SliceMachineConfig;\n\tpath?: string;\n};\n\ntype ProjectManagerInitProjectArgs = {\n\tlog?: (message: string) => void;\n};\n\ntype ProjectManagerDetectPackageManager = {\n\troot?: string;\n};\n\ntype ProjectManagerInstallDependenciesArgs = {\n\tdependencies: Record<string, string>;\n\tdev?: boolean;\n\tpackageManager?: PackageManager;\n\tlog?: (message: string) => void;\n};\n\ntype ProjectManagerInstallDependenciesReturnType = {\n\texecaProcess: ExecaChildProcess;\n};\n\ntype ProjectManagerReadEnvironmentReturnType = {\n\tenvironment: string | undefined;\n\terrors: (DecodeError | HookError)[];\n};\n\ntype ProjectManagerUpdateEnvironmentArgs = {\n\tenvironment: string | undefined;\n};\n\ntype ProjectManagerFetchActiveEnvironmentReturnType =\n\t| { type: \"ok\"; activeEnvironment: Environment }\n\t| { type: \"error\"; error: InvalidActiveEnvironmentError };\n\nexport class ProjectManager extends BaseManager {\n\tprivate _cachedRoot: string | undefined;\n\tprivate _cachedSliceMachineConfigPath: string | undefined;\n\tprivate _cachedSliceMachineConfig: SliceMachineConfig | undefined;\n\tprivate _cachedEnvironments: Environment[] | undefined;\n\n\tasync getSliceMachineConfigPath(\n\t\targs?: ProjectManagerGetSliceMachineConfigPathArgs,\n\t): Promise<string> {\n\t\tif (this._cachedSliceMachineConfigPath && !args?.ignoreCache) {\n\t\t\treturn this._cachedSliceMachineConfigPath;\n\t\t}\n\n\t\ttry {\n\t\t\tthis._cachedSliceMachineConfigPath = await locateFileUpward(\n\t\t\t\tSLICE_MACHINE_CONFIG_FILENAME,\n\t\t\t\t{ startDir: this.cwd },\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Could not find a ${SLICE_MACHINE_CONFIG_FILENAME} file. Please create a config file at the root of your project.`,\n\t\t\t);\n\t\t}\n\n\t\treturn this._cachedSliceMachineConfigPath;\n\t}\n\n\tasync getRoot(args?: ProjectManagerGetRootArgs): Promise<string> {\n\t\tif (this._cachedRoot && !args?.ignoreCache) {\n\t\t\treturn this._cachedRoot;\n\t\t}\n\n\t\tconst sliceMachineConfigFilePath = await this.getSliceMachineConfigPath({\n\t\t\tignoreCache: args?.ignoreCache,\n\t\t});\n\n\t\tthis._cachedRoot = path.dirname(sliceMachineConfigFilePath);\n\n\t\treturn this._cachedRoot;\n\t}\n\n\tasync suggestRoot(): Promise<string> {\n\t\tconst suggestedRootPackageJSON = await locateFileUpward(\"package.json\", {\n\t\t\tstartDir: this.cwd,\n\t\t});\n\n\t\treturn path.dirname(suggestedRootPackageJSON);\n\t}\n\n\tasync suggestSliceMachineConfigPath(): Promise<string> {\n\t\tconst suggestedRoot = await this.suggestRoot();\n\n\t\treturn path.resolve(suggestedRoot, SLICE_MACHINE_CONFIG_FILENAME);\n\t}\n\n\tasync checkIsTypeScript(\n\t\targs?: ProjectManagerCheckIsTypeScriptArgs,\n\t): Promise<boolean> {\n\t\tconst root = args?.rootOverride || (await this.getRoot());\n\t\tconst rootTSConfigPath = path.resolve(root, TS_CONFIG_FILENAME);\n\n\t\t// We just care if the file exists, we don't need access to it\n\t\treturn existsSync(rootTSConfigPath);\n\t}\n\n\tasync getSliceMachineConfig(): Promise<SliceMachineConfig> {\n\t\tif (this._cachedSliceMachineConfig) {\n\t\t\treturn this._cachedSliceMachineConfig;\n\t\t} else {\n\t\t\treturn await this.loadSliceMachineConfig();\n\t\t}\n\t}\n\n\tasync writeSliceMachineConfig(\n\t\targs: ProjectManagerWriteSliceMachineConfigArgs,\n\t): Promise<void> {\n\t\tconst configFilePath =\n\t\t\targs.path || (await this.getSliceMachineConfigPath());\n\n\t\tconst config = await format(\n\t\t\tJSON.stringify(args.config, null, 2),\n\t\t\tconfigFilePath,\n\t\t);\n\n\t\tawait fs.writeFile(configFilePath, config, \"utf-8\");\n\t\tdelete this._cachedSliceMachineConfig; // Clear config cache\n\t}\n\n\tasync loadSliceMachineConfig(): Promise<SliceMachineConfig> {\n\t\t// TODO: Reload plugins with a fresh plugin runner. Plugins may\n\t\t// have been added or removed.\n\t\tconst configFilePath = await this.getSliceMachineConfigPath();\n\n\t\tlet rawConfig: unknown | undefined;\n\t\ttry {\n\t\t\tconst contents = await fs.readFile(configFilePath, \"utf8\");\n\t\t\trawConfig = JSON.parse(contents);\n\t\t} catch (error) {\n\t\t\tif (error instanceof SyntaxError) {\n\t\t\t\tthrow new SliceMachineError(\n\t\t\t\t\t`Could not parse config file at ${configFilePath}.\\n\\nError Message: ${error.message}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Noop, more specific error is thrown after\n\t\t}\n\n\t\tif (!rawConfig) {\n\t\t\t// TODO: Write a more friendly and useful message.\n\t\t\tthrow new Error(\"No config found.\");\n\t\t}\n\n\t\tconst { value: sliceMachineConfig, error } =\n\t\t\tdecodeSliceMachineConfig(rawConfig);\n\n\t\tif (error) {\n\t\t\t// TODO: Write a more friendly and useful message.\n\t\t\tthrow new Error(`Invalid config. ${error.errors.join(\", \")}`, {\n\t\t\t\tcause: { rawConfig },\n\t\t\t});\n\t\t}\n\n\t\t// Allow cached config reading using `SliceMachineManager.prototype.getProjectConfig()`.\n\t\tthis._cachedSliceMachineConfig = sliceMachineConfig;\n\n\t\treturn sliceMachineConfig;\n\t}\n\n\tasync locateSliceMachineUIDir(): Promise<string> {\n\t\tconst projectRoot = await this.getRoot();\n\n\t\tconst sliceMachinePackageJSONPath = requireResolve(\n\t\t\t`${SLICE_MACHINE_NPM_PACKAGE_NAME}/package.json`,\n\t\t\tpath.join(projectRoot, \"index.js\"),\n\t\t);\n\n\t\treturn path.dirname(sliceMachinePackageJSONPath);\n\t}\n\n\t/**\n\t * Returns the project's repository name (i.e. the production environment). It\n\t * ignores the currently selected environment.\n\t *\n\t * Use this method to retrieve the production environment domain.\n\t *\n\t * @returns The project's repository name.\n\t */\n\tasync getRepositoryName(): Promise<string> {\n\t\tconst sliceMachineConfig = await this.getSliceMachineConfig();\n\n\t\treturn sliceMachineConfig.repositoryName;\n\t}\n\n\t/**\n\t * Returns the currently selected environment domain if set. If an environment\n\t * is not set, it returns the project's repository name (the production\n\t * environment).\n\t *\n\t * Use this method to retrieve the repository name to be sent with Prismic API\n\t * requests.\n\t *\n\t * @returns The resolved repository name.\n\t */\n\tasync getResolvedRepositoryName(): Promise<string> {\n\t\tconst repositoryName = await this.getRepositoryName();\n\n\t\tconst supportsEnvironments = this.project.checkSupportsEnvironments();\n\t\tif (!supportsEnvironments) {\n\t\t\treturn repositoryName;\n\t\t}\n\n\t\tconst { environment } = await this.project.readEnvironment();\n\n\t\treturn environment ?? repositoryName;\n\t}\n\n\tasync getAdapterName(): Promise<string> {\n\t\tconst sliceMachineConfig = await this.getSliceMachineConfig();\n\t\tconst adapterName =\n\t\t\ttypeof sliceMachineConfig.adapter === \"string\"\n\t\t\t\t? sliceMachineConfig.adapter\n\t\t\t\t: sliceMachineConfig.adapter.resolve;\n\n\t\treturn adapterName;\n\t}\n\n\tasync locateAdapterDir(): Promise<string> {\n\t\tconst projectRoot = await this.getRoot();\n\t\tconst adapterName = await this.getAdapterName();\n\t\tconst adapterPackageJSONPath = requireResolve(\n\t\t\t`${adapterName}/package.json`,\n\t\t\tpath.join(projectRoot, \"index.js\"),\n\t\t);\n\n\t\treturn path.dirname(adapterPackageJSONPath);\n\t}\n\n\tasync initProject(args?: ProjectManagerInitProjectArgs): Promise<void> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\t// eslint-disable-next-line no-console\n\t\tconst log = args?.log || console.log.bind(this);\n\n\t\tconst { errors } = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"project:init\",\n\t\t\t{\n\t\t\t\tlog,\n\t\t\t\tinstallDependencies: async (args) => {\n\t\t\t\t\tconst { execaProcess } = await this.installDependencies({\n\t\t\t\t\t\tdependencies: args.dependencies,\n\t\t\t\t\t\tdev: args.dev,\n\t\t\t\t\t\tlog,\n\t\t\t\t\t});\n\n\t\t\t\t\tawait execaProcess;\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\tif (errors.length > 0) {\n\t\t\t// TODO: Provide better error message.\n\t\t\tthrow new SliceMachineError(\n\t\t\t\t`Failed to initialize project: ${errors.join(\", \")}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync detectPackageManager(\n\t\targs?: ProjectManagerDetectPackageManager,\n\t): Promise<PackageManager> {\n\t\tconst projectRoot = args?.root || (await this.getRoot());\n\n\t\tconst packageManager = await niDetect({\n\t\t\tautoInstall: true,\n\t\t\tcwd: projectRoot,\n\t\t});\n\n\t\treturn packageManager || \"npm\";\n\t}\n\n\tasync installDependencies(\n\t\targs: ProjectManagerInstallDependenciesArgs,\n\t): Promise<ProjectManagerInstallDependenciesReturnType> {\n\t\tconst packageManager =\n\t\t\targs.packageManager || (await this.detectPackageManager());\n\n\t\t// eslint-disable-next-line no-console\n\t\tconst log = args.log || console.log.bind(this);\n\n\t\tconst wrappedLogger = (data: Buffer | string | null) => {\n\t\t\tif (data instanceof Buffer) {\n\t\t\t\tlog(data.toString());\n\t\t\t} else if (typeof data === \"string\") {\n\t\t\t\tlog(data);\n\t\t\t}\n\t\t};\n\n\t\ttry {\n\t\t\tconst { execaProcess } = await installDependencies({\n\t\t\t\tpackageManager,\n\t\t\t\tdependencies: args.dependencies,\n\t\t\t\tdev: args.dev,\n\t\t\t});\n\n\t\t\t// Don't clutter console with logs when process is non TTY (CI, etc.)\n\t\t\tif (process.stdout.isTTY || process.env.NODE_ENV === \"test\") {\n\t\t\t\texecaProcess.stdout?.on(\"data\", wrappedLogger);\n\t\t\t}\n\t\t\texecaProcess.stderr?.on(\"data\", wrappedLogger);\n\n\t\t\treturn {\n\t\t\t\texecaProcess,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tif (\n\t\t\t\terror instanceof Error &&\n\t\t\t\t\"shortMessage\" in error &&\n\t\t\t\t\"stderr\" in error\n\t\t\t) {\n\t\t\t\tthrow new InternalError(\"Package installation failed\", {\n\t\t\t\t\tcause: error,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tcheckSupportsEnvironments(): boolean {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\treturn (\n\t\t\tthis.sliceMachinePluginRunner.hooksForType(\"project:environment:read\")\n\t\t\t\t.length > 0 &&\n\t\t\tthis.sliceMachinePluginRunner.hooksForType(\"project:environment:update\")\n\t\t\t\t.length > 0\n\t\t);\n\t}\n\n\tasync readEnvironment(): Promise<ProjectManagerReadEnvironmentReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tawait this._assertAdapterSupportsEnvironments();\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"project:environment:read\",\n\t\t\tundefined,\n\t\t);\n\t\tconst { data, errors } = decodeHookResult(\n\t\t\tt.type({\n\t\t\t\tenvironment: t.union([t.undefined, t.string]),\n\t\t\t}),\n\t\t\thookResult,\n\t\t);\n\n\t\t// An undefined value is equivalent to the production environment.\n\t\t// We cast to undefined.\n\t\tconst repositoryName = await this.project.getRepositoryName();\n\t\tconst environmentDomain =\n\t\t\tdata[0]?.environment === repositoryName\n\t\t\t\t? undefined\n\t\t\t\t: data[0]?.environment;\n\n\t\treturn {\n\t\t\tenvironment: environmentDomain,\n\t\t\terrors,\n\t\t};\n\t}\n\n\tasync updateEnvironment(\n\t\targs: ProjectManagerUpdateEnvironmentArgs,\n\t): Promise<OnlyHookErrors<CallHookReturnType<ProjectEnvironmentUpdateHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tawait this._assertAdapterSupportsEnvironments();\n\n\t\tconst repositoryName = await this.project.getRepositoryName();\n\t\tconst environment =\n\t\t\targs.environment === repositoryName ? undefined : args.environment;\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"project:environment:update\",\n\t\t\t{ environment },\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync fetchActiveEnvironment(): Promise<ProjectManagerFetchActiveEnvironmentReturnType> {\n\t\tconst { environment: activeEnvironmentDomain } =\n\t\t\tawait this.readEnvironment();\n\n\t\t// We can assume an environment cannot change its kind. If the\n\t\t// environment exists in the cached list, we are confident it\n\t\t// will not change.\n\t\tconst cachedActiveEnvironment = findEnvironment(\n\t\t\tactiveEnvironmentDomain,\n\t\t\tthis._cachedEnvironments || [],\n\t\t);\n\t\tif (cachedActiveEnvironment) {\n\t\t\treturn { type: \"ok\", activeEnvironment: cachedActiveEnvironment };\n\t\t}\n\n\t\t// If the environment is not in the cached environments list, we\n\t\t// must fetch a fresh list and set the cache.\n\t\tconst { environments } = await this.prismicRepository.fetchEnvironments();\n\t\t// TODO: Remove the wrapping if statement when\n\t\t// `this.prismicRepository.fetchEnvironments()` is able to throw\n\t\t// normally. The method returns an object with an `error`\n\t\t// property at the time of this writing, which means we need to\n\t\t// check if the `environments` property exists.\n\t\tif (environments) {\n\t\t\tthis._cachedEnvironments = environments;\n\t\t}\n\n\t\tconst activeEnvironment = findEnvironment(\n\t\t\tactiveEnvironmentDomain,\n\t\t\tthis._cachedEnvironments || [],\n\t\t);\n\n\t\tif (!activeEnvironment) {\n\t\t\treturn {\n\t\t\t\ttype: \"error\",\n\t\t\t\terror: new InvalidActiveEnvironmentError(),\n\t\t\t};\n\t\t}\n\n\t\treturn { type: \"ok\", activeEnvironment: activeEnvironment };\n\t}\n\n\tasync detectVersionControlSystem(): Promise<string | \"_unknown\"> {\n\t\ttry {\n\t\t\tconst projectRoot = await this.getRoot();\n\n\t\t\tif (existsSync(path.join(projectRoot, \".git\"))) {\n\t\t\t\treturn \"Git\";\n\t\t\t}\n\n\t\t\tif (existsSync(path.join(projectRoot, \".svn\"))) {\n\t\t\t\treturn \"SVN\";\n\t\t\t}\n\n\t\t\tif (existsSync(path.join(projectRoot, \".hg\"))) {\n\t\t\t\treturn \"Mercurial\";\n\t\t\t}\n\n\t\t\tif (existsSync(path.join(projectRoot, \"CVS\"))) {\n\t\t\t\treturn \"CVS\";\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (import.meta.env.DEV) {\n\t\t\t\tconsole.error(\"Failed to detect Version Control System:\", error);\n\t\t\t}\n\t\t}\n\n\t\treturn \"_unknown\";\n\t}\n\n\tprivate async _assertAdapterSupportsEnvironments(): Promise<void> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst supportsEnvironments = this.checkSupportsEnvironments();\n\n\t\tif (!supportsEnvironments) {\n\t\t\tconst adapterName = await this.project.getAdapterName();\n\n\t\t\tthrow new PluginError(\n\t\t\t\t`${adapterName} does not support environments. Use an adapter that implements the \\`project:environment:read\\` and \\`project:environment:update\\` hooks to use environments.`,\n\t\t\t);\n\t\t}\n\t}\n}\n"],"names":["BaseManager","locateFileUpward","SLICE_MACHINE_CONFIG_FILENAME","path","TS_CONFIG_FILENAME","existsSync","format","fs","error","SliceMachineError","decodeSliceMachineConfig","requireResolve","SLICE_MACHINE_NPM_PACKAGE_NAME","assertPluginsInitialized","errors","args","niDetect","installDependencies","InternalError","decodeHookResult","t","findEnvironment","InvalidActiveEnvironmentError","PluginError"],"mappings":"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"}
@@ -2,6 +2,7 @@ import { ExecaChildProcess } from "execa";
2
2
  import { HookError, CallHookReturnType, ProjectEnvironmentUpdateHook } from "@slicemachine/plugin-kit";
3
3
  import { DecodeError } from "../../lib/DecodeError";
4
4
  import { PackageManager, SliceMachineConfig, OnlyHookErrors } from "../../types";
5
+ import { InvalidActiveEnvironmentError } from "../../errors";
5
6
  import { BaseManager } from "../BaseManager";
6
7
  import { Environment } from "../prismicRepository/types";
7
8
  type ProjectManagerGetSliceMachineConfigPathArgs = {
@@ -40,7 +41,11 @@ type ProjectManagerUpdateEnvironmentArgs = {
40
41
  environment: string | undefined;
41
42
  };
42
43
  type ProjectManagerFetchActiveEnvironmentReturnType = {
44
+ type: "ok";
43
45
  activeEnvironment: Environment;
46
+ } | {
47
+ type: "error";
48
+ error: InvalidActiveEnvironmentError;
44
49
  };
45
50
  export declare class ProjectManager extends BaseManager {
46
51
  private _cachedRoot;
@@ -243,7 +243,7 @@ Error Message: ${error2.message}`);
243
243
  const { environment: activeEnvironmentDomain } = await this.readEnvironment();
244
244
  const cachedActiveEnvironment = findEnvironment(activeEnvironmentDomain, this._cachedEnvironments || []);
245
245
  if (cachedActiveEnvironment) {
246
- return { activeEnvironment: cachedActiveEnvironment };
246
+ return { type: "ok", activeEnvironment: cachedActiveEnvironment };
247
247
  }
248
248
  const { environments } = await this.prismicRepository.fetchEnvironments();
249
249
  if (environments) {
@@ -251,9 +251,12 @@ Error Message: ${error2.message}`);
251
251
  }
252
252
  const activeEnvironment = findEnvironment(activeEnvironmentDomain, this._cachedEnvironments || []);
253
253
  if (!activeEnvironment) {
254
- throw new InvalidActiveEnvironmentError();
254
+ return {
255
+ type: "error",
256
+ error: new InvalidActiveEnvironmentError()
257
+ };
255
258
  }
256
- return { activeEnvironment };
259
+ return { type: "ok", activeEnvironment };
257
260
  }
258
261
  async detectVersionControlSystem() {
259
262
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectManager.js","sources":["../../../../src/managers/project/ProjectManager.ts"],"sourcesContent":["import * as fs from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport { detect as niDetect } from \"@antfu/ni\";\nimport { ExecaChildProcess } from \"execa\";\nimport {\n\tHookError,\n\tCallHookReturnType,\n\tProjectEnvironmentUpdateHook,\n} from \"@slicemachine/plugin-kit\";\nimport * as t from \"io-ts\";\n\nimport { DecodeError } from \"../../lib/DecodeError\";\nimport { assertPluginsInitialized } from \"../../lib/assertPluginsInitialized\";\nimport { decodeHookResult } from \"../../lib/decodeHookResult\";\nimport { decodeSliceMachineConfig } from \"../../lib/decodeSliceMachineConfig\";\nimport { findEnvironment } from \"../../lib/findEnvironment\";\nimport { format } from \"../../lib/format\";\nimport { installDependencies } from \"../../lib/installDependencies\";\nimport { locateFileUpward } from \"../../lib/locateFileUpward\";\nimport { requireResolve } from \"../../lib/requireResolve\";\n\nimport {\n\tPackageManager,\n\tSliceMachineConfig,\n\tOnlyHookErrors,\n} from \"../../types\";\n\nimport {\n\tSliceMachineError,\n\tInternalError,\n\tPluginError,\n\tInvalidActiveEnvironmentError,\n} from \"../../errors\";\n\nimport { SLICE_MACHINE_CONFIG_FILENAME } from \"../../constants/SLICE_MACHINE_CONFIG_FILENAME\";\nimport { TS_CONFIG_FILENAME } from \"../../constants/TS_CONFIG_FILENAME\";\nimport { SLICE_MACHINE_NPM_PACKAGE_NAME } from \"../../constants/SLICE_MACHINE_NPM_PACKAGE_NAME\";\n\nimport { BaseManager } from \"../BaseManager\";\nimport { Environment } from \"../prismicRepository/types\";\n\ntype ProjectManagerGetSliceMachineConfigPathArgs = {\n\tignoreCache?: boolean;\n};\n\ntype ProjectManagerGetRootArgs = {\n\tignoreCache?: boolean;\n};\n\ntype ProjectManagerCheckIsTypeScriptArgs = {\n\trootOverride?: string;\n};\n\ntype ProjectManagerWriteSliceMachineConfigArgs = {\n\tconfig: SliceMachineConfig;\n\tpath?: string;\n};\n\ntype ProjectManagerInitProjectArgs = {\n\tlog?: (message: string) => void;\n};\n\ntype ProjectManagerDetectPackageManager = {\n\troot?: string;\n};\n\ntype ProjectManagerInstallDependenciesArgs = {\n\tdependencies: Record<string, string>;\n\tdev?: boolean;\n\tpackageManager?: PackageManager;\n\tlog?: (message: string) => void;\n};\n\ntype ProjectManagerInstallDependenciesReturnType = {\n\texecaProcess: ExecaChildProcess;\n};\n\ntype ProjectManagerReadEnvironmentReturnType = {\n\tenvironment: string | undefined;\n\terrors: (DecodeError | HookError)[];\n};\n\ntype ProjectManagerUpdateEnvironmentArgs = {\n\tenvironment: string | undefined;\n};\n\ntype ProjectManagerFetchActiveEnvironmentReturnType = {\n\tactiveEnvironment: Environment;\n};\n\nexport class ProjectManager extends BaseManager {\n\tprivate _cachedRoot: string | undefined;\n\tprivate _cachedSliceMachineConfigPath: string | undefined;\n\tprivate _cachedSliceMachineConfig: SliceMachineConfig | undefined;\n\tprivate _cachedEnvironments: Environment[] | undefined;\n\n\tasync getSliceMachineConfigPath(\n\t\targs?: ProjectManagerGetSliceMachineConfigPathArgs,\n\t): Promise<string> {\n\t\tif (this._cachedSliceMachineConfigPath && !args?.ignoreCache) {\n\t\t\treturn this._cachedSliceMachineConfigPath;\n\t\t}\n\n\t\ttry {\n\t\t\tthis._cachedSliceMachineConfigPath = await locateFileUpward(\n\t\t\t\tSLICE_MACHINE_CONFIG_FILENAME,\n\t\t\t\t{ startDir: this.cwd },\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Could not find a ${SLICE_MACHINE_CONFIG_FILENAME} file. Please create a config file at the root of your project.`,\n\t\t\t);\n\t\t}\n\n\t\treturn this._cachedSliceMachineConfigPath;\n\t}\n\n\tasync getRoot(args?: ProjectManagerGetRootArgs): Promise<string> {\n\t\tif (this._cachedRoot && !args?.ignoreCache) {\n\t\t\treturn this._cachedRoot;\n\t\t}\n\n\t\tconst sliceMachineConfigFilePath = await this.getSliceMachineConfigPath({\n\t\t\tignoreCache: args?.ignoreCache,\n\t\t});\n\n\t\tthis._cachedRoot = path.dirname(sliceMachineConfigFilePath);\n\n\t\treturn this._cachedRoot;\n\t}\n\n\tasync suggestRoot(): Promise<string> {\n\t\tconst suggestedRootPackageJSON = await locateFileUpward(\"package.json\", {\n\t\t\tstartDir: this.cwd,\n\t\t});\n\n\t\treturn path.dirname(suggestedRootPackageJSON);\n\t}\n\n\tasync suggestSliceMachineConfigPath(): Promise<string> {\n\t\tconst suggestedRoot = await this.suggestRoot();\n\n\t\treturn path.resolve(suggestedRoot, SLICE_MACHINE_CONFIG_FILENAME);\n\t}\n\n\tasync checkIsTypeScript(\n\t\targs?: ProjectManagerCheckIsTypeScriptArgs,\n\t): Promise<boolean> {\n\t\tconst root = args?.rootOverride || (await this.getRoot());\n\t\tconst rootTSConfigPath = path.resolve(root, TS_CONFIG_FILENAME);\n\n\t\t// We just care if the file exists, we don't need access to it\n\t\treturn existsSync(rootTSConfigPath);\n\t}\n\n\tasync getSliceMachineConfig(): Promise<SliceMachineConfig> {\n\t\tif (this._cachedSliceMachineConfig) {\n\t\t\treturn this._cachedSliceMachineConfig;\n\t\t} else {\n\t\t\treturn await this.loadSliceMachineConfig();\n\t\t}\n\t}\n\n\tasync writeSliceMachineConfig(\n\t\targs: ProjectManagerWriteSliceMachineConfigArgs,\n\t): Promise<void> {\n\t\tconst configFilePath =\n\t\t\targs.path || (await this.getSliceMachineConfigPath());\n\n\t\tconst config = await format(\n\t\t\tJSON.stringify(args.config, null, 2),\n\t\t\tconfigFilePath,\n\t\t);\n\n\t\tawait fs.writeFile(configFilePath, config, \"utf-8\");\n\t\tdelete this._cachedSliceMachineConfig; // Clear config cache\n\t}\n\n\tasync loadSliceMachineConfig(): Promise<SliceMachineConfig> {\n\t\t// TODO: Reload plugins with a fresh plugin runner. Plugins may\n\t\t// have been added or removed.\n\t\tconst configFilePath = await this.getSliceMachineConfigPath();\n\n\t\tlet rawConfig: unknown | undefined;\n\t\ttry {\n\t\t\tconst contents = await fs.readFile(configFilePath, \"utf8\");\n\t\t\trawConfig = JSON.parse(contents);\n\t\t} catch (error) {\n\t\t\tif (error instanceof SyntaxError) {\n\t\t\t\tthrow new SliceMachineError(\n\t\t\t\t\t`Could not parse config file at ${configFilePath}.\\n\\nError Message: ${error.message}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Noop, more specific error is thrown after\n\t\t}\n\n\t\tif (!rawConfig) {\n\t\t\t// TODO: Write a more friendly and useful message.\n\t\t\tthrow new Error(\"No config found.\");\n\t\t}\n\n\t\tconst { value: sliceMachineConfig, error } =\n\t\t\tdecodeSliceMachineConfig(rawConfig);\n\n\t\tif (error) {\n\t\t\t// TODO: Write a more friendly and useful message.\n\t\t\tthrow new Error(`Invalid config. ${error.errors.join(\", \")}`, {\n\t\t\t\tcause: { rawConfig },\n\t\t\t});\n\t\t}\n\n\t\t// Allow cached config reading using `SliceMachineManager.prototype.getProjectConfig()`.\n\t\tthis._cachedSliceMachineConfig = sliceMachineConfig;\n\n\t\treturn sliceMachineConfig;\n\t}\n\n\tasync locateSliceMachineUIDir(): Promise<string> {\n\t\tconst projectRoot = await this.getRoot();\n\n\t\tconst sliceMachinePackageJSONPath = requireResolve(\n\t\t\t`${SLICE_MACHINE_NPM_PACKAGE_NAME}/package.json`,\n\t\t\tpath.join(projectRoot, \"index.js\"),\n\t\t);\n\n\t\treturn path.dirname(sliceMachinePackageJSONPath);\n\t}\n\n\t/**\n\t * Returns the project's repository name (i.e. the production environment). It\n\t * ignores the currently selected environment.\n\t *\n\t * Use this method to retrieve the production environment domain.\n\t *\n\t * @returns The project's repository name.\n\t */\n\tasync getRepositoryName(): Promise<string> {\n\t\tconst sliceMachineConfig = await this.getSliceMachineConfig();\n\n\t\treturn sliceMachineConfig.repositoryName;\n\t}\n\n\t/**\n\t * Returns the currently selected environment domain if set. If an environment\n\t * is not set, it returns the project's repository name (the production\n\t * environment).\n\t *\n\t * Use this method to retrieve the repository name to be sent with Prismic API\n\t * requests.\n\t *\n\t * @returns The resolved repository name.\n\t */\n\tasync getResolvedRepositoryName(): Promise<string> {\n\t\tconst repositoryName = await this.getRepositoryName();\n\n\t\tconst supportsEnvironments = this.project.checkSupportsEnvironments();\n\t\tif (!supportsEnvironments) {\n\t\t\treturn repositoryName;\n\t\t}\n\n\t\tconst { environment } = await this.project.readEnvironment();\n\n\t\treturn environment ?? repositoryName;\n\t}\n\n\tasync getAdapterName(): Promise<string> {\n\t\tconst sliceMachineConfig = await this.getSliceMachineConfig();\n\t\tconst adapterName =\n\t\t\ttypeof sliceMachineConfig.adapter === \"string\"\n\t\t\t\t? sliceMachineConfig.adapter\n\t\t\t\t: sliceMachineConfig.adapter.resolve;\n\n\t\treturn adapterName;\n\t}\n\n\tasync locateAdapterDir(): Promise<string> {\n\t\tconst projectRoot = await this.getRoot();\n\t\tconst adapterName = await this.getAdapterName();\n\t\tconst adapterPackageJSONPath = requireResolve(\n\t\t\t`${adapterName}/package.json`,\n\t\t\tpath.join(projectRoot, \"index.js\"),\n\t\t);\n\n\t\treturn path.dirname(adapterPackageJSONPath);\n\t}\n\n\tasync initProject(args?: ProjectManagerInitProjectArgs): Promise<void> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\t// eslint-disable-next-line no-console\n\t\tconst log = args?.log || console.log.bind(this);\n\n\t\tconst { errors } = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"project:init\",\n\t\t\t{\n\t\t\t\tlog,\n\t\t\t\tinstallDependencies: async (args) => {\n\t\t\t\t\tconst { execaProcess } = await this.installDependencies({\n\t\t\t\t\t\tdependencies: args.dependencies,\n\t\t\t\t\t\tdev: args.dev,\n\t\t\t\t\t\tlog,\n\t\t\t\t\t});\n\n\t\t\t\t\tawait execaProcess;\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\tif (errors.length > 0) {\n\t\t\t// TODO: Provide better error message.\n\t\t\tthrow new SliceMachineError(\n\t\t\t\t`Failed to initialize project: ${errors.join(\", \")}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync detectPackageManager(\n\t\targs?: ProjectManagerDetectPackageManager,\n\t): Promise<PackageManager> {\n\t\tconst projectRoot = args?.root || (await this.getRoot());\n\n\t\tconst packageManager = await niDetect({\n\t\t\tautoInstall: true,\n\t\t\tcwd: projectRoot,\n\t\t});\n\n\t\treturn packageManager || \"npm\";\n\t}\n\n\tasync installDependencies(\n\t\targs: ProjectManagerInstallDependenciesArgs,\n\t): Promise<ProjectManagerInstallDependenciesReturnType> {\n\t\tconst packageManager =\n\t\t\targs.packageManager || (await this.detectPackageManager());\n\n\t\t// eslint-disable-next-line no-console\n\t\tconst log = args.log || console.log.bind(this);\n\n\t\tconst wrappedLogger = (data: Buffer | string | null) => {\n\t\t\tif (data instanceof Buffer) {\n\t\t\t\tlog(data.toString());\n\t\t\t} else if (typeof data === \"string\") {\n\t\t\t\tlog(data);\n\t\t\t}\n\t\t};\n\n\t\ttry {\n\t\t\tconst { execaProcess } = await installDependencies({\n\t\t\t\tpackageManager,\n\t\t\t\tdependencies: args.dependencies,\n\t\t\t\tdev: args.dev,\n\t\t\t});\n\n\t\t\t// Don't clutter console with logs when process is non TTY (CI, etc.)\n\t\t\tif (process.stdout.isTTY || process.env.NODE_ENV === \"test\") {\n\t\t\t\texecaProcess.stdout?.on(\"data\", wrappedLogger);\n\t\t\t}\n\t\t\texecaProcess.stderr?.on(\"data\", wrappedLogger);\n\n\t\t\treturn {\n\t\t\t\texecaProcess,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tif (\n\t\t\t\terror instanceof Error &&\n\t\t\t\t\"shortMessage\" in error &&\n\t\t\t\t\"stderr\" in error\n\t\t\t) {\n\t\t\t\tthrow new InternalError(\"Package installation failed\", {\n\t\t\t\t\tcause: error,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tcheckSupportsEnvironments(): boolean {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\treturn (\n\t\t\tthis.sliceMachinePluginRunner.hooksForType(\"project:environment:read\")\n\t\t\t\t.length > 0 &&\n\t\t\tthis.sliceMachinePluginRunner.hooksForType(\"project:environment:update\")\n\t\t\t\t.length > 0\n\t\t);\n\t}\n\n\tasync readEnvironment(): Promise<ProjectManagerReadEnvironmentReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tawait this._assertAdapterSupportsEnvironments();\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"project:environment:read\",\n\t\t\tundefined,\n\t\t);\n\t\tconst { data, errors } = decodeHookResult(\n\t\t\tt.type({\n\t\t\t\tenvironment: t.union([t.undefined, t.string]),\n\t\t\t}),\n\t\t\thookResult,\n\t\t);\n\n\t\t// An undefined value is equivalent to the production environment.\n\t\t// We cast to undefined.\n\t\tconst repositoryName = await this.project.getRepositoryName();\n\t\tconst environmentDomain =\n\t\t\tdata[0]?.environment === repositoryName\n\t\t\t\t? undefined\n\t\t\t\t: data[0]?.environment;\n\n\t\treturn {\n\t\t\tenvironment: environmentDomain,\n\t\t\terrors,\n\t\t};\n\t}\n\n\tasync updateEnvironment(\n\t\targs: ProjectManagerUpdateEnvironmentArgs,\n\t): Promise<OnlyHookErrors<CallHookReturnType<ProjectEnvironmentUpdateHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tawait this._assertAdapterSupportsEnvironments();\n\n\t\tconst repositoryName = await this.project.getRepositoryName();\n\t\tconst environment =\n\t\t\targs.environment === repositoryName ? undefined : args.environment;\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"project:environment:update\",\n\t\t\t{ environment },\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync fetchActiveEnvironment(): Promise<ProjectManagerFetchActiveEnvironmentReturnType> {\n\t\tconst { environment: activeEnvironmentDomain } =\n\t\t\tawait this.readEnvironment();\n\n\t\t// We can assume an environment cannot change its kind. If the\n\t\t// environment exists in the cached list, we are confident it\n\t\t// will not change.\n\t\tconst cachedActiveEnvironment = findEnvironment(\n\t\t\tactiveEnvironmentDomain,\n\t\t\tthis._cachedEnvironments || [],\n\t\t);\n\t\tif (cachedActiveEnvironment) {\n\t\t\treturn { activeEnvironment: cachedActiveEnvironment };\n\t\t}\n\n\t\t// If the environment is not in the cached environments list, we\n\t\t// must fetch a fresh list and set the cache.\n\t\tconst { environments } = await this.prismicRepository.fetchEnvironments();\n\t\t// TODO: Remove the wrapping if statement when\n\t\t// `this.prismicRepository.fetchEnvironments()` is able to throw\n\t\t// normally. The method returns an object with an `error`\n\t\t// property at the time of this writing, which means we need to\n\t\t// check if the `environments` property exists.\n\t\tif (environments) {\n\t\t\tthis._cachedEnvironments = environments;\n\t\t}\n\n\t\tconst activeEnvironment = findEnvironment(\n\t\t\tactiveEnvironmentDomain,\n\t\t\tthis._cachedEnvironments || [],\n\t\t);\n\n\t\tif (!activeEnvironment) {\n\t\t\tthrow new InvalidActiveEnvironmentError();\n\t\t}\n\n\t\treturn { activeEnvironment };\n\t}\n\n\tasync detectVersionControlSystem(): Promise<string | \"_unknown\"> {\n\t\ttry {\n\t\t\tconst projectRoot = await this.getRoot();\n\n\t\t\tif (existsSync(path.join(projectRoot, \".git\"))) {\n\t\t\t\treturn \"Git\";\n\t\t\t}\n\n\t\t\tif (existsSync(path.join(projectRoot, \".svn\"))) {\n\t\t\t\treturn \"SVN\";\n\t\t\t}\n\n\t\t\tif (existsSync(path.join(projectRoot, \".hg\"))) {\n\t\t\t\treturn \"Mercurial\";\n\t\t\t}\n\n\t\t\tif (existsSync(path.join(projectRoot, \"CVS\"))) {\n\t\t\t\treturn \"CVS\";\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (import.meta.env.DEV) {\n\t\t\t\tconsole.error(\"Failed to detect Version Control System:\", error);\n\t\t\t}\n\t\t}\n\n\t\treturn \"_unknown\";\n\t}\n\n\tprivate async _assertAdapterSupportsEnvironments(): Promise<void> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst supportsEnvironments = this.checkSupportsEnvironments();\n\n\t\tif (!supportsEnvironments) {\n\t\t\tconst adapterName = await this.project.getAdapterName();\n\n\t\t\tthrow new PluginError(\n\t\t\t\t`${adapterName} does not support environments. Use an adapter that implements the \\`project:environment:read\\` and \\`project:environment:update\\` hooks to use environments.`,\n\t\t\t);\n\t\t}\n\t}\n}\n"],"names":["error","args","niDetect"],"mappings":"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"}
1
+ {"version":3,"file":"ProjectManager.js","sources":["../../../../src/managers/project/ProjectManager.ts"],"sourcesContent":["import * as fs from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport { detect as niDetect } from \"@antfu/ni\";\nimport { ExecaChildProcess } from \"execa\";\nimport {\n\tHookError,\n\tCallHookReturnType,\n\tProjectEnvironmentUpdateHook,\n} from \"@slicemachine/plugin-kit\";\nimport * as t from \"io-ts\";\n\nimport { DecodeError } from \"../../lib/DecodeError\";\nimport { assertPluginsInitialized } from \"../../lib/assertPluginsInitialized\";\nimport { decodeHookResult } from \"../../lib/decodeHookResult\";\nimport { decodeSliceMachineConfig } from \"../../lib/decodeSliceMachineConfig\";\nimport { findEnvironment } from \"../../lib/findEnvironment\";\nimport { format } from \"../../lib/format\";\nimport { installDependencies } from \"../../lib/installDependencies\";\nimport { locateFileUpward } from \"../../lib/locateFileUpward\";\nimport { requireResolve } from \"../../lib/requireResolve\";\n\nimport {\n\tPackageManager,\n\tSliceMachineConfig,\n\tOnlyHookErrors,\n} from \"../../types\";\n\nimport {\n\tSliceMachineError,\n\tInternalError,\n\tPluginError,\n\tInvalidActiveEnvironmentError,\n} from \"../../errors\";\n\nimport { SLICE_MACHINE_CONFIG_FILENAME } from \"../../constants/SLICE_MACHINE_CONFIG_FILENAME\";\nimport { TS_CONFIG_FILENAME } from \"../../constants/TS_CONFIG_FILENAME\";\nimport { SLICE_MACHINE_NPM_PACKAGE_NAME } from \"../../constants/SLICE_MACHINE_NPM_PACKAGE_NAME\";\n\nimport { BaseManager } from \"../BaseManager\";\nimport { Environment } from \"../prismicRepository/types\";\n\ntype ProjectManagerGetSliceMachineConfigPathArgs = {\n\tignoreCache?: boolean;\n};\n\ntype ProjectManagerGetRootArgs = {\n\tignoreCache?: boolean;\n};\n\ntype ProjectManagerCheckIsTypeScriptArgs = {\n\trootOverride?: string;\n};\n\ntype ProjectManagerWriteSliceMachineConfigArgs = {\n\tconfig: SliceMachineConfig;\n\tpath?: string;\n};\n\ntype ProjectManagerInitProjectArgs = {\n\tlog?: (message: string) => void;\n};\n\ntype ProjectManagerDetectPackageManager = {\n\troot?: string;\n};\n\ntype ProjectManagerInstallDependenciesArgs = {\n\tdependencies: Record<string, string>;\n\tdev?: boolean;\n\tpackageManager?: PackageManager;\n\tlog?: (message: string) => void;\n};\n\ntype ProjectManagerInstallDependenciesReturnType = {\n\texecaProcess: ExecaChildProcess;\n};\n\ntype ProjectManagerReadEnvironmentReturnType = {\n\tenvironment: string | undefined;\n\terrors: (DecodeError | HookError)[];\n};\n\ntype ProjectManagerUpdateEnvironmentArgs = {\n\tenvironment: string | undefined;\n};\n\ntype ProjectManagerFetchActiveEnvironmentReturnType =\n\t| { type: \"ok\"; activeEnvironment: Environment }\n\t| { type: \"error\"; error: InvalidActiveEnvironmentError };\n\nexport class ProjectManager extends BaseManager {\n\tprivate _cachedRoot: string | undefined;\n\tprivate _cachedSliceMachineConfigPath: string | undefined;\n\tprivate _cachedSliceMachineConfig: SliceMachineConfig | undefined;\n\tprivate _cachedEnvironments: Environment[] | undefined;\n\n\tasync getSliceMachineConfigPath(\n\t\targs?: ProjectManagerGetSliceMachineConfigPathArgs,\n\t): Promise<string> {\n\t\tif (this._cachedSliceMachineConfigPath && !args?.ignoreCache) {\n\t\t\treturn this._cachedSliceMachineConfigPath;\n\t\t}\n\n\t\ttry {\n\t\t\tthis._cachedSliceMachineConfigPath = await locateFileUpward(\n\t\t\t\tSLICE_MACHINE_CONFIG_FILENAME,\n\t\t\t\t{ startDir: this.cwd },\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Could not find a ${SLICE_MACHINE_CONFIG_FILENAME} file. Please create a config file at the root of your project.`,\n\t\t\t);\n\t\t}\n\n\t\treturn this._cachedSliceMachineConfigPath;\n\t}\n\n\tasync getRoot(args?: ProjectManagerGetRootArgs): Promise<string> {\n\t\tif (this._cachedRoot && !args?.ignoreCache) {\n\t\t\treturn this._cachedRoot;\n\t\t}\n\n\t\tconst sliceMachineConfigFilePath = await this.getSliceMachineConfigPath({\n\t\t\tignoreCache: args?.ignoreCache,\n\t\t});\n\n\t\tthis._cachedRoot = path.dirname(sliceMachineConfigFilePath);\n\n\t\treturn this._cachedRoot;\n\t}\n\n\tasync suggestRoot(): Promise<string> {\n\t\tconst suggestedRootPackageJSON = await locateFileUpward(\"package.json\", {\n\t\t\tstartDir: this.cwd,\n\t\t});\n\n\t\treturn path.dirname(suggestedRootPackageJSON);\n\t}\n\n\tasync suggestSliceMachineConfigPath(): Promise<string> {\n\t\tconst suggestedRoot = await this.suggestRoot();\n\n\t\treturn path.resolve(suggestedRoot, SLICE_MACHINE_CONFIG_FILENAME);\n\t}\n\n\tasync checkIsTypeScript(\n\t\targs?: ProjectManagerCheckIsTypeScriptArgs,\n\t): Promise<boolean> {\n\t\tconst root = args?.rootOverride || (await this.getRoot());\n\t\tconst rootTSConfigPath = path.resolve(root, TS_CONFIG_FILENAME);\n\n\t\t// We just care if the file exists, we don't need access to it\n\t\treturn existsSync(rootTSConfigPath);\n\t}\n\n\tasync getSliceMachineConfig(): Promise<SliceMachineConfig> {\n\t\tif (this._cachedSliceMachineConfig) {\n\t\t\treturn this._cachedSliceMachineConfig;\n\t\t} else {\n\t\t\treturn await this.loadSliceMachineConfig();\n\t\t}\n\t}\n\n\tasync writeSliceMachineConfig(\n\t\targs: ProjectManagerWriteSliceMachineConfigArgs,\n\t): Promise<void> {\n\t\tconst configFilePath =\n\t\t\targs.path || (await this.getSliceMachineConfigPath());\n\n\t\tconst config = await format(\n\t\t\tJSON.stringify(args.config, null, 2),\n\t\t\tconfigFilePath,\n\t\t);\n\n\t\tawait fs.writeFile(configFilePath, config, \"utf-8\");\n\t\tdelete this._cachedSliceMachineConfig; // Clear config cache\n\t}\n\n\tasync loadSliceMachineConfig(): Promise<SliceMachineConfig> {\n\t\t// TODO: Reload plugins with a fresh plugin runner. Plugins may\n\t\t// have been added or removed.\n\t\tconst configFilePath = await this.getSliceMachineConfigPath();\n\n\t\tlet rawConfig: unknown | undefined;\n\t\ttry {\n\t\t\tconst contents = await fs.readFile(configFilePath, \"utf8\");\n\t\t\trawConfig = JSON.parse(contents);\n\t\t} catch (error) {\n\t\t\tif (error instanceof SyntaxError) {\n\t\t\t\tthrow new SliceMachineError(\n\t\t\t\t\t`Could not parse config file at ${configFilePath}.\\n\\nError Message: ${error.message}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Noop, more specific error is thrown after\n\t\t}\n\n\t\tif (!rawConfig) {\n\t\t\t// TODO: Write a more friendly and useful message.\n\t\t\tthrow new Error(\"No config found.\");\n\t\t}\n\n\t\tconst { value: sliceMachineConfig, error } =\n\t\t\tdecodeSliceMachineConfig(rawConfig);\n\n\t\tif (error) {\n\t\t\t// TODO: Write a more friendly and useful message.\n\t\t\tthrow new Error(`Invalid config. ${error.errors.join(\", \")}`, {\n\t\t\t\tcause: { rawConfig },\n\t\t\t});\n\t\t}\n\n\t\t// Allow cached config reading using `SliceMachineManager.prototype.getProjectConfig()`.\n\t\tthis._cachedSliceMachineConfig = sliceMachineConfig;\n\n\t\treturn sliceMachineConfig;\n\t}\n\n\tasync locateSliceMachineUIDir(): Promise<string> {\n\t\tconst projectRoot = await this.getRoot();\n\n\t\tconst sliceMachinePackageJSONPath = requireResolve(\n\t\t\t`${SLICE_MACHINE_NPM_PACKAGE_NAME}/package.json`,\n\t\t\tpath.join(projectRoot, \"index.js\"),\n\t\t);\n\n\t\treturn path.dirname(sliceMachinePackageJSONPath);\n\t}\n\n\t/**\n\t * Returns the project's repository name (i.e. the production environment). It\n\t * ignores the currently selected environment.\n\t *\n\t * Use this method to retrieve the production environment domain.\n\t *\n\t * @returns The project's repository name.\n\t */\n\tasync getRepositoryName(): Promise<string> {\n\t\tconst sliceMachineConfig = await this.getSliceMachineConfig();\n\n\t\treturn sliceMachineConfig.repositoryName;\n\t}\n\n\t/**\n\t * Returns the currently selected environment domain if set. If an environment\n\t * is not set, it returns the project's repository name (the production\n\t * environment).\n\t *\n\t * Use this method to retrieve the repository name to be sent with Prismic API\n\t * requests.\n\t *\n\t * @returns The resolved repository name.\n\t */\n\tasync getResolvedRepositoryName(): Promise<string> {\n\t\tconst repositoryName = await this.getRepositoryName();\n\n\t\tconst supportsEnvironments = this.project.checkSupportsEnvironments();\n\t\tif (!supportsEnvironments) {\n\t\t\treturn repositoryName;\n\t\t}\n\n\t\tconst { environment } = await this.project.readEnvironment();\n\n\t\treturn environment ?? repositoryName;\n\t}\n\n\tasync getAdapterName(): Promise<string> {\n\t\tconst sliceMachineConfig = await this.getSliceMachineConfig();\n\t\tconst adapterName =\n\t\t\ttypeof sliceMachineConfig.adapter === \"string\"\n\t\t\t\t? sliceMachineConfig.adapter\n\t\t\t\t: sliceMachineConfig.adapter.resolve;\n\n\t\treturn adapterName;\n\t}\n\n\tasync locateAdapterDir(): Promise<string> {\n\t\tconst projectRoot = await this.getRoot();\n\t\tconst adapterName = await this.getAdapterName();\n\t\tconst adapterPackageJSONPath = requireResolve(\n\t\t\t`${adapterName}/package.json`,\n\t\t\tpath.join(projectRoot, \"index.js\"),\n\t\t);\n\n\t\treturn path.dirname(adapterPackageJSONPath);\n\t}\n\n\tasync initProject(args?: ProjectManagerInitProjectArgs): Promise<void> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\t// eslint-disable-next-line no-console\n\t\tconst log = args?.log || console.log.bind(this);\n\n\t\tconst { errors } = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"project:init\",\n\t\t\t{\n\t\t\t\tlog,\n\t\t\t\tinstallDependencies: async (args) => {\n\t\t\t\t\tconst { execaProcess } = await this.installDependencies({\n\t\t\t\t\t\tdependencies: args.dependencies,\n\t\t\t\t\t\tdev: args.dev,\n\t\t\t\t\t\tlog,\n\t\t\t\t\t});\n\n\t\t\t\t\tawait execaProcess;\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\tif (errors.length > 0) {\n\t\t\t// TODO: Provide better error message.\n\t\t\tthrow new SliceMachineError(\n\t\t\t\t`Failed to initialize project: ${errors.join(\", \")}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync detectPackageManager(\n\t\targs?: ProjectManagerDetectPackageManager,\n\t): Promise<PackageManager> {\n\t\tconst projectRoot = args?.root || (await this.getRoot());\n\n\t\tconst packageManager = await niDetect({\n\t\t\tautoInstall: true,\n\t\t\tcwd: projectRoot,\n\t\t});\n\n\t\treturn packageManager || \"npm\";\n\t}\n\n\tasync installDependencies(\n\t\targs: ProjectManagerInstallDependenciesArgs,\n\t): Promise<ProjectManagerInstallDependenciesReturnType> {\n\t\tconst packageManager =\n\t\t\targs.packageManager || (await this.detectPackageManager());\n\n\t\t// eslint-disable-next-line no-console\n\t\tconst log = args.log || console.log.bind(this);\n\n\t\tconst wrappedLogger = (data: Buffer | string | null) => {\n\t\t\tif (data instanceof Buffer) {\n\t\t\t\tlog(data.toString());\n\t\t\t} else if (typeof data === \"string\") {\n\t\t\t\tlog(data);\n\t\t\t}\n\t\t};\n\n\t\ttry {\n\t\t\tconst { execaProcess } = await installDependencies({\n\t\t\t\tpackageManager,\n\t\t\t\tdependencies: args.dependencies,\n\t\t\t\tdev: args.dev,\n\t\t\t});\n\n\t\t\t// Don't clutter console with logs when process is non TTY (CI, etc.)\n\t\t\tif (process.stdout.isTTY || process.env.NODE_ENV === \"test\") {\n\t\t\t\texecaProcess.stdout?.on(\"data\", wrappedLogger);\n\t\t\t}\n\t\t\texecaProcess.stderr?.on(\"data\", wrappedLogger);\n\n\t\t\treturn {\n\t\t\t\texecaProcess,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tif (\n\t\t\t\terror instanceof Error &&\n\t\t\t\t\"shortMessage\" in error &&\n\t\t\t\t\"stderr\" in error\n\t\t\t) {\n\t\t\t\tthrow new InternalError(\"Package installation failed\", {\n\t\t\t\t\tcause: error,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tcheckSupportsEnvironments(): boolean {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\treturn (\n\t\t\tthis.sliceMachinePluginRunner.hooksForType(\"project:environment:read\")\n\t\t\t\t.length > 0 &&\n\t\t\tthis.sliceMachinePluginRunner.hooksForType(\"project:environment:update\")\n\t\t\t\t.length > 0\n\t\t);\n\t}\n\n\tasync readEnvironment(): Promise<ProjectManagerReadEnvironmentReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tawait this._assertAdapterSupportsEnvironments();\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"project:environment:read\",\n\t\t\tundefined,\n\t\t);\n\t\tconst { data, errors } = decodeHookResult(\n\t\t\tt.type({\n\t\t\t\tenvironment: t.union([t.undefined, t.string]),\n\t\t\t}),\n\t\t\thookResult,\n\t\t);\n\n\t\t// An undefined value is equivalent to the production environment.\n\t\t// We cast to undefined.\n\t\tconst repositoryName = await this.project.getRepositoryName();\n\t\tconst environmentDomain =\n\t\t\tdata[0]?.environment === repositoryName\n\t\t\t\t? undefined\n\t\t\t\t: data[0]?.environment;\n\n\t\treturn {\n\t\t\tenvironment: environmentDomain,\n\t\t\terrors,\n\t\t};\n\t}\n\n\tasync updateEnvironment(\n\t\targs: ProjectManagerUpdateEnvironmentArgs,\n\t): Promise<OnlyHookErrors<CallHookReturnType<ProjectEnvironmentUpdateHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tawait this._assertAdapterSupportsEnvironments();\n\n\t\tconst repositoryName = await this.project.getRepositoryName();\n\t\tconst environment =\n\t\t\targs.environment === repositoryName ? undefined : args.environment;\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"project:environment:update\",\n\t\t\t{ environment },\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync fetchActiveEnvironment(): Promise<ProjectManagerFetchActiveEnvironmentReturnType> {\n\t\tconst { environment: activeEnvironmentDomain } =\n\t\t\tawait this.readEnvironment();\n\n\t\t// We can assume an environment cannot change its kind. If the\n\t\t// environment exists in the cached list, we are confident it\n\t\t// will not change.\n\t\tconst cachedActiveEnvironment = findEnvironment(\n\t\t\tactiveEnvironmentDomain,\n\t\t\tthis._cachedEnvironments || [],\n\t\t);\n\t\tif (cachedActiveEnvironment) {\n\t\t\treturn { type: \"ok\", activeEnvironment: cachedActiveEnvironment };\n\t\t}\n\n\t\t// If the environment is not in the cached environments list, we\n\t\t// must fetch a fresh list and set the cache.\n\t\tconst { environments } = await this.prismicRepository.fetchEnvironments();\n\t\t// TODO: Remove the wrapping if statement when\n\t\t// `this.prismicRepository.fetchEnvironments()` is able to throw\n\t\t// normally. The method returns an object with an `error`\n\t\t// property at the time of this writing, which means we need to\n\t\t// check if the `environments` property exists.\n\t\tif (environments) {\n\t\t\tthis._cachedEnvironments = environments;\n\t\t}\n\n\t\tconst activeEnvironment = findEnvironment(\n\t\t\tactiveEnvironmentDomain,\n\t\t\tthis._cachedEnvironments || [],\n\t\t);\n\n\t\tif (!activeEnvironment) {\n\t\t\treturn {\n\t\t\t\ttype: \"error\",\n\t\t\t\terror: new InvalidActiveEnvironmentError(),\n\t\t\t};\n\t\t}\n\n\t\treturn { type: \"ok\", activeEnvironment: activeEnvironment };\n\t}\n\n\tasync detectVersionControlSystem(): Promise<string | \"_unknown\"> {\n\t\ttry {\n\t\t\tconst projectRoot = await this.getRoot();\n\n\t\t\tif (existsSync(path.join(projectRoot, \".git\"))) {\n\t\t\t\treturn \"Git\";\n\t\t\t}\n\n\t\t\tif (existsSync(path.join(projectRoot, \".svn\"))) {\n\t\t\t\treturn \"SVN\";\n\t\t\t}\n\n\t\t\tif (existsSync(path.join(projectRoot, \".hg\"))) {\n\t\t\t\treturn \"Mercurial\";\n\t\t\t}\n\n\t\t\tif (existsSync(path.join(projectRoot, \"CVS\"))) {\n\t\t\t\treturn \"CVS\";\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (import.meta.env.DEV) {\n\t\t\t\tconsole.error(\"Failed to detect Version Control System:\", error);\n\t\t\t}\n\t\t}\n\n\t\treturn \"_unknown\";\n\t}\n\n\tprivate async _assertAdapterSupportsEnvironments(): Promise<void> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst supportsEnvironments = this.checkSupportsEnvironments();\n\n\t\tif (!supportsEnvironments) {\n\t\t\tconst adapterName = await this.project.getAdapterName();\n\n\t\t\tthrow new PluginError(\n\t\t\t\t`${adapterName} does not support environments. Use an adapter that implements the \\`project:environment:read\\` and \\`project:environment:update\\` hooks to use environments.`,\n\t\t\t);\n\t\t}\n\t}\n}\n"],"names":["error","args","niDetect"],"mappings":"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"}
@@ -64,8 +64,12 @@ class TelemetryManager extends BaseManager.BaseManager {
64
64
  if (_includeEnvironmentKind) {
65
65
  if (this.project.checkSupportsEnvironments()) {
66
66
  try {
67
- const { activeEnvironment } = await this.project.fetchActiveEnvironment();
68
- environmentKind = activeEnvironment.kind;
67
+ const activeEnvironmentResult = await this.project.fetchActiveEnvironment();
68
+ if (activeEnvironmentResult.type === "ok") {
69
+ environmentKind = activeEnvironmentResult.activeEnvironment.kind;
70
+ } else {
71
+ throw activeEnvironmentResult.error;
72
+ }
69
73
  } catch {
70
74
  environmentKind = "_unknown";
71
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TelemetryManager.cjs","sources":["../../../../src/managers/telemetry/TelemetryManager.ts"],"sourcesContent":["import {\n\tExperiment,\n\tRemoteEvaluationClient,\n\tVariant,\n} from \"@amplitude/experiment-node-server\";\nimport { randomUUID } from \"node:crypto\";\nimport { Analytics, GroupParams, TrackParams } from \"@segment/analytics-node\";\n\nimport { readPrismicrc } from \"../../lib/prismicrc\";\n\nimport { API_TOKENS } from \"../../constants/API_TOKENS\";\n\nimport { BaseManager } from \"../BaseManager\";\n\nimport {\n\tHumanSegmentEventType,\n\tHumanSegmentEventTypes,\n\tSegmentEvents,\n} from \"./types\";\nimport { Environment } from \"../prismicRepository/types\";\n\ntype TelemetryManagerInitTelemetryArgs = {\n\tappName: string;\n\tappVersion: string;\n};\n\ntype TelemetryManagerTrackArgs = SegmentEvents & {\n\t_includeEnvironmentKind?: boolean;\n};\n\ntype TelemetryManagerIdentifyArgs = {\n\tuserID: string;\n\tintercomHash: string;\n};\n\ntype TelemetryManagerGroupArgs = {\n\tmanualLibsCount: number;\n\tdownloadedLibsCount: number;\n\tnpmLibsCount: number;\n\tdownloadedLibs: string[];\n};\n\ntype TelemetryManagerContext = {\n\tapp: {\n\t\tname: string;\n\t\tversion: string;\n\t};\n};\n\nfunction assertTelemetryInitialized(\n\tsegmentClient: (() => Analytics) | undefined,\n): asserts segmentClient is NonNullable<typeof segmentClient> {\n\tif (segmentClient === undefined) {\n\t\tthrow new Error(\n\t\t\t\"Telemetry has not been initialized. Run `SliceMachineManager.telemetry.prototype.initTelemetry()` before re-calling this method.\",\n\t\t);\n\t}\n}\n\nexport class TelemetryManager extends BaseManager {\n\tprivate _segmentClient: (() => Analytics) | undefined = undefined;\n\tprivate _anonymousID: string | undefined = undefined;\n\tprivate _userID: string | undefined = undefined;\n\tprivate _context: TelemetryManagerContext | undefined = undefined;\n\tprivate _experiment: RemoteEvaluationClient | undefined = undefined;\n\n\tasync initTelemetry(args: TelemetryManagerInitTelemetryArgs): Promise<void> {\n\t\tconst isTelemetryEnabled = await this.checkIsTelemetryEnabled();\n\n\t\tthis._segmentClient = () => {\n\t\t\tconst analytics = new Analytics({\n\t\t\t\twriteKey: API_TOKENS.SegmentKey,\n\t\t\t\t// Since it's a local app, we do not benefit from event batching the way a server would normally do, all tracking event will be awaited.\n\t\t\t\tmaxEventsInBatch: 1,\n\t\t\t\t// TODO: Verify that this actually does not send data to Segment when false.\n\t\t\t\tdisable: !isTelemetryEnabled,\n\t\t\t});\n\n\t\t\tanalytics.on(\"error\", (error) => {\n\t\t\t\t// noop - We don't care if the tracking event\n\t\t\t\t// failed. Some users or networks intentionally\n\t\t\t\t// block Segment, so we can't block the app if\n\t\t\t\t// a tracking event is unsuccessful.\n\t\t\t\tif (import.meta.env.DEV) {\n\t\t\t\t\tconsole.error(`An error occurred with Segment`, error);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn analytics;\n\t\t};\n\n\t\tif (isTelemetryEnabled) {\n\t\t\tthis.initExperiment();\n\t\t}\n\n\t\tthis._anonymousID = randomUUID();\n\t\tthis._context = { app: { name: args.appName, version: args.appVersion } };\n\t}\n\n\t// TODO: Should `userId` be automatically populated by the logged in\n\t// user? We already have their info via UserRepository.\n\tasync track(args: TelemetryManagerTrackArgs): Promise<void> {\n\t\tconst { event, repository, _includeEnvironmentKind, ...properties } = args;\n\t\tlet repositoryName = repository;\n\n\t\tif (repositoryName === undefined) {\n\t\t\ttry {\n\t\t\t\trepositoryName = await this.project.getRepositoryName();\n\t\t\t} catch (error) {\n\t\t\t\t// noop, happen only when the user is not in a project\n\t\t\t}\n\t\t}\n\n\t\tlet environmentKind: Environment[\"kind\"] | \"_unknown\" | undefined =\n\t\t\tundefined;\n\t\tif (_includeEnvironmentKind) {\n\t\t\tif (this.project.checkSupportsEnvironments()) {\n\t\t\t\ttry {\n\t\t\t\t\tconst { activeEnvironment } =\n\t\t\t\t\t\tawait this.project.fetchActiveEnvironment();\n\t\t\t\t\tenvironmentKind = activeEnvironment.kind;\n\t\t\t\t} catch {\n\t\t\t\t\tenvironmentKind = \"_unknown\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Assume only the production environment can be\n\t\t\t\t// used if the project's adapter does not\n\t\t\t\t// support environments.\n\t\t\t\tenvironmentKind = \"prod\";\n\t\t\t}\n\t\t}\n\n\t\tconst payload: {\n\t\t\tevent: HumanSegmentEventTypes;\n\t\t\tuserId?: string;\n\t\t\tanonymousId?: string;\n\t\t\tproperties?: Record<string, unknown>;\n\t\t\tcontext?: Partial<TelemetryManagerContext> & {\n\t\t\t\tgroupId?: {\n\t\t\t\t\tRepository?: string;\n\t\t\t\t};\n\t\t\t};\n\t\t} = {\n\t\t\tevent: HumanSegmentEventType[event],\n\t\t\tproperties: {\n\t\t\t\tnodeVersion: process.versions.node,\n\t\t\t\tenvironmentKind,\n\t\t\t\t...properties,\n\t\t\t},\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tif (this._userID) {\n\t\t\tpayload.userId = this._userID;\n\t\t} else {\n\t\t\tpayload.anonymousId = this._anonymousID;\n\t\t}\n\n\t\tif (repositoryName) {\n\t\t\tpayload.context ||= {};\n\t\t\tpayload.context.groupId ||= {};\n\t\t\tpayload.context.groupId.Repository = repositoryName;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\t// TODO: Make sure client fails gracefully when no internet connection\n\t\t\tthis._segmentClient().track(\n\t\t\t\tpayload as TrackParams,\n\t\t\t\t(maybeError?: unknown) => {\n\t\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t`An error occurred during Segment tracking`,\n\t\t\t\t\t\t\tmaybeError,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\t// TODO: Should `userID` and `intercomHash` be automatically populated\n\t// by the logged in user? We already have their info via\n\t// UserRepository.\n\tidentify(args: TelemetryManagerIdentifyArgs): Promise<void> {\n\t\tconst payload = {\n\t\t\tuserId: args.userID,\n\t\t\tanonymousId: this._anonymousID,\n\t\t\tintegrations: {\n\t\t\t\tIntercom: {\n\t\t\t\t\tuser_hash: args.intercomHash,\n\t\t\t\t},\n\t\t\t},\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tthis._userID = args.userID;\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\t// TODO: Make sure client fails gracefully when no internet connection\n\t\t\tthis._segmentClient().identify(payload, (maybeError?: unknown) => {\n\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\tconsole.warn(`An error occurred during Segment identify`, maybeError);\n\t\t\t\t}\n\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tasync group(args: TelemetryManagerGroupArgs): Promise<void> {\n\t\tlet repositoryName;\n\n\t\ttry {\n\t\t\trepositoryName = await this.project.getRepositoryName();\n\t\t} catch (error) {\n\t\t\t// noop, happen only when the user is not in a project\n\t\t}\n\n\t\tconst payload: {\n\t\t\tgroupId?: string;\n\t\t\tuserId?: string;\n\t\t\tanonymousId?: string;\n\t\t\ttraits?: Record<string, unknown>;\n\t\t\tcontext?: Partial<TelemetryManagerContext> & {\n\t\t\t\tgroupId?: {\n\t\t\t\t\tRepository?: string;\n\t\t\t\t};\n\t\t\t};\n\t\t} = {\n\t\t\ttraits: args,\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tif (this._userID) {\n\t\t\tpayload.userId = this._userID;\n\t\t} else {\n\t\t\tpayload.anonymousId = this._anonymousID;\n\t\t}\n\n\t\tif (repositoryName) {\n\t\t\tpayload.groupId = repositoryName;\n\t\t\tpayload.context ||= {};\n\t\t\tpayload.context.groupId ||= {};\n\t\t\tpayload.context.groupId.Repository = repositoryName;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\tthis._segmentClient().group(\n\t\t\t\tpayload as GroupParams,\n\t\t\t\t(maybeError?: unknown) => {\n\t\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\t\tconsole.warn(`An error occurred during Segment group`, maybeError);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\tasync checkIsTelemetryEnabled(): Promise<boolean> {\n\t\tlet root: string;\n\t\ttry {\n\t\t\troot = await this.project\n\t\t\t\t.getRoot()\n\t\t\t\t.catch(() => this.project.suggestRoot());\n\n\t\t\treturn readPrismicrc(root).telemetry !== false;\n\t\t} catch {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tprivate initExperiment(): void {\n\t\ttry {\n\t\t\tthis._experiment = Experiment.initializeRemote(API_TOKENS.AmplitudeKey);\n\t\t} catch (error) {\n\t\t\tif (import.meta.env.DEV) {\n\t\t\t\tconsole.error(\"Error initializing experiment\", error);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync getExperimentVariant(variantKey: string): Promise<Variant | undefined> {\n\t\tif (this._experiment) {\n\t\t\ttry {\n\t\t\t\tconst repositoryName = await this.project.getRepositoryName();\n\t\t\t\tconst variants = await this._experiment.fetchV2({\n\t\t\t\t\tuser_id: this._userID,\n\t\t\t\t\tuser_properties: {\n\t\t\t\t\t\tRepository: repositoryName,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tconst variantValue = variants[variantKey].value;\n\t\t\t\tif (variantValue) {\n\t\t\t\t\tawait this.track({\n\t\t\t\t\t\tevent: \"experiment:exposure\",\n\t\t\t\t\t\tflag_key: variantKey,\n\t\t\t\t\t\tvariant: variantValue,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn variants[variantKey];\n\t\t\t} catch (error) {\n\t\t\t\tif (import.meta.env.DEV) {\n\t\t\t\t\tconsole.error(\"Error fetching experiment variant\", error);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n}\n"],"names":["BaseManager","Analytics","API_TOKENS","randomUUID","HumanSegmentEventType","readPrismicrc","Experiment"],"mappings":"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"}
1
+ {"version":3,"file":"TelemetryManager.cjs","sources":["../../../../src/managers/telemetry/TelemetryManager.ts"],"sourcesContent":["import {\n\tExperiment,\n\tRemoteEvaluationClient,\n\tVariant,\n} from \"@amplitude/experiment-node-server\";\nimport { randomUUID } from \"node:crypto\";\nimport { Analytics, GroupParams, TrackParams } from \"@segment/analytics-node\";\n\nimport { readPrismicrc } from \"../../lib/prismicrc\";\n\nimport { API_TOKENS } from \"../../constants/API_TOKENS\";\n\nimport { BaseManager } from \"../BaseManager\";\n\nimport {\n\tHumanSegmentEventType,\n\tHumanSegmentEventTypes,\n\tSegmentEvents,\n} from \"./types\";\nimport { Environment } from \"../prismicRepository/types\";\n\ntype TelemetryManagerInitTelemetryArgs = {\n\tappName: string;\n\tappVersion: string;\n};\n\ntype TelemetryManagerTrackArgs = SegmentEvents & {\n\t_includeEnvironmentKind?: boolean;\n};\n\ntype TelemetryManagerIdentifyArgs = {\n\tuserID: string;\n\tintercomHash: string;\n};\n\ntype TelemetryManagerGroupArgs = {\n\tmanualLibsCount: number;\n\tdownloadedLibsCount: number;\n\tnpmLibsCount: number;\n\tdownloadedLibs: string[];\n};\n\ntype TelemetryManagerContext = {\n\tapp: {\n\t\tname: string;\n\t\tversion: string;\n\t};\n};\n\nfunction assertTelemetryInitialized(\n\tsegmentClient: (() => Analytics) | undefined,\n): asserts segmentClient is NonNullable<typeof segmentClient> {\n\tif (segmentClient === undefined) {\n\t\tthrow new Error(\n\t\t\t\"Telemetry has not been initialized. Run `SliceMachineManager.telemetry.prototype.initTelemetry()` before re-calling this method.\",\n\t\t);\n\t}\n}\n\nexport class TelemetryManager extends BaseManager {\n\tprivate _segmentClient: (() => Analytics) | undefined = undefined;\n\tprivate _anonymousID: string | undefined = undefined;\n\tprivate _userID: string | undefined = undefined;\n\tprivate _context: TelemetryManagerContext | undefined = undefined;\n\tprivate _experiment: RemoteEvaluationClient | undefined = undefined;\n\n\tasync initTelemetry(args: TelemetryManagerInitTelemetryArgs): Promise<void> {\n\t\tconst isTelemetryEnabled = await this.checkIsTelemetryEnabled();\n\n\t\tthis._segmentClient = () => {\n\t\t\tconst analytics = new Analytics({\n\t\t\t\twriteKey: API_TOKENS.SegmentKey,\n\t\t\t\t// Since it's a local app, we do not benefit from event batching the way a server would normally do, all tracking event will be awaited.\n\t\t\t\tmaxEventsInBatch: 1,\n\t\t\t\t// TODO: Verify that this actually does not send data to Segment when false.\n\t\t\t\tdisable: !isTelemetryEnabled,\n\t\t\t});\n\n\t\t\tanalytics.on(\"error\", (error) => {\n\t\t\t\t// noop - We don't care if the tracking event\n\t\t\t\t// failed. Some users or networks intentionally\n\t\t\t\t// block Segment, so we can't block the app if\n\t\t\t\t// a tracking event is unsuccessful.\n\t\t\t\tif (import.meta.env.DEV) {\n\t\t\t\t\tconsole.error(`An error occurred with Segment`, error);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn analytics;\n\t\t};\n\n\t\tif (isTelemetryEnabled) {\n\t\t\tthis.initExperiment();\n\t\t}\n\n\t\tthis._anonymousID = randomUUID();\n\t\tthis._context = { app: { name: args.appName, version: args.appVersion } };\n\t}\n\n\t// TODO: Should `userId` be automatically populated by the logged in\n\t// user? We already have their info via UserRepository.\n\tasync track(args: TelemetryManagerTrackArgs): Promise<void> {\n\t\tconst { event, repository, _includeEnvironmentKind, ...properties } = args;\n\t\tlet repositoryName = repository;\n\n\t\tif (repositoryName === undefined) {\n\t\t\ttry {\n\t\t\t\trepositoryName = await this.project.getRepositoryName();\n\t\t\t} catch (error) {\n\t\t\t\t// noop, happen only when the user is not in a project\n\t\t\t}\n\t\t}\n\n\t\tlet environmentKind: Environment[\"kind\"] | \"_unknown\" | undefined =\n\t\t\tundefined;\n\t\tif (_includeEnvironmentKind) {\n\t\t\tif (this.project.checkSupportsEnvironments()) {\n\t\t\t\ttry {\n\t\t\t\t\tconst activeEnvironmentResult =\n\t\t\t\t\t\tawait this.project.fetchActiveEnvironment();\n\n\t\t\t\t\tif (activeEnvironmentResult.type === \"ok\") {\n\t\t\t\t\t\tenvironmentKind = activeEnvironmentResult.activeEnvironment.kind;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow activeEnvironmentResult.error;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\tenvironmentKind = \"_unknown\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Assume only the production environment can be\n\t\t\t\t// used if the project's adapter does not\n\t\t\t\t// support environments.\n\t\t\t\tenvironmentKind = \"prod\";\n\t\t\t}\n\t\t}\n\n\t\tconst payload: {\n\t\t\tevent: HumanSegmentEventTypes;\n\t\t\tuserId?: string;\n\t\t\tanonymousId?: string;\n\t\t\tproperties?: Record<string, unknown>;\n\t\t\tcontext?: Partial<TelemetryManagerContext> & {\n\t\t\t\tgroupId?: {\n\t\t\t\t\tRepository?: string;\n\t\t\t\t};\n\t\t\t};\n\t\t} = {\n\t\t\tevent: HumanSegmentEventType[event],\n\t\t\tproperties: {\n\t\t\t\tnodeVersion: process.versions.node,\n\t\t\t\tenvironmentKind,\n\t\t\t\t...properties,\n\t\t\t},\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tif (this._userID) {\n\t\t\tpayload.userId = this._userID;\n\t\t} else {\n\t\t\tpayload.anonymousId = this._anonymousID;\n\t\t}\n\n\t\tif (repositoryName) {\n\t\t\tpayload.context ||= {};\n\t\t\tpayload.context.groupId ||= {};\n\t\t\tpayload.context.groupId.Repository = repositoryName;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\t// TODO: Make sure client fails gracefully when no internet connection\n\t\t\tthis._segmentClient().track(\n\t\t\t\tpayload as TrackParams,\n\t\t\t\t(maybeError?: unknown) => {\n\t\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t`An error occurred during Segment tracking`,\n\t\t\t\t\t\t\tmaybeError,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\t// TODO: Should `userID` and `intercomHash` be automatically populated\n\t// by the logged in user? We already have their info via\n\t// UserRepository.\n\tidentify(args: TelemetryManagerIdentifyArgs): Promise<void> {\n\t\tconst payload = {\n\t\t\tuserId: args.userID,\n\t\t\tanonymousId: this._anonymousID,\n\t\t\tintegrations: {\n\t\t\t\tIntercom: {\n\t\t\t\t\tuser_hash: args.intercomHash,\n\t\t\t\t},\n\t\t\t},\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tthis._userID = args.userID;\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\t// TODO: Make sure client fails gracefully when no internet connection\n\t\t\tthis._segmentClient().identify(payload, (maybeError?: unknown) => {\n\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\tconsole.warn(`An error occurred during Segment identify`, maybeError);\n\t\t\t\t}\n\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tasync group(args: TelemetryManagerGroupArgs): Promise<void> {\n\t\tlet repositoryName;\n\n\t\ttry {\n\t\t\trepositoryName = await this.project.getRepositoryName();\n\t\t} catch (error) {\n\t\t\t// noop, happen only when the user is not in a project\n\t\t}\n\n\t\tconst payload: {\n\t\t\tgroupId?: string;\n\t\t\tuserId?: string;\n\t\t\tanonymousId?: string;\n\t\t\ttraits?: Record<string, unknown>;\n\t\t\tcontext?: Partial<TelemetryManagerContext> & {\n\t\t\t\tgroupId?: {\n\t\t\t\t\tRepository?: string;\n\t\t\t\t};\n\t\t\t};\n\t\t} = {\n\t\t\ttraits: args,\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tif (this._userID) {\n\t\t\tpayload.userId = this._userID;\n\t\t} else {\n\t\t\tpayload.anonymousId = this._anonymousID;\n\t\t}\n\n\t\tif (repositoryName) {\n\t\t\tpayload.groupId = repositoryName;\n\t\t\tpayload.context ||= {};\n\t\t\tpayload.context.groupId ||= {};\n\t\t\tpayload.context.groupId.Repository = repositoryName;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\tthis._segmentClient().group(\n\t\t\t\tpayload as GroupParams,\n\t\t\t\t(maybeError?: unknown) => {\n\t\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\t\tconsole.warn(`An error occurred during Segment group`, maybeError);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\tasync checkIsTelemetryEnabled(): Promise<boolean> {\n\t\tlet root: string;\n\t\ttry {\n\t\t\troot = await this.project\n\t\t\t\t.getRoot()\n\t\t\t\t.catch(() => this.project.suggestRoot());\n\n\t\t\treturn readPrismicrc(root).telemetry !== false;\n\t\t} catch {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tprivate initExperiment(): void {\n\t\ttry {\n\t\t\tthis._experiment = Experiment.initializeRemote(API_TOKENS.AmplitudeKey);\n\t\t} catch (error) {\n\t\t\tif (import.meta.env.DEV) {\n\t\t\t\tconsole.error(\"Error initializing experiment\", error);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync getExperimentVariant(variantKey: string): Promise<Variant | undefined> {\n\t\tif (this._experiment) {\n\t\t\ttry {\n\t\t\t\tconst repositoryName = await this.project.getRepositoryName();\n\t\t\t\tconst variants = await this._experiment.fetchV2({\n\t\t\t\t\tuser_id: this._userID,\n\t\t\t\t\tuser_properties: {\n\t\t\t\t\t\tRepository: repositoryName,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tconst variantValue = variants[variantKey].value;\n\t\t\t\tif (variantValue) {\n\t\t\t\t\tawait this.track({\n\t\t\t\t\t\tevent: \"experiment:exposure\",\n\t\t\t\t\t\tflag_key: variantKey,\n\t\t\t\t\t\tvariant: variantValue,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn variants[variantKey];\n\t\t\t} catch (error) {\n\t\t\t\tif (import.meta.env.DEV) {\n\t\t\t\t\tconsole.error(\"Error fetching experiment variant\", error);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n}\n"],"names":["BaseManager","Analytics","API_TOKENS","randomUUID","HumanSegmentEventType","readPrismicrc","Experiment"],"mappings":"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"}
@@ -62,8 +62,12 @@ class TelemetryManager extends BaseManager {
62
62
  if (_includeEnvironmentKind) {
63
63
  if (this.project.checkSupportsEnvironments()) {
64
64
  try {
65
- const { activeEnvironment } = await this.project.fetchActiveEnvironment();
66
- environmentKind = activeEnvironment.kind;
65
+ const activeEnvironmentResult = await this.project.fetchActiveEnvironment();
66
+ if (activeEnvironmentResult.type === "ok") {
67
+ environmentKind = activeEnvironmentResult.activeEnvironment.kind;
68
+ } else {
69
+ throw activeEnvironmentResult.error;
70
+ }
67
71
  } catch {
68
72
  environmentKind = "_unknown";
69
73
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TelemetryManager.js","sources":["../../../../src/managers/telemetry/TelemetryManager.ts"],"sourcesContent":["import {\n\tExperiment,\n\tRemoteEvaluationClient,\n\tVariant,\n} from \"@amplitude/experiment-node-server\";\nimport { randomUUID } from \"node:crypto\";\nimport { Analytics, GroupParams, TrackParams } from \"@segment/analytics-node\";\n\nimport { readPrismicrc } from \"../../lib/prismicrc\";\n\nimport { API_TOKENS } from \"../../constants/API_TOKENS\";\n\nimport { BaseManager } from \"../BaseManager\";\n\nimport {\n\tHumanSegmentEventType,\n\tHumanSegmentEventTypes,\n\tSegmentEvents,\n} from \"./types\";\nimport { Environment } from \"../prismicRepository/types\";\n\ntype TelemetryManagerInitTelemetryArgs = {\n\tappName: string;\n\tappVersion: string;\n};\n\ntype TelemetryManagerTrackArgs = SegmentEvents & {\n\t_includeEnvironmentKind?: boolean;\n};\n\ntype TelemetryManagerIdentifyArgs = {\n\tuserID: string;\n\tintercomHash: string;\n};\n\ntype TelemetryManagerGroupArgs = {\n\tmanualLibsCount: number;\n\tdownloadedLibsCount: number;\n\tnpmLibsCount: number;\n\tdownloadedLibs: string[];\n};\n\ntype TelemetryManagerContext = {\n\tapp: {\n\t\tname: string;\n\t\tversion: string;\n\t};\n};\n\nfunction assertTelemetryInitialized(\n\tsegmentClient: (() => Analytics) | undefined,\n): asserts segmentClient is NonNullable<typeof segmentClient> {\n\tif (segmentClient === undefined) {\n\t\tthrow new Error(\n\t\t\t\"Telemetry has not been initialized. Run `SliceMachineManager.telemetry.prototype.initTelemetry()` before re-calling this method.\",\n\t\t);\n\t}\n}\n\nexport class TelemetryManager extends BaseManager {\n\tprivate _segmentClient: (() => Analytics) | undefined = undefined;\n\tprivate _anonymousID: string | undefined = undefined;\n\tprivate _userID: string | undefined = undefined;\n\tprivate _context: TelemetryManagerContext | undefined = undefined;\n\tprivate _experiment: RemoteEvaluationClient | undefined = undefined;\n\n\tasync initTelemetry(args: TelemetryManagerInitTelemetryArgs): Promise<void> {\n\t\tconst isTelemetryEnabled = await this.checkIsTelemetryEnabled();\n\n\t\tthis._segmentClient = () => {\n\t\t\tconst analytics = new Analytics({\n\t\t\t\twriteKey: API_TOKENS.SegmentKey,\n\t\t\t\t// Since it's a local app, we do not benefit from event batching the way a server would normally do, all tracking event will be awaited.\n\t\t\t\tmaxEventsInBatch: 1,\n\t\t\t\t// TODO: Verify that this actually does not send data to Segment when false.\n\t\t\t\tdisable: !isTelemetryEnabled,\n\t\t\t});\n\n\t\t\tanalytics.on(\"error\", (error) => {\n\t\t\t\t// noop - We don't care if the tracking event\n\t\t\t\t// failed. Some users or networks intentionally\n\t\t\t\t// block Segment, so we can't block the app if\n\t\t\t\t// a tracking event is unsuccessful.\n\t\t\t\tif (import.meta.env.DEV) {\n\t\t\t\t\tconsole.error(`An error occurred with Segment`, error);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn analytics;\n\t\t};\n\n\t\tif (isTelemetryEnabled) {\n\t\t\tthis.initExperiment();\n\t\t}\n\n\t\tthis._anonymousID = randomUUID();\n\t\tthis._context = { app: { name: args.appName, version: args.appVersion } };\n\t}\n\n\t// TODO: Should `userId` be automatically populated by the logged in\n\t// user? We already have their info via UserRepository.\n\tasync track(args: TelemetryManagerTrackArgs): Promise<void> {\n\t\tconst { event, repository, _includeEnvironmentKind, ...properties } = args;\n\t\tlet repositoryName = repository;\n\n\t\tif (repositoryName === undefined) {\n\t\t\ttry {\n\t\t\t\trepositoryName = await this.project.getRepositoryName();\n\t\t\t} catch (error) {\n\t\t\t\t// noop, happen only when the user is not in a project\n\t\t\t}\n\t\t}\n\n\t\tlet environmentKind: Environment[\"kind\"] | \"_unknown\" | undefined =\n\t\t\tundefined;\n\t\tif (_includeEnvironmentKind) {\n\t\t\tif (this.project.checkSupportsEnvironments()) {\n\t\t\t\ttry {\n\t\t\t\t\tconst { activeEnvironment } =\n\t\t\t\t\t\tawait this.project.fetchActiveEnvironment();\n\t\t\t\t\tenvironmentKind = activeEnvironment.kind;\n\t\t\t\t} catch {\n\t\t\t\t\tenvironmentKind = \"_unknown\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Assume only the production environment can be\n\t\t\t\t// used if the project's adapter does not\n\t\t\t\t// support environments.\n\t\t\t\tenvironmentKind = \"prod\";\n\t\t\t}\n\t\t}\n\n\t\tconst payload: {\n\t\t\tevent: HumanSegmentEventTypes;\n\t\t\tuserId?: string;\n\t\t\tanonymousId?: string;\n\t\t\tproperties?: Record<string, unknown>;\n\t\t\tcontext?: Partial<TelemetryManagerContext> & {\n\t\t\t\tgroupId?: {\n\t\t\t\t\tRepository?: string;\n\t\t\t\t};\n\t\t\t};\n\t\t} = {\n\t\t\tevent: HumanSegmentEventType[event],\n\t\t\tproperties: {\n\t\t\t\tnodeVersion: process.versions.node,\n\t\t\t\tenvironmentKind,\n\t\t\t\t...properties,\n\t\t\t},\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tif (this._userID) {\n\t\t\tpayload.userId = this._userID;\n\t\t} else {\n\t\t\tpayload.anonymousId = this._anonymousID;\n\t\t}\n\n\t\tif (repositoryName) {\n\t\t\tpayload.context ||= {};\n\t\t\tpayload.context.groupId ||= {};\n\t\t\tpayload.context.groupId.Repository = repositoryName;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\t// TODO: Make sure client fails gracefully when no internet connection\n\t\t\tthis._segmentClient().track(\n\t\t\t\tpayload as TrackParams,\n\t\t\t\t(maybeError?: unknown) => {\n\t\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t`An error occurred during Segment tracking`,\n\t\t\t\t\t\t\tmaybeError,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\t// TODO: Should `userID` and `intercomHash` be automatically populated\n\t// by the logged in user? We already have their info via\n\t// UserRepository.\n\tidentify(args: TelemetryManagerIdentifyArgs): Promise<void> {\n\t\tconst payload = {\n\t\t\tuserId: args.userID,\n\t\t\tanonymousId: this._anonymousID,\n\t\t\tintegrations: {\n\t\t\t\tIntercom: {\n\t\t\t\t\tuser_hash: args.intercomHash,\n\t\t\t\t},\n\t\t\t},\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tthis._userID = args.userID;\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\t// TODO: Make sure client fails gracefully when no internet connection\n\t\t\tthis._segmentClient().identify(payload, (maybeError?: unknown) => {\n\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\tconsole.warn(`An error occurred during Segment identify`, maybeError);\n\t\t\t\t}\n\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tasync group(args: TelemetryManagerGroupArgs): Promise<void> {\n\t\tlet repositoryName;\n\n\t\ttry {\n\t\t\trepositoryName = await this.project.getRepositoryName();\n\t\t} catch (error) {\n\t\t\t// noop, happen only when the user is not in a project\n\t\t}\n\n\t\tconst payload: {\n\t\t\tgroupId?: string;\n\t\t\tuserId?: string;\n\t\t\tanonymousId?: string;\n\t\t\ttraits?: Record<string, unknown>;\n\t\t\tcontext?: Partial<TelemetryManagerContext> & {\n\t\t\t\tgroupId?: {\n\t\t\t\t\tRepository?: string;\n\t\t\t\t};\n\t\t\t};\n\t\t} = {\n\t\t\ttraits: args,\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tif (this._userID) {\n\t\t\tpayload.userId = this._userID;\n\t\t} else {\n\t\t\tpayload.anonymousId = this._anonymousID;\n\t\t}\n\n\t\tif (repositoryName) {\n\t\t\tpayload.groupId = repositoryName;\n\t\t\tpayload.context ||= {};\n\t\t\tpayload.context.groupId ||= {};\n\t\t\tpayload.context.groupId.Repository = repositoryName;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\tthis._segmentClient().group(\n\t\t\t\tpayload as GroupParams,\n\t\t\t\t(maybeError?: unknown) => {\n\t\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\t\tconsole.warn(`An error occurred during Segment group`, maybeError);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\tasync checkIsTelemetryEnabled(): Promise<boolean> {\n\t\tlet root: string;\n\t\ttry {\n\t\t\troot = await this.project\n\t\t\t\t.getRoot()\n\t\t\t\t.catch(() => this.project.suggestRoot());\n\n\t\t\treturn readPrismicrc(root).telemetry !== false;\n\t\t} catch {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tprivate initExperiment(): void {\n\t\ttry {\n\t\t\tthis._experiment = Experiment.initializeRemote(API_TOKENS.AmplitudeKey);\n\t\t} catch (error) {\n\t\t\tif (import.meta.env.DEV) {\n\t\t\t\tconsole.error(\"Error initializing experiment\", error);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync getExperimentVariant(variantKey: string): Promise<Variant | undefined> {\n\t\tif (this._experiment) {\n\t\t\ttry {\n\t\t\t\tconst repositoryName = await this.project.getRepositoryName();\n\t\t\t\tconst variants = await this._experiment.fetchV2({\n\t\t\t\t\tuser_id: this._userID,\n\t\t\t\t\tuser_properties: {\n\t\t\t\t\t\tRepository: repositoryName,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tconst variantValue = variants[variantKey].value;\n\t\t\t\tif (variantValue) {\n\t\t\t\t\tawait this.track({\n\t\t\t\t\t\tevent: \"experiment:exposure\",\n\t\t\t\t\t\tflag_key: variantKey,\n\t\t\t\t\t\tvariant: variantValue,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn variants[variantKey];\n\t\t\t} catch (error) {\n\t\t\t\tif (import.meta.env.DEV) {\n\t\t\t\t\tconsole.error(\"Error fetching experiment variant\", error);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n}\n"],"names":["Experiment"],"mappings":";;;;;;;;;;;;;;AAiDA,SAAS,2BACR,eAA4C;AAE5C,MAAI,kBAAkB,QAAW;AAC1B,UAAA,IAAI,MACT,kIAAkI;AAAA,EAEpI;AACD;AAEM,MAAO,yBAAyB,YAAW;AAAA,EAA3C;AAAA;AACG;AACA;AACA;AACA;AACA;AAAA;AAAA,EAER,MAAM,cAAc,MAAuC;AACpD,UAAA,qBAAqB,MAAM,KAAK;AAEtC,SAAK,iBAAiB,MAAK;AACpB,YAAA,YAAY,IAAI,UAAU;AAAA,QAC/B,UAAU,WAAW;AAAA;AAAA,QAErB,kBAAkB;AAAA;AAAA,QAElB,SAAS,CAAC;AAAA,MAAA,CACV;AAES,gBAAA,GAAG,SAAS,CAAC,UAAS;AAAA,MAO/B,CACA;AAEM,aAAA;AAAA,IAAA;AAGR,QAAI,oBAAoB;AACvB,WAAK,eAAc;AAAA,IACpB;AAEA,SAAK,eAAe;AACf,SAAA,WAAW,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,SAAS,KAAK;EAC5D;AAAA;AAAA;AAAA,EAIA,MAAM,MAAM,MAA+B;;AAC1C,UAAM,EAAE,OAAO,YAAY,yBAAyB,GAAG,WAAe,IAAA;AACtE,QAAI,iBAAiB;AAErB,QAAI,mBAAmB,QAAW;AAC7B,UAAA;AACc,yBAAA,MAAM,KAAK,QAAQ;eAC5B,OAAO;AAAA,MAEhB;AAAA,IACD;AAEA,QAAI,kBACH;AACD,QAAI,yBAAyB;AACxB,UAAA,KAAK,QAAQ,6BAA6B;AACzC,YAAA;AACH,gBAAM,EAAE,kBAAiB,IACxB,MAAM,KAAK,QAAQ,uBAAsB;AAC1C,4BAAkB,kBAAkB;AAAA,QAAA,QAC7B;AACW,4BAAA;AAAA,QACnB;AAAA,MAAA,OACM;AAIY,0BAAA;AAAA,MACnB;AAAA,IACD;AAEA,UAAM,UAUF;AAAA,MACH,OAAO,sBAAsB,KAAK;AAAA,MAClC,YAAY;AAAA,QACX,aAAa,QAAQ,SAAS;AAAA,QAC9B;AAAA,QACA,GAAG;AAAA,MACH;AAAA,MACD,SAAS,EAAE,GAAG,KAAK,SAAU;AAAA,IAAA;AAG9B,QAAI,KAAK,SAAS;AACjB,cAAQ,SAAS,KAAK;AAAA,IAAA,OAChB;AACN,cAAQ,cAAc,KAAK;AAAA,IAC5B;AAEA,QAAI,gBAAgB;AACnB,cAAQ,YAAR,QAAQ,UAAY;AACZ,oBAAA,SAAQ,YAAR,GAAQ,UAAY;AACpB,cAAA,QAAQ,QAAQ,aAAa;AAAA,IACtC;AAEO,WAAA,IAAI,QAAQ,CAAC,YAAW;AAC9B,iCAA2B,KAAK,cAAc;AAG9C,WAAK,eAAc,EAAG,MACrB,SACA,CAAC,eAAwB;AACpB,YAAA,cAAc,OAAqB;AAE9B,kBAAA,KACP,6CACA,UAAU;AAAA,QAEZ;;OAGA;AAAA,IAAA,CAEF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,MAAkC;AAC1C,UAAM,UAAU;AAAA,MACf,QAAQ,KAAK;AAAA,MACb,aAAa,KAAK;AAAA,MAClB,cAAc;AAAA,QACb,UAAU;AAAA,UACT,WAAW,KAAK;AAAA,QAChB;AAAA,MACD;AAAA,MACD,SAAS,EAAE,GAAG,KAAK,SAAU;AAAA,IAAA;AAG9B,SAAK,UAAU,KAAK;AAEb,WAAA,IAAI,QAAQ,CAAC,YAAW;AAC9B,iCAA2B,KAAK,cAAc;AAG9C,WAAK,eAAc,EAAG,SAAS,SAAS,CAAC,eAAwB;AAC5D,YAAA,cAAc,OAAqB;AAE9B,kBAAA,KAAK,6CAA6C,UAAU;AAAA,QACrE;;OAGA;AAAA,IAAA,CACD;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,MAA+B;;AACtC,QAAA;AAEA,QAAA;AACc,uBAAA,MAAM,KAAK,QAAQ;aAC5B,OAAO;AAAA,IAEhB;AAEA,UAAM,UAUF;AAAA,MACH,QAAQ;AAAA,MACR,SAAS,EAAE,GAAG,KAAK,SAAU;AAAA,IAAA;AAG9B,QAAI,KAAK,SAAS;AACjB,cAAQ,SAAS,KAAK;AAAA,IAAA,OAChB;AACN,cAAQ,cAAc,KAAK;AAAA,IAC5B;AAEA,QAAI,gBAAgB;AACnB,cAAQ,UAAU;AAClB,cAAQ,YAAR,QAAQ,UAAY;AACZ,oBAAA,SAAQ,YAAR,GAAQ,UAAY;AACpB,cAAA,QAAQ,QAAQ,aAAa;AAAA,IACtC;AAEO,WAAA,IAAI,QAAQ,CAAC,YAAW;AAC9B,iCAA2B,KAAK,cAAc;AAE9C,WAAK,eAAc,EAAG,MACrB,SACA,CAAC,eAAwB;AACpB,YAAA,cAAc,OAAqB;AAE9B,kBAAA,KAAK,0CAA0C,UAAU;AAAA,QAClE;;OAGA;AAAA,IAAA,CAEF;AAAA,EACF;AAAA,EAEA,MAAM,0BAAuB;AACxB,QAAA;AACA,QAAA;AACI,aAAA,MAAM,KAAK,QAChB,QAAS,EACT,MAAM,MAAM,KAAK,QAAQ,YAAA,CAAa;AAEjC,aAAA,cAAc,IAAI,EAAE,cAAc;AAAA,IAAA,QAClC;AACA,aAAA;AAAA,IACR;AAAA,EACD;AAAA,EAEQ,iBAAc;AACjB,QAAA;AACH,WAAK,cAAcA,IAAA,WAAW,iBAAiB,WAAW,YAAY;AAAA,aAC9D,OAAO;AAAA,IAIhB;AAAA,EACD;AAAA,EAEA,MAAM,qBAAqB,YAAkB;AAC5C,QAAI,KAAK,aAAa;AACjB,UAAA;AACH,cAAM,iBAAiB,MAAM,KAAK,QAAQ,kBAAiB;AAC3D,cAAM,WAAW,MAAM,KAAK,YAAY,QAAQ;AAAA,UAC/C,SAAS,KAAK;AAAA,UACd,iBAAiB;AAAA,YAChB,YAAY;AAAA,UACZ;AAAA,QAAA,CACD;AAEK,cAAA,eAAe,SAAS,UAAU,EAAE;AAC1C,YAAI,cAAc;AACjB,gBAAM,KAAK,MAAM;AAAA,YAChB,OAAO;AAAA,YACP,UAAU;AAAA,YACV,SAAS;AAAA,UAAA,CACT;AAAA,QACF;AAEA,eAAO,SAAS,UAAU;AAAA,eAClB,OAAO;AAAA,MAIhB;AAAA,IACD;AAEO,WAAA;AAAA,EACR;AACA;"}
1
+ {"version":3,"file":"TelemetryManager.js","sources":["../../../../src/managers/telemetry/TelemetryManager.ts"],"sourcesContent":["import {\n\tExperiment,\n\tRemoteEvaluationClient,\n\tVariant,\n} from \"@amplitude/experiment-node-server\";\nimport { randomUUID } from \"node:crypto\";\nimport { Analytics, GroupParams, TrackParams } from \"@segment/analytics-node\";\n\nimport { readPrismicrc } from \"../../lib/prismicrc\";\n\nimport { API_TOKENS } from \"../../constants/API_TOKENS\";\n\nimport { BaseManager } from \"../BaseManager\";\n\nimport {\n\tHumanSegmentEventType,\n\tHumanSegmentEventTypes,\n\tSegmentEvents,\n} from \"./types\";\nimport { Environment } from \"../prismicRepository/types\";\n\ntype TelemetryManagerInitTelemetryArgs = {\n\tappName: string;\n\tappVersion: string;\n};\n\ntype TelemetryManagerTrackArgs = SegmentEvents & {\n\t_includeEnvironmentKind?: boolean;\n};\n\ntype TelemetryManagerIdentifyArgs = {\n\tuserID: string;\n\tintercomHash: string;\n};\n\ntype TelemetryManagerGroupArgs = {\n\tmanualLibsCount: number;\n\tdownloadedLibsCount: number;\n\tnpmLibsCount: number;\n\tdownloadedLibs: string[];\n};\n\ntype TelemetryManagerContext = {\n\tapp: {\n\t\tname: string;\n\t\tversion: string;\n\t};\n};\n\nfunction assertTelemetryInitialized(\n\tsegmentClient: (() => Analytics) | undefined,\n): asserts segmentClient is NonNullable<typeof segmentClient> {\n\tif (segmentClient === undefined) {\n\t\tthrow new Error(\n\t\t\t\"Telemetry has not been initialized. Run `SliceMachineManager.telemetry.prototype.initTelemetry()` before re-calling this method.\",\n\t\t);\n\t}\n}\n\nexport class TelemetryManager extends BaseManager {\n\tprivate _segmentClient: (() => Analytics) | undefined = undefined;\n\tprivate _anonymousID: string | undefined = undefined;\n\tprivate _userID: string | undefined = undefined;\n\tprivate _context: TelemetryManagerContext | undefined = undefined;\n\tprivate _experiment: RemoteEvaluationClient | undefined = undefined;\n\n\tasync initTelemetry(args: TelemetryManagerInitTelemetryArgs): Promise<void> {\n\t\tconst isTelemetryEnabled = await this.checkIsTelemetryEnabled();\n\n\t\tthis._segmentClient = () => {\n\t\t\tconst analytics = new Analytics({\n\t\t\t\twriteKey: API_TOKENS.SegmentKey,\n\t\t\t\t// Since it's a local app, we do not benefit from event batching the way a server would normally do, all tracking event will be awaited.\n\t\t\t\tmaxEventsInBatch: 1,\n\t\t\t\t// TODO: Verify that this actually does not send data to Segment when false.\n\t\t\t\tdisable: !isTelemetryEnabled,\n\t\t\t});\n\n\t\t\tanalytics.on(\"error\", (error) => {\n\t\t\t\t// noop - We don't care if the tracking event\n\t\t\t\t// failed. Some users or networks intentionally\n\t\t\t\t// block Segment, so we can't block the app if\n\t\t\t\t// a tracking event is unsuccessful.\n\t\t\t\tif (import.meta.env.DEV) {\n\t\t\t\t\tconsole.error(`An error occurred with Segment`, error);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn analytics;\n\t\t};\n\n\t\tif (isTelemetryEnabled) {\n\t\t\tthis.initExperiment();\n\t\t}\n\n\t\tthis._anonymousID = randomUUID();\n\t\tthis._context = { app: { name: args.appName, version: args.appVersion } };\n\t}\n\n\t// TODO: Should `userId` be automatically populated by the logged in\n\t// user? We already have their info via UserRepository.\n\tasync track(args: TelemetryManagerTrackArgs): Promise<void> {\n\t\tconst { event, repository, _includeEnvironmentKind, ...properties } = args;\n\t\tlet repositoryName = repository;\n\n\t\tif (repositoryName === undefined) {\n\t\t\ttry {\n\t\t\t\trepositoryName = await this.project.getRepositoryName();\n\t\t\t} catch (error) {\n\t\t\t\t// noop, happen only when the user is not in a project\n\t\t\t}\n\t\t}\n\n\t\tlet environmentKind: Environment[\"kind\"] | \"_unknown\" | undefined =\n\t\t\tundefined;\n\t\tif (_includeEnvironmentKind) {\n\t\t\tif (this.project.checkSupportsEnvironments()) {\n\t\t\t\ttry {\n\t\t\t\t\tconst activeEnvironmentResult =\n\t\t\t\t\t\tawait this.project.fetchActiveEnvironment();\n\n\t\t\t\t\tif (activeEnvironmentResult.type === \"ok\") {\n\t\t\t\t\t\tenvironmentKind = activeEnvironmentResult.activeEnvironment.kind;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow activeEnvironmentResult.error;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\tenvironmentKind = \"_unknown\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Assume only the production environment can be\n\t\t\t\t// used if the project's adapter does not\n\t\t\t\t// support environments.\n\t\t\t\tenvironmentKind = \"prod\";\n\t\t\t}\n\t\t}\n\n\t\tconst payload: {\n\t\t\tevent: HumanSegmentEventTypes;\n\t\t\tuserId?: string;\n\t\t\tanonymousId?: string;\n\t\t\tproperties?: Record<string, unknown>;\n\t\t\tcontext?: Partial<TelemetryManagerContext> & {\n\t\t\t\tgroupId?: {\n\t\t\t\t\tRepository?: string;\n\t\t\t\t};\n\t\t\t};\n\t\t} = {\n\t\t\tevent: HumanSegmentEventType[event],\n\t\t\tproperties: {\n\t\t\t\tnodeVersion: process.versions.node,\n\t\t\t\tenvironmentKind,\n\t\t\t\t...properties,\n\t\t\t},\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tif (this._userID) {\n\t\t\tpayload.userId = this._userID;\n\t\t} else {\n\t\t\tpayload.anonymousId = this._anonymousID;\n\t\t}\n\n\t\tif (repositoryName) {\n\t\t\tpayload.context ||= {};\n\t\t\tpayload.context.groupId ||= {};\n\t\t\tpayload.context.groupId.Repository = repositoryName;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\t// TODO: Make sure client fails gracefully when no internet connection\n\t\t\tthis._segmentClient().track(\n\t\t\t\tpayload as TrackParams,\n\t\t\t\t(maybeError?: unknown) => {\n\t\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t`An error occurred during Segment tracking`,\n\t\t\t\t\t\t\tmaybeError,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\t// TODO: Should `userID` and `intercomHash` be automatically populated\n\t// by the logged in user? We already have their info via\n\t// UserRepository.\n\tidentify(args: TelemetryManagerIdentifyArgs): Promise<void> {\n\t\tconst payload = {\n\t\t\tuserId: args.userID,\n\t\t\tanonymousId: this._anonymousID,\n\t\t\tintegrations: {\n\t\t\t\tIntercom: {\n\t\t\t\t\tuser_hash: args.intercomHash,\n\t\t\t\t},\n\t\t\t},\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tthis._userID = args.userID;\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\t// TODO: Make sure client fails gracefully when no internet connection\n\t\t\tthis._segmentClient().identify(payload, (maybeError?: unknown) => {\n\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\tconsole.warn(`An error occurred during Segment identify`, maybeError);\n\t\t\t\t}\n\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tasync group(args: TelemetryManagerGroupArgs): Promise<void> {\n\t\tlet repositoryName;\n\n\t\ttry {\n\t\t\trepositoryName = await this.project.getRepositoryName();\n\t\t} catch (error) {\n\t\t\t// noop, happen only when the user is not in a project\n\t\t}\n\n\t\tconst payload: {\n\t\t\tgroupId?: string;\n\t\t\tuserId?: string;\n\t\t\tanonymousId?: string;\n\t\t\ttraits?: Record<string, unknown>;\n\t\t\tcontext?: Partial<TelemetryManagerContext> & {\n\t\t\t\tgroupId?: {\n\t\t\t\t\tRepository?: string;\n\t\t\t\t};\n\t\t\t};\n\t\t} = {\n\t\t\ttraits: args,\n\t\t\tcontext: { ...this._context },\n\t\t};\n\n\t\tif (this._userID) {\n\t\t\tpayload.userId = this._userID;\n\t\t} else {\n\t\t\tpayload.anonymousId = this._anonymousID;\n\t\t}\n\n\t\tif (repositoryName) {\n\t\t\tpayload.groupId = repositoryName;\n\t\t\tpayload.context ||= {};\n\t\t\tpayload.context.groupId ||= {};\n\t\t\tpayload.context.groupId.Repository = repositoryName;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tassertTelemetryInitialized(this._segmentClient);\n\n\t\t\tthis._segmentClient().group(\n\t\t\t\tpayload as GroupParams,\n\t\t\t\t(maybeError?: unknown) => {\n\t\t\t\t\tif (maybeError && import.meta.env.DEV) {\n\t\t\t\t\t\t// TODO: Not sure how we want to deal with that\n\t\t\t\t\t\tconsole.warn(`An error occurred during Segment group`, maybeError);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\tasync checkIsTelemetryEnabled(): Promise<boolean> {\n\t\tlet root: string;\n\t\ttry {\n\t\t\troot = await this.project\n\t\t\t\t.getRoot()\n\t\t\t\t.catch(() => this.project.suggestRoot());\n\n\t\t\treturn readPrismicrc(root).telemetry !== false;\n\t\t} catch {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tprivate initExperiment(): void {\n\t\ttry {\n\t\t\tthis._experiment = Experiment.initializeRemote(API_TOKENS.AmplitudeKey);\n\t\t} catch (error) {\n\t\t\tif (import.meta.env.DEV) {\n\t\t\t\tconsole.error(\"Error initializing experiment\", error);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync getExperimentVariant(variantKey: string): Promise<Variant | undefined> {\n\t\tif (this._experiment) {\n\t\t\ttry {\n\t\t\t\tconst repositoryName = await this.project.getRepositoryName();\n\t\t\t\tconst variants = await this._experiment.fetchV2({\n\t\t\t\t\tuser_id: this._userID,\n\t\t\t\t\tuser_properties: {\n\t\t\t\t\t\tRepository: repositoryName,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tconst variantValue = variants[variantKey].value;\n\t\t\t\tif (variantValue) {\n\t\t\t\t\tawait this.track({\n\t\t\t\t\t\tevent: \"experiment:exposure\",\n\t\t\t\t\t\tflag_key: variantKey,\n\t\t\t\t\t\tvariant: variantValue,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn variants[variantKey];\n\t\t\t} catch (error) {\n\t\t\t\tif (import.meta.env.DEV) {\n\t\t\t\t\tconsole.error(\"Error fetching experiment variant\", error);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n}\n"],"names":["Experiment"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slicemachine/manager",
3
- "version": "0.25.2-beta.1",
3
+ "version": "0.25.2-beta.10",
4
4
  "description": "Manage all aspects of a Slice Machine project.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -70,7 +70,7 @@
70
70
  "@prismicio/mocks": "2.14.0",
71
71
  "@prismicio/types-internal": "3.11.2",
72
72
  "@segment/analytics-node": "^2.1.2",
73
- "@slicemachine/plugin-kit": "0.4.80-beta.1",
73
+ "@slicemachine/plugin-kit": "0.4.80-beta.11",
74
74
  "cookie": "^1.0.1",
75
75
  "cors": "^2.8.5",
76
76
  "execa": "^7.1.1",
@@ -194,7 +194,7 @@ export class PrismicAuthManager {
194
194
  server.once("listening", () => {
195
195
  resolve();
196
196
  });
197
- server.listen(args.port);
197
+ server.listen(args.port, "127.0.0.1");
198
198
  });
199
199
 
200
200
  if (args.onListenCallback) {
@@ -103,13 +103,18 @@ const _fetchGitHubReleaseBodyForRelease = async (
103
103
  const cache = args.cache || {};
104
104
 
105
105
  if (Object.keys(cache).length < 1) {
106
- const releases = await fetchAllGitHubReleases({
107
- repositoryOwner: args.repositoryOwner,
108
- repositoryName: args.repositoryName,
109
- });
106
+ try {
107
+ const releases = await fetchAllGitHubReleases({
108
+ repositoryOwner: args.repositoryOwner,
109
+ repositoryName: args.repositoryName,
110
+ });
110
111
 
111
- for (const release of releases) {
112
- cache[release.name] = release;
112
+ for (const release of releases) {
113
+ cache[release.name] = release;
114
+ }
115
+ } catch (error) {
116
+ // noop - Fetch all releases failed, no need to track this error in Sentry.
117
+ return undefined;
113
118
  }
114
119
  }
115
120
 
@@ -17,6 +17,7 @@ import {
17
17
  PrismicUserProfile,
18
18
  } from "../auth/PrismicAuthManager";
19
19
  import { createPrismicAuthManager } from "../auth/createPrismicAuthManager";
20
+ import { UnauthenticatedError } from "../errors";
20
21
 
21
22
  import { API_ENDPOINTS, APIEndpoints } from "../constants/API_ENDPOINTS";
22
23
 
@@ -207,16 +208,17 @@ export class SliceMachineManager {
207
208
  name: "__stub__",
208
209
  message: "__stub__",
209
210
  reason: "__stub__",
210
- status: 401,
211
+ status: 403,
211
212
  };
212
213
  } else if (
214
+ error instanceof UnauthenticatedError ||
213
215
  error instanceof prismicCustomTypesClient.UnauthorizedError
214
216
  ) {
215
217
  authError = {
216
218
  name: "__stub__",
217
219
  message: "__stub__",
218
220
  reason: "__stub__",
219
- status: 403,
221
+ status: 401,
220
222
  };
221
223
  } else {
222
224
  throw error;
@@ -85,9 +85,9 @@ type ProjectManagerUpdateEnvironmentArgs = {
85
85
  environment: string | undefined;
86
86
  };
87
87
 
88
- type ProjectManagerFetchActiveEnvironmentReturnType = {
89
- activeEnvironment: Environment;
90
- };
88
+ type ProjectManagerFetchActiveEnvironmentReturnType =
89
+ | { type: "ok"; activeEnvironment: Environment }
90
+ | { type: "error"; error: InvalidActiveEnvironmentError };
91
91
 
92
92
  export class ProjectManager extends BaseManager {
93
93
  private _cachedRoot: string | undefined;
@@ -451,7 +451,7 @@ export class ProjectManager extends BaseManager {
451
451
  this._cachedEnvironments || [],
452
452
  );
453
453
  if (cachedActiveEnvironment) {
454
- return { activeEnvironment: cachedActiveEnvironment };
454
+ return { type: "ok", activeEnvironment: cachedActiveEnvironment };
455
455
  }
456
456
 
457
457
  // If the environment is not in the cached environments list, we
@@ -472,10 +472,13 @@ export class ProjectManager extends BaseManager {
472
472
  );
473
473
 
474
474
  if (!activeEnvironment) {
475
- throw new InvalidActiveEnvironmentError();
475
+ return {
476
+ type: "error",
477
+ error: new InvalidActiveEnvironmentError(),
478
+ };
476
479
  }
477
480
 
478
- return { activeEnvironment };
481
+ return { type: "ok", activeEnvironment: activeEnvironment };
479
482
  }
480
483
 
481
484
  async detectVersionControlSystem(): Promise<string | "_unknown"> {
@@ -116,9 +116,14 @@ export class TelemetryManager extends BaseManager {
116
116
  if (_includeEnvironmentKind) {
117
117
  if (this.project.checkSupportsEnvironments()) {
118
118
  try {
119
- const { activeEnvironment } =
119
+ const activeEnvironmentResult =
120
120
  await this.project.fetchActiveEnvironment();
121
- environmentKind = activeEnvironment.kind;
121
+
122
+ if (activeEnvironmentResult.type === "ok") {
123
+ environmentKind = activeEnvironmentResult.activeEnvironment.kind;
124
+ } else {
125
+ throw activeEnvironmentResult.error;
126
+ }
122
127
  } catch {
123
128
  environmentKind = "_unknown";
124
129
  }