@sanity/cli-core 1.2.1 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SanityCommand.js +3 -3
- package/dist/SanityCommand.js.map +1 -1
- package/dist/{index.d.ts → _exports/index.d.ts} +247 -124
- package/dist/_exports/index.js +40 -0
- package/dist/_exports/index.js.map +1 -0
- package/dist/config/cli/schemas.js +50 -50
- package/dist/config/cli/schemas.js.map +1 -1
- package/dist/config/findProjectRoot.js +3 -1
- package/dist/config/findProjectRoot.js.map +1 -1
- package/dist/config/findProjectRootSync.js +3 -1
- package/dist/config/findProjectRootSync.js.map +1 -1
- package/dist/config/studio/readStudioConfig.js +13 -11
- package/dist/config/studio/readStudioConfig.js.map +1 -1
- package/dist/config/studio/readStudioConfig.worker.js +1 -1
- package/dist/config/studio/readStudioConfig.worker.js.map +1 -1
- package/dist/exitCodes.js +17 -0
- package/dist/exitCodes.js.map +1 -0
- package/dist/services/apiClient.js +2 -2
- package/dist/services/apiClient.js.map +1 -1
- package/dist/services/cliTokenCache.js +25 -0
- package/dist/services/cliTokenCache.js.map +1 -0
- package/dist/services/cliUserConfig.js +89 -48
- package/dist/services/cliUserConfig.js.map +1 -1
- package/dist/services/getCliToken.js +12 -7
- package/dist/services/getCliToken.js.map +1 -1
- package/dist/{util → telemetry}/getCliTelemetry.js +1 -1
- package/dist/telemetry/getCliTelemetry.js.map +1 -0
- package/dist/telemetry/noopTelemetry.js +23 -0
- package/dist/telemetry/noopTelemetry.js.map +1 -0
- package/dist/telemetry/readNDJSON.js.map +1 -0
- package/dist/util/environment/getStudioEnvironmentVariables.js +3 -1
- package/dist/util/environment/getStudioEnvironmentVariables.js.map +1 -1
- package/dist/util/readJsonFileSync.js +26 -0
- package/dist/util/readJsonFileSync.js.map +1 -0
- package/dist/util/readPackageJson.js +17 -17
- package/dist/util/readPackageJson.js.map +1 -1
- package/dist/util/resolveLocalPackage.js +6 -2
- package/dist/util/resolveLocalPackage.js.map +1 -1
- package/dist/util/writeJsonFileSync.js +19 -0
- package/dist/util/writeJsonFileSync.js.map +1 -0
- package/package.json +22 -25
- package/dist/index.js +0 -39
- package/dist/index.js.map +0 -1
- package/dist/util/getCliTelemetry.js.map +0 -1
- package/dist/util/getUserConfig.js +0 -15
- package/dist/util/getUserConfig.js.map +0 -1
- package/dist/util/readNDJSON.js.map +0 -1
- package/dist/util/writeJsonFile.js +0 -19
- package/dist/util/writeJsonFile.js.map +0 -1
- /package/dist/{util → telemetry}/readNDJSON.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/_exports/index.ts"],"sourcesContent":["export * from '../config/cli/getCliConfig.js'\nexport * from '../config/cli/getCliConfigSync.js'\nexport {type CliConfig} from '../config/cli/types/cliConfig.js'\nexport {type UserViteConfig} from '../config/cli/types/userViteConfig.js'\nexport * from '../config/findProjectRoot.js'\nexport * from '../config/findProjectRootSync.js'\nexport * from '../config/studio/getStudioConfig.js'\nexport * from '../config/studio/getStudioWorkspaces.js'\nexport * from '../config/studio/isStudioConfig.js'\nexport * from '../config/util/findConfigsPaths.js'\nexport * from '../config/util/findStudioConfigPath.js'\nexport {type ProjectRootResult} from '../config/util/recursivelyResolveProjectRoot.js'\nexport * from '../debug.js'\nexport * from '../errors/NonInteractiveError.js'\nexport * from '../errors/NotFoundError.js'\nexport * from '../errors/ProjectRootNotFoundError.js'\nexport * from '../exitCodes.js'\nexport * from '../loaders/studio/studioWorkerTask.js'\nexport * from '../loaders/tsx/tsxWorkerTask.js'\nexport * from '../SanityCommand.js'\nexport * from '../services/apiClient.js'\nexport * from '../services/cliUserConfig.js'\nexport * from '../services/getCliToken.js'\nexport {\n clearCliTelemetry,\n CLI_TELEMETRY_SYMBOL,\n getCliTelemetry,\n setCliTelemetry,\n} from '../telemetry/getCliTelemetry.js'\nexport {getTelemetryBaseInfo} from '../telemetry/getTelemetryBaseInfo.js'\nexport {noopLogger} from '../telemetry/noopTelemetry.js'\nexport {\n type CLITelemetryStore,\n type ConsentInformation,\n type TelemetryUserProperties,\n} from '../telemetry/types.js'\nexport {type Output, type SanityOrgUser} from '../types.js'\nexport {doImport} from '../util/doImport.js'\nexport * from '../util/environment/mockBrowserEnvironment.js'\nexport * from '../util/getSanityEnvVar.js'\nexport * from '../util/getSanityUrl.js'\nexport * from '../util/importModule.js'\nexport * from '../util/isCi.js'\nexport * from '../util/isInteractive.js'\nexport * from '../util/isStaging.js'\nexport * from '../util/normalizePath.js'\nexport * from '../util/promisifyWorker.js'\nexport * from '../util/readPackageJson.js'\nexport * from '../util/resolveLocalPackage.js'\nexport * from '../util/safeStructuredClone.js'\nexport * from '../ux/colorizeJson.js'\nexport * from '../ux/timer.js'\n"],"names":["clearCliTelemetry","CLI_TELEMETRY_SYMBOL","getCliTelemetry","setCliTelemetry","getTelemetryBaseInfo","noopLogger","doImport"],"mappings":"AAAA,cAAc,gCAA+B;AAC7C,cAAc,oCAAmC;AAGjD,cAAc,+BAA8B;AAC5C,cAAc,mCAAkC;AAChD,cAAc,sCAAqC;AACnD,cAAc,0CAAyC;AACvD,cAAc,qCAAoC;AAClD,cAAc,qCAAoC;AAClD,cAAc,yCAAwC;AAEtD,cAAc,cAAa;AAC3B,cAAc,mCAAkC;AAChD,cAAc,6BAA4B;AAC1C,cAAc,wCAAuC;AACrD,cAAc,kBAAiB;AAC/B,cAAc,wCAAuC;AACrD,cAAc,kCAAiC;AAC/C,cAAc,sBAAqB;AACnC,cAAc,2BAA0B;AACxC,cAAc,+BAA8B;AAC5C,cAAc,6BAA4B;AAC1C,SACEA,iBAAiB,EACjBC,oBAAoB,EACpBC,eAAe,EACfC,eAAe,QACV,kCAAiC;AACxC,SAAQC,oBAAoB,QAAO,uCAAsC;AACzE,SAAQC,UAAU,QAAO,gCAA+B;AAOxD,SAAQC,QAAQ,QAAO,sBAAqB;AAC5C,cAAc,gDAA+C;AAC7D,cAAc,6BAA4B;AAC1C,cAAc,0BAAyB;AACvC,cAAc,0BAAyB;AACvC,cAAc,kBAAiB;AAC/B,cAAc,2BAA0B;AACxC,cAAc,uBAAsB;AACpC,cAAc,2BAA0B;AACxC,cAAc,6BAA4B;AAC1C,cAAc,6BAA4B;AAC1C,cAAc,iCAAgC;AAC9C,cAAc,iCAAgC;AAC9C,cAAc,wBAAuB;AACrC,cAAc,iBAAgB"}
|
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
1
|
+
import { z } from 'zod/mini';
|
|
2
2
|
/**
|
|
3
3
|
* @public
|
|
4
4
|
*/ export const cliConfigSchema = z.object({
|
|
5
|
-
api: z.object({
|
|
6
|
-
dataset: z.
|
|
7
|
-
projectId: z.
|
|
8
|
-
})
|
|
9
|
-
app: z.object({
|
|
10
|
-
entry: z.
|
|
11
|
-
icon: z.
|
|
12
|
-
id: z.
|
|
13
|
-
organizationId: z.
|
|
14
|
-
title: z.
|
|
15
|
-
})
|
|
16
|
-
autoUpdates: z.
|
|
17
|
-
deployment: z.object({
|
|
18
|
-
appId: z.
|
|
19
|
-
autoUpdates: z.
|
|
20
|
-
})
|
|
21
|
-
graphql: z.array(z.object({
|
|
22
|
-
filterSuffix: z.
|
|
23
|
-
generation: z.enum([
|
|
5
|
+
api: z.optional(z.object({
|
|
6
|
+
dataset: z.optional(z.string()),
|
|
7
|
+
projectId: z.optional(z.string())
|
|
8
|
+
})),
|
|
9
|
+
app: z.optional(z.object({
|
|
10
|
+
entry: z.optional(z.string()),
|
|
11
|
+
icon: z.optional(z.string()),
|
|
12
|
+
id: z.optional(z.string()),
|
|
13
|
+
organizationId: z.optional(z.string()),
|
|
14
|
+
title: z.optional(z.string())
|
|
15
|
+
})),
|
|
16
|
+
autoUpdates: z.optional(z.boolean()),
|
|
17
|
+
deployment: z.optional(z.object({
|
|
18
|
+
appId: z.optional(z.string()),
|
|
19
|
+
autoUpdates: z.optional(z.boolean())
|
|
20
|
+
})),
|
|
21
|
+
graphql: z.optional(z.array(z.object({
|
|
22
|
+
filterSuffix: z.optional(z.string()),
|
|
23
|
+
generation: z.optional(z.enum([
|
|
24
24
|
'gen1',
|
|
25
25
|
'gen2',
|
|
26
26
|
'gen3'
|
|
27
|
-
])
|
|
28
|
-
id: z.
|
|
29
|
-
nonNullDocumentFields: z.
|
|
30
|
-
playground: z.
|
|
31
|
-
source: z.
|
|
32
|
-
tag: z.
|
|
33
|
-
workspace: z.
|
|
34
|
-
}))
|
|
35
|
-
mediaLibrary: z.object({
|
|
36
|
-
aspectsPath: z.
|
|
37
|
-
})
|
|
38
|
-
project: z.object({
|
|
39
|
-
basePath: z.
|
|
40
|
-
})
|
|
41
|
-
reactCompiler: z.
|
|
42
|
-
reactStrictMode: z.
|
|
43
|
-
schemaExtraction: z.object({
|
|
44
|
-
enabled: z.
|
|
45
|
-
enforceRequiredFields: z.
|
|
46
|
-
path: z.
|
|
47
|
-
watchPatterns: z.array(z.string())
|
|
48
|
-
workspace: z.
|
|
49
|
-
})
|
|
50
|
-
server: z.object({
|
|
51
|
-
hostname: z.
|
|
52
|
-
port: z.
|
|
53
|
-
})
|
|
54
|
-
studioHost: z.
|
|
55
|
-
vite: z.
|
|
56
|
-
typegen: z.
|
|
27
|
+
])),
|
|
28
|
+
id: z.optional(z.string()),
|
|
29
|
+
nonNullDocumentFields: z.optional(z.boolean()),
|
|
30
|
+
playground: z.optional(z.boolean()),
|
|
31
|
+
source: z.optional(z.string()),
|
|
32
|
+
tag: z.optional(z.string()),
|
|
33
|
+
workspace: z.optional(z.string())
|
|
34
|
+
}))),
|
|
35
|
+
mediaLibrary: z.optional(z.object({
|
|
36
|
+
aspectsPath: z.optional(z.string())
|
|
37
|
+
})),
|
|
38
|
+
project: z.optional(z.object({
|
|
39
|
+
basePath: z.optional(z.string())
|
|
40
|
+
})),
|
|
41
|
+
reactCompiler: z.optional(z.custom()),
|
|
42
|
+
reactStrictMode: z.optional(z.boolean()),
|
|
43
|
+
schemaExtraction: z.optional(z.object({
|
|
44
|
+
enabled: z.optional(z.boolean()),
|
|
45
|
+
enforceRequiredFields: z.optional(z.boolean()),
|
|
46
|
+
path: z.optional(z.string()),
|
|
47
|
+
watchPatterns: z.optional(z.array(z.string())),
|
|
48
|
+
workspace: z.optional(z.string())
|
|
49
|
+
})),
|
|
50
|
+
server: z.optional(z.object({
|
|
51
|
+
hostname: z.optional(z.string()),
|
|
52
|
+
port: z.optional(z.number())
|
|
53
|
+
})),
|
|
54
|
+
studioHost: z.optional(z.string()),
|
|
55
|
+
vite: z.optional(z.custom()),
|
|
56
|
+
typegen: z.optional(z.custom())
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
//# sourceMappingURL=schemas.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/config/cli/schemas.ts"],"sourcesContent":["import {type PluginOptions as ReactCompilerConfig} from 'babel-plugin-react-compiler'\nimport {z} from 'zod'\n\nimport {type CliConfig, type TypeGenConfig} from './types/cliConfig'\nimport {type UserViteConfig} from './types/userViteConfig'\n\n/**\n * @public\n */\nexport const cliConfigSchema = z.object({\n api: z\n .object({\n dataset: z.
|
|
1
|
+
{"version":3,"sources":["../../../src/config/cli/schemas.ts"],"sourcesContent":["import {type PluginOptions as ReactCompilerConfig} from 'babel-plugin-react-compiler'\nimport {z} from 'zod/mini'\n\nimport {type CliConfig, type TypeGenConfig} from './types/cliConfig'\nimport {type UserViteConfig} from './types/userViteConfig'\n\n/**\n * @public\n */\nexport const cliConfigSchema = z.object({\n api: z.optional(\n z.object({\n dataset: z.optional(z.string()),\n projectId: z.optional(z.string()),\n }),\n ),\n\n app: z.optional(\n z.object({\n entry: z.optional(z.string()),\n icon: z.optional(z.string()),\n id: z.optional(z.string()),\n organizationId: z.optional(z.string()),\n title: z.optional(z.string()),\n }),\n ),\n\n autoUpdates: z.optional(z.boolean()),\n\n deployment: z.optional(\n z.object({\n appId: z.optional(z.string()),\n autoUpdates: z.optional(z.boolean()),\n }),\n ),\n\n graphql: z.optional(\n z.array(\n z.object({\n filterSuffix: z.optional(z.string()),\n generation: z.optional(z.enum(['gen1', 'gen2', 'gen3'])),\n id: z.optional(z.string()),\n nonNullDocumentFields: z.optional(z.boolean()),\n playground: z.optional(z.boolean()),\n source: z.optional(z.string()),\n tag: z.optional(z.string()),\n workspace: z.optional(z.string()),\n }),\n ),\n ),\n\n mediaLibrary: z.optional(\n z.object({\n aspectsPath: z.optional(z.string()),\n }),\n ),\n\n project: z.optional(\n z.object({\n basePath: z.optional(z.string()),\n }),\n ),\n\n reactCompiler: z.optional(z.custom<ReactCompilerConfig>()),\n\n reactStrictMode: z.optional(z.boolean()),\n\n schemaExtraction: z.optional(\n z.object({\n enabled: z.optional(z.boolean()),\n enforceRequiredFields: z.optional(z.boolean()),\n path: z.optional(z.string()),\n watchPatterns: z.optional(z.array(z.string())),\n workspace: z.optional(z.string()),\n }),\n ),\n\n server: z.optional(\n z.object({\n hostname: z.optional(z.string()),\n port: z.optional(z.number()),\n }),\n ),\n\n studioHost: z.optional(z.string()),\n\n vite: z.optional(z.custom<UserViteConfig>()),\n\n typegen: z.optional(z.custom<Partial<TypeGenConfig> & {enabled?: boolean}>()),\n}) satisfies z.core.$ZodType<CliConfig>\n"],"names":["z","cliConfigSchema","object","api","optional","dataset","string","projectId","app","entry","icon","id","organizationId","title","autoUpdates","boolean","deployment","appId","graphql","array","filterSuffix","generation","enum","nonNullDocumentFields","playground","source","tag","workspace","mediaLibrary","aspectsPath","project","basePath","reactCompiler","custom","reactStrictMode","schemaExtraction","enabled","enforceRequiredFields","path","watchPatterns","server","hostname","port","number","studioHost","vite","typegen"],"mappings":"AACA,SAAQA,CAAC,QAAO,WAAU;AAK1B;;CAEC,GACD,OAAO,MAAMC,kBAAkBD,EAAEE,MAAM,CAAC;IACtCC,KAAKH,EAAEI,QAAQ,CACbJ,EAAEE,MAAM,CAAC;QACPG,SAASL,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;QAC5BC,WAAWP,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;IAChC;IAGFE,KAAKR,EAAEI,QAAQ,CACbJ,EAAEE,MAAM,CAAC;QACPO,OAAOT,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;QAC1BI,MAAMV,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;QACzBK,IAAIX,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;QACvBM,gBAAgBZ,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;QACnCO,OAAOb,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;IAC5B;IAGFQ,aAAad,EAAEI,QAAQ,CAACJ,EAAEe,OAAO;IAEjCC,YAAYhB,EAAEI,QAAQ,CACpBJ,EAAEE,MAAM,CAAC;QACPe,OAAOjB,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;QAC1BQ,aAAad,EAAEI,QAAQ,CAACJ,EAAEe,OAAO;IACnC;IAGFG,SAASlB,EAAEI,QAAQ,CACjBJ,EAAEmB,KAAK,CACLnB,EAAEE,MAAM,CAAC;QACPkB,cAAcpB,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;QACjCe,YAAYrB,EAAEI,QAAQ,CAACJ,EAAEsB,IAAI,CAAC;YAAC;YAAQ;YAAQ;SAAO;QACtDX,IAAIX,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;QACvBiB,uBAAuBvB,EAAEI,QAAQ,CAACJ,EAAEe,OAAO;QAC3CS,YAAYxB,EAAEI,QAAQ,CAACJ,EAAEe,OAAO;QAChCU,QAAQzB,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;QAC3BoB,KAAK1B,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;QACxBqB,WAAW3B,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;IAChC;IAIJsB,cAAc5B,EAAEI,QAAQ,CACtBJ,EAAEE,MAAM,CAAC;QACP2B,aAAa7B,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;IAClC;IAGFwB,SAAS9B,EAAEI,QAAQ,CACjBJ,EAAEE,MAAM,CAAC;QACP6B,UAAU/B,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;IAC/B;IAGF0B,eAAehC,EAAEI,QAAQ,CAACJ,EAAEiC,MAAM;IAElCC,iBAAiBlC,EAAEI,QAAQ,CAACJ,EAAEe,OAAO;IAErCoB,kBAAkBnC,EAAEI,QAAQ,CAC1BJ,EAAEE,MAAM,CAAC;QACPkC,SAASpC,EAAEI,QAAQ,CAACJ,EAAEe,OAAO;QAC7BsB,uBAAuBrC,EAAEI,QAAQ,CAACJ,EAAEe,OAAO;QAC3CuB,MAAMtC,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;QACzBiC,eAAevC,EAAEI,QAAQ,CAACJ,EAAEmB,KAAK,CAACnB,EAAEM,MAAM;QAC1CqB,WAAW3B,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;IAChC;IAGFkC,QAAQxC,EAAEI,QAAQ,CAChBJ,EAAEE,MAAM,CAAC;QACPuC,UAAUzC,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;QAC7BoC,MAAM1C,EAAEI,QAAQ,CAACJ,EAAE2C,MAAM;IAC3B;IAGFC,YAAY5C,EAAEI,QAAQ,CAACJ,EAAEM,MAAM;IAE/BuC,MAAM7C,EAAEI,QAAQ,CAACJ,EAAEiC,MAAM;IAEzBa,SAAS9C,EAAEI,QAAQ,CAACJ,EAAEiC,MAAM;AAC9B,GAAuC"}
|
|
@@ -32,7 +32,9 @@ import { recursivelyResolveProjectRoot } from './util/recursivelyResolveProjectR
|
|
|
32
32
|
throw err;
|
|
33
33
|
}
|
|
34
34
|
const message = err instanceof Error ? err.message : `${err}`;
|
|
35
|
-
throw new Error(`Error occurred trying to resolve project root:\n${message}
|
|
35
|
+
throw new Error(`Error occurred trying to resolve project root:\n${message}`, {
|
|
36
|
+
cause: err
|
|
37
|
+
});
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
40
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config/findProjectRoot.ts"],"sourcesContent":["import {ProjectRootNotFoundError} from '../errors/ProjectRootNotFoundError.js'\nimport {findAppConfigPath} from './util/findAppConfigPath.js'\nimport {tryFindStudioConfigPath} from './util/findStudioConfigPath.js'\nimport {\n type ProjectRootResult,\n recursivelyResolveProjectRoot,\n} from './util/recursivelyResolveProjectRoot.js'\n\n/**\n * Resolve project root directory and type.\n *\n * Project root is:\n * - `studio` - A pre-blueprints Sanity studio root (containing `sanity.config.(ts|js)`)\n * - `app` - A Sanity app root (containing `sanity.cli.(ts|js)`)\n *\n * If a Sanity Studio v2/v1 root is found (containing `sanity.json` with `root: true`),\n * an error is thrown, as v2/v1 is no longer supported.\n *\n * @internal\n */\nexport async function findProjectRoot(cwd: string): Promise<ProjectRootResult> {\n try {\n // First try to find a studio project root, looks for `sanity.config.(ts|js)`\n const studioProjectRoot = await resolveProjectRootForStudio(cwd)\n if (studioProjectRoot) {\n return studioProjectRoot\n }\n\n // Second try to find a app project root, looks for `sanity.cli.(ts|js)`\n const appProjectRoot = await resolveProjectRootForApp(cwd)\n if (appProjectRoot) {\n return appProjectRoot\n }\n\n // If nothing is found throw a specific error\n throw new ProjectRootNotFoundError('No project root found')\n } catch (err: unknown) {\n if (err instanceof ProjectRootNotFoundError) {\n throw err\n }\n const message = err instanceof Error ? err.message : `${err}`\n throw new Error(`Error occurred trying to resolve project root:\\n${message}
|
|
1
|
+
{"version":3,"sources":["../../src/config/findProjectRoot.ts"],"sourcesContent":["import {ProjectRootNotFoundError} from '../errors/ProjectRootNotFoundError.js'\nimport {findAppConfigPath} from './util/findAppConfigPath.js'\nimport {tryFindStudioConfigPath} from './util/findStudioConfigPath.js'\nimport {\n type ProjectRootResult,\n recursivelyResolveProjectRoot,\n} from './util/recursivelyResolveProjectRoot.js'\n\n/**\n * Resolve project root directory and type.\n *\n * Project root is:\n * - `studio` - A pre-blueprints Sanity studio root (containing `sanity.config.(ts|js)`)\n * - `app` - A Sanity app root (containing `sanity.cli.(ts|js)`)\n *\n * If a Sanity Studio v2/v1 root is found (containing `sanity.json` with `root: true`),\n * an error is thrown, as v2/v1 is no longer supported.\n *\n * @internal\n */\nexport async function findProjectRoot(cwd: string): Promise<ProjectRootResult> {\n try {\n // First try to find a studio project root, looks for `sanity.config.(ts|js)`\n const studioProjectRoot = await resolveProjectRootForStudio(cwd)\n if (studioProjectRoot) {\n return studioProjectRoot\n }\n\n // Second try to find a app project root, looks for `sanity.cli.(ts|js)`\n const appProjectRoot = await resolveProjectRootForApp(cwd)\n if (appProjectRoot) {\n return appProjectRoot\n }\n\n // If nothing is found throw a specific error\n throw new ProjectRootNotFoundError('No project root found')\n } catch (err: unknown) {\n if (err instanceof ProjectRootNotFoundError) {\n throw err\n }\n const message = err instanceof Error ? err.message : `${err}`\n throw new Error(`Error occurred trying to resolve project root:\\n${message}`, {cause: err})\n }\n}\n\n/**\n * Recursively searches for a project configuration file in the given directory and its parents.\n * Throws if Sanity v2 studio root is found.\n *\n * @param basePath - The base path to start searching from\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion.\n * @returns A promise that resolves to an object if config is found, false otherwise\n * @internal\n */\nasync function resolveProjectRootForStudio(\n basePath: string,\n iterations = 0,\n): Promise<false | ProjectRootResult> {\n return recursivelyResolveProjectRoot(basePath, tryFindStudioConfigPath, 'studio', iterations)\n}\n\n/**\n * Recursively searches for a app project configuration file in the given directory and its parents.\n *\n * @param basePath - The base path to start searching from\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion.\n * @returns A promise that resolves to an object if config is found, false otherwise\n * @internal\n */\nasync function resolveProjectRootForApp(\n basePath: string,\n iterations = 0,\n): Promise<false | ProjectRootResult> {\n return recursivelyResolveProjectRoot(basePath, findAppConfigPath, 'app', iterations)\n}\n"],"names":["ProjectRootNotFoundError","findAppConfigPath","tryFindStudioConfigPath","recursivelyResolveProjectRoot","findProjectRoot","cwd","studioProjectRoot","resolveProjectRootForStudio","appProjectRoot","resolveProjectRootForApp","err","message","Error","cause","basePath","iterations"],"mappings":"AAAA,SAAQA,wBAAwB,QAAO,wCAAuC;AAC9E,SAAQC,iBAAiB,QAAO,8BAA6B;AAC7D,SAAQC,uBAAuB,QAAO,iCAAgC;AACtE,SAEEC,6BAA6B,QACxB,0CAAyC;AAEhD;;;;;;;;;;;CAWC,GACD,OAAO,eAAeC,gBAAgBC,GAAW;IAC/C,IAAI;QACF,6EAA6E;QAC7E,MAAMC,oBAAoB,MAAMC,4BAA4BF;QAC5D,IAAIC,mBAAmB;YACrB,OAAOA;QACT;QAEA,wEAAwE;QACxE,MAAME,iBAAiB,MAAMC,yBAAyBJ;QACtD,IAAIG,gBAAgB;YAClB,OAAOA;QACT;QAEA,6CAA6C;QAC7C,MAAM,IAAIR,yBAAyB;IACrC,EAAE,OAAOU,KAAc;QACrB,IAAIA,eAAeV,0BAA0B;YAC3C,MAAMU;QACR;QACA,MAAMC,UAAUD,eAAeE,QAAQF,IAAIC,OAAO,GAAG,GAAGD,KAAK;QAC7D,MAAM,IAAIE,MAAM,CAAC,gDAAgD,EAAED,SAAS,EAAE;YAACE,OAAOH;QAAG;IAC3F;AACF;AAEA;;;;;;;;CAQC,GACD,eAAeH,4BACbO,QAAgB,EAChBC,aAAa,CAAC;IAEd,OAAOZ,8BAA8BW,UAAUZ,yBAAyB,UAAUa;AACpF;AAEA;;;;;;;CAOC,GACD,eAAeN,yBACbK,QAAgB,EAChBC,aAAa,CAAC;IAEd,OAAOZ,8BAA8BW,UAAUb,mBAAmB,OAAOc;AAC3E"}
|
|
@@ -58,7 +58,9 @@ import { findAppConfigPathSync, findStudioConfigPathSync } from './util/configPa
|
|
|
58
58
|
throw err;
|
|
59
59
|
}
|
|
60
60
|
const message = err instanceof Error ? err.message : `${err}`;
|
|
61
|
-
throw new Error(`Error occurred trying to resolve project root:\n${message}
|
|
61
|
+
throw new Error(`Error occurred trying to resolve project root:\n${message}`, {
|
|
62
|
+
cause: err
|
|
63
|
+
});
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
66
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config/findProjectRootSync.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path'\n\nimport {ProjectRootNotFoundError} from '../errors/ProjectRootNotFoundError.js'\nimport {findAppConfigPathSync, findStudioConfigPathSync} from './util/configPathsSync.js'\nimport {ProjectRootResult} from './util/recursivelyResolveProjectRoot.js'\n\n/**\n * Generic recursive search function for project configuration files (synchronous version).\n *\n * @param basePath - The base path to start searching from\n * @param findConfigFn - Function that looks for config files in a given directory\n * @param projectType - The type of project ('app' | 'studio')\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion\n * @returns An object if config is found, false otherwise\n * @internal\n */\nfunction recursivelyResolveProjectRootSync(\n basePath: string,\n findConfigFn: (path: string) => string | undefined,\n projectType: 'app' | 'studio',\n iterations = 0,\n): false | ProjectRootResult {\n const configPath = findConfigFn(basePath)\n\n if (configPath) {\n return {\n directory: dirname(configPath),\n path: configPath,\n type: projectType,\n }\n }\n\n const parentDir = resolve(basePath, '..')\n if (parentDir === basePath || iterations > 50) {\n // Reached root (or max depth), give up\n return false\n }\n\n return recursivelyResolveProjectRootSync(parentDir, findConfigFn, projectType, iterations + 1)\n}\n\n/**\n * Resolve project root directory and type synchronously.\n *\n * Project root is:\n * - `studio` - A pre-blueprints Sanity studio root (containing `sanity.config.(ts|js)`)\n * - `app` - A Sanity app root (containing `sanity.cli.(ts|js)`)\n *\n * If a Sanity Studio v2/v1 root is found (containing `sanity.json` with `root: true`),\n * an error is thrown, as v2/v1 is no longer supported.\n *\n * @param cwd - Current working directory to start searching from\n * @returns Project root result\n * @internal\n */\nexport function findProjectRootSync(cwd: string): ProjectRootResult {\n try {\n // First try to find a studio project root, looks for `sanity.config.(ts|js)`\n const studioProjectRoot = resolveProjectRootForStudioSync(cwd)\n if (studioProjectRoot) {\n return studioProjectRoot\n }\n\n // Second try to find a app project root, looks for `sanity.cli.(ts|js)`\n const appProjectRoot = resolveProjectRootForAppSync(cwd)\n if (appProjectRoot) {\n return appProjectRoot\n }\n\n // If nothing is found throw a specific error\n throw new ProjectRootNotFoundError(`No project root found in ${cwd}`)\n } catch (err: unknown) {\n if (err instanceof ProjectRootNotFoundError) {\n throw err\n }\n const message = err instanceof Error ? err.message : `${err}`\n throw new Error(`Error occurred trying to resolve project root:\\n${message}
|
|
1
|
+
{"version":3,"sources":["../../src/config/findProjectRootSync.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path'\n\nimport {ProjectRootNotFoundError} from '../errors/ProjectRootNotFoundError.js'\nimport {findAppConfigPathSync, findStudioConfigPathSync} from './util/configPathsSync.js'\nimport {ProjectRootResult} from './util/recursivelyResolveProjectRoot.js'\n\n/**\n * Generic recursive search function for project configuration files (synchronous version).\n *\n * @param basePath - The base path to start searching from\n * @param findConfigFn - Function that looks for config files in a given directory\n * @param projectType - The type of project ('app' | 'studio')\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion\n * @returns An object if config is found, false otherwise\n * @internal\n */\nfunction recursivelyResolveProjectRootSync(\n basePath: string,\n findConfigFn: (path: string) => string | undefined,\n projectType: 'app' | 'studio',\n iterations = 0,\n): false | ProjectRootResult {\n const configPath = findConfigFn(basePath)\n\n if (configPath) {\n return {\n directory: dirname(configPath),\n path: configPath,\n type: projectType,\n }\n }\n\n const parentDir = resolve(basePath, '..')\n if (parentDir === basePath || iterations > 50) {\n // Reached root (or max depth), give up\n return false\n }\n\n return recursivelyResolveProjectRootSync(parentDir, findConfigFn, projectType, iterations + 1)\n}\n\n/**\n * Resolve project root directory and type synchronously.\n *\n * Project root is:\n * - `studio` - A pre-blueprints Sanity studio root (containing `sanity.config.(ts|js)`)\n * - `app` - A Sanity app root (containing `sanity.cli.(ts|js)`)\n *\n * If a Sanity Studio v2/v1 root is found (containing `sanity.json` with `root: true`),\n * an error is thrown, as v2/v1 is no longer supported.\n *\n * @param cwd - Current working directory to start searching from\n * @returns Project root result\n * @internal\n */\nexport function findProjectRootSync(cwd: string): ProjectRootResult {\n try {\n // First try to find a studio project root, looks for `sanity.config.(ts|js)`\n const studioProjectRoot = resolveProjectRootForStudioSync(cwd)\n if (studioProjectRoot) {\n return studioProjectRoot\n }\n\n // Second try to find a app project root, looks for `sanity.cli.(ts|js)`\n const appProjectRoot = resolveProjectRootForAppSync(cwd)\n if (appProjectRoot) {\n return appProjectRoot\n }\n\n // If nothing is found throw a specific error\n throw new ProjectRootNotFoundError(`No project root found in ${cwd}`)\n } catch (err: unknown) {\n if (err instanceof ProjectRootNotFoundError) {\n throw err\n }\n const message = err instanceof Error ? err.message : `${err}`\n throw new Error(`Error occurred trying to resolve project root:\\n${message}`, {cause: err})\n }\n}\n\n/**\n * Recursively searches for a project configuration file in the given directory and its parents.\n * Throws if Sanity v2 studio root is found.\n *\n * @param basePath - The base path to start searching from\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion.\n * @returns An object if config is found, false otherwise\n * @internal\n */\nfunction resolveProjectRootForStudioSync(\n basePath: string,\n iterations = 0,\n): false | ProjectRootResult {\n return recursivelyResolveProjectRootSync(basePath, findStudioConfigPathSync, 'studio', iterations)\n}\n\n/**\n * Recursively searches for a app project configuration file in the given directory and its parents.\n *\n * @param basePath - The base path to start searching from\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion.\n * @returns An object if config is found, false otherwise\n * @internal\n */\nfunction resolveProjectRootForAppSync(basePath: string, iterations = 0): false | ProjectRootResult {\n return recursivelyResolveProjectRootSync(basePath, findAppConfigPathSync, 'app', iterations)\n}\n"],"names":["dirname","resolve","ProjectRootNotFoundError","findAppConfigPathSync","findStudioConfigPathSync","recursivelyResolveProjectRootSync","basePath","findConfigFn","projectType","iterations","configPath","directory","path","type","parentDir","findProjectRootSync","cwd","studioProjectRoot","resolveProjectRootForStudioSync","appProjectRoot","resolveProjectRootForAppSync","err","message","Error","cause"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAW;AAE1C,SAAQC,wBAAwB,QAAO,wCAAuC;AAC9E,SAAQC,qBAAqB,EAAEC,wBAAwB,QAAO,4BAA2B;AAGzF;;;;;;;;;CASC,GACD,SAASC,kCACPC,QAAgB,EAChBC,YAAkD,EAClDC,WAA6B,EAC7BC,aAAa,CAAC;IAEd,MAAMC,aAAaH,aAAaD;IAEhC,IAAII,YAAY;QACd,OAAO;YACLC,WAAWX,QAAQU;YACnBE,MAAMF;YACNG,MAAML;QACR;IACF;IAEA,MAAMM,YAAYb,QAAQK,UAAU;IACpC,IAAIQ,cAAcR,YAAYG,aAAa,IAAI;QAC7C,uCAAuC;QACvC,OAAO;IACT;IAEA,OAAOJ,kCAAkCS,WAAWP,cAAcC,aAAaC,aAAa;AAC9F;AAEA;;;;;;;;;;;;;CAaC,GACD,OAAO,SAASM,oBAAoBC,GAAW;IAC7C,IAAI;QACF,6EAA6E;QAC7E,MAAMC,oBAAoBC,gCAAgCF;QAC1D,IAAIC,mBAAmB;YACrB,OAAOA;QACT;QAEA,wEAAwE;QACxE,MAAME,iBAAiBC,6BAA6BJ;QACpD,IAAIG,gBAAgB;YAClB,OAAOA;QACT;QAEA,6CAA6C;QAC7C,MAAM,IAAIjB,yBAAyB,CAAC,yBAAyB,EAAEc,KAAK;IACtE,EAAE,OAAOK,KAAc;QACrB,IAAIA,eAAenB,0BAA0B;YAC3C,MAAMmB;QACR;QACA,MAAMC,UAAUD,eAAeE,QAAQF,IAAIC,OAAO,GAAG,GAAGD,KAAK;QAC7D,MAAM,IAAIE,MAAM,CAAC,gDAAgD,EAAED,SAAS,EAAE;YAACE,OAAOH;QAAG;IAC3F;AACF;AAEA;;;;;;;;CAQC,GACD,SAASH,gCACPZ,QAAgB,EAChBG,aAAa,CAAC;IAEd,OAAOJ,kCAAkCC,UAAUF,0BAA0B,UAAUK;AACzF;AAEA;;;;;;;CAOC,GACD,SAASW,6BAA6Bd,QAAgB,EAAEG,aAAa,CAAC;IACpE,OAAOJ,kCAAkCC,UAAUH,uBAAuB,OAAOM;AACnF"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { dirname } from 'node:path';
|
|
2
|
-
import { z } from 'zod';
|
|
2
|
+
import { z } from 'zod/mini';
|
|
3
3
|
import { studioWorkerTask } from '../../loaders/studio/studioWorkerTask.js';
|
|
4
4
|
const schemaSchema = z.looseObject({
|
|
5
|
-
name: z.
|
|
5
|
+
name: z.optional(z.string()),
|
|
6
6
|
types: z.array(z.looseObject({}))
|
|
7
7
|
});
|
|
8
8
|
const sourceSchema = z.looseObject({
|
|
@@ -15,19 +15,19 @@ const sourceSchema = z.looseObject({
|
|
|
15
15
|
// Raw workspace schema (resolvePlugins: false) - unstable_sources not yet populated
|
|
16
16
|
const rawWorkspaceSchema = z.looseObject({
|
|
17
17
|
...sourceSchema.shape,
|
|
18
|
-
basePath: z.
|
|
19
|
-
name: z.
|
|
20
|
-
plugins: z.array(z.unknown())
|
|
21
|
-
schema:
|
|
22
|
-
title: z.
|
|
23
|
-
unstable_sources: z.array(sourceSchema)
|
|
18
|
+
basePath: z.optional(z.string()),
|
|
19
|
+
name: z.optional(z.string()),
|
|
20
|
+
plugins: z.optional(z.array(z.unknown())),
|
|
21
|
+
schema: z.optional(schemaSchema),
|
|
22
|
+
title: z.optional(z.string()),
|
|
23
|
+
unstable_sources: z.optional(z.array(sourceSchema))
|
|
24
24
|
});
|
|
25
25
|
// Resolved config schema (resolvePlugins: true) - all fields required
|
|
26
26
|
const resolvedWorkspaceSchema = z.looseObject({
|
|
27
27
|
...sourceSchema.shape,
|
|
28
28
|
basePath: z.string(),
|
|
29
29
|
name: z.string(),
|
|
30
|
-
plugins: z.array(z.unknown())
|
|
30
|
+
plugins: z.optional(z.array(z.unknown())),
|
|
31
31
|
title: z.string(),
|
|
32
32
|
unstable_sources: z.array(sourceSchema)
|
|
33
33
|
});
|
|
@@ -48,8 +48,10 @@ export async function readStudioConfig(configPath, options) {
|
|
|
48
48
|
try {
|
|
49
49
|
return options.resolvePlugins ? resolvedConfigSchema.parse(result) : rawConfigSchema.parse(result);
|
|
50
50
|
} catch (err) {
|
|
51
|
-
if (err instanceof z.ZodError) {
|
|
52
|
-
throw new
|
|
51
|
+
if (err instanceof z.core.$ZodError) {
|
|
52
|
+
throw new TypeError(`Invalid studio config at ${configPath}:\n${formatZodIssues(err.issues)}`, {
|
|
53
|
+
cause: err
|
|
54
|
+
});
|
|
53
55
|
}
|
|
54
56
|
throw err;
|
|
55
57
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/config/studio/readStudioConfig.ts"],"sourcesContent":["import {dirname} from 'node:path'\n\nimport {z} from 'zod'\n\nimport {studioWorkerTask} from '../../loaders/studio/studioWorkerTask.js'\n\nconst schemaSchema = z.looseObject({\n name: z.
|
|
1
|
+
{"version":3,"sources":["../../../src/config/studio/readStudioConfig.ts"],"sourcesContent":["import {dirname} from 'node:path'\n\nimport {z} from 'zod/mini'\n\nimport {studioWorkerTask} from '../../loaders/studio/studioWorkerTask.js'\n\nconst schemaSchema = z.looseObject({\n name: z.optional(z.string()),\n types: z.array(z.looseObject({})),\n})\n\nconst sourceSchema = z.looseObject({\n dataset: z.string(),\n projectId: z.string(),\n schema: z.looseObject({_original: schemaSchema}),\n})\n\n// Raw workspace schema (resolvePlugins: false) - unstable_sources not yet populated\nconst rawWorkspaceSchema = z.looseObject({\n ...sourceSchema.shape,\n basePath: z.optional(z.string()),\n name: z.optional(z.string()),\n plugins: z.optional(z.array(z.unknown())),\n schema: z.optional(schemaSchema),\n title: z.optional(z.string()),\n unstable_sources: z.optional(z.array(sourceSchema)),\n})\n\n// Resolved config schema (resolvePlugins: true) - all fields required\nconst resolvedWorkspaceSchema = z.looseObject({\n ...sourceSchema.shape,\n basePath: z.string(),\n name: z.string(),\n plugins: z.optional(z.array(z.unknown())),\n title: z.string(),\n unstable_sources: z.array(sourceSchema),\n})\n\nconst rawConfigSchema = z.union([z.array(rawWorkspaceSchema), rawWorkspaceSchema])\nconst resolvedConfigSchema = z.array(resolvedWorkspaceSchema)\n\nexport type RawStudioConfig = z.infer<typeof rawConfigSchema>\nexport type ResolvedStudioConfig = z.infer<typeof resolvedConfigSchema>\n\nexport interface ReadStudioConfigOptions {\n /**\n * Whether or not to resolve the plugins defined in the config.\n *\n * In some cases, you need this in order to have the full picture of what the studio\n * would \"see\". As an example, plugins can define schema types that are not explicitly\n * defined in the users' schema types. In order to get the full picture, you need to\n * resolve the plugins, which is an asyncronous operation.\n *\n * In other cases, it might be enough to only do a shallow pass. As an example, if you\n * only need to know about the defined workspace, or the user-defined schema types,\n * this can be set to `false` - which should resolve faster (and potentially \"safer\")\n * in terms of not triggering all kinds of browser behavior that may or may not be\n * loaded as the plugins are resolved.\n */\n resolvePlugins: boolean\n}\n\nexport async function readStudioConfig(\n configPath: string,\n options: {resolvePlugins: true},\n): Promise<ResolvedStudioConfig>\n\nexport async function readStudioConfig(\n configPath: string,\n options: {resolvePlugins: false},\n): Promise<RawStudioConfig>\n\nexport async function readStudioConfig(\n configPath: string,\n options: ReadStudioConfigOptions,\n): Promise<RawStudioConfig | ResolvedStudioConfig> {\n const result = await studioWorkerTask(new URL('readStudioConfig.worker.js', import.meta.url), {\n name: 'studioConfig',\n studioRootPath: dirname(configPath),\n workerData: {configPath, resolvePlugins: options.resolvePlugins},\n })\n\n try {\n return options.resolvePlugins\n ? resolvedConfigSchema.parse(result)\n : rawConfigSchema.parse(result)\n } catch (err) {\n if (err instanceof z.core.$ZodError) {\n throw new TypeError(\n `Invalid studio config at ${configPath}:\\n${formatZodIssues(err.issues)}`,\n {\n cause: err,\n },\n )\n }\n\n throw err\n }\n}\n\n/**\n * Recursively extracts leaf-level messages from Zod issues, including\n * those nested inside union errors. Note that `prettifyError` from Zod\n * only gives a high-level summary for union errors, so this function is\n * needed to get the full details of all validation issues in a readable format.\n *\n * @internal exported for testing only\n */\nexport function formatZodIssues(issues: z.core.$ZodIssue[], indent = 2): string {\n const lines: string[] = []\n const prefix = ' '.repeat(indent)\n\n for (const issue of issues) {\n if (issue.code === 'invalid_union' && 'errors' in issue && Array.isArray(issue.errors)) {\n for (const [i, unionIssues] of issue.errors.entries()) {\n lines.push(`${prefix}Union option ${i + 1}:`, formatZodIssues(unionIssues, indent + 2))\n }\n } else {\n const path = issue.path.length > 0 ? ` at \"${issue.path.join('.')}\"` : ''\n lines.push(`${prefix}- ${issue.message}${path}`)\n }\n }\n\n return lines.join('\\n')\n}\n"],"names":["dirname","z","studioWorkerTask","schemaSchema","looseObject","name","optional","string","types","array","sourceSchema","dataset","projectId","schema","_original","rawWorkspaceSchema","shape","basePath","plugins","unknown","title","unstable_sources","resolvedWorkspaceSchema","rawConfigSchema","union","resolvedConfigSchema","readStudioConfig","configPath","options","result","URL","url","studioRootPath","workerData","resolvePlugins","parse","err","core","$ZodError","TypeError","formatZodIssues","issues","cause","indent","lines","prefix","repeat","issue","code","Array","isArray","errors","i","unionIssues","entries","push","path","length","join","message"],"mappings":"AAAA,SAAQA,OAAO,QAAO,YAAW;AAEjC,SAAQC,CAAC,QAAO,WAAU;AAE1B,SAAQC,gBAAgB,QAAO,2CAA0C;AAEzE,MAAMC,eAAeF,EAAEG,WAAW,CAAC;IACjCC,MAAMJ,EAAEK,QAAQ,CAACL,EAAEM,MAAM;IACzBC,OAAOP,EAAEQ,KAAK,CAACR,EAAEG,WAAW,CAAC,CAAC;AAChC;AAEA,MAAMM,eAAeT,EAAEG,WAAW,CAAC;IACjCO,SAASV,EAAEM,MAAM;IACjBK,WAAWX,EAAEM,MAAM;IACnBM,QAAQZ,EAAEG,WAAW,CAAC;QAACU,WAAWX;IAAY;AAChD;AAEA,oFAAoF;AACpF,MAAMY,qBAAqBd,EAAEG,WAAW,CAAC;IACvC,GAAGM,aAAaM,KAAK;IACrBC,UAAUhB,EAAEK,QAAQ,CAACL,EAAEM,MAAM;IAC7BF,MAAMJ,EAAEK,QAAQ,CAACL,EAAEM,MAAM;IACzBW,SAASjB,EAAEK,QAAQ,CAACL,EAAEQ,KAAK,CAACR,EAAEkB,OAAO;IACrCN,QAAQZ,EAAEK,QAAQ,CAACH;IACnBiB,OAAOnB,EAAEK,QAAQ,CAACL,EAAEM,MAAM;IAC1Bc,kBAAkBpB,EAAEK,QAAQ,CAACL,EAAEQ,KAAK,CAACC;AACvC;AAEA,sEAAsE;AACtE,MAAMY,0BAA0BrB,EAAEG,WAAW,CAAC;IAC5C,GAAGM,aAAaM,KAAK;IACrBC,UAAUhB,EAAEM,MAAM;IAClBF,MAAMJ,EAAEM,MAAM;IACdW,SAASjB,EAAEK,QAAQ,CAACL,EAAEQ,KAAK,CAACR,EAAEkB,OAAO;IACrCC,OAAOnB,EAAEM,MAAM;IACfc,kBAAkBpB,EAAEQ,KAAK,CAACC;AAC5B;AAEA,MAAMa,kBAAkBtB,EAAEuB,KAAK,CAAC;IAACvB,EAAEQ,KAAK,CAACM;IAAqBA;CAAmB;AACjF,MAAMU,uBAAuBxB,EAAEQ,KAAK,CAACa;AAiCrC,OAAO,eAAeI,iBACpBC,UAAkB,EAClBC,OAAgC;IAEhC,MAAMC,SAAS,MAAM3B,iBAAiB,IAAI4B,IAAI,8BAA8B,YAAYC,GAAG,GAAG;QAC5F1B,MAAM;QACN2B,gBAAgBhC,QAAQ2B;QACxBM,YAAY;YAACN;YAAYO,gBAAgBN,QAAQM,cAAc;QAAA;IACjE;IAEA,IAAI;QACF,OAAON,QAAQM,cAAc,GACzBT,qBAAqBU,KAAK,CAACN,UAC3BN,gBAAgBY,KAAK,CAACN;IAC5B,EAAE,OAAOO,KAAK;QACZ,IAAIA,eAAenC,EAAEoC,IAAI,CAACC,SAAS,EAAE;YACnC,MAAM,IAAIC,UACR,CAAC,yBAAyB,EAAEZ,WAAW,GAAG,EAAEa,gBAAgBJ,IAAIK,MAAM,GAAG,EACzE;gBACEC,OAAON;YACT;QAEJ;QAEA,MAAMA;IACR;AACF;AAEA;;;;;;;CAOC,GACD,OAAO,SAASI,gBAAgBC,MAA0B,EAAEE,SAAS,CAAC;IACpE,MAAMC,QAAkB,EAAE;IAC1B,MAAMC,SAAS,IAAIC,MAAM,CAACH;IAE1B,KAAK,MAAMI,SAASN,OAAQ;QAC1B,IAAIM,MAAMC,IAAI,KAAK,mBAAmB,YAAYD,SAASE,MAAMC,OAAO,CAACH,MAAMI,MAAM,GAAG;YACtF,KAAK,MAAM,CAACC,GAAGC,YAAY,IAAIN,MAAMI,MAAM,CAACG,OAAO,GAAI;gBACrDV,MAAMW,IAAI,CAAC,GAAGV,OAAO,aAAa,EAAEO,IAAI,EAAE,CAAC,CAAC,EAAEZ,gBAAgBa,aAAaV,SAAS;YACtF;QACF,OAAO;YACL,MAAMa,OAAOT,MAAMS,IAAI,CAACC,MAAM,GAAG,IAAI,CAAC,KAAK,EAAEV,MAAMS,IAAI,CAACE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG;YACvEd,MAAMW,IAAI,CAAC,GAAGV,OAAO,EAAE,EAAEE,MAAMY,OAAO,GAAGH,MAAM;QACjD;IACF;IAEA,OAAOZ,MAAMc,IAAI,CAAC;AACpB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isMainThread, parentPort, workerData } from 'node:worker_threads';
|
|
2
|
-
import { z } from 'zod';
|
|
2
|
+
import { z } from 'zod/mini';
|
|
3
3
|
import { subdebug } from '../../debug.js';
|
|
4
4
|
import { doImport } from '../../util/doImport.js';
|
|
5
5
|
import { safeStructuredClone } from '../../util/safeStructuredClone.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/config/studio/readStudioConfig.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {z} from 'zod'\n\nimport {subdebug} from '../../debug.js'\nimport {doImport} from '../../util/doImport.js'\nimport {safeStructuredClone} from '../../util/safeStructuredClone.js'\nimport {getStudioWorkspaces} from './getStudioWorkspaces.js'\n\nif (isMainThread || !parentPort) {\n throw new Error('Should only be run in a worker!')\n}\n\nconst debug = subdebug('readStudioConfig.worker')\n\nconst {configPath, resolvePlugins} = z\n .object({configPath: z.string(), resolvePlugins: z.boolean()})\n .parse(workerData)\n\ndebug('Parsing config path %s', configPath)\n\nlet {default: config} = await doImport(configPath)\n\ndebug('Imported config %o', config)\n\nif (resolvePlugins) {\n debug('Resolving workspaces')\n config = await getStudioWorkspaces(configPath)\n debug('Resolved workspaces %o', config)\n}\n\nparentPort.postMessage(safeStructuredClone(config))\n"],"names":["isMainThread","parentPort","workerData","z","subdebug","doImport","safeStructuredClone","getStudioWorkspaces","Error","debug","configPath","resolvePlugins","object","string","boolean","parse","default","config","postMessage"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,UAAU,EAAEC,UAAU,QAAO,sBAAqB;AAExE,SAAQC,CAAC,QAAO,
|
|
1
|
+
{"version":3,"sources":["../../../src/config/studio/readStudioConfig.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {z} from 'zod/mini'\n\nimport {subdebug} from '../../debug.js'\nimport {doImport} from '../../util/doImport.js'\nimport {safeStructuredClone} from '../../util/safeStructuredClone.js'\nimport {getStudioWorkspaces} from './getStudioWorkspaces.js'\n\nif (isMainThread || !parentPort) {\n throw new Error('Should only be run in a worker!')\n}\n\nconst debug = subdebug('readStudioConfig.worker')\n\nconst {configPath, resolvePlugins} = z\n .object({configPath: z.string(), resolvePlugins: z.boolean()})\n .parse(workerData)\n\ndebug('Parsing config path %s', configPath)\n\nlet {default: config} = await doImport(configPath)\n\ndebug('Imported config %o', config)\n\nif (resolvePlugins) {\n debug('Resolving workspaces')\n config = await getStudioWorkspaces(configPath)\n debug('Resolved workspaces %o', config)\n}\n\nparentPort.postMessage(safeStructuredClone(config))\n"],"names":["isMainThread","parentPort","workerData","z","subdebug","doImport","safeStructuredClone","getStudioWorkspaces","Error","debug","configPath","resolvePlugins","object","string","boolean","parse","default","config","postMessage"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,UAAU,EAAEC,UAAU,QAAO,sBAAqB;AAExE,SAAQC,CAAC,QAAO,WAAU;AAE1B,SAAQC,QAAQ,QAAO,iBAAgB;AACvC,SAAQC,QAAQ,QAAO,yBAAwB;AAC/C,SAAQC,mBAAmB,QAAO,oCAAmC;AACrE,SAAQC,mBAAmB,QAAO,2BAA0B;AAE5D,IAAIP,gBAAgB,CAACC,YAAY;IAC/B,MAAM,IAAIO,MAAM;AAClB;AAEA,MAAMC,QAAQL,SAAS;AAEvB,MAAM,EAACM,UAAU,EAAEC,cAAc,EAAC,GAAGR,EAClCS,MAAM,CAAC;IAACF,YAAYP,EAAEU,MAAM;IAAIF,gBAAgBR,EAAEW,OAAO;AAAE,GAC3DC,KAAK,CAACb;AAETO,MAAM,0BAA0BC;AAEhC,IAAI,EAACM,SAASC,MAAM,EAAC,GAAG,MAAMZ,SAASK;AAEvCD,MAAM,sBAAsBQ;AAE5B,IAAIN,gBAAgB;IAClBF,MAAM;IACNQ,SAAS,MAAMV,oBAAoBG;IACnCD,MAAM,0BAA0BQ;AAClC;AAEAhB,WAAWiB,WAAW,CAACZ,oBAAoBW"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard exit codes for CLI commands.
|
|
3
|
+
*
|
|
4
|
+
* - 0, 1, 2 align with oclif defaults and Unix convention.
|
|
5
|
+
* - 3 is application-defined (oclif does not use it).
|
|
6
|
+
* - 130 follows the Unix convention of 128 + signal number (SIGINT = 2).
|
|
7
|
+
*
|
|
8
|
+
* @see CLAUDE.md "Exit Code Convention" for usage guidance and examples.
|
|
9
|
+
*/ export const exitCodes = {
|
|
10
|
+
/** Something went wrong that is not the user's fault (API errors, network, missing config, etc.). */ RUNTIME_ERROR: 1,
|
|
11
|
+
/** The user interrupted via Ctrl+C (128 + SIGINT). Handled by SanityCommand.catch(). */ SIGINT: 130,
|
|
12
|
+
/** Command completed normally. */ SUCCESS: 0,
|
|
13
|
+
/** The user provided invalid input (bad args, unknown flags, validation failures). */ USAGE_ERROR: 2,
|
|
14
|
+
/** The user declined a confirmation or chose not to proceed. */ USER_ABORT: 3
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=exitCodes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/exitCodes.ts"],"sourcesContent":["/**\n * Standard exit codes for CLI commands.\n *\n * - 0, 1, 2 align with oclif defaults and Unix convention.\n * - 3 is application-defined (oclif does not use it).\n * - 130 follows the Unix convention of 128 + signal number (SIGINT = 2).\n *\n * @see CLAUDE.md \"Exit Code Convention\" for usage guidance and examples.\n */\nexport const exitCodes = {\n /** Something went wrong that is not the user's fault (API errors, network, missing config, etc.). */\n RUNTIME_ERROR: 1,\n /** The user interrupted via Ctrl+C (128 + SIGINT). Handled by SanityCommand.catch(). */\n SIGINT: 130,\n /** Command completed normally. */\n SUCCESS: 0,\n /** The user provided invalid input (bad args, unknown flags, validation failures). */\n USAGE_ERROR: 2,\n /** The user declined a confirmation or chose not to proceed. */\n USER_ABORT: 3,\n} as const\n"],"names":["exitCodes","RUNTIME_ERROR","SIGINT","SUCCESS","USAGE_ERROR","USER_ABORT"],"mappings":"AAAA;;;;;;;;CAQC,GACD,OAAO,MAAMA,YAAY;IACvB,mGAAmG,GACnGC,eAAe;IACf,sFAAsF,GACtFC,QAAQ;IACR,gCAAgC,GAChCC,SAAS;IACT,oFAAoF,GACpFC,aAAa;IACb,8DAA8D,GAC9DC,YAAY;AACd,EAAU"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { styleText } from 'node:util';
|
|
2
2
|
import { createClient, requester as defaultRequester, isHttpError } from '@sanity/client';
|
|
3
3
|
import { generateHelpUrl } from '../util/generateHelpUrl.js';
|
|
4
4
|
import { getCliToken } from './getCliToken.js';
|
|
@@ -84,7 +84,7 @@ const CLI_REQUEST_TAG_PREFIX = 'sanity.cli';
|
|
|
84
84
|
}
|
|
85
85
|
const statusCode = isHttpError(err) && err.response.body.statusCode;
|
|
86
86
|
if (statusCode === 401) {
|
|
87
|
-
err.message = `${err.message}. You may need to login again with ${
|
|
87
|
+
err.message = `${err.message}. You may need to login again with ${styleText('cyan', 'sanity login')}.\nFor more information, see ${generateHelpUrl('cli-errors')}.`;
|
|
88
88
|
}
|
|
89
89
|
return err;
|
|
90
90
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/apiClient.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../src/services/apiClient.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\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 // Suppress browser token warning since we mock browser environment in workers\n ignoreBrowserTokenWarning: true,\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 // Suppress browser token warning since we mock browser environment in workers\n ignoreBrowserTokenWarning: true,\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 ${styleText('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":["styleText","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","ignoreBrowserTokenWarning","requestTagPrefix","useCdn","useProjectHostname","getProjectCliClient","onError","err","isReqResError","statusCode","response","body","message","Object","prototype","hasOwnProperty","call"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,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;QAC5B,8EAA8E;QAC9EG,2BAA2B;QAC3BxB;QACAyB,kBAAkBlB;QAClBG;QACAgB,QAAQ;QACRC,oBAAoB;QACpB,GAAGd,MAAM;IACX;AACF;AA6BA;;;;;;;CAOC,GACD,OAAO,eAAee,oBAAoB,EACxCnB,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;QAC5B,8EAA8E;QAC9EG,2BAA2B;QAC3BxB;QACAyB,kBAAkBlB;QAClBG;QACAgB,QAAQ;QACRC,oBAAoB;QACpB,GAAGd,MAAM;IACX;AACF;AAEA;;;;;;CAMC,GACD,SAASG;IACP,OAAO;QACLa,SAAS,CAACC;YACR,IAAI,CAACA,OAAO,CAACC,cAAcD,MAAM;gBAC/B,OAAOA;YACT;YAEA,MAAME,aAAa9B,YAAY4B,QAAQA,IAAIG,QAAQ,CAACC,IAAI,CAACF,UAAU;YACnE,IAAIA,eAAe,KAAK;gBACtBF,IAAIK,OAAO,GAAG,GAAGL,IAAIK,OAAO,CAAC,mCAAmC,EAAErC,UAAU,QAAQ,gBAAgB,6BAA6B,EAAEK,gBAAgB,cAAc,CAAC,CAAC;YACrK;YAEA,OAAO2B;QACT;IACF;AACF;AAEA,SAASC,cAAcD,GAAU;IAC/B,OAAOM,OAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACT,KAAK;AACnD"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module-level cache for the CLI auth token, shared between
|
|
3
|
+
* `getCliToken` (reads/writes) and `setCliUserConfig` (invalidates).
|
|
4
|
+
*
|
|
5
|
+
* Extracted into its own module to avoid a circular dependency
|
|
6
|
+
* between `cliUserConfig.ts` and `getCliToken.ts`.
|
|
7
|
+
*/ let cachedToken;
|
|
8
|
+
export function getCachedToken() {
|
|
9
|
+
return cachedToken;
|
|
10
|
+
}
|
|
11
|
+
export function setCachedToken(token) {
|
|
12
|
+
cachedToken = token;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Clear the in-process token cache so the next `getCliToken()` call
|
|
16
|
+
* re-reads from disk or the environment.
|
|
17
|
+
*
|
|
18
|
+
* Called automatically by `setCliUserConfig('authToken', ...)`.
|
|
19
|
+
*
|
|
20
|
+
* @internal
|
|
21
|
+
*/ export function clearCliTokenCache() {
|
|
22
|
+
cachedToken = undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=cliTokenCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/services/cliTokenCache.ts"],"sourcesContent":["/**\n * Module-level cache for the CLI auth token, shared between\n * `getCliToken` (reads/writes) and `setCliUserConfig` (invalidates).\n *\n * Extracted into its own module to avoid a circular dependency\n * between `cliUserConfig.ts` and `getCliToken.ts`.\n */\nlet cachedToken: string | undefined\n\nexport function getCachedToken(): string | undefined {\n return cachedToken\n}\n\nexport function setCachedToken(token: string | undefined): void {\n cachedToken = token\n}\n\n/**\n * Clear the in-process token cache so the next `getCliToken()` call\n * re-reads from disk or the environment.\n *\n * Called automatically by `setCliUserConfig('authToken', ...)`.\n *\n * @internal\n */\nexport function clearCliTokenCache(): void {\n cachedToken = undefined\n}\n"],"names":["cachedToken","getCachedToken","setCachedToken","token","clearCliTokenCache","undefined"],"mappings":"AAAA;;;;;;CAMC,GACD,IAAIA;AAEJ,OAAO,SAASC;IACd,OAAOD;AACT;AAEA,OAAO,SAASE,eAAeC,KAAyB;IACtDH,cAAcG;AAChB;AAEA;;;;;;;CAOC,GACD,OAAO,SAASC;IACdJ,cAAcK;AAChB"}
|