snapshot of https://github.com/dream-num/univer.git (dev, 2026-09-16; blobs > 131072B omitted)
Some checks failed
📦 Build / build (push) Has been cancelled
🧪 CI Test / test shard (1/4) (push) Has been cancelled
🧪 CI Test / test shard (2/4) (push) Has been cancelled
🧪 CI Test / test shard (3/4) (push) Has been cancelled
🧪 CI Test / test shard (4/4) (push) Has been cancelled
🧪 CI Test / test (push) Has been cancelled
🧪 CI Test / eslint (push) Has been cancelled
🧪 CI Test / typecheck (push) Has been cancelled
🔫 Sync to Pro / dispatch-sync (push) Has been cancelled
🔮 Sync Mirror / sync (push) Has been cancelled

This commit is contained in:
upstream-mirror
2026-09-16 05:09:45 +05:00
commit bcf6ef63ad
7118 changed files with 1236854 additions and 0 deletions

View File

@@ -0,0 +1 @@
export const PRESET_LOCALE_SOURCE_DIR = 'src/locales';

View File

@@ -0,0 +1,49 @@
import type { IEntryConfig } from '../tsdown/types.ts';
import { existsSync, readdirSync, statSync } from 'node:fs';
import path from 'node:path';
import { PRESET_LOCALE_SOURCE_DIR } from './constants.ts';
function getPresetLocaleEntries(packageDir: string): IEntryConfig[] {
const localeDir = path.join(packageDir, PRESET_LOCALE_SOURCE_DIR);
if (!existsSync(localeDir)) {
return [];
}
const entries: IEntryConfig[] = [];
for (const fileName of readdirSync(localeDir).sort((left, right) => left.localeCompare(right))) {
const fullPath = path.join(localeDir, fileName);
if (statSync(fullPath).isDirectory() || !fileName.endsWith('.ts') || !fileName.includes('-')) {
continue;
}
entries.push({
key: `locales/${fileName.replace(/\.ts$/, '')}`,
path: fullPath,
type: 'locale',
});
}
return entries;
}
export function getPresetModuleEntries(packageDir: string): IEntryConfig[] {
const entries: IEntryConfig[] = [{
key: 'index',
path: path.join(packageDir, 'src/index.ts'),
type: 'index',
}];
const workerEntry = path.join(packageDir, 'src/worker.ts');
if (existsSync(workerEntry)) {
entries.push({
key: 'worker',
path: workerEntry,
type: 'worker',
});
}
return [...entries, ...getPresetLocaleEntries(packageDir)];
}

View File

@@ -0,0 +1,130 @@
import type { TModuleFormat } from '../tsdown/configs/module.ts';
import type { IPackageJson } from '../tsdown/types.ts';
import type { IPresetBuildOptions, IPresetPackageJson } from './types.ts';
import { existsSync, readFileSync, rmSync } from 'node:fs';
import path from 'node:path';
import process from 'node:process';
import { pathToFileURL } from 'node:url';
import { mergeConfig, build as tsdownBuild } from 'tsdown';
import { createModuleConfig } from '../tsdown/configs/module.ts';
import { BUILD_OUTPUT_DIRECTORIES, CLEANUP_DIRECTORIES } from '../tsdown/constants.ts';
import { createBaseConfig, createInputPlugins } from '../tsdown/utils/base-config.ts';
import { getPresetModuleEntries } from './entries.ts';
import { generatePresetLocales } from './locale.ts';
import { buildPresetStyles } from './style.ts';
export { generatePresetLocales } from './locale.ts';
export type { IPresetBuildOptions } from './types.ts';
function readPackageJson(packageDir: string): IPresetPackageJson {
return JSON.parse(readFileSync(path.join(packageDir, 'package.json'), 'utf8')) as IPresetPackageJson;
}
function getExternalPackages(packageJson: IPresetPackageJson) {
return [...new Set([
...Object.keys(packageJson.dependencies ?? {}),
...Object.keys(packageJson.peerDependencies ?? {}),
'react',
'react-dom',
'rxjs',
])]
.sort((left, right) => left.localeCompare(right))
.flatMap((packageName) => [packageName, `${packageName}/*`]);
}
async function loadUserConfig(options: IPresetBuildOptions, packageDir: string) {
if (!options.tsdownConfigPath) {
return null;
}
const configPath = path.resolve(packageDir, options.tsdownConfigPath);
let userConfig = (await import(pathToFileURL(configPath).href)).default;
if (typeof userConfig === 'function') {
userConfig = await userConfig();
}
return userConfig;
}
function mergeUserConfig(configs: any[], userConfig: any) {
if (!userConfig) {
return configs;
}
return configs.map((config) => mergeConfig(config, userConfig));
}
export function createPresetModuleEntryGroups(entries: ReturnType<typeof getPresetModuleEntries>) {
const primaryEntries = entries.filter((entry) => entry.type === 'index' || entry.type === 'locale');
const isolatedEntries = entries.filter((entry) => entry.type !== 'index' && entry.type !== 'locale');
return [
...(primaryEntries.length > 0 ? [primaryEntries] : []),
...isolatedEntries.map((entry) => [entry]),
];
}
export function removePresetOutputs(packageDir = process.cwd()) {
for (const dir of CLEANUP_DIRECTORIES) {
const targetDir = path.resolve(packageDir, dir);
if (existsSync(targetDir)) {
rmSync(targetDir, { force: true, recursive: true });
}
}
}
export function preparePresetPackage(packageDir = process.cwd()) {
const packageJson = readPackageJson(packageDir);
if (packageJson.name === '@univerjs/presets') {
return [];
}
return generatePresetLocales({ packageDir });
}
export async function buildPresetPackage(options: IPresetBuildOptions = {}) {
const packageDir = process.cwd();
const packageJson = readPackageJson(packageDir);
if (options.cleanup) {
removePresetOutputs(packageDir);
}
const externalPackages = getExternalPackages(packageJson);
const baseConfig = createBaseConfig({
entries: [],
externalPackages,
facadeExternalPackages: externalPackages,
packageDir,
packageJson: packageJson as IPackageJson,
plugins: [],
});
const plugins = createInputPlugins(packageDir);
const userConfig = await loadUserConfig(options, packageDir);
const moduleFormats: TModuleFormat[] = ['esm', 'cjs'];
const moduleConfigs = createPresetModuleEntryGroups(getPresetModuleEntries(packageDir)).flatMap((entries) => {
return moduleFormats.map((format) => createModuleConfig({
baseConfig,
enableObfuscation: false,
entries,
externalPackages,
facadeExternalPackages: externalPackages,
format,
outDir: BUILD_OUTPUT_DIRECTORIES[format],
packageDir,
plugins,
}));
});
for (const config of mergeUserConfig(moduleConfigs, userConfig)) {
await tsdownBuild(config);
}
await buildPresetStyles({
packageDir,
packageJson,
});
}

View File

@@ -0,0 +1,98 @@
import type { IGeneratePresetLocalesOptions, IPresetPackageJson } from './types.ts';
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
import path from 'node:path';
import { discoverUniverUiLocales } from '../locale/index.ts';
import { PRESET_LOCALE_SOURCE_DIR } from './constants.ts';
function readPackageJson(packageDir: string): IPresetPackageJson {
return JSON.parse(readFileSync(path.join(packageDir, 'package.json'), 'utf8')) as IPresetPackageJson;
}
function convertImportNameFromPackageName(name: string) {
return name
.replace(/^@univerjs(?:-[^/]+)?\//, 'univerjs')
.replace(/[^a-zA-Z0-9_$]/g, '');
}
function compareStrings(left: string, right: string) {
if (left < right) {
return -1;
}
if (left > right) {
return 1;
}
return 0;
}
function getDependencyNames(pkg: IPresetPackageJson) {
return Object.keys(pkg.dependencies ?? {})
.filter((name) => name.startsWith('@univerjs'))
.sort(compareStrings);
}
function getDependencyLocaleSubpath(packageDir: string, dependencyName: string, locale: string) {
const dependencyDir = path.join(packageDir, 'node_modules', dependencyName);
if (
existsSync(path.join(dependencyDir, 'lib/es/locale', `${locale}.js`))
|| existsSync(path.join(dependencyDir, 'src/locale', `${locale}.ts`))
) {
return 'locale';
}
if (
existsSync(path.join(dependencyDir, 'lib/es/locales', `${locale}.js`))
|| existsSync(path.join(dependencyDir, 'src/locales', `${locale}.ts`))
) {
return 'locales';
}
return null;
}
export function generatePresetLocales(options: IGeneratePresetLocalesOptions): string[] {
const { packageDir } = options;
const pkg = readPackageJson(packageDir);
const dependencyNames = getDependencyNames(pkg);
const localeDir = path.join(packageDir, PRESET_LOCALE_SOURCE_DIR);
rmSync(localeDir, { force: true, recursive: true });
mkdirSync(localeDir, { recursive: true });
const generated: string[] = [];
for (const locale of discoverUniverUiLocales({ rootDir: packageDir })) {
const dependenciesWithLocale = dependencyNames
.map((dependencyName) => ({
dependencyName,
localeSubpath: getDependencyLocaleSubpath(packageDir, dependencyName, locale),
}))
.filter((dependency): dependency is { dependencyName: string; localeSubpath: 'locale' | 'locales' } => dependency.localeSubpath !== null);
if (dependenciesWithLocale.length === 0) {
continue;
}
let content = '';
for (const { dependencyName, localeSubpath } of dependenciesWithLocale) {
content += `import ${convertImportNameFromPackageName(dependencyName)} from '${dependencyName}/${localeSubpath}/${locale}';\n`;
}
content += '\nexport default Object.assign(\n';
content += ' {},\n';
for (const { dependencyName } of dependenciesWithLocale) {
content += ` ${convertImportNameFromPackageName(dependencyName)},\n`;
}
content += ');\n';
writeFileSync(path.join(localeDir, `${locale}.ts`), content);
generated.push(locale);
}
return generated;
}

View File

@@ -0,0 +1,58 @@
import type { IPresetPackageJson } from './types.ts';
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
import path from 'node:path';
function getDependencyDir(packageDir: string, dependencyName: string) {
return path.join(packageDir, 'node_modules', dependencyName);
}
function getBuiltStyleDependencyCssFiles(packageDir: string, packageJson: IPresetPackageJson) {
return Object.keys(packageJson.dependencies ?? {})
.flatMap((dependencyName) => {
if (!dependencyName.startsWith('@univerjs')) {
return [];
}
const dependencyDir = getDependencyDir(packageDir, dependencyName);
const sourceGlobalCss = path.join(dependencyDir, 'src/global.css');
const builtCss = path.join(dependencyDir, 'lib/index.css');
if (!existsSync(sourceGlobalCss)) {
return [];
}
if (!existsSync(builtCss)) {
throw new Error(`Missing built CSS for ${dependencyName}. Build dependency packages before building preset CSS.`);
}
return [builtCss];
});
}
function writePresetCss(packageDir: string, cssFiles: string[]) {
const outputFile = path.join(packageDir, 'lib/index.css');
mkdirSync(path.dirname(outputFile), { recursive: true });
const content = cssFiles
.map((cssFile) => readFileSync(cssFile, 'utf8').trimEnd())
.filter(Boolean)
.join('\n');
writeFileSync(outputFile, `${content}\n`);
}
export async function buildPresetStyles(options: {
packageDir: string;
packageJson: IPresetPackageJson;
}) {
const { packageDir, packageJson } = options;
const cssFiles = getBuiltStyleDependencyCssFiles(packageDir, packageJson);
if (cssFiles.length === 0) {
rmSync(path.join(packageDir, 'lib/index.css'), { force: true });
return;
}
writePresetCss(packageDir, cssFiles);
}

View File

@@ -0,0 +1,15 @@
export interface IPresetBuildOptions {
cleanup?: boolean;
tsdownConfigPath?: string;
}
export interface IPresetPackageJson {
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
name: string;
peerDependencies?: Record<string, string>;
}
export interface IGeneratePresetLocalesOptions {
packageDir: string;
}