@sanity/cli 3.59.2-canary.33 → 3.59.2-corel-presentation-lcapi.562

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/lib/_chunks-cjs/cli.js +34360 -26058
  2. package/lib/_chunks-cjs/cli.js.map +1 -1
  3. package/lib/_chunks-cjs/cliWorker.js.map +1 -1
  4. package/lib/_chunks-cjs/generateAction.js.map +1 -1
  5. package/lib/_chunks-cjs/getCliConfig.js +1 -1
  6. package/lib/_chunks-cjs/getCliConfig.js.map +1 -1
  7. package/lib/_chunks-cjs/journeyConfig.js.map +1 -1
  8. package/lib/_chunks-cjs/loadEnv.js +200 -202
  9. package/lib/_chunks-cjs/loadEnv.js.map +1 -1
  10. package/lib/index.d.mts +37 -1
  11. package/lib/index.d.ts +37 -1
  12. package/lib/index.esm.js +223 -224
  13. package/lib/index.esm.js.map +1 -1
  14. package/lib/index.js.map +1 -1
  15. package/lib/index.mjs +223 -224
  16. package/lib/index.mjs.map +1 -1
  17. package/lib/workers/getCliConfig.js.map +1 -1
  18. package/lib/workers/typegenGenerate.js.map +1 -1
  19. package/package.json +17 -19
  20. package/src/CommandRunner.ts +1 -2
  21. package/src/actions/init-project/{bootstrapTemplate.ts → bootstrapLocalTemplate.ts} +8 -21
  22. package/src/actions/init-project/bootstrapRemoteTemplate.ts +118 -0
  23. package/src/actions/init-project/git.ts +2 -2
  24. package/src/actions/init-project/initProject.ts +158 -146
  25. package/src/actions/init-project/readPackageJson.ts +18 -0
  26. package/src/actions/init-project/templates/nextjs/index.ts +16 -0
  27. package/src/actions/init-project/templates/nextjs/schemaTypes/blog.ts +2 -2
  28. package/src/actions/init-project/updateInitialTemplateMetadata.ts +24 -0
  29. package/src/actions/login/login.ts +2 -3
  30. package/src/actions/versions/findSanityModuleVersions.ts +0 -1
  31. package/src/commands/index.ts +2 -2
  32. package/src/commands/init/initCommand.ts +7 -67
  33. package/src/commands/learn/learnCommand.ts +20 -0
  34. package/src/commands/logout/logoutCommand.ts +1 -1
  35. package/src/outputters/cliOutputter.ts +21 -8
  36. package/src/studioDependencies.ts +1 -1
  37. package/src/types.ts +41 -1
  38. package/src/util/frameworkPort.ts +63 -0
  39. package/src/util/generateCommandsDocumentation.ts +7 -4
  40. package/src/util/getCliConfig.ts +1 -1
  41. package/src/util/getProviderName.ts +9 -0
  42. package/src/util/remoteTemplate.ts +320 -0
  43. package/templates/get-started/plugins/sanity-plugin-tutorial/GetStartedTutorial.tsx +4 -4
  44. package/src/actions/init-plugin/initPlugin.ts +0 -119
  45. package/src/actions/init-plugin/pluginTemplates.ts +0 -38
  46. package/src/actions/init-project/reconfigureV2Project.ts +0 -446
  47. package/src/commands/upgrade/upgradeCommand.ts +0 -38
  48. package/src/commands/upgrade/upgradeDependencies.ts +0 -289
@@ -1 +1 @@
1
- {"version":3,"file":"cliWorker.js","sources":["../../src/util/cliWorker.ts"],"sourcesContent":["import path from 'node:path'\n\nimport pkgDir from 'pkg-dir'\n\n/**\n * Because we're bundling the CLI into a single file, the classic approach of\n * checking `isMainThread()` and spawning a thread on `__dirname` does not work,\n * as it leads to the entire CLI being re-executed in the worker thread.\n *\n * To make things worse, the built CLI makes it difficult to resolve paths to\n * built source files (that contains the unpackaged worker).\n *\n * This function takes a path relative to the `src/workers` folder, resolves\n * the location of that within the installed location (eg global Sanity CLI)\n * and ensures we can resolve the actual module before trying to spawn the\n * worker thread.\n *\n * @param workerPath - _RELATIVE_ path (relative to `src/workers`) to the worker\n * @returns Full, absolute path to the worker\n * @internal\n */\nexport async function getCliWorkerPath(workerPath: string): Promise<string> {\n const cliDir = await pkgDir(__dirname)\n if (!cliDir) {\n throw new Error('Failed to find root @sanity/cli module directory')\n }\n\n const resolvedPath = path.resolve(cliDir, 'lib', 'workers', workerPath)\n try {\n return require.resolve(resolvedPath)\n } catch (err) {\n throw new Error(`Unable to resolve path for worker: ${workerPath}`)\n }\n}\n"],"names":["pkgDir","path"],"mappings":";;;;;;AAqBA,eAAsB,iBAAiB,YAAqC;AACpE,QAAA,SAAS,MAAMA,wBAAO,SAAS;AACrC,MAAI,CAAC;AACG,UAAA,IAAI,MAAM,kDAAkD;AAGpE,QAAM,eAAeC,cAAAA,QAAK,QAAQ,QAAQ,OAAO,WAAW,UAAU;AAClE,MAAA;AACK,WAAA,QAAQ,QAAQ,YAAY;AAAA,EAAA,QACvB;AACZ,UAAM,IAAI,MAAM,sCAAsC,UAAU,EAAE;AAAA,EACpE;AACF;;"}
1
+ {"version":3,"file":"cliWorker.js","sources":["../../src/util/cliWorker.ts"],"sourcesContent":["import path from 'node:path'\n\nimport pkgDir from 'pkg-dir'\n\n/**\n * Because we're bundling the CLI into a single file, the classic approach of\n * checking `isMainThread()` and spawning a thread on `__dirname` does not work,\n * as it leads to the entire CLI being re-executed in the worker thread.\n *\n * To make things worse, the built CLI makes it difficult to resolve paths to\n * built source files (that contains the unpackaged worker).\n *\n * This function takes a path relative to the `src/workers` folder, resolves\n * the location of that within the installed location (eg global Sanity CLI)\n * and ensures we can resolve the actual module before trying to spawn the\n * worker thread.\n *\n * @param workerPath - _RELATIVE_ path (relative to `src/workers`) to the worker\n * @returns Full, absolute path to the worker\n * @internal\n */\nexport async function getCliWorkerPath(workerPath: string): Promise<string> {\n const cliDir = await pkgDir(__dirname)\n if (!cliDir) {\n throw new Error('Failed to find root @sanity/cli module directory')\n }\n\n const resolvedPath = path.resolve(cliDir, 'lib', 'workers', workerPath)\n try {\n return require.resolve(resolvedPath)\n } catch (err) {\n throw new Error(`Unable to resolve path for worker: ${workerPath}`)\n }\n}\n"],"names":["pkgDir","path"],"mappings":";;;;;;AAqBA,eAAsB,iBAAiB,YAAqC;AACpE,QAAA,SAAS,MAAMA,gBAAA,QAAO,SAAS;AACrC,MAAI,CAAC;AACG,UAAA,IAAI,MAAM,kDAAkD;AAGpE,QAAM,eAAeC,cAAAA,QAAK,QAAQ,QAAQ,OAAO,WAAW,UAAU;AAClE,MAAA;AACK,WAAA,QAAQ,QAAQ,YAAY;AAAA,EAAA,QACvB;AACZ,UAAM,IAAI,MAAM,sCAAsC,UAAU,EAAE;AAAA,EAAA;AAEtE;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"generateAction.js","sources":["../../src/actions/typegen/generate.telemetry.ts","../../src/actions/typegen/generateAction.ts"],"sourcesContent":["import {defineTrace} from '@sanity/telemetry'\n\ninterface TypesGeneratedTraceAttrubutes {\n outputSize: number\n queriesCount: number\n schemaTypesCount: number\n queryFilesCount: number\n filesWithErrors: number\n typeNodesGenerated: number\n unknownTypeNodesGenerated: number\n unknownTypeNodesRatio: number\n emptyUnionTypeNodesGenerated: number\n configOverloadClientMethods: boolean\n}\n\nexport const TypesGeneratedTrace = defineTrace<TypesGeneratedTraceAttrubutes>({\n name: 'Types Generated',\n version: 0,\n description: 'Trace emitted when generating TypeScript types for queries',\n})\n","import {constants, mkdir, open, stat} from 'node:fs/promises'\nimport {dirname, join} from 'node:path'\nimport {Worker} from 'node:worker_threads'\n\nimport {readConfig} from '@sanity/codegen'\nimport {format as prettierFormat, resolveConfig as resolvePrettierConfig} from 'prettier'\n\nimport {type CliCommandArguments, type CliCommandContext} from '../../types'\nimport {getCliWorkerPath} from '../../util/cliWorker'\nimport {\n type TypegenGenerateTypesWorkerData,\n type TypegenGenerateTypesWorkerMessage,\n} from '../../workers/typegenGenerate'\nimport {TypesGeneratedTrace} from './generate.telemetry'\n\nexport interface TypegenGenerateTypesCommandFlags {\n 'config-path'?: string\n}\n\nconst generatedFileWarning = `/**\n * ---------------------------------------------------------------------------------\n * This file has been generated by Sanity TypeGen.\n * Command: \\`sanity typegen generate\\`\n *\n * Any modifications made directly to this file will be overwritten the next time\n * the TypeScript definitions are generated. Please make changes to the Sanity\n * schema definitions and/or GROQ queries if you need to update these types.\n *\n * For more information on how to use Sanity TypeGen, visit the official documentation:\n * https://www.sanity.io/docs/sanity-typegen\n * ---------------------------------------------------------------------------------\n */\\n\\n`\n\nexport default async function typegenGenerateAction(\n args: CliCommandArguments<TypegenGenerateTypesCommandFlags>,\n context: CliCommandContext,\n): Promise<void> {\n const flags = args.extOptions\n const {output, workDir, telemetry} = context\n\n const trace = telemetry.trace(TypesGeneratedTrace)\n trace.start()\n\n const codegenConfig = await readConfig(flags['config-path'] || 'sanity-typegen.json')\n\n try {\n const schemaStats = await stat(codegenConfig.schema)\n if (!schemaStats.isFile()) {\n throw new Error(`Schema path is not a file: ${codegenConfig.schema}`)\n }\n } catch (err) {\n if (err.code === 'ENOENT') {\n // If the user has not provided a specific schema path (eg we're using the default), give some help\n const hint =\n codegenConfig.schema === './schema.json' ? ` - did you run \"sanity schema extract\"?` : ''\n throw new Error(`Schema file not found: ${codegenConfig.schema}${hint}`)\n }\n throw err\n }\n\n const outputPath = join(process.cwd(), codegenConfig.generates)\n const outputDir = dirname(outputPath)\n await mkdir(outputDir, {recursive: true})\n const workerPath = await getCliWorkerPath('typegenGenerate')\n\n const spinner = output.spinner({}).start('Generating types')\n\n const worker = new Worker(workerPath, {\n workerData: {\n workDir,\n schemaPath: codegenConfig.schema,\n searchPath: codegenConfig.path,\n overloadClientMethods: codegenConfig.overloadClientMethods,\n } satisfies TypegenGenerateTypesWorkerData,\n // eslint-disable-next-line no-process-env\n env: process.env,\n })\n\n const typeFile = await open(\n outputPath,\n // eslint-disable-next-line no-bitwise\n constants.O_TRUNC | constants.O_CREAT | constants.O_WRONLY,\n )\n\n typeFile.write(generatedFileWarning)\n\n const stats = {\n queryFilesCount: 0,\n errors: 0,\n queriesCount: 0,\n schemaTypesCount: 0,\n unknownTypeNodesGenerated: 0,\n typeNodesGenerated: 0,\n emptyUnionTypeNodesGenerated: 0,\n size: 0,\n }\n\n await new Promise<void>((resolve, reject) => {\n worker.addListener('message', (msg: TypegenGenerateTypesWorkerMessage) => {\n if (msg.type === 'error') {\n if (msg.fatal) {\n trace.error(msg.error)\n reject(msg.error)\n return\n }\n const errorMessage = msg.filename\n ? `${msg.error.message} in \"${msg.filename}\"`\n : msg.error.message\n spinner.fail(errorMessage)\n stats.errors++\n return\n }\n if (msg.type === 'complete') {\n resolve()\n return\n }\n\n if (msg.type === 'typemap') {\n let typeMapStr = `// Query TypeMap\\n`\n typeMapStr += msg.typeMap\n typeFile.write(typeMapStr)\n stats.size += Buffer.byteLength(typeMapStr)\n return\n }\n\n let fileTypeString = `// Source: ${msg.filename}\\n`\n\n if (msg.type === 'schema') {\n stats.schemaTypesCount += msg.length\n fileTypeString += msg.schema\n typeFile.write(fileTypeString)\n return\n }\n\n if (msg.type === 'types') {\n stats.queryFilesCount++\n for (const {\n queryName,\n query,\n type,\n typeNodesGenerated,\n unknownTypeNodesGenerated,\n emptyUnionTypeNodesGenerated,\n } of msg.types) {\n fileTypeString += `// Variable: ${queryName}\\n`\n fileTypeString += `// Query: ${query.replace(/(\\r\\n|\\n|\\r)/gm, '').trim()}\\n`\n fileTypeString += type\n stats.queriesCount++\n stats.typeNodesGenerated += typeNodesGenerated\n stats.unknownTypeNodesGenerated += unknownTypeNodesGenerated\n stats.emptyUnionTypeNodesGenerated += emptyUnionTypeNodesGenerated\n }\n typeFile.write(`${fileTypeString}\\n`)\n stats.size += Buffer.byteLength(fileTypeString)\n }\n })\n worker.addListener('error', reject)\n })\n\n await typeFile.close()\n\n const prettierConfig = codegenConfig.formatGeneratedCode\n ? await resolvePrettierConfig(outputPath).catch((err) => {\n output.warn(`Failed to load prettier config: ${err.message}`)\n return null\n })\n : null\n\n if (prettierConfig) {\n const formatFile = await open(outputPath, constants.O_RDWR)\n try {\n const code = await formatFile.readFile()\n const formattedCode = await prettierFormat(code.toString(), {\n ...prettierConfig,\n parser: 'typescript' as const,\n })\n await formatFile.truncate()\n await formatFile.write(formattedCode, 0)\n\n spinner.info('Formatted generated types with Prettier')\n } catch (err) {\n output.warn(`Failed to format generated types with Prettier: ${err.message}`)\n } finally {\n await formatFile.close()\n }\n }\n\n trace.log({\n outputSize: stats.size,\n queriesCount: stats.queriesCount,\n schemaTypesCount: stats.schemaTypesCount,\n queryFilesCount: stats.queryFilesCount,\n filesWithErrors: stats.errors,\n typeNodesGenerated: stats.typeNodesGenerated,\n unknownTypeNodesGenerated: stats.unknownTypeNodesGenerated,\n unknownTypeNodesRatio:\n stats.typeNodesGenerated > 0 ? stats.unknownTypeNodesGenerated / stats.typeNodesGenerated : 0,\n emptyUnionTypeNodesGenerated: stats.emptyUnionTypeNodesGenerated,\n configOverloadClientMethods: codegenConfig.overloadClientMethods,\n })\n\n trace.complete()\n if (stats.errors > 0) {\n spinner.warn(`Encountered errors in ${stats.errors} files while generating types`)\n }\n\n spinner.succeed(\n `Generated TypeScript types for ${stats.schemaTypesCount} schema types and ${stats.queriesCount} GROQ queries in ${stats.queryFilesCount} files into: ${codegenConfig.generates}`,\n )\n}\n"],"names":["defineTrace","telemetry","readConfig","stat","join","dirname","mkdir","getCliWorkerPath","Worker","open","constants","resolvePrettierConfig","prettierFormat"],"mappings":"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"}
1
+ {"version":3,"file":"generateAction.js","sources":["../../src/actions/typegen/generate.telemetry.ts","../../src/actions/typegen/generateAction.ts"],"sourcesContent":["import {defineTrace} from '@sanity/telemetry'\n\ninterface TypesGeneratedTraceAttrubutes {\n outputSize: number\n queriesCount: number\n schemaTypesCount: number\n queryFilesCount: number\n filesWithErrors: number\n typeNodesGenerated: number\n unknownTypeNodesGenerated: number\n unknownTypeNodesRatio: number\n emptyUnionTypeNodesGenerated: number\n configOverloadClientMethods: boolean\n}\n\nexport const TypesGeneratedTrace = defineTrace<TypesGeneratedTraceAttrubutes>({\n name: 'Types Generated',\n version: 0,\n description: 'Trace emitted when generating TypeScript types for queries',\n})\n","import {constants, mkdir, open, stat} from 'node:fs/promises'\nimport {dirname, join} from 'node:path'\nimport {Worker} from 'node:worker_threads'\n\nimport {readConfig} from '@sanity/codegen'\nimport {format as prettierFormat, resolveConfig as resolvePrettierConfig} from 'prettier'\n\nimport {type CliCommandArguments, type CliCommandContext} from '../../types'\nimport {getCliWorkerPath} from '../../util/cliWorker'\nimport {\n type TypegenGenerateTypesWorkerData,\n type TypegenGenerateTypesWorkerMessage,\n} from '../../workers/typegenGenerate'\nimport {TypesGeneratedTrace} from './generate.telemetry'\n\nexport interface TypegenGenerateTypesCommandFlags {\n 'config-path'?: string\n}\n\nconst generatedFileWarning = `/**\n * ---------------------------------------------------------------------------------\n * This file has been generated by Sanity TypeGen.\n * Command: \\`sanity typegen generate\\`\n *\n * Any modifications made directly to this file will be overwritten the next time\n * the TypeScript definitions are generated. Please make changes to the Sanity\n * schema definitions and/or GROQ queries if you need to update these types.\n *\n * For more information on how to use Sanity TypeGen, visit the official documentation:\n * https://www.sanity.io/docs/sanity-typegen\n * ---------------------------------------------------------------------------------\n */\\n\\n`\n\nexport default async function typegenGenerateAction(\n args: CliCommandArguments<TypegenGenerateTypesCommandFlags>,\n context: CliCommandContext,\n): Promise<void> {\n const flags = args.extOptions\n const {output, workDir, telemetry} = context\n\n const trace = telemetry.trace(TypesGeneratedTrace)\n trace.start()\n\n const codegenConfig = await readConfig(flags['config-path'] || 'sanity-typegen.json')\n\n try {\n const schemaStats = await stat(codegenConfig.schema)\n if (!schemaStats.isFile()) {\n throw new Error(`Schema path is not a file: ${codegenConfig.schema}`)\n }\n } catch (err) {\n if (err.code === 'ENOENT') {\n // If the user has not provided a specific schema path (eg we're using the default), give some help\n const hint =\n codegenConfig.schema === './schema.json' ? ` - did you run \"sanity schema extract\"?` : ''\n throw new Error(`Schema file not found: ${codegenConfig.schema}${hint}`)\n }\n throw err\n }\n\n const outputPath = join(process.cwd(), codegenConfig.generates)\n const outputDir = dirname(outputPath)\n await mkdir(outputDir, {recursive: true})\n const workerPath = await getCliWorkerPath('typegenGenerate')\n\n const spinner = output.spinner({}).start('Generating types')\n\n const worker = new Worker(workerPath, {\n workerData: {\n workDir,\n schemaPath: codegenConfig.schema,\n searchPath: codegenConfig.path,\n overloadClientMethods: codegenConfig.overloadClientMethods,\n } satisfies TypegenGenerateTypesWorkerData,\n // eslint-disable-next-line no-process-env\n env: process.env,\n })\n\n const typeFile = await open(\n outputPath,\n // eslint-disable-next-line no-bitwise\n constants.O_TRUNC | constants.O_CREAT | constants.O_WRONLY,\n )\n\n typeFile.write(generatedFileWarning)\n\n const stats = {\n queryFilesCount: 0,\n errors: 0,\n queriesCount: 0,\n schemaTypesCount: 0,\n unknownTypeNodesGenerated: 0,\n typeNodesGenerated: 0,\n emptyUnionTypeNodesGenerated: 0,\n size: 0,\n }\n\n await new Promise<void>((resolve, reject) => {\n worker.addListener('message', (msg: TypegenGenerateTypesWorkerMessage) => {\n if (msg.type === 'error') {\n if (msg.fatal) {\n trace.error(msg.error)\n reject(msg.error)\n return\n }\n const errorMessage = msg.filename\n ? `${msg.error.message} in \"${msg.filename}\"`\n : msg.error.message\n spinner.fail(errorMessage)\n stats.errors++\n return\n }\n if (msg.type === 'complete') {\n resolve()\n return\n }\n\n if (msg.type === 'typemap') {\n let typeMapStr = `// Query TypeMap\\n`\n typeMapStr += msg.typeMap\n typeFile.write(typeMapStr)\n stats.size += Buffer.byteLength(typeMapStr)\n return\n }\n\n let fileTypeString = `// Source: ${msg.filename}\\n`\n\n if (msg.type === 'schema') {\n stats.schemaTypesCount += msg.length\n fileTypeString += msg.schema\n typeFile.write(fileTypeString)\n return\n }\n\n if (msg.type === 'types') {\n stats.queryFilesCount++\n for (const {\n queryName,\n query,\n type,\n typeNodesGenerated,\n unknownTypeNodesGenerated,\n emptyUnionTypeNodesGenerated,\n } of msg.types) {\n fileTypeString += `// Variable: ${queryName}\\n`\n fileTypeString += `// Query: ${query.replace(/(\\r\\n|\\n|\\r)/gm, '').trim()}\\n`\n fileTypeString += type\n stats.queriesCount++\n stats.typeNodesGenerated += typeNodesGenerated\n stats.unknownTypeNodesGenerated += unknownTypeNodesGenerated\n stats.emptyUnionTypeNodesGenerated += emptyUnionTypeNodesGenerated\n }\n typeFile.write(`${fileTypeString}\\n`)\n stats.size += Buffer.byteLength(fileTypeString)\n }\n })\n worker.addListener('error', reject)\n })\n\n await typeFile.close()\n\n const prettierConfig = codegenConfig.formatGeneratedCode\n ? await resolvePrettierConfig(outputPath).catch((err) => {\n output.warn(`Failed to load prettier config: ${err.message}`)\n return null\n })\n : null\n\n if (prettierConfig) {\n const formatFile = await open(outputPath, constants.O_RDWR)\n try {\n const code = await formatFile.readFile()\n const formattedCode = await prettierFormat(code.toString(), {\n ...prettierConfig,\n parser: 'typescript' as const,\n })\n await formatFile.truncate()\n await formatFile.write(formattedCode, 0)\n\n spinner.info('Formatted generated types with Prettier')\n } catch (err) {\n output.warn(`Failed to format generated types with Prettier: ${err.message}`)\n } finally {\n await formatFile.close()\n }\n }\n\n trace.log({\n outputSize: stats.size,\n queriesCount: stats.queriesCount,\n schemaTypesCount: stats.schemaTypesCount,\n queryFilesCount: stats.queryFilesCount,\n filesWithErrors: stats.errors,\n typeNodesGenerated: stats.typeNodesGenerated,\n unknownTypeNodesGenerated: stats.unknownTypeNodesGenerated,\n unknownTypeNodesRatio:\n stats.typeNodesGenerated > 0 ? stats.unknownTypeNodesGenerated / stats.typeNodesGenerated : 0,\n emptyUnionTypeNodesGenerated: stats.emptyUnionTypeNodesGenerated,\n configOverloadClientMethods: codegenConfig.overloadClientMethods,\n })\n\n trace.complete()\n if (stats.errors > 0) {\n spinner.warn(`Encountered errors in ${stats.errors} files while generating types`)\n }\n\n spinner.succeed(\n `Generated TypeScript types for ${stats.schemaTypesCount} schema types and ${stats.queriesCount} GROQ queries in ${stats.queryFilesCount} files into: ${codegenConfig.generates}`,\n )\n}\n"],"names":["defineTrace","telemetry","readConfig","stat","join","dirname","mkdir","getCliWorkerPath","Worker","open","constants","resolvePrettierConfig","prettierFormat"],"mappings":"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"}
@@ -16,7 +16,7 @@ async function getCliConfig(cwd, { forked } = {}) {
16
16
  return await getCliConfigForked(cwd);
17
17
  } catch {
18
18
  }
19
- const { unregister } = require("esbuild-register/dist/node").register();
19
+ const { unregister } = require("esbuild-register/dist/node").register({ supported: { "dynamic-import": !0 } });
20
20
  try {
21
21
  return getSanityCliConfig(cwd) || getSanityJsonConfig(cwd);
22
22
  } catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"getCliConfig.js","sources":["../../src/util/dynamicRequire.ts","../../src/util/getCliConfig.ts"],"sourcesContent":["// Prevent webpack from bundling in webpack context,\n// use regular node require for unbundled context\n\n/* eslint-disable camelcase, no-undef */\ndeclare const __webpack_require__: boolean\ndeclare const __non_webpack_require__: typeof require\n\nconst requireFunc: typeof require =\n typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require\n/* eslint-enable camelcase, no-undef */\n\nexport function dynamicRequire<T = any>(request: string): T {\n const mod = requireFunc(request)\n return mod.__esModule && mod.default ? mod.default : mod\n}\n\ndynamicRequire.resolve = requireFunc.resolve\n","/* eslint-disable no-sync */\n\n/**\n * Reads the Sanity CLI config from one of the following files (in preferred order):\n * - sanity.cli.js\n * - sanity.cli.ts\n *\n * Note: There are two ways of using this:\n * a) `getCliConfig(cwd)`\n * b) `getCliConfig(cwd, {forked: true})`\n *\n * Approach a is generally a bit faster as it avoids the forking startup time, while\n * approach b could be considered \"safer\" since any side-effects of running the config\n * file will not bleed into the current CLI process directly.\n */\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport {Worker} from 'node:worker_threads'\n\nimport {type CliConfig, type SanityJson} from '../types'\nimport {getCliWorkerPath} from './cliWorker'\nimport {dynamicRequire} from './dynamicRequire'\n\nexport type CliMajorVersion = 2 | 3\n\nexport type CliConfigResult =\n | {config: SanityJson; path: string; version: 2}\n | {config: CliConfig; path: string; version: 3}\n | {config: null; path: string; version: CliMajorVersion}\n\nexport async function getCliConfig(\n cwd: string,\n {forked}: {forked?: boolean} = {},\n): Promise<CliConfigResult | null> {\n if (forked) {\n try {\n return await getCliConfigForked(cwd)\n } catch (err) {\n // Intentional noop - try unforked variant\n }\n }\n\n const {unregister} = __DEV__\n ? {unregister: () => undefined}\n : require('esbuild-register/dist/node').register()\n\n try {\n const v3Config = getSanityCliConfig(cwd)\n if (v3Config) {\n return v3Config\n }\n\n return getSanityJsonConfig(cwd)\n } catch (err) {\n throw err\n } finally {\n unregister()\n }\n}\n\nexport function getCliConfigSync(cwd: string): CliConfigResult | null {\n const v3Config = getSanityCliConfig(cwd)\n return v3Config ? v3Config : getSanityJsonConfig(cwd)\n}\n\nasync function getCliConfigForked(cwd: string): Promise<CliConfigResult | null> {\n const workerPath = await getCliWorkerPath('getCliConfig')\n return new Promise((resolve, reject) => {\n const worker = new Worker(workerPath, {\n workerData: cwd,\n // eslint-disable-next-line no-process-env\n env: process.env,\n })\n worker.on('message', (message) => {\n if (message.type === 'config') {\n resolve(message.config)\n } else {\n const error = new Error(message.error)\n ;(error as any).type = message.errorType\n reject(new Error(message.error))\n }\n })\n worker.on('error', reject)\n worker.on('exit', (code) => {\n if (code !== 0) {\n reject(new Error(`Worker stopped with exit code ${code}`))\n }\n })\n })\n}\n\nfunction getSanityJsonConfig(cwd: string): CliConfigResult | null {\n const configPath = path.join(cwd, 'sanity.json')\n\n if (!fs.existsSync(configPath)) {\n return null\n }\n\n return {\n config: loadJsonConfig(configPath),\n path: configPath,\n version: 2,\n }\n}\n\nfunction getSanityCliConfig(cwd: string): CliConfigResult | null {\n const jsConfigPath = path.join(cwd, 'sanity.cli.js')\n const tsConfigPath = path.join(cwd, 'sanity.cli.ts')\n\n const [js, ts] = [fs.existsSync(jsConfigPath), fs.existsSync(tsConfigPath)]\n\n if (!js && !ts) {\n return null\n }\n\n if (!js && ts) {\n return {\n config: importConfig(tsConfigPath),\n path: tsConfigPath,\n version: 3,\n }\n }\n\n if (js && ts) {\n warn('Found both `sanity.cli.js` and `sanity.cli.ts` - using sanity.cli.js')\n }\n\n return {\n config: importConfig(jsConfigPath),\n path: jsConfigPath,\n version: 3,\n }\n}\n\nfunction loadJsonConfig(filePath: string): SanityJson | null {\n try {\n const content = fs.readFileSync(filePath, 'utf8')\n return JSON.parse(content)\n } catch (err) {\n console.error(`Error reading \"${filePath}\": ${err.message}`)\n return null\n }\n}\n\nfunction importConfig(filePath: string): CliConfig | null {\n try {\n const config = dynamicRequire<CliConfig | {default: CliConfig} | null>(filePath)\n if (config === null || typeof config !== 'object') {\n throw new Error('Module export is not a configuration object')\n }\n\n return 'default' in config ? config.default : config\n } catch (err) {\n // If attempting to import `defineCliConfig` or similar from `sanity/cli`,\n // accept the fact that it might not be installed. Instead, let the CLI\n // give a warning about the `sanity` module not being installed\n if (err.code === 'MODULE_NOT_FOUND' && err.message.includes('sanity/cli')) {\n return null\n }\n\n console.error(`Error reading \"${filePath}\": ${err.message}`)\n return null\n }\n}\n\nfunction warn(warning: string) {\n if (typeof process.send === 'function') {\n process.send({type: 'warning', warning})\n } else {\n console.warn(warning)\n }\n}\n"],"names":["getCliWorkerPath","Worker","path","fs"],"mappings":"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"}
1
+ {"version":3,"file":"getCliConfig.js","sources":["../../src/util/dynamicRequire.ts","../../src/util/getCliConfig.ts"],"sourcesContent":["// Prevent webpack from bundling in webpack context,\n// use regular node require for unbundled context\n\n/* eslint-disable camelcase, no-undef */\ndeclare const __webpack_require__: boolean\ndeclare const __non_webpack_require__: typeof require\n\nconst requireFunc: typeof require =\n typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require\n/* eslint-enable camelcase, no-undef */\n\nexport function dynamicRequire<T = any>(request: string): T {\n const mod = requireFunc(request)\n return mod.__esModule && mod.default ? mod.default : mod\n}\n\ndynamicRequire.resolve = requireFunc.resolve\n","/* eslint-disable no-sync */\n\n/**\n * Reads the Sanity CLI config from one of the following files (in preferred order):\n * - sanity.cli.js\n * - sanity.cli.ts\n *\n * Note: There are two ways of using this:\n * a) `getCliConfig(cwd)`\n * b) `getCliConfig(cwd, {forked: true})`\n *\n * Approach a is generally a bit faster as it avoids the forking startup time, while\n * approach b could be considered \"safer\" since any side-effects of running the config\n * file will not bleed into the current CLI process directly.\n */\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport {Worker} from 'node:worker_threads'\n\nimport {type CliConfig, type SanityJson} from '../types'\nimport {getCliWorkerPath} from './cliWorker'\nimport {dynamicRequire} from './dynamicRequire'\n\nexport type CliMajorVersion = 2 | 3\n\nexport type CliConfigResult =\n | {config: SanityJson; path: string; version: 2}\n | {config: CliConfig; path: string; version: 3}\n | {config: null; path: string; version: CliMajorVersion}\n\nexport async function getCliConfig(\n cwd: string,\n {forked}: {forked?: boolean} = {},\n): Promise<CliConfigResult | null> {\n if (forked) {\n try {\n return await getCliConfigForked(cwd)\n } catch (err) {\n // Intentional noop - try unforked variant\n }\n }\n\n const {unregister} = __DEV__\n ? {unregister: () => undefined}\n : require('esbuild-register/dist/node').register({supported: {'dynamic-import': true}})\n\n try {\n const v3Config = getSanityCliConfig(cwd)\n if (v3Config) {\n return v3Config\n }\n\n return getSanityJsonConfig(cwd)\n } catch (err) {\n throw err\n } finally {\n unregister()\n }\n}\n\nexport function getCliConfigSync(cwd: string): CliConfigResult | null {\n const v3Config = getSanityCliConfig(cwd)\n return v3Config ? v3Config : getSanityJsonConfig(cwd)\n}\n\nasync function getCliConfigForked(cwd: string): Promise<CliConfigResult | null> {\n const workerPath = await getCliWorkerPath('getCliConfig')\n return new Promise((resolve, reject) => {\n const worker = new Worker(workerPath, {\n workerData: cwd,\n // eslint-disable-next-line no-process-env\n env: process.env,\n })\n worker.on('message', (message) => {\n if (message.type === 'config') {\n resolve(message.config)\n } else {\n const error = new Error(message.error)\n ;(error as any).type = message.errorType\n reject(new Error(message.error))\n }\n })\n worker.on('error', reject)\n worker.on('exit', (code) => {\n if (code !== 0) {\n reject(new Error(`Worker stopped with exit code ${code}`))\n }\n })\n })\n}\n\nfunction getSanityJsonConfig(cwd: string): CliConfigResult | null {\n const configPath = path.join(cwd, 'sanity.json')\n\n if (!fs.existsSync(configPath)) {\n return null\n }\n\n return {\n config: loadJsonConfig(configPath),\n path: configPath,\n version: 2,\n }\n}\n\nfunction getSanityCliConfig(cwd: string): CliConfigResult | null {\n const jsConfigPath = path.join(cwd, 'sanity.cli.js')\n const tsConfigPath = path.join(cwd, 'sanity.cli.ts')\n\n const [js, ts] = [fs.existsSync(jsConfigPath), fs.existsSync(tsConfigPath)]\n\n if (!js && !ts) {\n return null\n }\n\n if (!js && ts) {\n return {\n config: importConfig(tsConfigPath),\n path: tsConfigPath,\n version: 3,\n }\n }\n\n if (js && ts) {\n warn('Found both `sanity.cli.js` and `sanity.cli.ts` - using sanity.cli.js')\n }\n\n return {\n config: importConfig(jsConfigPath),\n path: jsConfigPath,\n version: 3,\n }\n}\n\nfunction loadJsonConfig(filePath: string): SanityJson | null {\n try {\n const content = fs.readFileSync(filePath, 'utf8')\n return JSON.parse(content)\n } catch (err) {\n console.error(`Error reading \"${filePath}\": ${err.message}`)\n return null\n }\n}\n\nfunction importConfig(filePath: string): CliConfig | null {\n try {\n const config = dynamicRequire<CliConfig | {default: CliConfig} | null>(filePath)\n if (config === null || typeof config !== 'object') {\n throw new Error('Module export is not a configuration object')\n }\n\n return 'default' in config ? config.default : config\n } catch (err) {\n // If attempting to import `defineCliConfig` or similar from `sanity/cli`,\n // accept the fact that it might not be installed. Instead, let the CLI\n // give a warning about the `sanity` module not being installed\n if (err.code === 'MODULE_NOT_FOUND' && err.message.includes('sanity/cli')) {\n return null\n }\n\n console.error(`Error reading \"${filePath}\": ${err.message}`)\n return null\n }\n}\n\nfunction warn(warning: string) {\n if (typeof process.send === 'function') {\n process.send({type: 'warning', warning})\n } else {\n console.warn(warning)\n }\n}\n"],"names":["getCliWorkerPath","Worker","path","fs"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"journeyConfig.js","sources":["../../src/util/journeyConfig.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport {Worker} from 'node:worker_threads'\n\nimport {\n type BaseSchemaDefinition,\n type DocumentDefinition,\n type ObjectDefinition,\n} from '@sanity/types'\nimport {format} from 'prettier'\n\nimport {type CliApiClient} from '../types'\nimport {getCliWorkerPath} from './cliWorker'\n\n/**\n * A Journey schema is a server schema that is saved in the Journey API\n */\n\ninterface JourneySchemaWorkerData {\n schemasPath: string\n useTypeScript: boolean\n schemaUrl: string\n}\n\ntype JourneySchemaWorkerResult = {type: 'success'} | {type: 'error'; error: Error}\n\ninterface JourneyConfigResponse {\n projectId: string\n datasetName: string\n displayName: string\n schemaUrl: string\n isFirstProject: boolean // Always true for now, making it compatible with the existing getOrCreateProject\n}\n\ntype DocumentOrObject = DocumentDefinition | ObjectDefinition\ntype SchemaObject = BaseSchemaDefinition & {\n type: string\n fields?: SchemaObject[]\n of?: SchemaObject[]\n preview?: object\n}\n\n/**\n * Fetch a Journey schema from the Sanity schema club API and write it to disk\n */\nexport async function getAndWriteJourneySchema(data: JourneySchemaWorkerData): Promise<void> {\n const {schemasPath, useTypeScript, schemaUrl} = data\n try {\n const documentTypes = await fetchJourneySchema(schemaUrl)\n const fileExtension = useTypeScript ? 'ts' : 'js'\n\n // Write a file for each schema\n for (const documentType of documentTypes) {\n const filePath = path.join(schemasPath, `${documentType.name}.${fileExtension}`)\n await fs.writeFile(filePath, await assembleJourneySchemaTypeFileContent(documentType))\n }\n // Write an index file that exports all the schemas\n const indexContent = await assembleJourneyIndexContent(documentTypes)\n await fs.writeFile(path.join(schemasPath, `index.${fileExtension}`), indexContent)\n } catch (error) {\n throw new Error(`Failed to fetch remote schema: ${error.message}`)\n }\n}\n\n/**\n * Executes the `getAndWriteJourneySchema` operation within a worker thread.\n *\n * This method is designed to safely import network resources by leveraging the `--experimental-network-imports` flag.\n * Due to the experimental nature of this flag, its use is not recommended in the main process. Consequently,\n * the task is delegated to a worker thread to ensure both safety and compliance with best practices.\n *\n * The core functionality involves fetching schema definitions from our own trusted API and writing them to disk.\n * This includes handling both predefined and custom schemas. For custom schemas, a process ensures\n * that they undergo JSON parsing to remove any JavaScript code and are validated before being saved.\n *\n * Depending on the configuration, the schemas are saved as either TypeScript or JavaScript files, dictated by the `useTypeScript` flag within the `workerData`.\n *\n * @param workerData - An object containing the necessary data and flags for the worker thread, including the path to save schemas, flags indicating whether to use TypeScript, and any other relevant configuration details.\n * @returns A promise that resolves upon successful execution of the schema fetching and writing process or rejects if an error occurs during the operation.\n */\nexport async function getAndWriteJourneySchemaWorker(\n workerData: JourneySchemaWorkerData,\n): Promise<void> {\n const workerPath = await getCliWorkerPath('getAndWriteJourneySchema')\n return new Promise((resolve, reject) => {\n const worker = new Worker(workerPath, {\n workerData,\n env: {\n // eslint-disable-next-line no-process-env\n ...process.env,\n // Dynamic HTTPS imports are currently behind a Node flag\n NODE_OPTIONS: '--experimental-network-imports',\n NODE_NO_WARNINGS: '1',\n },\n })\n worker.on('message', (message: JourneySchemaWorkerResult) => {\n if (message.type === 'success') {\n resolve()\n } else {\n message.error.message = `Import schema worker failed: ${message.error.message}`\n reject(message.error)\n }\n })\n worker.on('error', (error) => {\n error.message = `Import schema worker failed: ${error.message}`\n reject(error)\n })\n worker.on('exit', (code) => {\n if (code !== 0) {\n reject(new Error(`Worker stopped with exit code ${code}`))\n }\n })\n })\n}\n\n/**\n * Fetch a Journey config from the Sanity schema club API\n *\n * @param projectId - The slug of the Journey schema to fetch\n * @returns The Journey schema as an array of Sanity document or object definitions\n */\nexport async function fetchJourneyConfig(\n apiClient: CliApiClient,\n projectId: string,\n): Promise<JourneyConfigResponse> {\n if (!projectId) {\n throw new Error('ProjectId is required')\n }\n if (!/^[a-zA-Z0-9-]+$/.test(projectId)) {\n throw new Error('Invalid projectId')\n }\n try {\n const response: {\n projectId: string\n dataset: string\n displayName?: string\n schemaUrl: string\n } = await apiClient({\n requireUser: true,\n requireProject: true,\n api: {projectId},\n })\n .config({apiVersion: 'v2024-02-23'})\n .request({\n method: 'GET',\n uri: `/journey/projects/${projectId}`,\n })\n\n return {\n projectId: response.projectId,\n datasetName: response.dataset,\n displayName: response.displayName || 'Sanity Project',\n // The endpoint returns a signed URL that can be used to fetch the schema as ESM\n schemaUrl: response.schemaUrl,\n isFirstProject: true,\n }\n } catch (err) {\n throw new Error(`Failed to fetch remote schema config: ${projectId}`)\n }\n}\n\n/**\n * Fetch a Journey schema from the Sanity schema club API\n *\n * @param projectId - The slug of the Journey schema to fetch\n * @returns The Journey schema as an array of Sanity document or object definitions\n */\nasync function fetchJourneySchema(schemaUrl: string): Promise<DocumentOrObject[]> {\n try {\n const response = await import(schemaUrl)\n return response.default\n } catch (err) {\n throw new Error(`Failed to fetch remote schema: ${schemaUrl}`)\n }\n}\n\n/**\n * Assemble a Journey schema type into a module export\n * Include the necessary imports and export the schema type as a named export\n *\n * @param schema - The Journey schema to export\n * @returns The Journey schema as a module export\n */\nasync function assembleJourneySchemaTypeFileContent(schemaType: DocumentOrObject): Promise<string> {\n const serialised = wrapSchemaTypeInHelpers(schemaType)\n const imports = getImports(serialised)\n const prettifiedSchemaType = await format(serialised, {\n parser: 'typescript',\n printWidth: 40,\n })\n // Start file with import, then export the schema type as a named export\n return `${imports}\\n\\nexport const ${schemaType.name} = ${prettifiedSchemaType}\\n`\n}\n\n/**\n * Assemble a list of Journey schema module exports into a single index file\n *\n * @param schemas - The Journey schemas to assemble into an index file\n * @returns The index file as a string\n */\nfunction assembleJourneyIndexContent(schemas: DocumentOrObject[]): Promise<string> {\n const sortedSchema = schemas.slice().sort((a, b) => (a.name > b.name ? 1 : -1))\n const imports = sortedSchema.map((schema) => `import { ${schema.name} } from './${schema.name}'`)\n const exports = sortedSchema.map((schema) => schema.name).join(',')\n const fileContents = `${imports.join('\\n')}\\n\\nexport const schemaTypes = [${exports}]`\n return format(fileContents, {parser: 'typescript'})\n}\n\n/**\n * Get the import statements for a schema type\n *\n * @param schemaType - The schema type to get the imports for\n * @returns The import statements for the schema type\n */\nfunction getImports(schemaType: string): string {\n const defaultImports = ['defineType', 'defineField']\n if (schemaType.includes('defineArrayMember')) {\n defaultImports.push('defineArrayMember')\n }\n return `import { ${defaultImports.join(', ')} } from 'sanity'`\n}\n\n/**\n * Serialize a singleSanity schema type (signular) into a string.\n * Wraps the schema object in the appropriate helper function.\n *\n * @param schemaType - The schema type to serialize\n * @returns The schema type as a string\n */\n/**\n * Serializes a single Sanity schema type into a string.\n * Wraps the schema object in the appropriate helper function.\n *\n * @param schemaType - The schema type to serialize\n * @param root - Whether the schemaType is the root object\n * @returns The serialized schema type as a string\n */\nexport function wrapSchemaTypeInHelpers(schemaType: SchemaObject, root: boolean = true): string {\n if (root) {\n return generateSchemaDefinition(schemaType, 'defineType')\n } else if (schemaType.type === 'array') {\n return `${generateSchemaDefinition(schemaType, 'defineField')},`\n }\n return `${generateSchemaDefinition(schemaType, 'defineField')},`\n\n function generateSchemaDefinition(\n object: SchemaObject,\n definitionType: 'defineType' | 'defineField',\n ): string {\n const {fields, preview, of, ...otherProperties} = object\n\n const serializedProps = serialize(otherProperties)\n const fieldsDef =\n fields && `fields: [${fields.map((f) => wrapSchemaTypeInHelpers(f, false)).join('')}]`\n const ofDef = of && `of: [${of.map((f) => `defineArrayMember({${serialize(f)}})`).join(',')}]`\n const previewDef = preview && `preview: {${serialize(preview)}}`\n\n const combinedDefinitions = [serializedProps, fieldsDef, ofDef, previewDef]\n .filter(Boolean)\n .join(',')\n return `${definitionType}({ ${combinedDefinitions} })`\n }\n\n function serialize(obj: object) {\n return Object.entries(obj)\n .map(([key, value]) => {\n if (key === 'prepare') {\n return `${value.toString()}`\n }\n if (typeof value === 'string') {\n return `${key}: \"${value}\"`\n }\n if (typeof value === 'object') {\n return `${key}: ${JSON.stringify(value)}`\n }\n return `${key}: ${value}`\n })\n .join(',')\n }\n}\n"],"names":["path","fs","getCliWorkerPath","Worker","format","exports"],"mappings":";;;;;;AA6CA,eAAsB,yBAAyB,MAA8C;AAC3F,QAAM,EAAC,aAAa,eAAe,UAAA,IAAa;AAC5C,MAAA;AACF,UAAM,gBAAgB,MAAM,mBAAmB,SAAS,GAClD,gBAAgB,gBAAgB,OAAO;AAG7C,eAAW,gBAAgB,eAAe;AAClC,YAAA,WAAWA,cAAAA,QAAK,KAAK,aAAa,GAAG,aAAa,IAAI,IAAI,aAAa,EAAE;AAC/E,YAAMC,YAAAA,QAAG,UAAU,UAAU,MAAM,qCAAqC,YAAY,CAAC;AAAA,IACvF;AAEM,UAAA,eAAe,MAAM,4BAA4B,aAAa;AAC9D,UAAAA,oBAAG,UAAUD,cAAK,QAAA,KAAK,aAAa,SAAS,aAAa,EAAE,GAAG,YAAY;AAAA,WAC1E,OAAO;AACd,UAAM,IAAI,MAAM,kCAAkC,MAAM,OAAO,EAAE;AAAA,EACnE;AACF;AAkBA,eAAsB,+BACpB,YACe;AACT,QAAA,aAAa,MAAME,2BAAiB,0BAA0B;AACpE,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AAChC,UAAA,SAAS,IAAIC,oBAAA,OAAO,YAAY;AAAA,MACpC;AAAA,MACA,KAAK;AAAA;AAAA,QAEH,GAAG,QAAQ;AAAA;AAAA,QAEX,cAAc;AAAA,QACd,kBAAkB;AAAA,MACpB;AAAA,IAAA,CACD;AACM,WAAA,GAAG,WAAW,CAAC,YAAuC;AACvD,cAAQ,SAAS,YACnB,aAEA,QAAQ,MAAM,UAAU,gCAAgC,QAAQ,MAAM,OAAO,IAC7E,OAAO,QAAQ,KAAK;AAAA,IAEvB,CAAA,GACD,OAAO,GAAG,SAAS,CAAC,UAAU;AAC5B,YAAM,UAAU,gCAAgC,MAAM,OAAO,IAC7D,OAAO,KAAK;AAAA,IACb,CAAA,GACD,OAAO,GAAG,QAAQ,CAAC,SAAS;AACtB,eAAS,KACX,OAAO,IAAI,MAAM,iCAAiC,IAAI,EAAE,CAAC;AAAA,IAAA,CAE5D;AAAA,EAAA,CACF;AACH;AAQsB,eAAA,mBACpB,WACA,WACgC;AAChC,MAAI,CAAC;AACG,UAAA,IAAI,MAAM,uBAAuB;AAErC,MAAA,CAAC,kBAAkB,KAAK,SAAS;AAC7B,UAAA,IAAI,MAAM,mBAAmB;AAEjC,MAAA;AACI,UAAA,WAKF,MAAM,UAAU;AAAA,MAClB,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,KAAK,EAAC,UAAS;AAAA,IAAA,CAChB,EACE,OAAO,EAAC,YAAY,cAAc,CAAA,EAClC,QAAQ;AAAA,MACP,QAAQ;AAAA,MACR,KAAK,qBAAqB,SAAS;AAAA,IAAA,CACpC;AAEI,WAAA;AAAA,MACL,WAAW,SAAS;AAAA,MACpB,aAAa,SAAS;AAAA,MACtB,aAAa,SAAS,eAAe;AAAA;AAAA,MAErC,WAAW,SAAS;AAAA,MACpB,gBAAgB;AAAA,IAAA;AAAA,EAClB,QACY;AACZ,UAAM,IAAI,MAAM,yCAAyC,SAAS,EAAE;AAAA,EACtE;AACF;AAQA,eAAe,mBAAmB,WAAgD;AAC5E,MAAA;AACe,YAAA,MAAM,OAAO,YACd;AAAA,EAAA,QACJ;AACZ,UAAM,IAAI,MAAM,kCAAkC,SAAS,EAAE;AAAA,EAC/D;AACF;AASA,eAAe,qCAAqC,YAA+C;AAC3F,QAAA,aAAa,wBAAwB,UAAU,GAC/C,UAAU,WAAW,UAAU,GAC/B,uBAAuB,MAAMC,SAAAA,OAAO,YAAY;AAAA,IACpD,QAAQ;AAAA,IACR,YAAY;AAAA,EAAA,CACb;AAED,SAAO,GAAG,OAAO;AAAA;AAAA,eAAoB,WAAW,IAAI,MAAM,oBAAoB;AAAA;AAChF;AAQA,SAAS,4BAA4B,SAA8C;AACjF,QAAM,eAAe,QAAQ,QAAQ,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAG,GACxE,UAAU,aAAa,IAAI,CAAC,WAAW,YAAY,OAAO,IAAI,cAAc,OAAO,IAAI,GAAG,GAC1FC,WAAU,aAAa,IAAI,CAAC,WAAW,OAAO,IAAI,EAAE,KAAK,GAAG,GAC5D,eAAe,GAAG,QAAQ,KAAK;AAAA,CAAI,CAAC;AAAA;AAAA,8BAAmCA,QAAO;AACpF,SAAOD,SAAO,OAAA,cAAc,EAAC,QAAQ,aAAa,CAAA;AACpD;AAQA,SAAS,WAAW,YAA4B;AACxC,QAAA,iBAAiB,CAAC,cAAc,aAAa;AACnD,SAAI,WAAW,SAAS,mBAAmB,KACzC,eAAe,KAAK,mBAAmB,GAElC,YAAY,eAAe,KAAK,IAAI,CAAC;AAC9C;AAiBgB,SAAA,wBAAwB,YAA0B,OAAgB,IAAc;AAC1F,MAAA;AACK,WAAA,yBAAyB,YAAY,YAAY;AACnD,MAAI,WAAW,SAAS;AAC7B,WAAO,GAAG,yBAAyB,YAAY,aAAa,CAAC;AAE/D,SAAO,GAAG,yBAAyB,YAAY,aAAa,CAAC;AAEpD,WAAA,yBACP,QACA,gBACQ;AACR,UAAM,EAAC,QAAQ,SAAS,IAAI,GAAG,gBAAA,IAAmB,QAE5C,kBAAkB,UAAU,eAAe,GAC3C,YACJ,UAAU,YAAY,OAAO,IAAI,CAAC,MAAM,wBAAwB,GAAG,EAAK,CAAC,EAAE,KAAK,EAAE,CAAC,KAC/E,QAAQ,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,sBAAsB,UAAU,CAAC,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,KACrF,aAAa,WAAW,aAAa,UAAU,OAAO,CAAC,KAEvD,sBAAsB,CAAC,iBAAiB,WAAW,OAAO,UAAU,EACvE,OAAO,OAAO,EACd,KAAK,GAAG;AACJ,WAAA,GAAG,cAAc,MAAM,mBAAmB;AAAA,EACnD;AAEA,WAAS,UAAU,KAAa;AAC9B,WAAO,OAAO,QAAQ,GAAG,EACtB,IAAI,CAAC,CAAC,KAAK,KAAK,MACX,QAAQ,YACH,GAAG,MAAM,UAAU,KAExB,OAAO,SAAU,WACZ,GAAG,GAAG,MAAM,KAAK,MAEtB,OAAO,SAAU,WACZ,GAAG,GAAG,KAAK,KAAK,UAAU,KAAK,CAAC,KAElC,GAAG,GAAG,KAAK,KAAK,EACxB,EACA,KAAK,GAAG;AAAA,EACb;AACF;;;;"}
1
+ {"version":3,"file":"journeyConfig.js","sources":["../../src/util/journeyConfig.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport {Worker} from 'node:worker_threads'\n\nimport {\n type BaseSchemaDefinition,\n type DocumentDefinition,\n type ObjectDefinition,\n} from '@sanity/types'\nimport {format} from 'prettier'\n\nimport {type CliApiClient} from '../types'\nimport {getCliWorkerPath} from './cliWorker'\n\n/**\n * A Journey schema is a server schema that is saved in the Journey API\n */\n\ninterface JourneySchemaWorkerData {\n schemasPath: string\n useTypeScript: boolean\n schemaUrl: string\n}\n\ntype JourneySchemaWorkerResult = {type: 'success'} | {type: 'error'; error: Error}\n\ninterface JourneyConfigResponse {\n projectId: string\n datasetName: string\n displayName: string\n schemaUrl: string\n isFirstProject: boolean // Always true for now, making it compatible with the existing getOrCreateProject\n}\n\ntype DocumentOrObject = DocumentDefinition | ObjectDefinition\ntype SchemaObject = BaseSchemaDefinition & {\n type: string\n fields?: SchemaObject[]\n of?: SchemaObject[]\n preview?: object\n}\n\n/**\n * Fetch a Journey schema from the Sanity schema club API and write it to disk\n */\nexport async function getAndWriteJourneySchema(data: JourneySchemaWorkerData): Promise<void> {\n const {schemasPath, useTypeScript, schemaUrl} = data\n try {\n const documentTypes = await fetchJourneySchema(schemaUrl)\n const fileExtension = useTypeScript ? 'ts' : 'js'\n\n // Write a file for each schema\n for (const documentType of documentTypes) {\n const filePath = path.join(schemasPath, `${documentType.name}.${fileExtension}`)\n await fs.writeFile(filePath, await assembleJourneySchemaTypeFileContent(documentType))\n }\n // Write an index file that exports all the schemas\n const indexContent = await assembleJourneyIndexContent(documentTypes)\n await fs.writeFile(path.join(schemasPath, `index.${fileExtension}`), indexContent)\n } catch (error) {\n throw new Error(`Failed to fetch remote schema: ${error.message}`)\n }\n}\n\n/**\n * Executes the `getAndWriteJourneySchema` operation within a worker thread.\n *\n * This method is designed to safely import network resources by leveraging the `--experimental-network-imports` flag.\n * Due to the experimental nature of this flag, its use is not recommended in the main process. Consequently,\n * the task is delegated to a worker thread to ensure both safety and compliance with best practices.\n *\n * The core functionality involves fetching schema definitions from our own trusted API and writing them to disk.\n * This includes handling both predefined and custom schemas. For custom schemas, a process ensures\n * that they undergo JSON parsing to remove any JavaScript code and are validated before being saved.\n *\n * Depending on the configuration, the schemas are saved as either TypeScript or JavaScript files, dictated by the `useTypeScript` flag within the `workerData`.\n *\n * @param workerData - An object containing the necessary data and flags for the worker thread, including the path to save schemas, flags indicating whether to use TypeScript, and any other relevant configuration details.\n * @returns A promise that resolves upon successful execution of the schema fetching and writing process or rejects if an error occurs during the operation.\n */\nexport async function getAndWriteJourneySchemaWorker(\n workerData: JourneySchemaWorkerData,\n): Promise<void> {\n const workerPath = await getCliWorkerPath('getAndWriteJourneySchema')\n return new Promise((resolve, reject) => {\n const worker = new Worker(workerPath, {\n workerData,\n env: {\n // eslint-disable-next-line no-process-env\n ...process.env,\n // Dynamic HTTPS imports are currently behind a Node flag\n NODE_OPTIONS: '--experimental-network-imports',\n NODE_NO_WARNINGS: '1',\n },\n })\n worker.on('message', (message: JourneySchemaWorkerResult) => {\n if (message.type === 'success') {\n resolve()\n } else {\n message.error.message = `Import schema worker failed: ${message.error.message}`\n reject(message.error)\n }\n })\n worker.on('error', (error) => {\n error.message = `Import schema worker failed: ${error.message}`\n reject(error)\n })\n worker.on('exit', (code) => {\n if (code !== 0) {\n reject(new Error(`Worker stopped with exit code ${code}`))\n }\n })\n })\n}\n\n/**\n * Fetch a Journey config from the Sanity schema club API\n *\n * @param projectId - The slug of the Journey schema to fetch\n * @returns The Journey schema as an array of Sanity document or object definitions\n */\nexport async function fetchJourneyConfig(\n apiClient: CliApiClient,\n projectId: string,\n): Promise<JourneyConfigResponse> {\n if (!projectId) {\n throw new Error('ProjectId is required')\n }\n if (!/^[a-zA-Z0-9-]+$/.test(projectId)) {\n throw new Error('Invalid projectId')\n }\n try {\n const response: {\n projectId: string\n dataset: string\n displayName?: string\n schemaUrl: string\n } = await apiClient({\n requireUser: true,\n requireProject: true,\n api: {projectId},\n })\n .config({apiVersion: 'v2024-02-23'})\n .request({\n method: 'GET',\n uri: `/journey/projects/${projectId}`,\n })\n\n return {\n projectId: response.projectId,\n datasetName: response.dataset,\n displayName: response.displayName || 'Sanity Project',\n // The endpoint returns a signed URL that can be used to fetch the schema as ESM\n schemaUrl: response.schemaUrl,\n isFirstProject: true,\n }\n } catch (err) {\n throw new Error(`Failed to fetch remote schema config: ${projectId}`)\n }\n}\n\n/**\n * Fetch a Journey schema from the Sanity schema club API\n *\n * @param projectId - The slug of the Journey schema to fetch\n * @returns The Journey schema as an array of Sanity document or object definitions\n */\nasync function fetchJourneySchema(schemaUrl: string): Promise<DocumentOrObject[]> {\n try {\n const response = await import(schemaUrl)\n return response.default\n } catch (err) {\n throw new Error(`Failed to fetch remote schema: ${schemaUrl}`)\n }\n}\n\n/**\n * Assemble a Journey schema type into a module export\n * Include the necessary imports and export the schema type as a named export\n *\n * @param schema - The Journey schema to export\n * @returns The Journey schema as a module export\n */\nasync function assembleJourneySchemaTypeFileContent(schemaType: DocumentOrObject): Promise<string> {\n const serialised = wrapSchemaTypeInHelpers(schemaType)\n const imports = getImports(serialised)\n const prettifiedSchemaType = await format(serialised, {\n parser: 'typescript',\n printWidth: 40,\n })\n // Start file with import, then export the schema type as a named export\n return `${imports}\\n\\nexport const ${schemaType.name} = ${prettifiedSchemaType}\\n`\n}\n\n/**\n * Assemble a list of Journey schema module exports into a single index file\n *\n * @param schemas - The Journey schemas to assemble into an index file\n * @returns The index file as a string\n */\nfunction assembleJourneyIndexContent(schemas: DocumentOrObject[]): Promise<string> {\n const sortedSchema = schemas.slice().sort((a, b) => (a.name > b.name ? 1 : -1))\n const imports = sortedSchema.map((schema) => `import { ${schema.name} } from './${schema.name}'`)\n const exports = sortedSchema.map((schema) => schema.name).join(',')\n const fileContents = `${imports.join('\\n')}\\n\\nexport const schemaTypes = [${exports}]`\n return format(fileContents, {parser: 'typescript'})\n}\n\n/**\n * Get the import statements for a schema type\n *\n * @param schemaType - The schema type to get the imports for\n * @returns The import statements for the schema type\n */\nfunction getImports(schemaType: string): string {\n const defaultImports = ['defineType', 'defineField']\n if (schemaType.includes('defineArrayMember')) {\n defaultImports.push('defineArrayMember')\n }\n return `import { ${defaultImports.join(', ')} } from 'sanity'`\n}\n\n/**\n * Serialize a singleSanity schema type (signular) into a string.\n * Wraps the schema object in the appropriate helper function.\n *\n * @param schemaType - The schema type to serialize\n * @returns The schema type as a string\n */\n/**\n * Serializes a single Sanity schema type into a string.\n * Wraps the schema object in the appropriate helper function.\n *\n * @param schemaType - The schema type to serialize\n * @param root - Whether the schemaType is the root object\n * @returns The serialized schema type as a string\n */\nexport function wrapSchemaTypeInHelpers(schemaType: SchemaObject, root: boolean = true): string {\n if (root) {\n return generateSchemaDefinition(schemaType, 'defineType')\n } else if (schemaType.type === 'array') {\n return `${generateSchemaDefinition(schemaType, 'defineField')},`\n }\n return `${generateSchemaDefinition(schemaType, 'defineField')},`\n\n function generateSchemaDefinition(\n object: SchemaObject,\n definitionType: 'defineType' | 'defineField',\n ): string {\n const {fields, preview, of, ...otherProperties} = object\n\n const serializedProps = serialize(otherProperties)\n const fieldsDef =\n fields && `fields: [${fields.map((f) => wrapSchemaTypeInHelpers(f, false)).join('')}]`\n const ofDef = of && `of: [${of.map((f) => `defineArrayMember({${serialize(f)}})`).join(',')}]`\n const previewDef = preview && `preview: {${serialize(preview)}}`\n\n const combinedDefinitions = [serializedProps, fieldsDef, ofDef, previewDef]\n .filter(Boolean)\n .join(',')\n return `${definitionType}({ ${combinedDefinitions} })`\n }\n\n function serialize(obj: object) {\n return Object.entries(obj)\n .map(([key, value]) => {\n if (key === 'prepare') {\n return `${value.toString()}`\n }\n if (typeof value === 'string') {\n return `${key}: \"${value}\"`\n }\n if (typeof value === 'object') {\n return `${key}: ${JSON.stringify(value)}`\n }\n return `${key}: ${value}`\n })\n .join(',')\n }\n}\n"],"names":["path","fs","getCliWorkerPath","Worker","format","exports"],"mappings":"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"}