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
209 lines (208 loc) • 8.71 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf, __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from == "object" || typeof from == "function")
for (let key of __getOwnPropNames(from))
!__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: !0 }) : target,
mod
));
var fs$1 = require("node:fs"), fs = require("node:fs/promises"), path = require("node:path"), readPkgUp = require("read-pkg-up"), runtime = require("./runtime.js"), chalk = require("chalk");
function _interopDefaultCompat(e) {
return e && typeof e == "object" && "default" in e ? e : { default: e };
}
var fs__default = /* @__PURE__ */ _interopDefaultCompat(fs), path__default = /* @__PURE__ */ _interopDefaultCompat(path), readPkgUp__default = /* @__PURE__ */ _interopDefaultCompat(readPkgUp), chalk__default = /* @__PURE__ */ _interopDefaultCompat(chalk);
const debug$1 = runtime.debug.extend("static");
async function buildStaticFiles(options) {
const {
cwd,
outputDir,
sourceMap = !1,
minify = !0,
basePath,
vite: extendViteConfig,
importMap,
reactCompiler,
entry,
isApp
} = options;
debug$1("Writing Sanity runtime files"), await runtime.writeSanityRuntime({
cwd,
reactStrictMode: !1,
watch: !1,
basePath,
entry,
isApp
}), debug$1("Resolving vite config");
const mode = "production";
let viteConfig = await runtime.getViteConfig({
cwd,
basePath,
outputDir,
minify,
sourceMap,
mode,
importMap,
reactCompiler,
isApp
});
extendViteConfig && (viteConfig = await runtime.extendViteConfigWithUserConfig({
command: "build",
mode
}, viteConfig, extendViteConfig), viteConfig = await runtime.finalizeViteConfig(viteConfig)), debug$1("Copying static files from /static to output dir");
const staticPath = path__default.default.join(outputDir, "static");
await copyDir(path__default.default.join(cwd, "static"), staticPath), debug$1("Writing favicons to output dir");
const faviconBasePath = `${basePath.replace(/\/+$/, "")}/static`;
await writeFavicons(faviconBasePath, staticPath), debug$1("Bundling using vite");
const {
build
} = await import("vite"), bundle = await build(viteConfig);
if (debug$1("Bundling complete"), Array.isArray(bundle) || !("output" in bundle))
return {
chunks: []
};
const stats = [];
return bundle.output.forEach((chunk) => {
chunk.type === "chunk" && stats.push({
name: chunk.name,
modules: Object.entries(chunk.modules).map(([rawFilePath, chunkModule]) => {
const filePath = rawFilePath.startsWith("\0") ? rawFilePath.slice(1) : rawFilePath;
return {
name: path__default.default.isAbsolute(filePath) ? path__default.default.relative(cwd, filePath) : filePath,
originalLength: chunkModule.originalLength,
renderedLength: chunkModule.renderedLength
};
})
});
}), {
chunks: stats
};
}
async function copyDir(srcDir, destDir, skipExisting) {
await fs__default.default.mkdir(destDir, {
recursive: !0
});
for (const file of await tryReadDir(srcDir)) {
const srcFile = path__default.default.resolve(srcDir, file);
if (srcFile === destDir)
continue;
const destFile = path__default.default.resolve(destDir, file);
(await fs__default.default.stat(srcFile)).isDirectory() ? await copyDir(srcFile, destFile, skipExisting) : skipExisting ? await fs__default.default.copyFile(srcFile, destFile, fs$1.constants.COPYFILE_EXCL).catch(skipIfExistsError) : await fs__default.default.copyFile(srcFile, destFile);
}
}
async function tryReadDir(dir) {
try {
return await fs__default.default.readdir(dir);
} catch (err) {
if (err.code === "ENOENT")
return [];
throw err;
}
}
function skipIfExistsError(err) {
if (err.code !== "EEXIST")
throw err;
}
async function writeFavicons(basePath, destDir) {
const sanityPkgPath = (await readPkgUp__default.default({
cwd: __dirname
}))?.path, faviconsPath = sanityPkgPath ? path__default.default.join(path__default.default.dirname(sanityPkgPath), "static", "favicons") : void 0;
if (!faviconsPath)
throw new Error("Unable to resolve `sanity` module root");
await fs__default.default.mkdir(destDir, {
recursive: !0
}), await copyDir(faviconsPath, destDir, !0), await writeWebManifest(basePath, destDir), await fs__default.default.copyFile(path__default.default.join(destDir, "favicon.ico"), path__default.default.join(destDir, "..", "favicon.ico"));
}
async function writeWebManifest(basePath, destDir) {
const content = JSON.stringify(runtime.generateWebManifest(basePath), null, 2);
await fs__default.default.writeFile(path__default.default.join(destDir, "manifest.webmanifest"), content, "utf8").catch(skipIfExistsError);
}
function sanityBasePathRedirectPlugin(basePath) {
return {
name: "sanity/server/sanity-base-path-redirect",
apply: "serve",
configurePreviewServer(vitePreviewServer) {
return () => {
basePath && vitePreviewServer.middlewares.use((req, res, next) => {
if (req.url !== "/") {
next();
return;
}
res.writeHead(302, {
Location: basePath
}), res.end();
});
};
}
};
}
const debug = runtime.debug.extend("preview");
async function startPreviewServer(options) {
const {
httpPort,
httpHost,
root,
vite: extendViteConfig,
isApp
} = options, startTime = Date.now(), indexPath = path__default.default.join(root, "index.html");
let basePath;
try {
const index = await fs__default.default.readFile(indexPath, "utf8");
basePath = tryResolveBasePathFromIndex(index);
} catch (err) {
if (err.code !== "ENOENT")
throw err;
const error = new Error(`Could not find a production build in the '${root}' directory.
Try building your ${isApp ? "application" : "studio "}app with 'sanity build' before starting the preview server.`);
throw error.name = "BUILD_NOT_FOUND", error;
}
const mode = "production";
let previewConfig = {
root,
base: basePath || "/",
plugins: [sanityBasePathRedirectPlugin(basePath)],
configFile: !1,
preview: {
port: httpPort,
host: httpHost,
strictPort: !0
},
// Needed for vite to not serve `root/dist`
build: {
outDir: root
},
mode
};
extendViteConfig && (previewConfig = await runtime.extendViteConfigWithUserConfig({
command: "serve",
mode
}, previewConfig, extendViteConfig)), debug("Creating vite server");
const {
preview
} = await import("vite"), server = await preview(previewConfig), warn = server.config.logger.warn, info = server.config.logger.info, url = server.resolvedUrls.local[0];
typeof basePath > "u" ? warn('Could not determine base path from index.html, using "/" as default') : basePath && basePath !== "/" && info(`Using resolved base path from static build: ${chalk__default.default.cyan(basePath)}`);
const startupDuration = Date.now() - startTime;
return info(`Sanity ${isApp ? "application" : "Studio"} using ${chalk__default.default.cyan(`vite@${require("vite/package.json").version}`)} ready in ${chalk__default.default.cyan(`${Math.ceil(startupDuration)}ms`)} and running at ${chalk__default.default.cyan(url)} (production preview mode)`), {
urls: server.resolvedUrls,
close: () => new Promise((resolve, reject) => server.httpServer.close((err) => err ? reject(err) : resolve()))
};
}
function tryResolveBasePathFromIndex(index) {
const basePath = index.match(/<script[^>]+src="(.*?)\/static\/sanity-/)?.[1];
if (!(typeof basePath > "u"))
return basePath === "" ? "/" : basePath;
}
exports.buildStaticFiles = buildStaticFiles;
exports.startPreviewServer = startPreviewServer;
//# sourceMappingURL=previewServer.js.map