stadtwerke/innungsapp/apps/mobile/metro/react-native-css-interop-me...

290 lines
12 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.withCssInterop = withCssInterop;
const fs_1 = __importDefault(require("fs"));
const promises_1 = __importDefault(require("fs/promises"));
const path_1 = __importDefault(require("path"));
const module_1 = require("module");
const nativewindRequire = (0, module_1.createRequire)(require.resolve("nativewind/metro"));
const connect_1 = __importDefault(nativewindRequire("connect"));
const debug_1 = nativewindRequire("debug");
const css_to_rn_1 = nativewindRequire("react-native-css-interop/dist/css-to-rn");
const expo_1 = nativewindRequire("react-native-css-interop/dist/metro/expo");
let haste;
let virtualModulesPossible = undefined;
const virtualModules = new Map();
const outputDirectory = path_1.default.resolve(__dirname, "../.cache/react-native-css-interop");
const isRadonIDE = "REACT_NATIVE_IDE_LIB_PATH" in process.env;
function withCssInterop(config, options) {
return typeof config === "function"
? async function WithCSSInterop() {
return getConfig(await config(), options);
}
: getConfig(config, options);
}
function getConfig(config, options) {
const debug = (0, debug_1.debug)(options.parent?.name || "react-native-css-interop");
debug("withCssInterop");
debug(`outputDirectory ${outputDirectory}`);
debug(`isRadonIDE: ${isRadonIDE}`);
(0, expo_1.expoColorSchemeWarning)();
const originalResolver = config.resolver?.resolveRequest;
const originalGetTransformOptions = config.transformer?.getTransformOptions;
const originalMiddleware = config.server?.enhanceMiddleware;
const poisonPillPath = "./interop-poison.pill";
fs_1.default.mkdirSync(outputDirectory, { recursive: true });
fs_1.default.writeFileSync(platformPath("ios"), "");
fs_1.default.writeFileSync(platformPath("android"), "");
fs_1.default.writeFileSync(platformPath("native"), "");
fs_1.default.writeFileSync(platformPath("macos"), "");
fs_1.default.writeFileSync(platformPath("windows"), "");
return {
...config,
transformerPath: require.resolve("react-native-css-interop/dist/metro/transformer"),
transformer: {
...config.transformer,
...{
cssInterop_transformerPath: config.transformerPath,
cssInterop_outputDirectory: path_1.default.relative(process.cwd(), outputDirectory),
},
async getTransformOptions(entryPoints, transformOptions, getDependenciesOf) {
debug(`getTransformOptions.dev ${transformOptions.dev}`);
debug(`getTransformOptions.platform ${transformOptions.platform}`);
debug(`getTransformOptions.virtualModulesPossible ${Boolean(virtualModulesPossible)}`);
const platform = transformOptions.platform || "native";
const filePath = platformPath(platform);
if (virtualModulesPossible) {
await virtualModulesPossible;
await startCSSProcessor(filePath, platform, transformOptions.dev, options, debug);
}
const writeToFileSystem = !virtualModulesPossible || !transformOptions.dev;
debug(`getTransformOptions.writeToFileSystem ${writeToFileSystem}`);
if (writeToFileSystem) {
debug(`getTransformOptions.output ${filePath}`);
const watchFn = isRadonIDE
? async (css) => {
const output = platform === "web"
? css.toString()
: getNativeJS((0, css_to_rn_1.cssToReactNativeRuntime)(css, options, debug), debug);
await promises_1.default.writeFile(filePath, output);
}
: undefined;
const css = await options.getCSSForPlatform(platform, watchFn);
const output = platform === "web"
? css.toString("utf-8")
: getNativeJS((0, css_to_rn_1.cssToReactNativeRuntime)(css, options, debug), debug);
await promises_1.default.mkdir(outputDirectory, { recursive: true });
await promises_1.default.writeFile(filePath, output);
if (platform !== "web") {
await promises_1.default.writeFile(filePath.replace(/\.js$/, ".map"), "");
}
debug(`getTransformOptions.finished`);
}
return Object.assign({}, await originalGetTransformOptions?.(entryPoints, transformOptions, getDependenciesOf));
},
},
server: {
...config.server,
enhanceMiddleware: (middleware, metroServer) => {
debug(`enhanceMiddleware.setup`);
const server = (0, connect_1.default)();
const bundler = metroServer.getBundler().getBundler();
if (options.forceWriteFileSystem) {
debug(`forceWriteFileSystem true`);
}
else {
if (!isRadonIDE) {
virtualModulesPossible = bundler
.getDependencyGraph()
.then(async (graph) => {
haste = graph?._haste;
if (graph?._fileSystem) {
ensureFileSystemPatched(graph._fileSystem);
}
ensureBundlerPatched(bundler);
});
server.use(async (_, __, next) => {
await virtualModulesPossible;
next();
});
}
}
return originalMiddleware
? server.use(originalMiddleware(middleware, metroServer))
: server.use(middleware);
},
},
resolver: {
...config.resolver,
sourceExts: [...(config?.resolver?.sourceExts || []), "css"],
resolveRequest: (context, moduleName, platform) => {
if (moduleName === poisonPillPath) {
return { type: "empty" };
}
const resolver = originalResolver ?? context.resolveRequest;
const resolved = resolver(context, moduleName, platform);
if (!("filePath" in resolved && resolved.filePath === options.input)) {
return resolved;
}
platform = platform || "native";
const filePath = platformPath(platform);
const development = context.isDev || context.dev;
const isWebProduction = !development && platform === "web";
debug(`resolveRequest.input ${resolved.filePath}`);
debug(`resolveRequest.resolvedTo: ${filePath}`);
debug(`resolveRequest.development: ${development}`);
debug(`resolveRequest.platform: ${platform}`);
if (virtualModulesPossible && !isWebProduction) {
startCSSProcessor(filePath, platform, development, options, debug);
}
return {
...resolved,
filePath,
};
},
},
};
}
async function startCSSProcessor(filePath, platform, isDev, { input, getCSSForPlatform, ...options }, debug) {
if (virtualModules.has(filePath)) {
return;
}
debug(`virtualModules ${filePath}`);
debug(`virtualModules.isDev ${isDev}`);
debug(`virtualModules.size ${virtualModules.size}`);
options = {
cache: {
keyframes: new Map(),
rules: new Map(),
rootVariables: {},
universalVariables: {},
},
...options,
};
if (!isDev) {
debug(`virtualModules.fastRefresh disabled`);
virtualModules.set(filePath, getCSSForPlatform(platform).then((css) => {
return platform === "web"
? css
: getNativeJS((0, css_to_rn_1.cssToReactNativeRuntime)(css, options), debug);
}));
}
else {
debug(`virtualModules.fastRefresh enabled`);
virtualModules.set(filePath, getCSSForPlatform(platform, (css) => {
debug(`virtualStyles.update ${platform}`);
virtualModules.set(filePath, Promise.resolve(platform === "web"
? css
: getNativeJS((0, css_to_rn_1.cssToReactNativeRuntime)(css, options), debug)));
debug(`virtualStyles.emit ${platform}`);
if (haste?.emit) {
haste.emit("change", {
eventsQueue: [
{
filePath,
metadata: {
modifiedTime: Date.now(),
size: 1,
type: "virtual",
},
type: "change",
},
],
});
}
}).then((css) => {
debug(`virtualStyles.initial ${platform}`);
return platform === "web"
? css
: getNativeJS((0, css_to_rn_1.cssToReactNativeRuntime)(css, options), debug);
}));
}
}
function ensureFileSystemPatched(fs) {
if (!fs || typeof fs.getSha1 !== "function") {
return fs;
}
if (!fs.getSha1.__css_interop_patched) {
const original_getSha1 = fs.getSha1.bind(fs);
fs.getSha1 = (filename) => {
if (virtualModules.has(filename)) {
return `${filename}-${Date.now()}`;
}
return original_getSha1(filename);
};
fs.getSha1.__css_interop_patched = true;
}
return fs;
}
function ensureBundlerPatched(bundler) {
if (bundler.transformFile.__css_interop__patched) {
return;
}
const transformFile = bundler.transformFile.bind(bundler);
bundler.transformFile = async function (filePath, transformOptions, fileBuffer) {
const virtualModule = virtualModules.get(filePath);
if (virtualModule) {
fileBuffer = Buffer.from(await virtualModule);
}
return transformFile(filePath, transformOptions, fileBuffer);
};
bundler.transformFile.__css_interop__patched = true;
}
function getNativeJS(data = {}, debug) {
debug("Start stringify");
const output = `(${stringify(data)})`;
debug(`Output size: ${Buffer.byteLength(output, "utf8")} bytes`);
return output;
}
function platformPath(platform = "native") {
return path_1.default.join(outputDirectory, `${platform}.${platform === "web" ? "css" : "js"}`);
}
function stringify(data) {
switch (typeof data) {
case "bigint":
case "symbol":
case "function":
throw new Error(`Cannot stringify ${typeof data}`);
case "string":
return `"${data}"`;
case "number":
return `${Math.round(data * 1000) / 1000}`;
case "boolean":
return `${data}`;
case "undefined":
return "null";
case "object": {
if (data === null) {
return "null";
}
else if (Array.isArray(data)) {
return `[${data
.map((value) => {
return value === null || value === undefined
? ""
: stringify(value);
})
.join(",")}]`;
}
else {
return `{${Object.entries(data)
.flatMap(([key, value]) => {
if (value === null || value === undefined) {
return [];
}
if (key.match(/[^a-zA-Z]/)) {
key = `"${key}"`;
}
value = stringify(value);
return [`${key}:${value}`];
})
.join(",")}}`;
}
}
}
}
//# sourceMappingURL=index.js.map