sanity
Version:
Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches
85 lines (73 loc) • 2.39 kB
text/typescript
/* eslint-disable no-sync */
import fs from 'fs'
import path from 'path'
import {firstValueFrom} from 'rxjs'
import {type Config, resolveConfig, type Workspace, type WorkspaceOptions} from 'sanity'
import {mockBrowserEnvironment} from './mockBrowserEnvironment'
const candidates = [
'sanity.config.js',
'sanity.config.jsx',
'sanity.config.ts',
'sanity.config.tsx',
]
interface GetStudioWorkspacesOptions {
configPath?: string
basePath: string
}
/**
* Note: Don't run this on the main thread, use it a forked process
*/
export function getStudioConfig({
basePath,
configPath: cfgPath,
}: GetStudioWorkspacesOptions): WorkspaceOptions[] {
let cleanup
try {
cleanup = mockBrowserEnvironment(basePath)
let configPath = cfgPath
if (configPath && !fs.existsSync(configPath)) {
throw new Error(`Failed to find config at "${cfgPath}"`)
} else if (!configPath) {
configPath = candidates
.map((candidate) => path.join(basePath, candidate))
.find((candidate) => fs.existsSync(candidate))
}
if (!configPath) {
throw new Error(`Failed to resolve sanity.config.(js|ts) for base path "${basePath}"`)
}
let config: Config | undefined
try {
// eslint-disable-next-line import/no-dynamic-require
const mod = require(configPath)
config = mod.__esModule && mod.default ? mod.default : mod
} catch (err) {
const message = `Failed to load configuration file "${configPath}":\n${err.message}`
// this helps preserve the stack trace
throw Object.assign(err, {message})
}
if (!config) throw new Error('Configuration did not export expected config shape')
const normalized = Array.isArray(config)
? config
: [{...config, name: config.name || 'default', basePath: config.basePath || '/'}]
return normalized
} finally {
cleanup?.()
}
}
/**
* Note: Don't run this on the main thread, use it a forked process
*/
export async function getStudioWorkspaces(
options: GetStudioWorkspacesOptions,
): Promise<Workspace[]> {
let cleanup
try {
cleanup = mockBrowserEnvironment(options.basePath)
const config = getStudioConfig(options)
const workspaces = await firstValueFrom(resolveConfig(config))
if (!workspaces) throw new Error('Failed to resolve configuration')
return workspaces
} finally {
cleanup?.()
}
}