@sanity/cli-core 0.1.0-alpha.8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SanityCommand.js +88 -5
- package/dist/SanityCommand.js.map +1 -1
- package/dist/_exports/request.d.ts +77 -0
- package/dist/_exports/request.js +7 -0
- package/dist/_exports/request.js.map +1 -0
- package/dist/_exports/ux.d.ts +75 -4
- package/dist/_exports/ux.js +2 -1
- package/dist/_exports/ux.js.map +1 -1
- package/dist/config/cli/getCliConfig.js +33 -33
- package/dist/config/cli/getCliConfig.js.map +1 -1
- package/dist/config/cli/getCliConfigSync.js +1 -1
- package/dist/config/cli/getCliConfigSync.js.map +1 -1
- package/dist/config/cli/schemas.js +7 -0
- package/dist/config/cli/schemas.js.map +1 -1
- package/dist/config/cli/types/cliConfig.js.map +1 -1
- package/dist/config/findProjectRoot.js +8 -4
- package/dist/config/findProjectRoot.js.map +1 -1
- package/dist/config/findProjectRootSync.js +7 -3
- package/dist/config/findProjectRootSync.js.map +1 -1
- package/dist/config/studio/getStudioConfig.js +0 -3
- package/dist/config/studio/getStudioConfig.js.map +1 -1
- package/dist/config/studio/getStudioWorkspaces.js +63 -0
- package/dist/config/studio/getStudioWorkspaces.js.map +1 -0
- package/dist/config/studio/isStudioConfig.js +19 -0
- package/dist/config/studio/isStudioConfig.js.map +1 -0
- package/dist/config/studio/readStudioConfig.worker.js +8 -34
- package/dist/config/studio/readStudioConfig.worker.js.map +1 -1
- package/dist/config/util/findStudioConfigPath.js +24 -3
- package/dist/config/util/findStudioConfigPath.js.map +1 -1
- package/dist/config/util/recursivelyResolveProjectRoot.js.map +1 -1
- package/dist/errors/NonInteractiveError.js +18 -0
- package/dist/errors/NonInteractiveError.js.map +1 -0
- package/dist/{util → errors}/NotFoundError.js +1 -1
- package/dist/errors/NotFoundError.js.map +1 -0
- package/dist/errors/ProjectRootNotFoundError.js +35 -0
- package/dist/errors/ProjectRootNotFoundError.js.map +1 -0
- package/dist/index.d.ts +1247 -36
- package/dist/index.js +14 -9
- package/dist/index.js.map +1 -1
- package/dist/loaders/studio/studioWorkerLoader.worker.js +102 -23
- package/dist/loaders/studio/studioWorkerLoader.worker.js.map +1 -1
- package/dist/loaders/studio/studioWorkerTask.js +55 -34
- package/dist/loaders/studio/studioWorkerTask.js.map +1 -1
- package/dist/loaders/tsx/tsxWorkerLoader.worker.js +3 -4
- package/dist/loaders/tsx/tsxWorkerLoader.worker.js.map +1 -1
- package/dist/loaders/tsx/tsxWorkerTask.js +4 -31
- package/dist/loaders/tsx/tsxWorkerTask.js.map +1 -1
- package/dist/request/createRequester.js +83 -0
- package/dist/request/createRequester.js.map +1 -0
- package/dist/services/apiClient.js +8 -4
- package/dist/services/apiClient.js.map +1 -1
- package/dist/services/cliUserConfig.js +5 -5
- package/dist/services/cliUserConfig.js.map +1 -1
- package/dist/services/getCliToken.js +2 -2
- package/dist/services/getCliToken.js.map +1 -1
- package/dist/telemetry/getTelemetryBaseInfo.js +33 -0
- package/dist/telemetry/getTelemetryBaseInfo.js.map +1 -0
- package/dist/telemetry/types.js +5 -0
- package/dist/telemetry/types.js.map +1 -0
- package/dist/util/doImport.js +2 -1
- package/dist/util/doImport.js.map +1 -1
- package/dist/util/environment/mockBrowserEnvironment.js +1 -0
- package/dist/util/environment/mockBrowserEnvironment.js.map +1 -1
- package/dist/util/getCliTelemetry.js +34 -0
- package/dist/util/getCliTelemetry.js.map +1 -0
- package/dist/util/getSanityUrl.js +4 -3
- package/dist/util/getSanityUrl.js.map +1 -1
- package/dist/util/importModule.js +32 -0
- package/dist/util/importModule.js.map +1 -0
- package/dist/util/isInteractive.js +1 -1
- package/dist/util/isInteractive.js.map +1 -1
- package/dist/util/isStaging.js +10 -0
- package/dist/util/isStaging.js.map +1 -0
- package/dist/util/normalizePath.js +12 -0
- package/dist/util/normalizePath.js.map +1 -0
- package/dist/util/promisifyWorker.js +72 -0
- package/dist/util/promisifyWorker.js.map +1 -0
- package/dist/util/readNDJSON.js +18 -0
- package/dist/util/readNDJSON.js.map +1 -0
- package/dist/util/readPackageJson.js +74 -0
- package/dist/util/readPackageJson.js.map +1 -0
- package/dist/ux/boxen.js +3 -0
- package/dist/ux/boxen.js.map +1 -0
- package/dist/ux/colorizeJson.js +6 -6
- package/dist/ux/colorizeJson.js.map +1 -1
- package/dist/ux/prompts.js +49 -1
- package/dist/ux/prompts.js.map +1 -1
- package/package.json +39 -31
- package/dist/SanityCommand.d.ts +0 -78
- package/dist/_exports/tree.d.ts +0 -1
- package/dist/_exports/tree.js +0 -3
- package/dist/_exports/tree.js.map +0 -1
- package/dist/config/cli/getCliConfig.d.ts +0 -16
- package/dist/config/cli/getCliConfig.worker.d.ts +0 -1
- package/dist/config/cli/getCliConfig.worker.js +0 -15
- package/dist/config/cli/getCliConfig.worker.js.map +0 -1
- package/dist/config/cli/getCliConfigSync.d.ts +0 -12
- package/dist/config/cli/schemas.d.ts +0 -104
- package/dist/config/cli/types/cliConfig.d.ts +0 -83
- package/dist/config/cli/types/userViteConfig.d.ts +0 -5
- package/dist/config/findProjectRoot.d.ts +0 -14
- package/dist/config/findProjectRootSync.d.ts +0 -27
- package/dist/config/studio/getStudioConfig.d.ts +0 -14
- package/dist/config/studio/readStudioConfig.d.ts +0 -96
- package/dist/config/studio/readStudioConfig.worker.d.ts +0 -1
- package/dist/config/util/configPathsSync.d.ts +0 -17
- package/dist/config/util/findAppConfigPath.d.ts +0 -8
- package/dist/config/util/findConfigsPaths.d.ts +0 -16
- package/dist/config/util/findStudioConfigPath.d.ts +0 -9
- package/dist/config/util/isSanityV2StudioRoot.d.ts +0 -8
- package/dist/config/util/recursivelyResolveProjectRoot.d.ts +0 -27
- package/dist/debug.d.ts +0 -15
- package/dist/loaders/studio/studioWorkerLoader.worker.d.ts +0 -1
- package/dist/loaders/studio/studioWorkerTask.d.ts +0 -40
- package/dist/loaders/tsx/tsxWorkerLoader.worker.d.ts +0 -1
- package/dist/loaders/tsx/tsxWorkerTask.d.ts +0 -28
- package/dist/services/apiClient.d.ts +0 -53
- package/dist/services/cliUserConfig.d.ts +0 -40
- package/dist/services/getCliToken.d.ts +0 -7
- package/dist/types.d.ts +0 -15
- package/dist/util/NotFoundError.d.ts +0 -20
- package/dist/util/NotFoundError.js.map +0 -1
- package/dist/util/createExpiringConfig.d.ts +0 -37
- package/dist/util/createExpiringConfig.js +0 -60
- package/dist/util/createExpiringConfig.js.map +0 -1
- package/dist/util/doImport.d.ts +0 -7
- package/dist/util/environment/getStudioEnvironmentVariables.d.ts +0 -12
- package/dist/util/environment/mockBrowserEnvironment.d.ts +0 -17
- package/dist/util/environment/setupBrowserStubs.d.ts +0 -10
- package/dist/util/environment/stubs.d.ts +0 -254
- package/dist/util/fileExists.d.ts +0 -9
- package/dist/util/generateHelpUrl.d.ts +0 -8
- package/dist/util/getEmptyAuth.d.ts +0 -5
- package/dist/util/getSanityEnvVar.d.ts +0 -19
- package/dist/util/getSanityUrl.d.ts +0 -5
- package/dist/util/getUserConfig.d.ts +0 -2
- package/dist/util/isCi.d.ts +0 -1
- package/dist/util/isInteractive.d.ts +0 -1
- package/dist/util/isRecord.d.ts +0 -8
- package/dist/util/isTrueish.d.ts +0 -1
- package/dist/util/parseStringFlag.d.ts +0 -10
- package/dist/util/parseStringFlag.js +0 -19
- package/dist/util/parseStringFlag.js.map +0 -1
- package/dist/util/readJsonFile.d.ts +0 -14
- package/dist/util/resolveLocalPackage.d.ts +0 -18
- package/dist/util/safeStructuredClone.d.ts +0 -8
- package/dist/util/tree.d.ts +0 -31
- package/dist/util/tree.js +0 -108
- package/dist/util/tree.js.map +0 -1
- package/dist/util/tryGetDefaultExport.d.ts +0 -5
- package/dist/util/writeJsonFile.d.ts +0 -9
- package/dist/ux/chalk.d.ts +0 -2
- package/dist/ux/chalk.js +0 -4
- package/dist/ux/chalk.js.map +0 -1
- package/dist/ux/colorizeJson.d.ts +0 -1
- package/dist/ux/formatObject.d.ts +0 -1
- package/dist/ux/formatObject.js +0 -9
- package/dist/ux/formatObject.js.map +0 -1
- package/dist/ux/logSymbols.d.ts +0 -1
- package/dist/ux/printKeyValue.d.ts +0 -1
- package/dist/ux/printKeyValue.js +0 -16
- package/dist/ux/printKeyValue.js.map +0 -1
- package/dist/ux/prompts.d.ts +0 -1
- package/dist/ux/spinner.d.ts +0 -1
- package/dist/ux/timer.d.ts +0 -12
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/request/createRequester.ts"],"sourcesContent":["import {getIt, type Requester} from 'get-it'\nimport {debug, headers, httpErrors, promise} from 'get-it/middleware'\nimport {readPackageUpSync} from 'read-package-up'\n\nlet cachedPkg: {name: string; version: string} | undefined\n\n/**\n * Options for configuring individual middleware in {@link createRequester}.\n *\n * Each key corresponds to a middleware. Omitting a key uses the default,\n * `false` disables it, and an object merges with the defaults.\n *\n * @public\n */\nexport type MiddlewareOptions = {\n debug?: false | {namespace?: string; verbose?: boolean}\n headers?: false | Record<string, string>\n httpErrors?: false\n promise?: false | {onlyBody?: boolean}\n}\n\n/**\n * Creates a `get-it` requester with a standard set of middleware.\n *\n * Default middleware (in order):\n * 1. `httpErrors()` — throw on HTTP error status codes\n * 2. `headers({'User-Agent': '@sanity/cli-core@<version>'})` — identify CLI requests\n * 3. `debug({verbose: true, namespace: 'sanity:cli'})` — debug logging\n * 4. `promise({onlyBody: true})` — return body directly (must be last)\n *\n * @param options - Optional configuration to disable or customize middleware\n * @returns A configured `get-it` requester\n * @public\n */\nexport function createRequester(options?: {middleware?: MiddlewareOptions}): Requester {\n const opts = options?.middleware\n\n const middleware = []\n\n // 1. httpErrors\n if (opts?.httpErrors !== false) {\n middleware.push(httpErrors())\n }\n\n // 2. headers\n if (opts?.headers !== false) {\n const customHeaders = typeof opts?.headers === 'object' ? opts.headers : {}\n const allHeaders = customHeaders['User-Agent']\n ? {...customHeaders}\n : {\n get ['User-Agent']() {\n const pkg = getPackageInfo()\n return `${pkg.name}@${pkg.version}`\n },\n ...customHeaders,\n }\n middleware.push(headers(allHeaders))\n }\n\n // 3. debug\n if (opts?.debug !== false) {\n const debugDefaults = {namespace: 'sanity:cli', verbose: true}\n const customDebug = typeof opts?.debug === 'object' ? opts.debug : {}\n middleware.push(debug({...debugDefaults, ...customDebug}))\n }\n\n // 4. promise (must be last)\n if (opts?.promise !== false) {\n const promiseDefaults = {onlyBody: true}\n const customPromise = typeof opts?.promise === 'object' ? opts.promise : {}\n middleware.push(promise({...promiseDefaults, ...customPromise}))\n }\n\n return getIt(middleware)\n}\n\n/**\n * Reads the nearest `package.json` to determine the name and version of the `@sanity/cli-core` package.\n *\n * @returns The name and version of the package\n * @internal\n */\nfunction getPackageInfo(): {name: string; version: string} {\n if (cachedPkg) return cachedPkg\n\n const result = readPackageUpSync({cwd: import.meta.dirname})\n if (!result) {\n throw new Error('Unable to resolve @sanity/cli-core package root')\n }\n\n cachedPkg = {\n name: result.packageJson.name ?? '@sanity/cli-core',\n version: result.packageJson.version ?? '0.0.0',\n }\n return cachedPkg\n}\n"],"names":["getIt","debug","headers","httpErrors","promise","readPackageUpSync","cachedPkg","createRequester","options","opts","middleware","push","customHeaders","allHeaders","pkg","getPackageInfo","name","version","debugDefaults","namespace","verbose","customDebug","promiseDefaults","onlyBody","customPromise","result","cwd","dirname","Error","packageJson"],"mappings":"AAAA,SAAQA,KAAK,QAAuB,SAAQ;AAC5C,SAAQC,KAAK,EAAEC,OAAO,EAAEC,UAAU,EAAEC,OAAO,QAAO,oBAAmB;AACrE,SAAQC,iBAAiB,QAAO,kBAAiB;AAEjD,IAAIC;AAiBJ;;;;;;;;;;;;CAYC,GACD,OAAO,SAASC,gBAAgBC,OAA0C;IACxE,MAAMC,OAAOD,SAASE;IAEtB,MAAMA,aAAa,EAAE;IAErB,gBAAgB;IAChB,IAAID,MAAMN,eAAe,OAAO;QAC9BO,WAAWC,IAAI,CAACR;IAClB;IAEA,aAAa;IACb,IAAIM,MAAMP,YAAY,OAAO;QAC3B,MAAMU,gBAAgB,OAAOH,MAAMP,YAAY,WAAWO,KAAKP,OAAO,GAAG,CAAC;QAC1E,MAAMW,aAAaD,aAAa,CAAC,aAAa,GAC1C;YAAC,GAAGA,aAAa;QAAA,IACjB;YACE,IAAI,CAAC,aAAa,IAAG;gBACnB,MAAME,MAAMC;gBACZ,OAAO,GAAGD,IAAIE,IAAI,CAAC,CAAC,EAAEF,IAAIG,OAAO,EAAE;YACrC;YACA,GAAGL,aAAa;QAClB;QACJF,WAAWC,IAAI,CAACT,QAAQW;IAC1B;IAEA,WAAW;IACX,IAAIJ,MAAMR,UAAU,OAAO;QACzB,MAAMiB,gBAAgB;YAACC,WAAW;YAAcC,SAAS;QAAI;QAC7D,MAAMC,cAAc,OAAOZ,MAAMR,UAAU,WAAWQ,KAAKR,KAAK,GAAG,CAAC;QACpES,WAAWC,IAAI,CAACV,MAAM;YAAC,GAAGiB,aAAa;YAAE,GAAGG,WAAW;QAAA;IACzD;IAEA,4BAA4B;IAC5B,IAAIZ,MAAML,YAAY,OAAO;QAC3B,MAAMkB,kBAAkB;YAACC,UAAU;QAAI;QACvC,MAAMC,gBAAgB,OAAOf,MAAML,YAAY,WAAWK,KAAKL,OAAO,GAAG,CAAC;QAC1EM,WAAWC,IAAI,CAACP,QAAQ;YAAC,GAAGkB,eAAe;YAAE,GAAGE,aAAa;QAAA;IAC/D;IAEA,OAAOxB,MAAMU;AACf;AAEA;;;;;CAKC,GACD,SAASK;IACP,IAAIT,WAAW,OAAOA;IAEtB,MAAMmB,SAASpB,kBAAkB;QAACqB,KAAK,YAAYC,OAAO;IAAA;IAC1D,IAAI,CAACF,QAAQ;QACX,MAAM,IAAIG,MAAM;IAClB;IAEAtB,YAAY;QACVU,MAAMS,OAAOI,WAAW,CAACb,IAAI,IAAI;QACjCC,SAASQ,OAAOI,WAAW,CAACZ,OAAO,IAAI;IACzC;IACA,OAAOX;AACT"}
|
|
@@ -9,15 +9,17 @@ const CLI_REQUEST_TAG_PREFIX = 'sanity.cli';
|
|
|
9
9
|
/**
|
|
10
10
|
* Create a "global" (unscoped) Sanity API client.
|
|
11
11
|
*
|
|
12
|
+
* @public
|
|
13
|
+
*
|
|
12
14
|
* @param options - The options to use for the client.
|
|
13
15
|
* @returns Promise that resolves to a configured Sanity API client.
|
|
14
|
-
*/ export async function getGlobalCliClient({ requireUser, token: providedToken, ...config }) {
|
|
16
|
+
*/ export async function getGlobalCliClient({ requireUser, token: providedToken, unauthenticated, ...config }) {
|
|
15
17
|
const requester = defaultRequester.clone();
|
|
16
18
|
requester.use(authErrors());
|
|
17
19
|
const sanityEnv = process.env.SANITY_INTERNAL_ENV || 'production';
|
|
18
20
|
const apiHost = apiHosts[sanityEnv];
|
|
19
|
-
// Use the provided token if
|
|
20
|
-
const token = providedToken || await getCliToken();
|
|
21
|
+
// Use the provided token if set, otherwise fall back to the stored CLI token (unless unauthenticated)
|
|
22
|
+
const token = providedToken || (unauthenticated ? undefined : await getCliToken());
|
|
21
23
|
// If the token is not set and requireUser is true, throw an error
|
|
22
24
|
if (!token && requireUser) {
|
|
23
25
|
throw new Error('You must login first - run "sanity login"');
|
|
@@ -35,7 +37,9 @@ const CLI_REQUEST_TAG_PREFIX = 'sanity.cli';
|
|
|
35
37
|
});
|
|
36
38
|
}
|
|
37
39
|
/**
|
|
38
|
-
* Create a "
|
|
40
|
+
* Create a "project" (scoped) Sanity API client.
|
|
41
|
+
*
|
|
42
|
+
* @public
|
|
39
43
|
*
|
|
40
44
|
* @param options - The options to use for the client.
|
|
41
45
|
* @returns Promise that resolves to a configured Sanity API client.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/apiClient.ts"],"sourcesContent":["import {ux} from '@oclif/core'\nimport {\n type ClientConfig,\n type ClientError,\n createClient,\n requester as defaultRequester,\n isHttpError,\n type SanityClient,\n type ServerError,\n} from '@sanity/client'\n\nimport {generateHelpUrl} from '../util/generateHelpUrl.js'\nimport {getCliToken} from './getCliToken.js'\n\nconst apiHosts: Record<string, string | undefined> = {\n staging: 'https://api.sanity.work',\n}\n\nconst CLI_REQUEST_TAG_PREFIX = 'sanity.cli'\n\n/**\n * @
|
|
1
|
+
{"version":3,"sources":["../../src/services/apiClient.ts"],"sourcesContent":["import {ux} from '@oclif/core'\nimport {\n type ClientConfig,\n type ClientError,\n createClient,\n requester as defaultRequester,\n isHttpError,\n type SanityClient,\n type ServerError,\n} from '@sanity/client'\n\nimport {generateHelpUrl} from '../util/generateHelpUrl.js'\nimport {getCliToken} from './getCliToken.js'\n\nconst apiHosts: Record<string, string | undefined> = {\n staging: 'https://api.sanity.work',\n}\n\nconst CLI_REQUEST_TAG_PREFIX = 'sanity.cli'\n\n/**\n * @public\n */\nexport interface GlobalCliClientOptions extends ClientConfig {\n /**\n * The API version to use for this client.\n */\n apiVersion: string\n\n /**\n * Whether to require a user to be authenticated to use this client.\n * Default: `false`.\n * Throws an error if `true` and user is not authenticated.\n */\n requireUser?: boolean\n\n /**\n * Whether to skip reading the stored CLI token. When `true`, the client will\n * have no token unless one is explicitly provided.\n * Default: `false`.\n */\n unauthenticated?: boolean\n}\n\n/**\n * Create a \"global\" (unscoped) Sanity API client.\n *\n * @public\n *\n * @param options - The options to use for the client.\n * @returns Promise that resolves to a configured Sanity API client.\n */\nexport async function getGlobalCliClient({\n requireUser,\n token: providedToken,\n unauthenticated,\n ...config\n}: GlobalCliClientOptions): Promise<SanityClient> {\n const requester = defaultRequester.clone()\n requester.use(authErrors())\n\n const sanityEnv = process.env.SANITY_INTERNAL_ENV || 'production'\n\n const apiHost = apiHosts[sanityEnv]\n\n // Use the provided token if set, otherwise fall back to the stored CLI token (unless unauthenticated)\n const token = providedToken || (unauthenticated ? undefined : await getCliToken())\n\n // If the token is not set and requireUser is true, throw an error\n if (!token && requireUser) {\n throw new Error('You must login first - run \"sanity login\"')\n }\n\n return createClient({\n ...(apiHost ? {apiHost} : {}),\n requester,\n requestTagPrefix: CLI_REQUEST_TAG_PREFIX,\n token,\n useCdn: false,\n useProjectHostname: false,\n ...config,\n })\n}\n\n/**\n * @public\n */\nexport interface ProjectCliClientOptions extends ClientConfig {\n /**\n * The API version to use for this client.\n */\n apiVersion: string\n\n /**\n * The project ID to use for this client.\n */\n projectId: string\n\n /**\n * The dataset to use for this client.\n */\n dataset?: string\n\n /**\n * Whether to require a user to be authenticated to use this client.\n * Default: `false`.\n * Throws an error if `true` and user is not authenticated.\n */\n requireUser?: boolean\n}\n\n/**\n * Create a \"project\" (scoped) Sanity API client.\n *\n * @public\n *\n * @param options - The options to use for the client.\n * @returns Promise that resolves to a configured Sanity API client.\n */\nexport async function getProjectCliClient({\n requireUser,\n token: providedToken,\n ...config\n}: ProjectCliClientOptions): Promise<SanityClient> {\n const requester = defaultRequester.clone()\n requester.use(authErrors())\n\n const sanityEnv = process.env.SANITY_INTERNAL_ENV || 'production'\n\n const apiHost = apiHosts[sanityEnv]\n\n // Use the provided token if it is set, otherwise get the token from the config file\n const token = providedToken || (await getCliToken())\n\n // If the token is not set and requireUser is true, throw an error\n if (!token && requireUser) {\n throw new Error('You must login first - run \"sanity login\"')\n }\n\n return createClient({\n ...(apiHost ? {apiHost} : {}),\n requester,\n requestTagPrefix: CLI_REQUEST_TAG_PREFIX,\n token,\n useCdn: false,\n useProjectHostname: true,\n ...config,\n })\n}\n\n/**\n * `get-it` middleware that checks for 401 authentication errors and extends the error with more\n * helpful guidance on what to do next.\n *\n * @returns get-it middleware with `onError` handler\n * @internal\n */\nfunction authErrors() {\n return {\n onError: (err: Error | null) => {\n if (!err || !isReqResError(err)) {\n return err\n }\n\n const statusCode = isHttpError(err) && err.response.body.statusCode\n if (statusCode === 401) {\n err.message = `${err.message}. You may need to login again with ${ux.colorize('cyan', 'sanity login')}.\\nFor more information, see ${generateHelpUrl('cli-errors')}.`\n }\n\n return err\n },\n }\n}\n\nfunction isReqResError(err: Error): err is ClientError | ServerError {\n return Object.prototype.hasOwnProperty.call(err, 'response')\n}\n"],"names":["ux","createClient","requester","defaultRequester","isHttpError","generateHelpUrl","getCliToken","apiHosts","staging","CLI_REQUEST_TAG_PREFIX","getGlobalCliClient","requireUser","token","providedToken","unauthenticated","config","clone","use","authErrors","sanityEnv","process","env","SANITY_INTERNAL_ENV","apiHost","undefined","Error","requestTagPrefix","useCdn","useProjectHostname","getProjectCliClient","onError","err","isReqResError","statusCode","response","body","message","colorize","Object","prototype","hasOwnProperty","call"],"mappings":"AAAA,SAAQA,EAAE,QAAO,cAAa;AAC9B,SAGEC,YAAY,EACZC,aAAaC,gBAAgB,EAC7BC,WAAW,QAGN,iBAAgB;AAEvB,SAAQC,eAAe,QAAO,6BAA4B;AAC1D,SAAQC,WAAW,QAAO,mBAAkB;AAE5C,MAAMC,WAA+C;IACnDC,SAAS;AACX;AAEA,MAAMC,yBAAyB;AA0B/B;;;;;;;CAOC,GACD,OAAO,eAAeC,mBAAmB,EACvCC,WAAW,EACXC,OAAOC,aAAa,EACpBC,eAAe,EACf,GAAGC,QACoB;IACvB,MAAMb,YAAYC,iBAAiBa,KAAK;IACxCd,UAAUe,GAAG,CAACC;IAEd,MAAMC,YAAYC,QAAQC,GAAG,CAACC,mBAAmB,IAAI;IAErD,MAAMC,UAAUhB,QAAQ,CAACY,UAAU;IAEnC,sGAAsG;IACtG,MAAMP,QAAQC,iBAAkBC,CAAAA,kBAAkBU,YAAY,MAAMlB,aAAY;IAEhF,kEAAkE;IAClE,IAAI,CAACM,SAASD,aAAa;QACzB,MAAM,IAAIc,MAAM;IAClB;IAEA,OAAOxB,aAAa;QAClB,GAAIsB,UAAU;YAACA;QAAO,IAAI,CAAC,CAAC;QAC5BrB;QACAwB,kBAAkBjB;QAClBG;QACAe,QAAQ;QACRC,oBAAoB;QACpB,GAAGb,MAAM;IACX;AACF;AA6BA;;;;;;;CAOC,GACD,OAAO,eAAec,oBAAoB,EACxClB,WAAW,EACXC,OAAOC,aAAa,EACpB,GAAGE,QACqB;IACxB,MAAMb,YAAYC,iBAAiBa,KAAK;IACxCd,UAAUe,GAAG,CAACC;IAEd,MAAMC,YAAYC,QAAQC,GAAG,CAACC,mBAAmB,IAAI;IAErD,MAAMC,UAAUhB,QAAQ,CAACY,UAAU;IAEnC,oFAAoF;IACpF,MAAMP,QAAQC,iBAAkB,MAAMP;IAEtC,kEAAkE;IAClE,IAAI,CAACM,SAASD,aAAa;QACzB,MAAM,IAAIc,MAAM;IAClB;IAEA,OAAOxB,aAAa;QAClB,GAAIsB,UAAU;YAACA;QAAO,IAAI,CAAC,CAAC;QAC5BrB;QACAwB,kBAAkBjB;QAClBG;QACAe,QAAQ;QACRC,oBAAoB;QACpB,GAAGb,MAAM;IACX;AACF;AAEA;;;;;;CAMC,GACD,SAASG;IACP,OAAO;QACLY,SAAS,CAACC;YACR,IAAI,CAACA,OAAO,CAACC,cAAcD,MAAM;gBAC/B,OAAOA;YACT;YAEA,MAAME,aAAa7B,YAAY2B,QAAQA,IAAIG,QAAQ,CAACC,IAAI,CAACF,UAAU;YACnE,IAAIA,eAAe,KAAK;gBACtBF,IAAIK,OAAO,GAAG,GAAGL,IAAIK,OAAO,CAAC,mCAAmC,EAAEpC,GAAGqC,QAAQ,CAAC,QAAQ,gBAAgB,6BAA6B,EAAEhC,gBAAgB,cAAc,CAAC,CAAC;YACvK;YAEA,OAAO0B;QACT;IACF;AACF;AAEA,SAASC,cAAcD,GAAU;IAC/B,OAAOO,OAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACV,KAAK;AACnD"}
|
|
@@ -27,7 +27,7 @@ const cliUserConfigSchema = {
|
|
|
27
27
|
* @param prop - The property to set the value for
|
|
28
28
|
* @param value - The value to set
|
|
29
29
|
* @internal
|
|
30
|
-
*/ export async function
|
|
30
|
+
*/ export async function setCliUserConfig(prop, value) {
|
|
31
31
|
const config = await readConfig();
|
|
32
32
|
const valueSchema = cliUserConfigSchema[prop];
|
|
33
33
|
if (!valueSchema) {
|
|
@@ -55,16 +55,16 @@ const cliUserConfigSchema = {
|
|
|
55
55
|
* @param prop - The property to get the value for
|
|
56
56
|
* @returns The value of the given property
|
|
57
57
|
* @internal
|
|
58
|
-
*/ export async function
|
|
58
|
+
*/ export async function getCliUserConfig(prop) {
|
|
59
59
|
const config = await readConfig();
|
|
60
60
|
const valueSchema = cliUserConfigSchema[prop];
|
|
61
61
|
if (!valueSchema) {
|
|
62
62
|
throw new Error(`No schema defined for config property "${prop}"`);
|
|
63
63
|
}
|
|
64
|
-
const {
|
|
64
|
+
const { success } = valueSchema.safeParse(config[prop]);
|
|
65
65
|
if (!success) {
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
debug('Ignoring invalid stored value for "%s", returning undefined', prop);
|
|
67
|
+
return undefined;
|
|
68
68
|
}
|
|
69
69
|
return config[prop];
|
|
70
70
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/cliUserConfig.ts"],"sourcesContent":["import {mkdir} from 'node:fs/promises'\nimport {homedir} from 'node:os'\nimport {dirname, join as joinPath} from 'node:path'\n\nimport {z} from 'zod'\n\nimport {debug} from '../debug.js'\nimport {readJsonFile} from '../util/readJsonFile.js'\nimport {writeJsonFile} from '../util/writeJsonFile.js'\n\nconst cliUserConfigSchema = {\n authToken: z.string().optional(),\n telemetryConsent: z\n .object({\n updatedAt: z.number().optional(),\n value: z\n .object({\n status: z.enum(['undetermined', 'unset', 'granted', 'denied']),\n type: z.string(),\n })\n .passthrough(),\n })\n .optional(),\n}\n\n/**\n * The CLI user configuration schema.\n *\n * @internal\n */\ntype CliUserConfig = z.infer<z.ZodObject<typeof cliUserConfigSchema>>\n\n/**\n * Set the config value for the given property.\n * Validates that the passed value adheres to the defined CLI config schema.\n *\n * @param prop - The property to set the value for\n * @param value - The value to set\n * @internal\n */\nexport async function
|
|
1
|
+
{"version":3,"sources":["../../src/services/cliUserConfig.ts"],"sourcesContent":["import {mkdir} from 'node:fs/promises'\nimport {homedir} from 'node:os'\nimport {dirname, join as joinPath} from 'node:path'\n\nimport {z} from 'zod'\n\nimport {debug} from '../debug.js'\nimport {readJsonFile} from '../util/readJsonFile.js'\nimport {writeJsonFile} from '../util/writeJsonFile.js'\n\nconst cliUserConfigSchema = {\n authToken: z.string().optional(),\n telemetryConsent: z\n .object({\n updatedAt: z.number().optional(),\n value: z\n .object({\n status: z.enum(['undetermined', 'unset', 'granted', 'denied']),\n type: z.string(),\n })\n .passthrough(),\n })\n .optional(),\n}\n\n/**\n * The CLI user configuration schema.\n *\n * @internal\n */\ntype CliUserConfig = z.infer<z.ZodObject<typeof cliUserConfigSchema>>\n\n/**\n * Set the config value for the given property.\n * Validates that the passed value adheres to the defined CLI config schema.\n *\n * @param prop - The property to set the value for\n * @param value - The value to set\n * @internal\n */\nexport async function setCliUserConfig<P extends keyof CliUserConfig>(\n prop: P,\n value: CliUserConfig[P],\n) {\n const config = await readConfig()\n const valueSchema = cliUserConfigSchema[prop]\n if (!valueSchema) {\n throw new Error(`No schema defined for config property \"${prop}\"`)\n }\n\n const {error, success} = valueSchema.safeParse(value)\n if (!success) {\n const message = error.issues\n .map(({message, path}) => `[${path.join('.')}] ${message}`)\n .join('\\n')\n\n throw new Error(`Invalid value for config property \"${prop}\": ${message}`)\n }\n\n const configPath = getCliUserConfigPath()\n await mkdir(dirname(configPath), {recursive: true})\n await writeJsonFile(configPath, {...config, [prop]: value}, {pretty: true})\n}\n\n/**\n * Get the config value for the given property\n *\n * @param prop - The property to get the value for\n * @returns The value of the given property\n * @internal\n */\nexport async function getCliUserConfig<P extends keyof CliUserConfig>(\n prop: P,\n): Promise<CliUserConfig[P]> {\n const config = await readConfig()\n const valueSchema = cliUserConfigSchema[prop]\n if (!valueSchema) {\n throw new Error(`No schema defined for config property \"${prop}\"`)\n }\n\n const {success} = valueSchema.safeParse(config[prop])\n if (!success) {\n debug('Ignoring invalid stored value for \"%s\", returning undefined', prop)\n return undefined as CliUserConfig[P]\n }\n\n return config[prop]\n}\n\n/**\n * Read the whole configuration from file system. If the file does not exist or could\n * not be loaded, an empty configuration object is returned.\n *\n * @returns The whole CLI configuration.\n * @internal\n */\nasync function readConfig(): Promise<CliUserConfig> {\n const defaultConfig: CliUserConfig = {}\n try {\n const config = await readJsonFile(getCliUserConfigPath())\n if (!config || typeof config !== 'object' || Array.isArray(config)) {\n throw new Error('Invalid config file - expected an object')\n }\n return config\n } catch (err: unknown) {\n debug('Failed to read CLI config file: %s', err instanceof Error ? err.message : `${err}`)\n return defaultConfig\n }\n}\n\n/**\n * Get the file system location for the CLI user configuration file.\n * Takes into account the active environment (staging vs production).\n * The file is located in the user's home directory under the `.config` directory.\n *\n * @returns The path to the CLI configuration file.\n * @internal\n */\nfunction getCliUserConfigPath() {\n const sanityEnvSuffix = process.env.SANITY_INTERNAL_ENV === 'staging' ? '-staging' : ''\n const cliConfigPath =\n process.env.SANITY_CLI_CONFIG_PATH ||\n joinPath(homedir(), '.config', `sanity${sanityEnvSuffix}`, 'config.json')\n\n return cliConfigPath\n}\n"],"names":["mkdir","homedir","dirname","join","joinPath","z","debug","readJsonFile","writeJsonFile","cliUserConfigSchema","authToken","string","optional","telemetryConsent","object","updatedAt","number","value","status","enum","type","passthrough","setCliUserConfig","prop","config","readConfig","valueSchema","Error","error","success","safeParse","message","issues","map","path","configPath","getCliUserConfigPath","recursive","pretty","getCliUserConfig","undefined","defaultConfig","Array","isArray","err","sanityEnvSuffix","process","env","SANITY_INTERNAL_ENV","cliConfigPath","SANITY_CLI_CONFIG_PATH"],"mappings":"AAAA,SAAQA,KAAK,QAAO,mBAAkB;AACtC,SAAQC,OAAO,QAAO,UAAS;AAC/B,SAAQC,OAAO,EAAEC,QAAQC,QAAQ,QAAO,YAAW;AAEnD,SAAQC,CAAC,QAAO,MAAK;AAErB,SAAQC,KAAK,QAAO,cAAa;AACjC,SAAQC,YAAY,QAAO,0BAAyB;AACpD,SAAQC,aAAa,QAAO,2BAA0B;AAEtD,MAAMC,sBAAsB;IAC1BC,WAAWL,EAAEM,MAAM,GAAGC,QAAQ;IAC9BC,kBAAkBR,EACfS,MAAM,CAAC;QACNC,WAAWV,EAAEW,MAAM,GAAGJ,QAAQ;QAC9BK,OAAOZ,EACJS,MAAM,CAAC;YACNI,QAAQb,EAAEc,IAAI,CAAC;gBAAC;gBAAgB;gBAAS;gBAAW;aAAS;YAC7DC,MAAMf,EAAEM,MAAM;QAChB,GACCU,WAAW;IAChB,GACCT,QAAQ;AACb;AASA;;;;;;;CAOC,GACD,OAAO,eAAeU,iBACpBC,IAAO,EACPN,KAAuB;IAEvB,MAAMO,SAAS,MAAMC;IACrB,MAAMC,cAAcjB,mBAAmB,CAACc,KAAK;IAC7C,IAAI,CAACG,aAAa;QAChB,MAAM,IAAIC,MAAM,CAAC,uCAAuC,EAAEJ,KAAK,CAAC,CAAC;IACnE;IAEA,MAAM,EAACK,KAAK,EAAEC,OAAO,EAAC,GAAGH,YAAYI,SAAS,CAACb;IAC/C,IAAI,CAACY,SAAS;QACZ,MAAME,UAAUH,MAAMI,MAAM,CACzBC,GAAG,CAAC,CAAC,EAACF,OAAO,EAAEG,IAAI,EAAC,GAAK,CAAC,CAAC,EAAEA,KAAK/B,IAAI,CAAC,KAAK,EAAE,EAAE4B,SAAS,EACzD5B,IAAI,CAAC;QAER,MAAM,IAAIwB,MAAM,CAAC,mCAAmC,EAAEJ,KAAK,GAAG,EAAEQ,SAAS;IAC3E;IAEA,MAAMI,aAAaC;IACnB,MAAMpC,MAAME,QAAQiC,aAAa;QAACE,WAAW;IAAI;IACjD,MAAM7B,cAAc2B,YAAY;QAAC,GAAGX,MAAM;QAAE,CAACD,KAAK,EAAEN;IAAK,GAAG;QAACqB,QAAQ;IAAI;AAC3E;AAEA;;;;;;CAMC,GACD,OAAO,eAAeC,iBACpBhB,IAAO;IAEP,MAAMC,SAAS,MAAMC;IACrB,MAAMC,cAAcjB,mBAAmB,CAACc,KAAK;IAC7C,IAAI,CAACG,aAAa;QAChB,MAAM,IAAIC,MAAM,CAAC,uCAAuC,EAAEJ,KAAK,CAAC,CAAC;IACnE;IAEA,MAAM,EAACM,OAAO,EAAC,GAAGH,YAAYI,SAAS,CAACN,MAAM,CAACD,KAAK;IACpD,IAAI,CAACM,SAAS;QACZvB,MAAM,+DAA+DiB;QACrE,OAAOiB;IACT;IAEA,OAAOhB,MAAM,CAACD,KAAK;AACrB;AAEA;;;;;;CAMC,GACD,eAAeE;IACb,MAAMgB,gBAA+B,CAAC;IACtC,IAAI;QACF,MAAMjB,SAAS,MAAMjB,aAAa6B;QAClC,IAAI,CAACZ,UAAU,OAAOA,WAAW,YAAYkB,MAAMC,OAAO,CAACnB,SAAS;YAClE,MAAM,IAAIG,MAAM;QAClB;QACA,OAAOH;IACT,EAAE,OAAOoB,KAAc;QACrBtC,MAAM,sCAAsCsC,eAAejB,QAAQiB,IAAIb,OAAO,GAAG,GAAGa,KAAK;QACzF,OAAOH;IACT;AACF;AAEA;;;;;;;CAOC,GACD,SAASL;IACP,MAAMS,kBAAkBC,QAAQC,GAAG,CAACC,mBAAmB,KAAK,YAAY,aAAa;IACrF,MAAMC,gBACJH,QAAQC,GAAG,CAACG,sBAAsB,IAClC9C,SAASH,WAAW,WAAW,CAAC,MAAM,EAAE4C,iBAAiB,EAAE;IAE7D,OAAOI;AACT"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getCliUserConfig } from './cliUserConfig.js';
|
|
2
2
|
let cachedToken;
|
|
3
3
|
/**
|
|
4
4
|
* Get the CLI authentication token from the environment or the config file
|
|
@@ -14,7 +14,7 @@ let cachedToken;
|
|
|
14
14
|
cachedToken = token.trim();
|
|
15
15
|
return cachedToken;
|
|
16
16
|
}
|
|
17
|
-
cachedToken = await
|
|
17
|
+
cachedToken = await getCliUserConfig('authToken');
|
|
18
18
|
return cachedToken;
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/getCliToken.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../src/services/getCliToken.ts"],"sourcesContent":["import {getCliUserConfig} from './cliUserConfig.js'\n\nlet cachedToken: string | undefined\n\n/**\n * Get the CLI authentication token from the environment or the config file\n *\n * @returns A promise that resolves to a CLI token, or undefined if no token is found\n * @internal\n */\nexport async function getCliToken(): Promise<string | undefined> {\n if (cachedToken !== undefined) {\n return cachedToken\n }\n\n const token = process.env.SANITY_AUTH_TOKEN\n if (token) {\n cachedToken = token.trim()\n return cachedToken\n }\n\n cachedToken = await getCliUserConfig('authToken')\n return cachedToken\n}\n"],"names":["getCliUserConfig","cachedToken","getCliToken","undefined","token","process","env","SANITY_AUTH_TOKEN","trim"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,qBAAoB;AAEnD,IAAIC;AAEJ;;;;;CAKC,GACD,OAAO,eAAeC;IACpB,IAAID,gBAAgBE,WAAW;QAC7B,OAAOF;IACT;IAEA,MAAMG,QAAQC,QAAQC,GAAG,CAACC,iBAAiB;IAC3C,IAAIH,OAAO;QACTH,cAAcG,MAAMI,IAAI;QACxB,OAAOP;IACT;IAEAA,cAAc,MAAMD,iBAAiB;IACrC,OAAOC;AACT"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { getCliToken } from '../services/getCliToken.js';
|
|
5
|
+
import { isStaging } from '../util/isStaging.js';
|
|
6
|
+
/**
|
|
7
|
+
* Gets the base telemetry information needed for file operations.
|
|
8
|
+
*
|
|
9
|
+
* This shared utility extracts common logic used by:
|
|
10
|
+
* - `generateTelemetryFilePath` - for generating session-specific file paths
|
|
11
|
+
* - `findTelemetryFiles` - for discovering all telemetry files via glob patterns
|
|
12
|
+
*
|
|
13
|
+
* @returns Promise resolving to base telemetry information
|
|
14
|
+
* @throws Error if no auth token is found
|
|
15
|
+
* @internal
|
|
16
|
+
*/ export async function getTelemetryBaseInfo() {
|
|
17
|
+
const token = await getCliToken();
|
|
18
|
+
if (!token) {
|
|
19
|
+
throw new Error('No auth token found - user must be logged in for telemetry');
|
|
20
|
+
}
|
|
21
|
+
const hashedToken = createHash('sha256').update(token).digest('hex').slice(0, 8);
|
|
22
|
+
const environment = isStaging() ? 'staging' : 'production';
|
|
23
|
+
const directory = join(tmpdir(), '.config', 'sanity');
|
|
24
|
+
const basePattern = `telemetry-${hashedToken}-${environment}`;
|
|
25
|
+
return {
|
|
26
|
+
basePattern,
|
|
27
|
+
directory,
|
|
28
|
+
environment,
|
|
29
|
+
hashedToken
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=getTelemetryBaseInfo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/telemetry/getTelemetryBaseInfo.ts"],"sourcesContent":["import {createHash} from 'node:crypto'\nimport {tmpdir} from 'node:os'\nimport {join} from 'node:path'\n\nimport {getCliToken} from '../services/getCliToken.js'\nimport {isStaging} from '../util/isStaging.js'\n\n/**\n * Base information needed for telemetry file operations.\n * Contains common data used by both file path generation and pattern matching.\n */\ninterface TelemetryBaseInfo {\n /** Base filename pattern without sessionId suffix */\n basePattern: string\n /** Base directory where telemetry files are stored */\n directory: string\n /** Environment: 'staging' or 'production' */\n environment: string\n /** Hashed token (first 8 chars of SHA256) for privacy */\n hashedToken: string\n}\n\n/**\n * Gets the base telemetry information needed for file operations.\n *\n * This shared utility extracts common logic used by:\n * - `generateTelemetryFilePath` - for generating session-specific file paths\n * - `findTelemetryFiles` - for discovering all telemetry files via glob patterns\n *\n * @returns Promise resolving to base telemetry information\n * @throws Error if no auth token is found\n * @internal\n */\nexport async function getTelemetryBaseInfo(): Promise<TelemetryBaseInfo> {\n const token = await getCliToken()\n if (!token) {\n throw new Error('No auth token found - user must be logged in for telemetry')\n }\n\n const hashedToken = createHash('sha256').update(token).digest('hex').slice(0, 8)\n const environment = isStaging() ? 'staging' : 'production'\n const directory = join(tmpdir(), '.config', 'sanity')\n const basePattern = `telemetry-${hashedToken}-${environment}`\n\n return {\n basePattern,\n directory,\n environment,\n hashedToken,\n }\n}\n"],"names":["createHash","tmpdir","join","getCliToken","isStaging","getTelemetryBaseInfo","token","Error","hashedToken","update","digest","slice","environment","directory","basePattern"],"mappings":"AAAA,SAAQA,UAAU,QAAO,cAAa;AACtC,SAAQC,MAAM,QAAO,UAAS;AAC9B,SAAQC,IAAI,QAAO,YAAW;AAE9B,SAAQC,WAAW,QAAO,6BAA4B;AACtD,SAAQC,SAAS,QAAO,uBAAsB;AAiB9C;;;;;;;;;;CAUC,GACD,OAAO,eAAeC;IACpB,MAAMC,QAAQ,MAAMH;IACpB,IAAI,CAACG,OAAO;QACV,MAAM,IAAIC,MAAM;IAClB;IAEA,MAAMC,cAAcR,WAAW,UAAUS,MAAM,CAACH,OAAOI,MAAM,CAAC,OAAOC,KAAK,CAAC,GAAG;IAC9E,MAAMC,cAAcR,cAAc,YAAY;IAC9C,MAAMS,YAAYX,KAAKD,UAAU,WAAW;IAC5C,MAAMa,cAAc,CAAC,UAAU,EAAEN,YAAY,CAAC,EAAEI,aAAa;IAE7D,OAAO;QACLE;QACAD;QACAD;QACAJ;IACF;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/telemetry/types.ts"],"sourcesContent":["import {type ConsentStatus, type TelemetryLogger} from '@sanity/telemetry'\n\nexport type ConsentInformation =\n | {\n reason: 'fetchError' | 'unauthenticated'\n status: Extract<ConsentStatus, 'undetermined'>\n }\n | {\n reason?: 'localOverride'\n status: Extract<ConsentStatus, 'denied'>\n }\n | {\n reason?: never\n status: Extract<ConsentStatus, 'granted'>\n }\n | {\n reason?: never\n status: Extract<ConsentStatus, 'unset'>\n }\n\n/**\n * @public\n */\nexport interface TelemetryUserProperties {\n cliVersion: string\n cpuArchitecture: string\n machinePlatform: string\n runtime: string\n runtimeVersion: string\n\n dataset?: string\n projectId?: string\n}\n\n/**\n * @public\n */\nexport type CLITelemetryStore = TelemetryLogger<TelemetryUserProperties>\n"],"names":[],"mappings":"AAkCA;;CAEC,GACD,WAAwE"}
|
package/dist/util/doImport.js
CHANGED
|
@@ -9,8 +9,9 @@ import { pathToFileURL } from 'node:url';
|
|
|
9
9
|
// Absolute paths in windows are not valid URLs and are not supported by import().
|
|
10
10
|
// We need to convert the path to a file URL.
|
|
11
11
|
// See: https://github.com/nodejs/node/issues/31710
|
|
12
|
+
const url = /^file:\/\//.test(source) ? source : pathToFileURL(source).href;
|
|
12
13
|
// eslint-disable-next-line no-restricted-syntax
|
|
13
|
-
return import(
|
|
14
|
+
return import(/* @vite-ignore */ url);
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
//# sourceMappingURL=doImport.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/util/doImport.ts"],"sourcesContent":["// Only file that should be using dynamic import\nimport {pathToFileURL} from 'node:url'\n\n/**\n * This function is a replacement for built in dynamic import\n * This handles the case for windows file paths especially for absolute paths.\n *\n * @param source - File path\n */\nexport function doImport(source: string) {\n // Absolute paths in windows are not valid URLs and are not supported by import().\n // We need to convert the path to a file URL.\n // See: https://github.com/nodejs/node/issues/31710\n // eslint-disable-next-line no-restricted-syntax\n return import(
|
|
1
|
+
{"version":3,"sources":["../../src/util/doImport.ts"],"sourcesContent":["// Only file that should be using dynamic import\nimport {pathToFileURL} from 'node:url'\n\n/**\n * This function is a replacement for built in dynamic import\n * This handles the case for windows file paths especially for absolute paths.\n *\n * @param source - File path\n */\nexport function doImport(source: string) {\n // Absolute paths in windows are not valid URLs and are not supported by import().\n // We need to convert the path to a file URL.\n // See: https://github.com/nodejs/node/issues/31710\n const url = /^file:\\/\\//.test(source) ? source : pathToFileURL(source).href\n // eslint-disable-next-line no-restricted-syntax\n return import(\n /* @vite-ignore */\n url\n )\n}\n"],"names":["pathToFileURL","doImport","source","url","test","href"],"mappings":"AAAA,gDAAgD;AAChD,SAAQA,aAAa,QAAO,WAAU;AAEtC;;;;;CAKC,GACD,OAAO,SAASC,SAASC,MAAc;IACrC,kFAAkF;IAClF,6CAA6C;IAC7C,mDAAmD;IACnD,MAAMC,MAAM,aAAaC,IAAI,CAACF,UAAUA,SAASF,cAAcE,QAAQG,IAAI;IAC3E,gDAAgD;IAChD,OAAO,MAAM,CACX,gBAAgB,GAChBF;AAEJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/util/environment/mockBrowserEnvironment.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../../../src/util/environment/mockBrowserEnvironment.ts"],"sourcesContent":["// TODO(SDK-983): Consider moving to @sanity/cli — only used there\nimport {getStudioEnvironmentVariables} from './getStudioEnvironmentVariables.js'\nimport {setupBrowserStubs} from './setupBrowserStubs.js'\n\n/**\n * Mocks a browser-like environment for processes in the main thread by:\n * - Injecting browser globals (window, document, ResizeObserver, etc.)\n * - Loading studio environment variables from the project's sanity installation into process.env\n *\n * This is useful for commands like `sanity exec` that have to run user scripts\n * in the main thread of the process (but in a child process).\n *\n * Be cautious when using this, since it will pollute the global namespace with browser globals.\n *\n * If your code can run in a worker thread, you should use the `studioWorkerTask` function instead.\n *\n * @param basePath - The root path of the Sanity Studio project\n * @returns A cleanup function that removes the injected globals and environment variables\n * @internal\n */\nexport async function mockBrowserEnvironment(basePath: string): Promise<() => void> {\n // 1. Setup browser globals\n const cleanupBrowserStubs = await setupBrowserStubs()\n\n // 2. Load and set environment variables into process.env\n const envVars = await getStudioEnvironmentVariables(basePath)\n const setEnvKeys: string[] = []\n const originalEnvValues: Record<string, string | undefined> = {}\n\n for (const [key, value] of Object.entries(envVars)) {\n // Store original value (if any) so we can restore it\n originalEnvValues[key] = process.env[key]\n process.env[key] = value\n setEnvKeys.push(key)\n }\n\n // Return cleanup function\n return () => {\n // Restore or delete environment variables\n for (const key of setEnvKeys) {\n if (originalEnvValues[key] === undefined) {\n delete process.env[key]\n } else {\n process.env[key] = originalEnvValues[key]\n }\n }\n\n // Clean up browser stubs\n cleanupBrowserStubs()\n }\n}\n"],"names":["getStudioEnvironmentVariables","setupBrowserStubs","mockBrowserEnvironment","basePath","cleanupBrowserStubs","envVars","setEnvKeys","originalEnvValues","key","value","Object","entries","process","env","push","undefined"],"mappings":"AAAA,kEAAkE;AAClE,SAAQA,6BAA6B,QAAO,qCAAoC;AAChF,SAAQC,iBAAiB,QAAO,yBAAwB;AAExD;;;;;;;;;;;;;;;CAeC,GACD,OAAO,eAAeC,uBAAuBC,QAAgB;IAC3D,2BAA2B;IAC3B,MAAMC,sBAAsB,MAAMH;IAElC,yDAAyD;IACzD,MAAMI,UAAU,MAAML,8BAA8BG;IACpD,MAAMG,aAAuB,EAAE;IAC/B,MAAMC,oBAAwD,CAAC;IAE/D,KAAK,MAAM,CAACC,KAAKC,MAAM,IAAIC,OAAOC,OAAO,CAACN,SAAU;QAClD,qDAAqD;QACrDE,iBAAiB,CAACC,IAAI,GAAGI,QAAQC,GAAG,CAACL,IAAI;QACzCI,QAAQC,GAAG,CAACL,IAAI,GAAGC;QACnBH,WAAWQ,IAAI,CAACN;IAClB;IAEA,0BAA0B;IAC1B,OAAO;QACL,0CAA0C;QAC1C,KAAK,MAAMA,OAAOF,WAAY;YAC5B,IAAIC,iBAAiB,CAACC,IAAI,KAAKO,WAAW;gBACxC,OAAOH,QAAQC,GAAG,CAACL,IAAI;YACzB,OAAO;gBACLI,QAAQC,GAAG,CAACL,IAAI,GAAGD,iBAAiB,CAACC,IAAI;YAC3C;QACF;QAEA,yBAAyB;QACzBJ;IACF;AACF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ux } from '@oclif/core';
|
|
2
|
+
import { noopLogger } from '@sanity/telemetry';
|
|
3
|
+
/**
|
|
4
|
+
* @public
|
|
5
|
+
* Symbol used to store the CLI telemetry store on globalThis.
|
|
6
|
+
* Use `getCliTelemetry()` to access the store instead of accessing this directly.
|
|
7
|
+
*/ export const CLI_TELEMETRY_SYMBOL = Symbol.for('sanity.cli.telemetry');
|
|
8
|
+
/**
|
|
9
|
+
* @public
|
|
10
|
+
*/ export function getCliTelemetry() {
|
|
11
|
+
const global = globalThis;
|
|
12
|
+
// This should never happen, but if it does, we return a noop logger to avoid errors.
|
|
13
|
+
if (!global[CLI_TELEMETRY_SYMBOL]) {
|
|
14
|
+
ux.warn('CLI telemetry not initialized, returning noop logger');
|
|
15
|
+
return noopLogger;
|
|
16
|
+
}
|
|
17
|
+
return global[CLI_TELEMETRY_SYMBOL];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Sets the global CLI telemetry store.
|
|
21
|
+
* @internal
|
|
22
|
+
*/ export function setCliTelemetry(telemetry) {
|
|
23
|
+
const global = globalThis;
|
|
24
|
+
global[CLI_TELEMETRY_SYMBOL] = telemetry;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Clears the global CLI telemetry store.
|
|
28
|
+
* @internal
|
|
29
|
+
*/ export function clearCliTelemetry() {
|
|
30
|
+
const global = globalThis;
|
|
31
|
+
delete global[CLI_TELEMETRY_SYMBOL];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=getCliTelemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/getCliTelemetry.ts"],"sourcesContent":["import {ux} from '@oclif/core'\nimport {noopLogger} from '@sanity/telemetry'\n\nimport {type CLITelemetryStore} from '../telemetry/types.js'\n\n/**\n * @public\n * Symbol used to store the CLI telemetry store on globalThis.\n * Use `getCliTelemetry()` to access the store instead of accessing this directly.\n */\nexport const CLI_TELEMETRY_SYMBOL = Symbol.for('sanity.cli.telemetry')\n\ntype GlobalWithTelemetry = typeof globalThis & {\n [CLI_TELEMETRY_SYMBOL]?: CLITelemetryStore\n}\n\n/**\n * @public\n */\nexport function getCliTelemetry(): CLITelemetryStore {\n const global = globalThis as GlobalWithTelemetry\n // This should never happen, but if it does, we return a noop logger to avoid errors.\n if (!global[CLI_TELEMETRY_SYMBOL]) {\n ux.warn('CLI telemetry not initialized, returning noop logger')\n return noopLogger\n }\n\n return global[CLI_TELEMETRY_SYMBOL]\n}\n\n/**\n * Sets the global CLI telemetry store.\n * @internal\n */\nexport function setCliTelemetry(telemetry: CLITelemetryStore): void {\n const global = globalThis as GlobalWithTelemetry\n global[CLI_TELEMETRY_SYMBOL] = telemetry\n}\n\n/**\n * Clears the global CLI telemetry store.\n * @internal\n */\nexport function clearCliTelemetry(): void {\n const global = globalThis as GlobalWithTelemetry\n delete global[CLI_TELEMETRY_SYMBOL]\n}\n"],"names":["ux","noopLogger","CLI_TELEMETRY_SYMBOL","Symbol","for","getCliTelemetry","global","globalThis","warn","setCliTelemetry","telemetry","clearCliTelemetry"],"mappings":"AAAA,SAAQA,EAAE,QAAO,cAAa;AAC9B,SAAQC,UAAU,QAAO,oBAAmB;AAI5C;;;;CAIC,GACD,OAAO,MAAMC,uBAAuBC,OAAOC,GAAG,CAAC,wBAAuB;AAMtE;;CAEC,GACD,OAAO,SAASC;IACd,MAAMC,SAASC;IACf,qFAAqF;IACrF,IAAI,CAACD,MAAM,CAACJ,qBAAqB,EAAE;QACjCF,GAAGQ,IAAI,CAAC;QACR,OAAOP;IACT;IAEA,OAAOK,MAAM,CAACJ,qBAAqB;AACrC;AAEA;;;CAGC,GACD,OAAO,SAASO,gBAAgBC,SAA4B;IAC1D,MAAMJ,SAASC;IACfD,MAAM,CAACJ,qBAAqB,GAAGQ;AACjC;AAEA;;;CAGC,GACD,OAAO,SAASC;IACd,MAAML,SAASC;IACf,OAAOD,MAAM,CAACJ,qBAAqB;AACrC"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @internal
|
|
3
|
-
* @returns The
|
|
4
|
-
*/ export function getSanityUrl() {
|
|
5
|
-
|
|
3
|
+
* @returns The Sanity URL for the given path, using the correct domain based on the environment
|
|
4
|
+
*/ export function getSanityUrl(path = '/') {
|
|
5
|
+
const domain = process.env.SANITY_INTERNAL_ENV === 'staging' ? 'https://www.sanity.work' : 'https://www.sanity.io';
|
|
6
|
+
return `${domain}${path.startsWith('/') ? path : `/${path}`}`;
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
//# sourceMappingURL=getSanityUrl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/util/getSanityUrl.ts"],"sourcesContent":["/**\n * @internal\n * @returns The
|
|
1
|
+
{"version":3,"sources":["../../src/util/getSanityUrl.ts"],"sourcesContent":["/**\n * @internal\n * @returns The Sanity URL for the given path, using the correct domain based on the environment\n */\nexport function getSanityUrl(path = '/') {\n const domain =\n process.env.SANITY_INTERNAL_ENV === 'staging'\n ? 'https://www.sanity.work'\n : 'https://www.sanity.io'\n return `${domain}${path.startsWith('/') ? path : `/${path}`}`\n}\n"],"names":["getSanityUrl","path","domain","process","env","SANITY_INTERNAL_ENV","startsWith"],"mappings":"AAAA;;;CAGC,GACD,OAAO,SAASA,aAAaC,OAAO,GAAG;IACrC,MAAMC,SACJC,QAAQC,GAAG,CAACC,mBAAmB,KAAK,YAChC,4BACA;IACN,OAAO,GAAGH,SAASD,KAAKK,UAAU,CAAC,OAAOL,OAAO,CAAC,CAAC,EAAEA,MAAM,EAAE;AAC/D"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
2
|
+
import { createJiti } from '@rexxars/jiti';
|
|
3
|
+
import { subdebug } from '../debug.js';
|
|
4
|
+
const debug = subdebug('importModule');
|
|
5
|
+
/**
|
|
6
|
+
* Imports a module using jiti and returns its exports.
|
|
7
|
+
* This is a thin wrapper around tsx to allow swapping out the underlying implementation in the future if needed.
|
|
8
|
+
*
|
|
9
|
+
* @param filePath - Path to the module to import.
|
|
10
|
+
* @param options - Options for the importModule function.
|
|
11
|
+
* @returns The exported module.
|
|
12
|
+
*
|
|
13
|
+
* @internal
|
|
14
|
+
*/ export async function importModule(filePath, options = {}) {
|
|
15
|
+
const { default: returnDefault = true, tsconfigPath } = options;
|
|
16
|
+
const jiti = createJiti(import.meta.url, {
|
|
17
|
+
debug: debug.enabled,
|
|
18
|
+
tsconfigPaths: typeof tsconfigPath === 'string' ? tsconfigPath : true
|
|
19
|
+
});
|
|
20
|
+
const fileURL = typeof filePath === 'string' ? pathToFileURL(filePath) : filePath;
|
|
21
|
+
debug(`Loading module: ${fileURLToPath(fileURL)}`, {
|
|
22
|
+
tsconfigPath
|
|
23
|
+
});
|
|
24
|
+
const jitiOptions = {};
|
|
25
|
+
// If the default option is true, add it to the jiti options
|
|
26
|
+
if (returnDefault) {
|
|
27
|
+
jitiOptions.default = true;
|
|
28
|
+
}
|
|
29
|
+
return jiti.import(fileURLToPath(fileURL), jitiOptions);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=importModule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/importModule.ts"],"sourcesContent":["import {fileURLToPath, pathToFileURL} from 'node:url'\n\nimport {createJiti, type JitiResolveOptions} from '@rexxars/jiti'\n\nimport {subdebug} from '../debug.js'\n\ninterface ImportModuleOptions {\n /**\n * Whether to return the default export of the module.\n * Default: true\n */\n default?: boolean\n\n /**\n * Path to the tsconfig file to use for the import. If not provided, the tsconfig\n * will be inferred from the nearest `tsconfig.json` file.\n */\n tsconfigPath?: string\n}\n\nconst debug = subdebug('importModule')\n\n/**\n * Imports a module using jiti and returns its exports.\n * This is a thin wrapper around tsx to allow swapping out the underlying implementation in the future if needed.\n *\n * @param filePath - Path to the module to import.\n * @param options - Options for the importModule function.\n * @returns The exported module.\n *\n * @internal\n */\nexport async function importModule<T = unknown>(\n filePath: string | URL,\n options: ImportModuleOptions = {},\n): Promise<T> {\n const {default: returnDefault = true, tsconfigPath} = options\n\n const jiti = createJiti(import.meta.url, {\n debug: debug.enabled,\n tsconfigPaths: typeof tsconfigPath === 'string' ? tsconfigPath : true,\n })\n\n const fileURL = typeof filePath === 'string' ? pathToFileURL(filePath) : filePath\n\n debug(`Loading module: ${fileURLToPath(fileURL)}`, {tsconfigPath})\n\n const jitiOptions: JitiResolveOptions & {default?: true} = {}\n\n // If the default option is true, add it to the jiti options\n if (returnDefault) {\n jitiOptions.default = true\n }\n\n return jiti.import<T>(fileURLToPath(fileURL), jitiOptions)\n}\n"],"names":["fileURLToPath","pathToFileURL","createJiti","subdebug","debug","importModule","filePath","options","default","returnDefault","tsconfigPath","jiti","url","enabled","tsconfigPaths","fileURL","jitiOptions","import"],"mappings":"AAAA,SAAQA,aAAa,EAAEC,aAAa,QAAO,WAAU;AAErD,SAAQC,UAAU,QAAgC,gBAAe;AAEjE,SAAQC,QAAQ,QAAO,cAAa;AAgBpC,MAAMC,QAAQD,SAAS;AAEvB;;;;;;;;;CASC,GACD,OAAO,eAAeE,aACpBC,QAAsB,EACtBC,UAA+B,CAAC,CAAC;IAEjC,MAAM,EAACC,SAASC,gBAAgB,IAAI,EAAEC,YAAY,EAAC,GAAGH;IAEtD,MAAMI,OAAOT,WAAW,YAAYU,GAAG,EAAE;QACvCR,OAAOA,MAAMS,OAAO;QACpBC,eAAe,OAAOJ,iBAAiB,WAAWA,eAAe;IACnE;IAEA,MAAMK,UAAU,OAAOT,aAAa,WAAWL,cAAcK,YAAYA;IAEzEF,MAAM,CAAC,gBAAgB,EAAEJ,cAAce,UAAU,EAAE;QAACL;IAAY;IAEhE,MAAMM,cAAqD,CAAC;IAE5D,4DAA4D;IAC5D,IAAIP,eAAe;QACjBO,YAAYR,OAAO,GAAG;IACxB;IAEA,OAAOG,KAAKM,MAAM,CAAIjB,cAAce,UAAUC;AAChD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/util/isInteractive.ts"],"sourcesContent":["export function isInteractive(): boolean {\n return process.
|
|
1
|
+
{"version":3,"sources":["../../src/util/isInteractive.ts"],"sourcesContent":["export function isInteractive(): boolean {\n return Boolean(process.stdin.isTTY) && process.env.TERM !== 'dumb' && !('CI' in process.env)\n}\n"],"names":["isInteractive","Boolean","process","stdin","isTTY","env","TERM"],"mappings":"AAAA,OAAO,SAASA;IACd,OAAOC,QAAQC,QAAQC,KAAK,CAACC,KAAK,KAAKF,QAAQG,GAAG,CAACC,IAAI,KAAK,UAAU,CAAE,CAAA,QAAQJ,QAAQG,GAAG,AAAD;AAC5F"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if the environment is staging.
|
|
3
|
+
*
|
|
4
|
+
* @returns True if the environment is staging, false otherwise
|
|
5
|
+
* @internal
|
|
6
|
+
*/ export function isStaging() {
|
|
7
|
+
return process.env.SANITY_INTERNAL_ENV === 'staging';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=isStaging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/isStaging.ts"],"sourcesContent":["/**\n * Checks if the environment is staging.\n *\n * @returns True if the environment is staging, false otherwise\n * @internal\n */\nexport function isStaging(): boolean {\n return process.env.SANITY_INTERNAL_ENV === 'staging'\n}\n"],"names":["isStaging","process","env","SANITY_INTERNAL_ENV"],"mappings":"AAAA;;;;;CAKC,GACD,OAAO,SAASA;IACd,OAAOC,QAAQC,GAAG,CAACC,mBAAmB,KAAK;AAC7C"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes a path for cross-platform comparison by converting backslashes to forward slashes.
|
|
3
|
+
* Useful for converting windows paths to unix paths.
|
|
4
|
+
*
|
|
5
|
+
* @param path - Path to normalize
|
|
6
|
+
* @returns Normalized path with forward slashes
|
|
7
|
+
* @public
|
|
8
|
+
*/ export function normalizePath(path) {
|
|
9
|
+
return path.replaceAll('\\', '/');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=normalizePath.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/normalizePath.ts"],"sourcesContent":["/**\n * Normalizes a path for cross-platform comparison by converting backslashes to forward slashes.\n * Useful for converting windows paths to unix paths.\n *\n * @param path - Path to normalize\n * @returns Normalized path with forward slashes\n * @public\n */\nexport function normalizePath(path: string): string {\n return path.replaceAll('\\\\', '/')\n}\n"],"names":["normalizePath","path","replaceAll"],"mappings":"AAAA;;;;;;;CAOC,GACD,OAAO,SAASA,cAAcC,IAAY;IACxC,OAAOA,KAAKC,UAAU,CAAC,MAAM;AAC/B"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Worker } from 'node:worker_threads';
|
|
2
|
+
import { subdebug } from '../debug.js';
|
|
3
|
+
const debug = subdebug('promisifyWorker');
|
|
4
|
+
/**
|
|
5
|
+
* Creates a Node.js Worker from the given file path and options, and wraps it
|
|
6
|
+
* in a Promise that resolves with the first message the worker sends, and
|
|
7
|
+
* rejects on error, message deserialization failure, or non-zero exit code.
|
|
8
|
+
* The worker is terminated after a message or error is received.
|
|
9
|
+
*
|
|
10
|
+
* @param filePath - URL to the worker file
|
|
11
|
+
* @param options - Options to pass to the Worker constructor
|
|
12
|
+
* @returns A promise that resolves with the first message from the worker
|
|
13
|
+
* @throws If the worker emits an error, a message deserialization error, or exits with a non-zero code
|
|
14
|
+
* @internal
|
|
15
|
+
*/ export function promisifyWorker(filePath, options) {
|
|
16
|
+
const { timeout, ...workerOptions } = options ?? {};
|
|
17
|
+
const worker = new Worker(filePath, workerOptions);
|
|
18
|
+
const fileName = `[${filePath.pathname}]`;
|
|
19
|
+
return new Promise((resolve, reject)=>{
|
|
20
|
+
let settled = false;
|
|
21
|
+
let timeoutId;
|
|
22
|
+
if (timeout !== undefined && timeout > 0) {
|
|
23
|
+
timeoutId = setTimeout(()=>{
|
|
24
|
+
settled = true;
|
|
25
|
+
reject(new Error(`Worker timed out after ${timeout}ms`));
|
|
26
|
+
void worker.terminate();
|
|
27
|
+
worker.removeAllListeners();
|
|
28
|
+
}, timeout);
|
|
29
|
+
}
|
|
30
|
+
worker.addListener('error', function onWorkerError(err) {
|
|
31
|
+
settled = true;
|
|
32
|
+
clearTimeout(timeoutId);
|
|
33
|
+
debug(`Worker error: ${err.message}`, err);
|
|
34
|
+
reject(new Error(`Worker error: ${err.message}`, {
|
|
35
|
+
cause: err
|
|
36
|
+
}));
|
|
37
|
+
cleanup();
|
|
38
|
+
});
|
|
39
|
+
// No cleanup() here — the worker is already dead after exiting,
|
|
40
|
+
// so there is nothing to terminate or remove listeners from.
|
|
41
|
+
worker.addListener('exit', function onWorkerExit(code) {
|
|
42
|
+
clearTimeout(timeoutId);
|
|
43
|
+
if (code > 0) {
|
|
44
|
+
debug(`${fileName} exited with code ${code}`);
|
|
45
|
+
reject(new Error(`Worker exited with code ${code}`));
|
|
46
|
+
} else if (!settled) {
|
|
47
|
+
debug(`${fileName} exited with code 0 without sending a message`);
|
|
48
|
+
reject(new Error('Worker exited without sending a message'));
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
worker.addListener('messageerror', function onWorkerMessageError(err) {
|
|
52
|
+
settled = true;
|
|
53
|
+
clearTimeout(timeoutId);
|
|
54
|
+
debug(`${fileName} message error: ${err.message}`, err);
|
|
55
|
+
reject(new Error(`Failed to deserialize worker message: ${err}`));
|
|
56
|
+
cleanup();
|
|
57
|
+
});
|
|
58
|
+
worker.addListener('message', function onWorkerMessage(message) {
|
|
59
|
+
settled = true;
|
|
60
|
+
clearTimeout(timeoutId);
|
|
61
|
+
debug(`${fileName} message %o`, message);
|
|
62
|
+
resolve(message);
|
|
63
|
+
cleanup();
|
|
64
|
+
});
|
|
65
|
+
function cleanup() {
|
|
66
|
+
setImmediate(()=>worker.terminate());
|
|
67
|
+
worker.removeAllListeners();
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
//# sourceMappingURL=promisifyWorker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/promisifyWorker.ts"],"sourcesContent":["import {Worker, type WorkerOptions} from 'node:worker_threads'\n\nimport {subdebug} from '../debug.js'\n\nconst debug = subdebug('promisifyWorker')\n\ninterface PromisifyWorkerOptions extends WorkerOptions {\n /** Optional timeout in milliseconds. If the worker does not respond within this time, it will be terminated and the promise rejected. */\n timeout?: number\n}\n\n/**\n * Creates a Node.js Worker from the given file path and options, and wraps it\n * in a Promise that resolves with the first message the worker sends, and\n * rejects on error, message deserialization failure, or non-zero exit code.\n * The worker is terminated after a message or error is received.\n *\n * @param filePath - URL to the worker file\n * @param options - Options to pass to the Worker constructor\n * @returns A promise that resolves with the first message from the worker\n * @throws If the worker emits an error, a message deserialization error, or exits with a non-zero code\n * @internal\n */\nexport function promisifyWorker<T = unknown>(\n filePath: URL,\n options?: PromisifyWorkerOptions,\n): Promise<T> {\n const {timeout, ...workerOptions} = options ?? {}\n const worker = new Worker(filePath, workerOptions)\n\n const fileName = `[${filePath.pathname}]`\n\n return new Promise<T>((resolve, reject) => {\n let settled = false\n let timeoutId: ReturnType<typeof setTimeout> | undefined\n\n if (timeout !== undefined && timeout > 0) {\n timeoutId = setTimeout(() => {\n settled = true\n reject(new Error(`Worker timed out after ${timeout}ms`))\n void worker.terminate()\n worker.removeAllListeners()\n }, timeout)\n }\n\n worker.addListener('error', function onWorkerError(err) {\n settled = true\n clearTimeout(timeoutId)\n debug(`Worker error: ${err.message}`, err)\n reject(new Error(`Worker error: ${err.message}`, {cause: err}))\n cleanup()\n })\n // No cleanup() here — the worker is already dead after exiting,\n // so there is nothing to terminate or remove listeners from.\n worker.addListener('exit', function onWorkerExit(code) {\n clearTimeout(timeoutId)\n if (code > 0) {\n debug(`${fileName} exited with code ${code}`)\n reject(new Error(`Worker exited with code ${code}`))\n } else if (!settled) {\n debug(`${fileName} exited with code 0 without sending a message`)\n reject(new Error('Worker exited without sending a message'))\n }\n })\n worker.addListener('messageerror', function onWorkerMessageError(err) {\n settled = true\n clearTimeout(timeoutId)\n debug(`${fileName} message error: ${err.message}`, err)\n reject(new Error(`Failed to deserialize worker message: ${err}`))\n cleanup()\n })\n worker.addListener('message', function onWorkerMessage(message) {\n settled = true\n clearTimeout(timeoutId)\n debug(`${fileName} message %o`, message)\n resolve(message)\n cleanup()\n })\n\n function cleanup() {\n setImmediate(() => worker.terminate())\n worker.removeAllListeners()\n }\n })\n}\n"],"names":["Worker","subdebug","debug","promisifyWorker","filePath","options","timeout","workerOptions","worker","fileName","pathname","Promise","resolve","reject","settled","timeoutId","undefined","setTimeout","Error","terminate","removeAllListeners","addListener","onWorkerError","err","clearTimeout","message","cause","cleanup","onWorkerExit","code","onWorkerMessageError","onWorkerMessage","setImmediate"],"mappings":"AAAA,SAAQA,MAAM,QAA2B,sBAAqB;AAE9D,SAAQC,QAAQ,QAAO,cAAa;AAEpC,MAAMC,QAAQD,SAAS;AAOvB;;;;;;;;;;;CAWC,GACD,OAAO,SAASE,gBACdC,QAAa,EACbC,OAAgC;IAEhC,MAAM,EAACC,OAAO,EAAE,GAAGC,eAAc,GAAGF,WAAW,CAAC;IAChD,MAAMG,SAAS,IAAIR,OAAOI,UAAUG;IAEpC,MAAME,WAAW,CAAC,CAAC,EAAEL,SAASM,QAAQ,CAAC,CAAC,CAAC;IAEzC,OAAO,IAAIC,QAAW,CAACC,SAASC;QAC9B,IAAIC,UAAU;QACd,IAAIC;QAEJ,IAAIT,YAAYU,aAAaV,UAAU,GAAG;YACxCS,YAAYE,WAAW;gBACrBH,UAAU;gBACVD,OAAO,IAAIK,MAAM,CAAC,uBAAuB,EAAEZ,QAAQ,EAAE,CAAC;gBACtD,KAAKE,OAAOW,SAAS;gBACrBX,OAAOY,kBAAkB;YAC3B,GAAGd;QACL;QAEAE,OAAOa,WAAW,CAAC,SAAS,SAASC,cAAcC,GAAG;YACpDT,UAAU;YACVU,aAAaT;YACbb,MAAM,CAAC,cAAc,EAAEqB,IAAIE,OAAO,EAAE,EAAEF;YACtCV,OAAO,IAAIK,MAAM,CAAC,cAAc,EAAEK,IAAIE,OAAO,EAAE,EAAE;gBAACC,OAAOH;YAAG;YAC5DI;QACF;QACA,gEAAgE;QAChE,6DAA6D;QAC7DnB,OAAOa,WAAW,CAAC,QAAQ,SAASO,aAAaC,IAAI;YACnDL,aAAaT;YACb,IAAIc,OAAO,GAAG;gBACZ3B,MAAM,GAAGO,SAAS,kBAAkB,EAAEoB,MAAM;gBAC5ChB,OAAO,IAAIK,MAAM,CAAC,wBAAwB,EAAEW,MAAM;YACpD,OAAO,IAAI,CAACf,SAAS;gBACnBZ,MAAM,GAAGO,SAAS,6CAA6C,CAAC;gBAChEI,OAAO,IAAIK,MAAM;YACnB;QACF;QACAV,OAAOa,WAAW,CAAC,gBAAgB,SAASS,qBAAqBP,GAAG;YAClET,UAAU;YACVU,aAAaT;YACbb,MAAM,GAAGO,SAAS,gBAAgB,EAAEc,IAAIE,OAAO,EAAE,EAAEF;YACnDV,OAAO,IAAIK,MAAM,CAAC,sCAAsC,EAAEK,KAAK;YAC/DI;QACF;QACAnB,OAAOa,WAAW,CAAC,WAAW,SAASU,gBAAgBN,OAAO;YAC5DX,UAAU;YACVU,aAAaT;YACbb,MAAM,GAAGO,SAAS,WAAW,CAAC,EAAEgB;YAChCb,QAAQa;YACRE;QACF;QAEA,SAASA;YACPK,aAAa,IAAMxB,OAAOW,SAAS;YACnCX,OAAOY,kBAAkB;QAC3B;IACF;AACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
/**
|
|
3
|
+
* Reads and parses an NDJSON (newline-delimited JSON) file containing telemetry events.
|
|
4
|
+
*
|
|
5
|
+
* @param filePath - Path to the NDJSON file
|
|
6
|
+
* @returns Promise resolving to array of parsed telemetry events
|
|
7
|
+
* @throws Error if file cannot be read or contains invalid JSON
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
10
|
+
*/ export async function readNDJSON(filePath) {
|
|
11
|
+
const content = await readFile(filePath, 'utf8');
|
|
12
|
+
if (!content.trim()) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
return content.trim().split('\n').filter(Boolean).map((line)=>JSON.parse(line));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=readNDJSON.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/readNDJSON.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\n\n/**\n * Reads and parses an NDJSON (newline-delimited JSON) file containing telemetry events.\n *\n * @param filePath - Path to the NDJSON file\n * @returns Promise resolving to array of parsed telemetry events\n * @throws Error if file cannot be read or contains invalid JSON\n *\n * @internal\n */\nexport async function readNDJSON<T>(filePath: string): Promise<T[]> {\n const content = await readFile(filePath, 'utf8')\n\n if (!content.trim()) {\n return []\n }\n\n return content\n .trim()\n .split('\\n')\n .filter(Boolean)\n .map((line) => JSON.parse(line) as T)\n}\n"],"names":["readFile","readNDJSON","filePath","content","trim","split","filter","Boolean","map","line","JSON","parse"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,mBAAkB;AAEzC;;;;;;;;CAQC,GACD,OAAO,eAAeC,WAAcC,QAAgB;IAClD,MAAMC,UAAU,MAAMH,SAASE,UAAU;IAEzC,IAAI,CAACC,QAAQC,IAAI,IAAI;QACnB,OAAO,EAAE;IACX;IAEA,OAAOD,QACJC,IAAI,GACJC,KAAK,CAAC,MACNC,MAAM,CAACC,SACPC,GAAG,CAAC,CAACC,OAASC,KAAKC,KAAK,CAACF;AAC9B"}
|