fix: 🐛 解决出码缺乏对于 i18n 数据的 params 的处理的问题

https://github.com/alibaba/lowcode-engine/issues/288

 Closes: #288
This commit is contained in:
Clarence-pan 2022-04-08 20:08:15 +08:00 committed by Clarence Pan
parent 57657fd76d
commit 2cf788c171
93 changed files with 2602 additions and 641 deletions

View File

@ -6,4 +6,5 @@ module.exports = {
collectCoverage: false,
collectCoverageFrom: ['src/**/*.{ts,tsx}', '!**/node_modules/**', '!**/vendor/**'],
testMatch: ['<rootDir>/tests/**/*.test.ts'],
setupFiles: ['./jest.setup.js'],
};

View File

@ -0,0 +1,12 @@
// 对于 standalone 模式的专门 polyfills
if (process.env.TEST_TARGET === 'standalone') {
// 模拟浏览器环境
global.window = global;
global.self = global;
// 将所有测试用例里面的 './src' 都替换为 './dist/standalone'
jest.mock('./src', () => require('./dist/standalone'));
}
// 如果在调试模式下,则不限制超时时间
jest.setTimeout(typeof v8debug === 'object' ? Infinity : 30 * 1000);

View File

@ -85,6 +85,7 @@
"lodash-es": "^4.17.21",
"mock-fs": "^5.1.2",
"moment": "^2.29.1",
"nanomatch": "^1.2.13",
"node-fetch": "2.x",
"path-browserify": "^1.0.1",
"prettier": "^2.5.1",

View File

@ -0,0 +1,55 @@
#!/usr/bin/env node
// @ts-check
const program = require('commander');
const { spawnSync } = require('child_process');
const glob = require('glob');
const fs = require('fs');
const path = require('path');
const _ = require('lodash');
program
.option('--npm <npm>', 'specify the npm command location or alias')
.arguments('<project>')
.action((project, options) => {
try {
if (!fs.existsSync(project)) {
throw new Error(`Project ${project} does not exist`);
}
const getProjectActualPath = [
() => path.resolve(process.cwd(), project),
() =>
path.resolve(
process.cwd(),
path.join(
project,
path.dirname(glob.sync('*/package.json', { cwd: project })[0] || ''),
),
),
]
.map((x) => _.memoize(x))
.find((x) => fs.existsSync(path.join(x(), 'package.json')));
if (!getProjectActualPath) {
throw new Error(`Project ${project} is not a valid project(no package.json)`);
}
const projectActualPath = getProjectActualPath();
if (path.resolve(process.cwd(), project) !== projectActualPath) {
console.log('Changing directory to', path.relative(process.cwd(), projectActualPath));
}
process.chdir(projectActualPath);
const npm = options.npm || 'npm';
const cmd = `${npm} install && ${npm} start`;
console.log('# %s', cmd);
spawnSync(cmd, { stdio: 'inherit', shell: true });
} catch (err) {
console.log(err);
process.exit(1);
}
});
program.parse(process.argv);

View File

@ -638,6 +638,7 @@ export default function createHelloWorldProjectBuilder() {
CodeGen.plugins.react.reactCommonDeps(),
CodeGen.plugins.common.esmodule({ fileType: 'jsx' }),
CodeGen.plugins.react.containerClass(),
CodeGen.plugins.react.containerInjectContext(),
CodeGen.plugins.react.containerInjectUtils(),
CodeGen.plugins.react.containerInjectDataSourceEngine(),
CodeGen.plugins.react.containerInjectI18n(),
@ -659,6 +660,7 @@ export default function createHelloWorldProjectBuilder() {
CodeGen.plugins.react.reactCommonDeps(),
CodeGen.plugins.common.esmodule({ fileType: 'jsx' }),
CodeGen.plugins.react.containerClass(),
CodeGen.plugins.react.containerInjectContext(),
CodeGen.plugins.react.containerInjectUtils(),
CodeGen.plugins.react.containerInjectDataSourceEngine(),
CodeGen.plugins.react.containerInjectI18n(),

View File

@ -5,6 +5,7 @@ import {
CodeGeneratorError,
ICodeChunk,
ICompiledModule,
IContextData,
IModuleBuilder,
IParseResult,
ISchemaParser,
@ -23,6 +24,7 @@ export function createModuleBuilder(
plugins: BuilderComponentPlugin[];
postProcessors: PostProcessor[];
mainFileName?: string;
contextData?: IContextData;
} = {
plugins: [],
postProcessors: [],
@ -41,7 +43,13 @@ export function createModuleBuilder(
let files: ResultFile[] = [];
const { chunks } = await chunkGenerator.run(input);
const { chunks } = await chunkGenerator.run(input, {
ir: input,
chunks: [],
depNames: [],
contextData: options.contextData || {},
});
chunks.forEach((fileChunkList) => {
const content = linker.link(fileChunkList);
const file = createResultFile(

View File

@ -14,7 +14,7 @@ import { SchemaParser } from '../parser/SchemaParser';
import { createResultDir, addDirectory, addFile } from '../utils/resultHelper';
import { createModuleBuilder } from './ModuleBuilder';
import { ProjectPreProcessor, ProjectPostProcessor } from '../types/core';
import { ProjectPreProcessor, ProjectPostProcessor, IContextData } from '../types/core';
import { CodeGeneratorError } from '../types/error';
interface IModuleInfo {
@ -36,6 +36,10 @@ export interface ProjectBuilderInitOptions {
projectPreProcessors?: ProjectPreProcessor[];
/** 项目级别的后置处理器 */
projectPostProcessors?: ProjectPostProcessor[];
/** 是否处于严格模式 */
inStrictMode?: boolean;
/** 一些额外的上下文数据 */
extraContextData?: Record<string, unknown>;
}
export class ProjectBuilder implements IProjectBuilder {
@ -57,6 +61,12 @@ export class ProjectBuilder implements IProjectBuilder {
/** 项目级别的后置处理器 */
private projectPostProcessors: ProjectPostProcessor[];
/** 是否处于严格模式 */
public readonly inStrictMode: boolean;
/** 一些额外的上下文数据 */
public readonly extraContextData: IContextData;
constructor({
template,
plugins,
@ -64,6 +74,8 @@ export class ProjectBuilder implements IProjectBuilder {
schemaParser = new SchemaParser(),
projectPreProcessors = [],
projectPostProcessors = [],
inStrictMode = false,
extraContextData = {},
}: ProjectBuilderInitOptions) {
this.template = template;
this.plugins = plugins;
@ -71,6 +83,8 @@ export class ProjectBuilder implements IProjectBuilder {
this.schemaParser = schemaParser;
this.projectPreProcessors = projectPreProcessors;
this.projectPostProcessors = projectPostProcessors;
this.inStrictMode = inStrictMode;
this.extraContextData = extraContextData;
}
async generateProject(originalSchema: ProjectSchema | string): Promise<ResultDir> {
@ -264,6 +278,10 @@ export class ProjectBuilder implements IProjectBuilder {
builders[pluginName] = createModuleBuilder({
plugins: this.plugins[pluginName],
postProcessors: this.postProcessors,
contextData: {
inStrictMode: this.inStrictMode,
...this.extraContextData,
},
...options,
});
}

View File

@ -25,16 +25,8 @@ import i18n from './plugins/project/i18n';
import utils from './plugins/project/utils';
import prettier from './postprocessor/prettier';
// 引入常用工具
import * as utilsCommon from './utils/common';
import * as utilsCompositeType from './utils/compositeType';
import * as utilsJsExpression from './utils/jsExpression';
import * as utilsJsSlot from './utils/jsSlot';
import * as utilsNodeToJSX from './utils/nodeToJSX';
import * as utilsResultHelper from './utils/resultHelper';
import * as utilsTemplateHelper from './utils/templateHelper';
import * as utilsValidate from './utils/validate';
import * as utilsSchema from './utils/schema';
// 引入全局常用工具
import * as globalUtils from './utils';
import * as CONSTANTS from './const';
@ -85,17 +77,7 @@ export default {
postprocessor: {
prettier,
},
utils: {
common: utilsCommon,
compositeType: utilsCompositeType,
jsExpression: utilsJsExpression,
jsSlot: utilsJsSlot,
nodeToJSX: utilsNodeToJSX,
resultHelper: utilsResultHelper,
templateHelper: utilsTemplateHelper,
validate: utilsValidate,
schema: utilsSchema,
},
utils: globalUtils,
chunkNames: {
COMMON_CHUNK_NAME,
CLASS_DEFINE_CHUNK_NAME,

View File

@ -134,19 +134,6 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
],
});
next.chunks.push({
type: ChunkType.STRING,
fileType: FileType.JSX,
name: CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod,
content: `
_i18nText(t) {
const locale = this._context.getLocale();
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
}
`,
linkAfter: [RAX_CHUNK_NAME.ClassRenderEnd],
});
next.chunks.push({
type: ChunkType.STRING,
fileType: FileType.JSX,

View File

@ -10,6 +10,7 @@ import {
IContainerInfo,
} from '../../../types';
import { RAX_CHUNK_NAME } from './const';
import { DEFAULT_LINK_AFTER } from '../../../const';
export interface PluginConfig {
fileType: string;
@ -46,6 +47,16 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport],
});
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
content: `
__$$i18n._inject2(this);
`,
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.ConstructorContent]],
});
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,

View File

@ -29,6 +29,11 @@ import { RAX_CHUNK_NAME } from './const';
export interface PluginConfig extends RaxFrameworkOptions {
fileType?: string;
/**
* handlers
* @deprecated 使 datasourceConfig.handlersPackages
*/
dataSourceHandlersPackageMap?: Record<string, string>;
}

View File

@ -0,0 +1,62 @@
import { CLASS_DEFINE_CHUNK_NAME } from '../../../const/generator';
import { Scope } from '../../../utils/Scope';
import {
BuilderComponentPlugin,
BuilderComponentPluginFactory,
ChunkType,
FileType,
ICodeStruct,
IContainerInfo,
} from '../../../types';
export interface PluginConfig {
fileType: string;
}
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
const cfg: PluginConfig = {
fileType: FileType.JSX,
...config,
};
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
const next: ICodeStruct = {
...pre,
};
const ir = next.ir as IContainerInfo;
const scope = Scope.createRootScope();
const { inStrictMode } = next.contextData;
if (inStrictMode) {
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
content: `
_context = this._createContext();
`,
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
});
// TODO: createContext......
} else {
// 非严格模式下,上下文就是自己
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
content: `
_context = this;
`,
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
});
}
return next;
};
return plugin;
};
export default pluginFactory;

View File

@ -31,13 +31,34 @@ import { isContainerSchema } from '../../../utils/schema';
import { REACT_CHUNK_NAME } from './const';
export interface PluginConfig {
fileType: string;
fileType?: string;
/**
*
*/
datasourceConfig?: {
/** 数据源引擎的版本 */
engineVersion?: string;
/** 数据源引擎的包名 */
enginePackage?: string;
/** 数据源 handlers 的版本 */
handlersVersion?: {
[key: string]: string;
};
/** 数据源 handlers 的包名 */
handlersPackages?: {
[key: string]: string;
};
};
}
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
const cfg: PluginConfig = {
fileType: FileType.JSX,
const cfg = {
...config,
fileType: config?.fileType || FileType.JSX,
};
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
@ -65,7 +86,9 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
};
const handlerFactoryExportName = `create${changeCase.pascal(dsType)}Handler`;
const handlerPkgName = `@alilc/lowcode-datasource-${changeCase.kebab(dsType)}-handler`;
const handlerPkgName =
cfg.datasourceConfig?.handlersPackages?.[dsType] ||
`@alilc/lowcode-datasource-${changeCase.kebab(dsType)}-handler`;
next.chunks.push({
type: ChunkType.STRING,

View File

@ -33,7 +33,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
name: COMMON_CHUNK_NAME.InternalDepsImport,
// TODO: 下面这个路径有没有更好的方式来获取?而非写死
content: `
import { i18n as _$$i18n } from '../../i18n';
import * as __$$i18n from '../../i18n';
`,
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport],
});
@ -41,13 +41,11 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: CLASS_DEFINE_CHUNK_NAME.InsMethod,
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
content: `
i18n = (i18nKey) => {
return _$$i18n(i18nKey);
}
__$$i18n._inject2(this);
`,
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]],
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.ConstructorContent]],
});
return next;

View File

@ -100,8 +100,8 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
fileType: cfg.fileType,
name: REACT_CHUNK_NAME.ClassRenderJSX,
content: `
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return ${jsxContent};
`,
linkAfter: [REACT_CHUNK_NAME.ClassRenderStart, REACT_CHUNK_NAME.ClassRenderPre],

View File

@ -18,7 +18,10 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
type: ChunkType.STRING,
fileType: FileType.JSX,
name: COMMON_CHUNK_NAME.ExternalDepsImport,
content: 'import React from \'react\';',
content: `
// 注意: 出码引擎注入的临时变量默认都以 "__$$" 开头,禁止在搭建的代码中直接访问。
// 例外react 框架的导出名和各种组件名除外。
import React from \'react\';`,
linkAfter: [],
});

View File

@ -23,11 +23,9 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
fileType: FileType.JS,
name: COMMON_CHUNK_NAME.FileMainContent,
content: `
import IntlMessageFormat from 'intl-messageformat';
const i18nConfig = ${i18nStr};
let locale = 'en-US';
let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN';
const getLocale = () => locale;
@ -35,23 +33,65 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const msg = i18nConfig && i18nConfig[locale] && i18nConfig[locale][id] || defaultMessage;
const isEmptyVariables = variables => (
Array.isArray(variables) && variables.length === 0
|| typeof variables === 'object' && (!variables || Object.keys(variables).length === 0)
);
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) => (
typeof msg === 'string'
? msg.replace(/\\\$\\{(\\w+)\\}/g, (match, key) => variables?.[key] ?? '')
: msg
);
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg = i18nConfig[locale]?.[id] ?? i18nConfig[locale.replace('-', '_')]?.[id] ?? defaultMessage;
if (msg == null) {
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
return \`\${id}\`;
return fallback === undefined ? \`\${id}\` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
}
const i18n = id => {
return i18nFormat({ id });
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')]
if (localMsg != null) {
return format(localMsg, variables);
}
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || "zh_CN"] ?? t.en_US, t.params);
}
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale, setLocale: target.setLocale
});
}
}
`,
linkAfter: [
COMMON_CHUNK_NAME.ExternalDepsImport,
@ -72,6 +112,7 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
setLocale,
i18n,
i18nFormat,
_inject2,
};
`,
linkAfter: [

View File

@ -5,6 +5,7 @@ import { createProjectBuilder } from '../generator/ProjectBuilder';
import esmodule from '../plugins/common/esmodule';
import containerClass from '../plugins/component/react/containerClass';
import containerInitState from '../plugins/component/react/containerInitState';
import containerInjectContext from '../plugins/component/react/containerInjectContext';
import containerInjectUtils from '../plugins/component/react/containerInjectUtils';
import containerInjectDataSourceEngine from '../plugins/component/react/containerInjectDataSourceEngine';
import containerInjectI18n from '../plugins/component/react/containerInjectI18n';
@ -31,6 +32,7 @@ export default function createIceJsProjectBuilder(): IProjectBuilder {
fileType: 'jsx',
}),
containerClass(),
containerInjectContext(),
containerInjectUtils(),
containerInjectDataSourceEngine(),
containerInjectI18n(),
@ -53,6 +55,7 @@ export default function createIceJsProjectBuilder(): IProjectBuilder {
fileType: 'jsx',
}),
containerClass(),
containerInjectContext(),
containerInjectUtils(),
containerInjectDataSourceEngine(),
containerInjectI18n(),
@ -86,6 +89,7 @@ export default function createIceJsProjectBuilder(): IProjectBuilder {
export const plugins = {
containerClass,
containerInitState,
containerInjectContext,
containerInjectUtils,
containerInjectI18n,
containerInjectDataSourceEngine,

View File

@ -25,16 +25,8 @@ import i18n from './plugins/project/i18n';
import utils from './plugins/project/utils';
import prettier from './postprocessor/prettier';
// 引入常用工具
import * as utilsCommon from './utils/common';
import * as utilsCompositeType from './utils/compositeType';
import * as utilsJsExpression from './utils/jsExpression';
import * as utilsJsSlot from './utils/jsSlot';
import * as utilsNodeToJSX from './utils/nodeToJSX';
import * as utilsResultHelper from './utils/resultHelper';
import * as utilsTemplateHelper from './utils/templateHelper';
import * as utilsValidate from './utils/validate';
import * as utilsSchema from './utils/schema';
// 引入全局常用工具
import * as globalUtils from './utils';
import * as CONSTANTS from './const';
@ -54,7 +46,6 @@ export default {
rax,
},
publishers: {
// TODO: 增加 web 端的 zip publisher
zip: createZipPublisher,
},
plugins: {
@ -85,17 +76,7 @@ export default {
postprocessor: {
prettier,
},
utils: {
common: utilsCommon,
compositeType: utilsCompositeType,
jsExpression: utilsJsExpression,
jsSlot: utilsJsSlot,
nodeToJSX: utilsNodeToJSX,
resultHelper: utilsResultHelper,
templateHelper: utilsTemplateHelper,
validate: utilsValidate,
schema: utilsSchema,
},
utils: globalUtils,
chunkNames: {
COMMON_CHUNK_NAME,
CLASS_DEFINE_CHUNK_NAME,

View File

@ -59,8 +59,22 @@ export interface IBaseCodeStruct {
export interface ICodeStruct extends IBaseCodeStruct {
ir: any;
// FIXME: 这个方案不太好,想清楚场景,结构化表达,不要那么通用
contextData: Record<string, any>;
contextData: IContextData;
}
/** 上下文数据,用来在插件之间共享一些数据 */
export interface IContextData {
/** 是否处于严格模式 */
inStrictMode?: boolean;
/** 是否使用了 Ref 的 API (this.$/this.$$) */
useRefApi?: boolean;
/**
*
*
*/
[key: string]: any;
}
export type BuilderComponentPlugin = (initStruct: ICodeStruct) => Promise<ICodeStruct>;

View File

@ -0,0 +1 @@
declare module 'nanomatch';

View File

@ -57,7 +57,11 @@ function generateObject(
options: CompositeValueGeneratorOptions = {},
): string {
if (value.type === 'i18n') {
return `this._i18nText(${JSON.stringify(value)})`;
// params 可能会绑定变量,这里需要处理下
if (value.params && typeof value.params === 'object') {
return `this._i18nText(${generateUnknownType(_.omit(value, 'type'), scope, options)})`;
}
return `this._i18nText(${JSON.stringify(_.omit(value, 'type'))})`; // TODO: 优化:这里可以考虑提取成个常量...
}
const body = Object.keys(value)

View File

@ -0,0 +1,28 @@
// 本文件是要导出到外面的,注意只导出比较稳定的东西
import * as common from './common';
import * as compositeType from './compositeType';
import * as jsExpression from './jsExpression';
import * as jsSlot from './jsSlot';
import * as nodeToJSX from './nodeToJSX';
import * as resultHelper from './resultHelper';
import * as templateHelper from './templateHelper';
import * as validate from './validate';
import * as schema from './schema';
import * as version from './version';
import * as scope from './Scope';
import * as expressionParser from './expressionParser';
export {
common,
compositeType,
jsExpression,
jsSlot,
nodeToJSX,
resultHelper,
templateHelper,
validate,
schema,
version,
scope,
expressionParser,
};

View File

@ -1,4 +1,5 @@
import { ResultFile, ResultDir } from '@alilc/lowcode-types';
import nm from 'nanomatch';
import { CodeGeneratorError } from '../types/error';
import { FlattenFile } from '../types/file';
@ -47,12 +48,204 @@ export function flattenResult(dir: ResultDir, cwd = ''): FlattenFile[] {
return [
...dir.files.map(
(file): FlattenFile => ({
pathName: `${cwd ? `${cwd}/` : ''}${file.name}${file.ext ? `.${file.ext}` : ''}`,
pathName: joinPath(cwd, `${file.name}${file.ext ? `.${file.ext}` : ''}`),
content: file.content,
}),
),
].concat(
...dir.dirs.map((subDir) =>
flattenResult(subDir, [cwd, subDir.name].filter((x) => x !== '' && x !== '.').join('/'))),
);
].concat(...dir.dirs.map((subDir) => flattenResult(subDir, joinPath(cwd, subDir.name))));
}
export type GlobOptions = {
/** 是否查找 ".xxx" 文件, 默认: 否 */
dot?: boolean;
};
/**
*
* @param result
* @param fileGlobExpr
* @param resultDirPath '.'
* @returns null
*/
export function findFile(
result: ResultDir,
fileGlobExpr: string,
options: GlobOptions = {},
resultDirPath = getResultNameOrDefault(result, ''),
): ResultFile | null {
const maxDepth = !/\/|\*\*/.test(fileGlobExpr) ? 1 : undefined; // 如果 glob 表达式里面压根不会匹配子目录,则深度限制为 1
const files = scanFiles(result, resultDirPath, maxDepth);
for (let [filePath, file] of files) {
if (nm.isMatch(filePath, fileGlobExpr, options)) {
return file;
}
}
return null;
}
/**
* 使 glob
* @param result
* @param fileGlobExpr
* @param resultDirPath '.'
* @returns [ [, ], ... ]
*/
export function* globFiles(
result: ResultDir,
fileGlobExpr: string,
options: GlobOptions = {},
resultDirPath = getResultNameOrDefault(result, ''),
): IterableIterator<[string, ResultFile]> {
const files = scanFiles(result, resultDirPath);
for (let [filePath, file] of files) {
if (nm.isMatch(filePath, fileGlobExpr, options)) {
yield [filePath, file];
}
}
}
/**
*
*/
export function* scanFiles(
result: ResultDir,
resultDirPath = getResultNameOrDefault(result, ''),
maxDepth = 10000,
): IterableIterator<[string, ResultFile]> {
for (let file of result.files) {
const fileName = getFileNameWithExt(file);
yield [joinPath(resultDirPath, fileName), file];
}
for (let subDir of result.dirs) {
yield* scanFiles(subDir, joinPath(resultDirPath, subDir.name), maxDepth - 1);
}
}
export function getFileNameWithExt(file: ResultFile) {
return `${file.name}${file.ext ? `.${file.ext}` : ''}`;
}
function getResultNameOrDefault(result: ResultDir, defaultDir = '/') {
return result.name && result.name !== '.' ? result.name : defaultDir;
}
function joinPath(...pathParts: string[]): string {
return pathParts
.filter((x) => x !== '' && x !== '.')
.join('/')
.replace(/\\+/g, '/')
.replace(/\/+/g, '/');
}
export function* scanDirs(
result: ResultDir,
resultDirPath = getResultNameOrDefault(result, ''),
maxDepth = 10000,
): IterableIterator<[string, ResultDir]> {
yield [resultDirPath, result];
for (let subDir of result.dirs) {
yield* scanDirs(subDir, joinPath(resultDirPath, subDir.name), maxDepth - 1);
}
}
export function* globDirs(
result: ResultDir,
dirGlobExpr: string,
options: GlobOptions = {},
resultDirPath = getResultNameOrDefault(result, ''),
): IterableIterator<[string, ResultDir]> {
const dirs = scanDirs(result, resultDirPath);
for (let [dirPath, dir] of dirs) {
if (nm.isMatch(dirPath, dirGlobExpr, options)) {
yield [dirPath, dir];
}
}
}
export function findDir(
result: ResultDir,
dirGlobExpr: string,
options: GlobOptions = {},
resultDirPath = getResultNameOrDefault(result, ''),
): ResultDir | null {
const dirs = scanDirs(result, resultDirPath);
for (let [dirPath, dir] of dirs) {
if (nm.isMatch(dirPath, dirGlobExpr, options)) {
return dir;
}
}
return null;
}
/**
*
* @param result
* @param filePathGlobExpr glob
* @param globOptions glob
* @returns
*/
export function removeFilesFromResult(
result: ResultDir,
filePathGlobExpr: string,
globOptions: GlobOptions = {},
): number {
let removedCount = 0;
const [dirPath, fileName] = splitPath(filePathGlobExpr);
const dirs = dirPath ? globDirs(result, dirPath) : [['', result] as const];
for (let [, dir] of dirs) {
const files = globFiles(dir, fileName, globOptions, '.');
for (let [, file] of files) {
dir.files.splice(dir.files.indexOf(file), 1);
removedCount += 1;
}
}
return removedCount;
}
/**
*
* @param result
* @param dirPathGlobExpr glob
* @param globOptions glob
* @returns
*/
export function removeDirsFromResult(
result: ResultDir,
dirPathGlobExpr: string,
globOptions: GlobOptions = {},
): number {
let removedCount = 0;
const [dirPath, fileName] = splitPath(dirPathGlobExpr);
const dirs = dirPath ? globDirs(result, dirPath) : [['', result] as const];
for (let [, dir] of dirs) {
const foundDirs = globDirs(dir, fileName, globOptions, '.');
for (let [, foundDir] of foundDirs) {
dir.dirs.splice(dir.dirs.indexOf(foundDir), 1);
removedCount += 1;
}
}
return removedCount;
}
/**
*
* @param filePath
* @returns [fileDirPath, fileName]
*/
function splitPath(filePath: string) {
const parts = filePath.split('/');
const fileName = parts.pop() || '';
return [joinPath(...parts), fileName];
}

View File

@ -1,8 +1,6 @@
import IntlMessageFormat from 'intl-messageformat';
const i18nConfig = {};
let locale = 'en-US';
let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN';
const getLocale = () => locale;
@ -10,22 +8,61 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const msg = (i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) || defaultMessage;
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === 'object' && (!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === 'string' ? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '') : msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg = i18nConfig[locale]?.[id] ?? i18nConfig[locale.replace('-', '_')]?.[id] ?? defaultMessage;
if (msg == null) {
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || 'zh_CN'] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -33,6 +33,8 @@ class Home$$Page extends Component {
constructor(props, context) {
super(props);
__$$i18n._inject2(this);
} /* end of constructor */
componentDidMount() {
@ -63,11 +65,6 @@ class Home$$Page extends Component {
);
} /* end of render */
_i18nText(t) {
const locale = this._context.getLocale();
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
}
_createContext() {
const self = this;
const context = {

View File

@ -1,8 +1,6 @@
import IntlMessageFormat from 'intl-messageformat';
const i18nConfig = {};
let locale = 'en-US';
let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN';
const getLocale = () => locale;
@ -10,22 +8,61 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const msg = (i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) || defaultMessage;
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === 'object' && (!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === 'string' ? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '') : msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg = i18nConfig[locale]?.[id] ?? i18nConfig[locale.replace('-', '_')]?.[id] ?? defaultMessage;
if (msg == null) {
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || 'zh_CN'] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -68,6 +68,8 @@ class Home$$Page extends Component {
constructor(props, context) {
super(props);
__$$i18n._inject2(this);
} /* end of constructor */
componentDidMount() {
@ -166,11 +168,6 @@ class Home$$Page extends Component {
);
} /* end of render */
_i18nText(t) {
const locale = this._context.getLocale();
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
}
_createContext() {
const self = this;
const context = {

View File

@ -1,8 +1,6 @@
import IntlMessageFormat from 'intl-messageformat';
const i18nConfig = {};
let locale = 'en-US';
let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN';
const getLocale = () => locale;
@ -10,22 +8,61 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const msg = (i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) || defaultMessage;
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === 'object' && (!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === 'string' ? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '') : msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg = i18nConfig[locale]?.[id] ?? i18nConfig[locale.replace('-', '_')]?.[id] ?? defaultMessage;
if (msg == null) {
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || 'zh_CN'] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -37,6 +37,8 @@ class Detail$$Page extends Component {
constructor(props, context) {
super(props);
__$$i18n._inject2(this);
} /* end of constructor */
componentDidMount() {
@ -72,11 +74,6 @@ class Detail$$Page extends Component {
);
} /* end of render */
_i18nText(t) {
const locale = this._context.getLocale();
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
}
_createContext() {
const self = this;
const context = {

View File

@ -37,6 +37,8 @@ class Home$$Page extends Component {
constructor(props, context) {
super(props);
__$$i18n._inject2(this);
} /* end of constructor */
componentDidMount() {
@ -72,11 +74,6 @@ class Home$$Page extends Component {
);
} /* end of render */
_i18nText(t) {
const locale = this._context.getLocale();
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
}
_createContext() {
const self = this;
const context = {

View File

@ -37,6 +37,8 @@ class List$$Page extends Component {
constructor(props, context) {
super(props);
__$$i18n._inject2(this);
} /* end of constructor */
componentDidMount() {
@ -75,11 +77,6 @@ class List$$Page extends Component {
);
} /* end of render */
_i18nText(t) {
const locale = this._context.getLocale();
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
}
_createContext() {
const self = this;
const context = {

View File

@ -1,8 +1,6 @@
import IntlMessageFormat from 'intl-messageformat';
const i18nConfig = {};
let locale = 'en-US';
let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN';
const getLocale = () => locale;
@ -10,22 +8,61 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const msg = (i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) || defaultMessage;
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === 'object' && (!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === 'string' ? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '') : msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg = i18nConfig[locale]?.[id] ?? i18nConfig[locale.replace('-', '_')]?.[id] ?? defaultMessage;
if (msg == null) {
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || 'zh_CN'] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -35,6 +35,8 @@ class Home$$Page extends Component {
constructor(props, context) {
super(props);
__$$i18n._inject2(this);
} /* end of constructor */
componentDidMount() {
@ -67,11 +69,6 @@ class Home$$Page extends Component {
);
} /* end of render */
_i18nText(t) {
const locale = this._context.getLocale();
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
}
_createContext() {
const self = this;
const context = {

View File

@ -1,5 +1,3 @@
import IntlMessageFormat from 'intl-messageformat';
const i18nConfig = {
'zh-CN': {
'hello-world': '你好,世界!',
@ -9,7 +7,7 @@ const i18nConfig = {
},
};
let locale = 'en-US';
let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN';
const getLocale = () => locale;
@ -17,22 +15,61 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const msg = (i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) || defaultMessage;
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === 'object' && (!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === 'string' ? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '') : msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg = i18nConfig[locale]?.[id] ?? i18nConfig[locale.replace('-', '_')]?.[id] ?? defaultMessage;
if (msg == null) {
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || 'zh_CN'] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -33,6 +33,8 @@ class Home$$Page extends Component {
constructor(props, context) {
super(props);
__$$i18n._inject2(this);
} /* end of constructor */
componentDidMount() {
@ -69,11 +71,6 @@ class Home$$Page extends Component {
);
} /* end of render */
_i18nText(t) {
const locale = this._context.getLocale();
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
}
_createContext() {
const self = this;
const context = {

View File

@ -1,5 +1,3 @@
import IntlMessageFormat from 'intl-messageformat';
const i18nConfig = {
'zh-CN': {
'hello-world': '你好,世界!',
@ -9,7 +7,7 @@ const i18nConfig = {
},
};
let locale = 'en-US';
let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN';
const getLocale = () => locale;
@ -17,22 +15,61 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const msg = (i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) || defaultMessage;
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === 'object' && (!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === 'string' ? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '') : msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg = i18nConfig[locale]?.[id] ?? i18nConfig[locale.replace('-', '_')]?.[id] ?? defaultMessage;
if (msg == null) {
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || 'zh_CN'] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -35,6 +35,8 @@ class Home$$Page extends Component {
constructor(props, context) {
super(props);
__$$i18n._inject2(this);
} /* end of constructor */
componentDidMount() {
@ -75,11 +77,6 @@ class Home$$Page extends Component {
);
} /* end of render */
_i18nText(t) {
const locale = this._context.getLocale();
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
}
_createContext() {
const self = this;
const context = {

View File

@ -1,5 +1,3 @@
import IntlMessageFormat from 'intl-messageformat';
const i18nConfig = {
'zh-CN': {
'hello-world': '你好,世界!',
@ -9,7 +7,7 @@ const i18nConfig = {
},
};
let locale = 'en-US';
let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN';
const getLocale = () => locale;
@ -17,22 +15,61 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const msg = (i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) || defaultMessage;
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === 'object' && (!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === 'string' ? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '') : msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg = i18nConfig[locale]?.[id] ?? i18nConfig[locale.replace('-', '_')]?.[id] ?? defaultMessage;
if (msg == null) {
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || 'zh_CN'] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -33,6 +33,8 @@ class Home$$Page extends Component {
constructor(props, context) {
super(props);
__$$i18n._inject2(this);
} /* end of constructor */
componentDidMount() {
@ -69,11 +71,6 @@ class Home$$Page extends Component {
);
} /* end of render */
_i18nText(t) {
const locale = this._context.getLocale();
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
}
_createContext() {
const self = this;
const context = {

View File

@ -1,5 +1,3 @@
import IntlMessageFormat from 'intl-messageformat';
const i18nConfig = {
'zh-CN': {
'hello-world': '你好,世界!',
@ -9,7 +7,7 @@ const i18nConfig = {
},
};
let locale = 'en-US';
let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN';
const getLocale = () => locale;
@ -17,22 +15,61 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const msg = (i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) || defaultMessage;
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === 'object' && (!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === 'string' ? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '') : msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg = i18nConfig[locale]?.[id] ?? i18nConfig[locale.replace('-', '_')]?.[id] ?? defaultMessage;
if (msg == null) {
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || 'zh_CN'] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -35,6 +35,8 @@ class Home$$Page extends Component {
constructor(props, context) {
super(props);
__$$i18n._inject2(this);
} /* end of constructor */
componentDidMount() {
@ -75,11 +77,6 @@ class Home$$Page extends Component {
);
} /* end of render */
_i18nText(t) {
const locale = this._context.getLocale();
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
}
_createContext() {
const self = this;
const context = {

View File

@ -1,5 +1,3 @@
import IntlMessageFormat from 'intl-messageformat';
const i18nConfig = {
'zh-CN': {
'hello-world': '你好,世界!',
@ -9,7 +7,7 @@ const i18nConfig = {
},
};
let locale = 'en-US';
let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN';
const getLocale = () => locale;
@ -17,22 +15,61 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const msg = (i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) || defaultMessage;
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === 'object' && (!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === 'string' ? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '') : msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg = i18nConfig[locale]?.[id] ?? i18nConfig[locale.replace('-', '_')]?.[id] ?? defaultMessage;
if (msg == null) {
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || 'zh_CN'] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -35,6 +35,8 @@ class Home$$Page extends Component {
constructor(props, context) {
super(props);
__$$i18n._inject2(this);
} /* end of constructor */
componentDidMount() {
@ -78,11 +80,6 @@ class Home$$Page extends Component {
);
} /* end of render */
_i18nText(t) {
const locale = this._context.getLocale();
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
}
_createContext() {
const self = this;
const context = {

View File

@ -1,5 +1,3 @@
import IntlMessageFormat from 'intl-messageformat';
const i18nConfig = {
'zh-CN': {
'hello-world': '你好,世界!',
@ -9,7 +7,7 @@ const i18nConfig = {
},
};
let locale = 'en-US';
let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN';
const getLocale = () => locale;
@ -17,22 +15,61 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const msg = (i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) || defaultMessage;
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === 'object' && (!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === 'string' ? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '') : msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg = i18nConfig[locale]?.[id] ?? i18nConfig[locale.replace('-', '_')]?.[id] ?? defaultMessage;
if (msg == null) {
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || 'zh_CN'] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -35,6 +35,8 @@ class Home$$Page extends Component {
constructor(props, context) {
super(props);
__$$i18n._inject2(this);
} /* end of constructor */
componentDidMount() {
@ -80,11 +82,6 @@ class Home$$Page extends Component {
);
} /* end of render */
_i18nText(t) {
const locale = this._context.getLocale();
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
}
_createContext() {
const self = this;
const context = {

View File

@ -1,8 +1,6 @@
import IntlMessageFormat from 'intl-messageformat';
const i18nConfig = {};
let locale = 'en-US';
let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN';
const getLocale = () => locale;
@ -10,22 +8,61 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const msg = (i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) || defaultMessage;
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === 'object' && (!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === 'string' ? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '') : msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg = i18nConfig[locale]?.[id] ?? i18nConfig[locale.replace('-', '_')]?.[id] ?? defaultMessage;
if (msg == null) {
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || 'zh_CN'] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -40,6 +40,8 @@ class Aaaa$$Page extends Component {
constructor(props, context) {
super(props);
__$$i18n._inject2(this);
} /* end of constructor */
componentDidMount() {
@ -70,11 +72,6 @@ class Aaaa$$Page extends Component {
);
} /* end of render */
_i18nText(t) {
const locale = this._context.getLocale();
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
}
_createContext() {
const self = this;
const context = {

View File

@ -1,5 +1,3 @@
import IntlMessageFormat from 'intl-messageformat';
const i18nConfig = {
'zh-CN': {
'hello-world': '你好,世界!',
@ -9,7 +7,7 @@ const i18nConfig = {
},
};
let locale = 'en-US';
let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN';
const getLocale = () => locale;
@ -17,22 +15,61 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const msg = (i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) || defaultMessage;
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === 'object' && (!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === 'string' ? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '') : msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg = i18nConfig[locale]?.[id] ?? i18nConfig[locale.replace('-', '_')]?.[id] ?? defaultMessage;
if (msg == null) {
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || 'zh_CN'] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -33,6 +33,8 @@ class Home$$Page extends Component {
constructor(props, context) {
super(props);
__$$i18n._inject2(this);
} /* end of constructor */
componentDidMount() {
@ -70,11 +72,6 @@ class Home$$Page extends Component {
);
} /* end of render */
_i18nText(t) {
const locale = this._context.getLocale();
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
}
_createContext() {
const self = this;
const context = {

View File

@ -1,8 +1,6 @@
import IntlMessageFormat from 'intl-messageformat';
const i18nConfig = {};
let locale = 'en-US';
let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN';
const getLocale = () => locale;
@ -10,22 +8,61 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const msg = (i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) || defaultMessage;
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === 'object' && (!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === 'string' ? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '') : msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg = i18nConfig[locale]?.[id] ?? i18nConfig[locale.replace('-', '_')]?.[id] ?? defaultMessage;
if (msg == null) {
console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace('-', '_')];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || 'zh_CN'] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -36,6 +36,8 @@ class Example$$Page extends Component {
constructor(props, context) {
super(props);
__$$i18n._inject2(this);
} /* end of constructor */
componentDidMount() {
@ -72,11 +74,6 @@ class Example$$Page extends Component {
);
} /* end of render */
_i18nText(t) {
const locale = this._context.getLocale();
return t[locale] ?? t[String(locale).replace('-', '_')] ?? t[t.use || 'zh_CN'] ?? t.en_US;
}
_createContext() {
const self = this;
const context = {

View File

@ -1,8 +1,9 @@
import IntlMessageFormat from "intl-messageformat";
const i18nConfig = {};
let locale = "en-US";
let locale =
typeof navigator === "object" && typeof navigator.language === "string"
? navigator.language
: "zh-CN";
const getLocale = () => locale;
@ -10,24 +11,67 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === "object" &&
(!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === "string"
? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? "")
: msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg =
(i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) ||
i18nConfig[locale]?.[id] ??
i18nConfig[locale.replace("-", "_")]?.[id] ??
defaultMessage;
if (msg == null) {
console.warn("[i18n]: unknown message id: %o (locale=%o)", id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace("-", "_")];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || "zh_CN"] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -1,3 +1,5 @@
// : "__$$" 访
// react
import React from "react";
import { Form, Input, NumberPicker, Select, Button } from "@alifd/next";
@ -10,11 +12,13 @@ import { create as __$$createDataSourceEngine } from "@alilc/lowcode-datasource-
import utils, { RefsManager } from "../../utils";
import { i18n as _$$i18n } from "../../i18n";
import * as __$$i18n from "../../i18n";
import "./index.css";
class Test$$Page extends React.Component {
_context = this;
_dataSourceConfig = this._defineDataSourceConfig();
_dataSourceEngine = __$$createDataSourceEngine(this._dataSourceConfig, this, {
runtimeConfig: true,
@ -39,6 +43,8 @@ class Test$$Page extends React.Component {
this._refsManager = new RefsManager();
__$$i18n._inject2(this);
this.state = { text: "outter" };
}
@ -113,10 +119,6 @@ class Test$$Page extends React.Component {
};
}
i18n = (i18nKey) => {
return _$$i18n(i18nKey);
};
componentDidMount() {
this._dataSourceEngine.reloadDataSource();
@ -124,8 +126,8 @@ class Test$$Page extends React.Component {
}
render() {
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return (
<div ref={this._refsManager.linkRef("outterView")} autoLoading={true}>
<Form

View File

@ -1,8 +1,9 @@
import IntlMessageFormat from "intl-messageformat";
const i18nConfig = {};
let locale = "en-US";
let locale =
typeof navigator === "object" && typeof navigator.language === "string"
? navigator.language
: "zh-CN";
const getLocale = () => locale;
@ -10,24 +11,67 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === "object" &&
(!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === "string"
? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? "")
: msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg =
(i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) ||
i18nConfig[locale]?.[id] ??
i18nConfig[locale.replace("-", "_")]?.[id] ??
defaultMessage;
if (msg == null) {
console.warn("[i18n]: unknown message id: %o (locale=%o)", id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace("-", "_")];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || "zh_CN"] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -1,3 +1,5 @@
// : "__$$" 访
// react
import React from "react";
import { Page } from "@alilc/b6-page";
@ -10,11 +12,13 @@ import { create as __$$createDataSourceEngine } from "@alilc/lowcode-datasource-
import utils from "../../utils";
import { i18n as _$$i18n } from "../../i18n";
import * as __$$i18n from "../../i18n";
import "./index.css";
class Aaaa$$Page extends React.Component {
_context = this;
_dataSourceConfig = this._defineDataSourceConfig();
_dataSourceEngine = __$$createDataSourceEngine(this._dataSourceConfig, this, {
runtimeConfig: true,
@ -36,6 +40,8 @@ class Aaaa$$Page extends React.Component {
this.utils = utils;
__$$i18n._inject2(this);
this.state = {};
}
@ -60,17 +66,13 @@ class Aaaa$$Page extends React.Component {
};
}
i18n = (i18nKey) => {
return _$$i18n(i18nKey);
};
componentDidMount() {
this._dataSourceEngine.reloadDataSource();
}
render() {
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return (
<div title="" backgroundColor="#fff" textColor="#333" style={{}}>
<Text

View File

@ -1,5 +1,3 @@
import IntlMessageFormat from "intl-messageformat";
const i18nConfig = {
"zh-CN": {
"i18n-jwg27yo4": "你好",
@ -11,7 +9,10 @@ const i18nConfig = {
},
};
let locale = "en-US";
let locale =
typeof navigator === "object" && typeof navigator.language === "string"
? navigator.language
: "zh-CN";
const getLocale = () => locale;
@ -19,24 +20,67 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === "object" &&
(!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === "string"
? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? "")
: msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg =
(i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) ||
i18nConfig[locale]?.[id] ??
i18nConfig[locale.replace("-", "_")]?.[id] ??
defaultMessage;
if (msg == null) {
console.warn("[i18n]: unknown message id: %o (locale=%o)", id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace("-", "_")];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || "zh_CN"] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -1,14 +1,18 @@
// : "__$$" 访
// react
import React from "react";
import { Form, Input, NumberPicker, Select, Button } from "@alifd/next";
import utils, { RefsManager } from "../../utils";
import { i18n as _$$i18n } from "../../i18n";
import * as __$$i18n from "../../i18n";
import "./index.css";
class Test$$Page extends React.Component {
_context = this;
constructor(props, context) {
super(props);
@ -16,6 +20,8 @@ class Test$$Page extends React.Component {
this._refsManager = new RefsManager();
__$$i18n._inject2(this);
this.state = { text: "outter" };
}
@ -27,17 +33,13 @@ class Test$$Page extends React.Component {
return this._refsManager.getAll(refName);
};
i18n = (i18nKey) => {
return _$$i18n(i18nKey);
};
componentDidMount() {
console.log("componentDidMount");
}
render() {
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return (
<div ref={this._refsManager.linkRef("outterView")} autoLoading={true}>
<Form

View File

@ -1,5 +1,3 @@
import IntlMessageFormat from "intl-messageformat";
const i18nConfig = {
"zh-CN": {
"i18n-jwg27yo4": "你好",
@ -11,7 +9,10 @@ const i18nConfig = {
},
};
let locale = "en-US";
let locale =
typeof navigator === "object" && typeof navigator.language === "string"
? navigator.language
: "zh-CN";
const getLocale = () => locale;
@ -19,24 +20,67 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === "object" &&
(!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === "string"
? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? "")
: msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg =
(i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) ||
i18nConfig[locale]?.[id] ??
i18nConfig[locale.replace("-", "_")]?.[id] ??
defaultMessage;
if (msg == null) {
console.warn("[i18n]: unknown message id: %o (locale=%o)", id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace("-", "_")];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || "zh_CN"] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -1,3 +1,5 @@
// : "__$$" 访
// react
import React from "react";
import Super, {
@ -13,7 +15,7 @@ import SuperOther from "@alifd/next";
import utils from "../../utils";
import { i18n as _$$i18n } from "../../i18n";
import * as __$$i18n from "../../i18n";
import "./index.css";
@ -24,23 +26,23 @@ const SelectOption = Select.Option;
const SearchTable = SearchTableExport.default;
class Test$$Page extends React.Component {
_context = this;
constructor(props, context) {
super(props);
this.utils = utils;
__$$i18n._inject2(this);
this.state = {};
}
i18n = (i18nKey) => {
return _$$i18n(i18nKey);
};
componentDidMount() {}
render() {
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return (
<div>
<Super title={this.state.title} />

View File

@ -1,8 +1,9 @@
import IntlMessageFormat from "intl-messageformat";
const i18nConfig = {};
let locale = "en-US";
let locale =
typeof navigator === "object" && typeof navigator.language === "string"
? navigator.language
: "zh-CN";
const getLocale = () => locale;
@ -10,24 +11,67 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === "object" &&
(!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === "string"
? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? "")
: msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg =
(i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) ||
i18nConfig[locale]?.[id] ??
i18nConfig[locale.replace("-", "_")]?.[id] ??
defaultMessage;
if (msg == null) {
console.warn("[i18n]: unknown message id: %o (locale=%o)", id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace("-", "_")];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || "zh_CN"] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -1,3 +1,5 @@
// : "__$$" 访
// react
import React from "react";
import {
@ -15,7 +17,7 @@ import { create as __$$createDataSourceEngine } from "@alilc/lowcode-datasource-
import utils, { RefsManager } from "../../utils";
import { i18n as _$$i18n } from "../../i18n";
import * as __$$i18n from "../../i18n";
import "./index.css";
@ -24,6 +26,8 @@ const NextBlockCell = NextBlock.Cell;
const AliSearchTable = AliSearchTableExport.default;
class Test$$Page extends React.Component {
_context = this;
_dataSourceConfig = this._defineDataSourceConfig();
_dataSourceEngine = __$$createDataSourceEngine(this._dataSourceConfig, this, {
runtimeConfig: true,
@ -45,6 +49,8 @@ class Test$$Page extends React.Component {
this._refsManager = new RefsManager();
__$$i18n._inject2(this);
this.state = { text: "outter", isShowDialog: false };
}
@ -81,10 +87,6 @@ class Test$$Page extends React.Component {
};
}
i18n = (i18nKey) => {
return _$$i18n(i18nKey);
};
componentWillUnmount() {
console.log("will umount");
}
@ -133,8 +135,8 @@ class Test$$Page extends React.Component {
}
render() {
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return (
<div
ref={this._refsManager.linkRef("outterView")}

View File

@ -1,8 +1,9 @@
import IntlMessageFormat from "intl-messageformat";
const i18nConfig = {};
let locale = "en-US";
let locale =
typeof navigator === "object" && typeof navigator.language === "string"
? navigator.language
: "zh-CN";
const getLocale = () => locale;
@ -10,24 +11,67 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === "object" &&
(!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === "string"
? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? "")
: msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg =
(i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) ||
i18nConfig[locale]?.[id] ??
i18nConfig[locale.replace("-", "_")]?.[id] ??
defaultMessage;
if (msg == null) {
console.warn("[i18n]: unknown message id: %o (locale=%o)", id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace("-", "_")];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || "zh_CN"] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -1,3 +1,5 @@
// : "__$$" 访
// react
import React from "react";
import {
@ -22,7 +24,7 @@ import { AliAutoSearchTable } from "@alife/mc-assets-1935/build/lowcode/index.js
import utils, { RefsManager } from "../../utils";
import { i18n as _$$i18n } from "../../i18n";
import * as __$$i18n from "../../i18n";
import "./index.css";
@ -31,6 +33,8 @@ const NextBlockCell = NextBlock.Cell;
const AliAutoSearchTableDefault = AliAutoSearchTable.default;
class Test$$Page extends React.Component {
_context = this;
constructor(props, context) {
super(props);
@ -38,6 +42,8 @@ class Test$$Page extends React.Component {
this._refsManager = new RefsManager();
__$$i18n._inject2(this);
this.state = {
name: "nongzhou",
gateways: [],
@ -55,10 +61,6 @@ class Test$$Page extends React.Component {
return this._refsManager.getAll(refName);
};
i18n = (i18nKey) => {
return _$$i18n(i18nKey);
};
componentWillUnmount() {
/* ... */
}
@ -90,8 +92,8 @@ class Test$$Page extends React.Component {
componentDidMount() {}
render() {
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return (
<div
ref={this._refsManager.linkRef("outterView")}

View File

@ -1,8 +1,9 @@
import IntlMessageFormat from "intl-messageformat";
const i18nConfig = {};
let locale = "en-US";
let locale =
typeof navigator === "object" && typeof navigator.language === "string"
? navigator.language
: "zh-CN";
const getLocale = () => locale;
@ -10,24 +11,67 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === "object" &&
(!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === "string"
? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? "")
: msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg =
(i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) ||
i18nConfig[locale]?.[id] ??
i18nConfig[locale.replace("-", "_")]?.[id] ??
defaultMessage;
if (msg == null) {
console.warn("[i18n]: unknown message id: %o (locale=%o)", id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace("-", "_")];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || "zh_CN"] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -1,3 +1,5 @@
// : "__$$" 访
// react
import React from "react";
import { Form, Input, NumberPicker, Select, Button } from "@alifd/next";
@ -10,11 +12,13 @@ import { create as __$$createDataSourceEngine } from "@alilc/lowcode-datasource-
import utils, { RefsManager } from "../../utils";
import { i18n as _$$i18n } from "../../i18n";
import * as __$$i18n from "../../i18n";
import "./index.css";
class Test$$Page extends React.Component {
_context = this;
_dataSourceConfig = this._defineDataSourceConfig();
_dataSourceEngine = __$$createDataSourceEngine(this._dataSourceConfig, this, {
runtimeConfig: true,
@ -39,6 +43,8 @@ class Test$$Page extends React.Component {
this._refsManager = new RefsManager();
__$$i18n._inject2(this);
this.state = { text: "outter" };
}
@ -113,10 +119,6 @@ class Test$$Page extends React.Component {
};
}
i18n = (i18nKey) => {
return _$$i18n(i18nKey);
};
componentDidMount() {
this._dataSourceEngine.reloadDataSource();
@ -124,8 +126,8 @@ class Test$$Page extends React.Component {
}
render() {
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return (
<div ref={this._refsManager.linkRef("outterView")} autoLoading={true}>
<Form

View File

@ -1,8 +1,9 @@
import IntlMessageFormat from "intl-messageformat";
const i18nConfig = {};
let locale = "en-US";
let locale =
typeof navigator === "object" && typeof navigator.language === "string"
? navigator.language
: "zh-CN";
const getLocale = () => locale;
@ -10,24 +11,67 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === "object" &&
(!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === "string"
? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? "")
: msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg =
(i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) ||
i18nConfig[locale]?.[id] ??
i18nConfig[locale.replace("-", "_")]?.[id] ??
defaultMessage;
if (msg == null) {
console.warn("[i18n]: unknown message id: %o (locale=%o)", id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace("-", "_")];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || "zh_CN"] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -1,3 +1,5 @@
// : "__$$" 访
// react
import React from "react";
import {
@ -21,13 +23,15 @@ import {
import utils, { RefsManager } from "../../utils";
import { i18n as _$$i18n } from "../../i18n";
import * as __$$i18n from "../../i18n";
import "./index.css";
const NextBlockCell = NextBlock.Cell;
class Test$$Page extends React.Component {
_context = this;
constructor(props, context) {
super(props);
@ -35,6 +39,8 @@ class Test$$Page extends React.Component {
this._refsManager = new RefsManager();
__$$i18n._inject2(this);
this.state = {
books: [],
currentStep: 0,
@ -97,10 +103,6 @@ class Test$$Page extends React.Component {
return this._refsManager.getAll(refName);
};
i18n = (i18nKey) => {
return _$$i18n(i18nKey);
};
componentDidUpdate(prevProps, prevState, snapshot) {}
componentWillUnmount() {}
@ -189,8 +191,8 @@ class Test$$Page extends React.Component {
componentDidMount() {}
render() {
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return (
<div
ref={this._refsManager.linkRef("outterView")}

View File

@ -1,8 +1,9 @@
import IntlMessageFormat from "intl-messageformat";
const i18nConfig = {};
let locale = "en-US";
let locale =
typeof navigator === "object" && typeof navigator.language === "string"
? navigator.language
: "zh-CN";
const getLocale = () => locale;
@ -10,24 +11,67 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === "object" &&
(!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === "string"
? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? "")
: msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg =
(i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) ||
i18nConfig[locale]?.[id] ??
i18nConfig[locale.replace("-", "_")]?.[id] ??
defaultMessage;
if (msg == null) {
console.warn("[i18n]: unknown message id: %o (locale=%o)", id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace("-", "_")];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || "zh_CN"] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -1,3 +1,5 @@
// : "__$$" 访
// react
import React from "react";
import { Page, Table } from "@alilc/lowcode-components";
@ -8,11 +10,13 @@ import { create as __$$createDataSourceEngine } from "@alilc/lowcode-datasource-
import utils from "../../utils";
import { i18n as _$$i18n } from "../../i18n";
import * as __$$i18n from "../../i18n";
import "./index.css";
class Example$$Page extends React.Component {
_context = this;
_dataSourceConfig = this._defineDataSourceConfig();
_dataSourceEngine = __$$createDataSourceEngine(this._dataSourceConfig, this, {
runtimeConfig: true,
@ -32,6 +36,8 @@ class Example$$Page extends React.Component {
this.utils = utils;
__$$i18n._inject2(this);
this.state = {};
}
@ -56,17 +62,13 @@ class Example$$Page extends React.Component {
};
}
i18n = (i18nKey) => {
return _$$i18n(i18nKey);
};
componentDidMount() {
this._dataSourceEngine.reloadDataSource();
}
render() {
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return (
<div>
<Table

View File

@ -1,3 +1,5 @@
// : "__$$" 访
// react
import React from "react";
import { Switch } from "@alifd/next";
@ -8,11 +10,13 @@ import { create as __$$createDataSourceEngine } from "@alilc/lowcode-datasource-
import utils from "../../utils";
import { i18n as _$$i18n } from "../../i18n";
import * as __$$i18n from "../../i18n";
import "./index.css";
class Index$$Page extends React.Component {
_context = this;
_dataSourceConfig = this._defineDataSourceConfig();
_dataSourceEngine = __$$createDataSourceEngine(this._dataSourceConfig, this, {
runtimeConfig: true,
@ -32,6 +36,8 @@ class Index$$Page extends React.Component {
this.utils = utils;
__$$i18n._inject2(this);
this.state = {};
}
@ -59,17 +65,13 @@ class Index$$Page extends React.Component {
};
}
i18n = (i18nKey) => {
return _$$i18n(i18nKey);
};
componentDidMount() {
this._dataSourceEngine.reloadDataSource();
}
render() {
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return (
<div>
<div>

View File

@ -1,8 +1,9 @@
import IntlMessageFormat from "intl-messageformat";
const i18nConfig = {};
let locale = "en-US";
let locale =
typeof navigator === "object" && typeof navigator.language === "string"
? navigator.language
: "zh-CN";
const getLocale = () => locale;
@ -10,24 +11,67 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === "object" &&
(!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === "string"
? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? "")
: msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg =
(i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) ||
i18nConfig[locale]?.[id] ??
i18nConfig[locale.replace("-", "_")]?.[id] ??
defaultMessage;
if (msg == null) {
console.warn("[i18n]: unknown message id: %o (locale=%o)", id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace("-", "_")];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || "zh_CN"] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -1,8 +1,9 @@
import IntlMessageFormat from "intl-messageformat";
const i18nConfig = {};
let locale = "en-US";
let locale =
typeof navigator === "object" && typeof navigator.language === "string"
? navigator.language
: "zh-CN";
const getLocale = () => locale;
@ -10,24 +11,67 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === "object" &&
(!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === "string"
? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? "")
: msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg =
(i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) ||
i18nConfig[locale]?.[id] ??
i18nConfig[locale.replace("-", "_")]?.[id] ??
defaultMessage;
if (msg == null) {
console.warn("[i18n]: unknown message id: %o (locale=%o)", id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace("-", "_")];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || "zh_CN"] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -1,3 +1,5 @@
// : "__$$" 访
// react
import React from "react";
import {
@ -25,7 +27,7 @@ import {
import utils, { RefsManager } from "../../utils";
import { i18n as _$$i18n } from "../../i18n";
import * as __$$i18n from "../../i18n";
import "./index.css";
@ -36,6 +38,8 @@ const AliAutoSearchTableDefault = AliAutoSearchTable.default;
const NextBlockCell = NextBlock.Cell;
class Test$$Page extends React.Component {
_context = this;
constructor(props, context) {
super(props);
@ -43,6 +47,8 @@ class Test$$Page extends React.Component {
this._refsManager = new RefsManager();
__$$i18n._inject2(this);
this.state = {
pkgs: [],
total: 0,
@ -71,10 +77,6 @@ class Test$$Page extends React.Component {
return this._refsManager.getAll(refName);
};
i18n = (i18nKey) => {
return _$$i18n(i18nKey);
};
componentDidUpdate(prevProps, prevState, snapshot) {}
componentWillUnmount() {}
@ -181,8 +183,8 @@ class Test$$Page extends React.Component {
}
render() {
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return (
<div
ref={this._refsManager.linkRef("outterView")}

View File

@ -1,8 +1,9 @@
import IntlMessageFormat from "intl-messageformat";
const i18nConfig = {};
let locale = "en-US";
let locale =
typeof navigator === "object" && typeof navigator.language === "string"
? navigator.language
: "zh-CN";
const getLocale = () => locale;
@ -10,24 +11,67 @@ const setLocale = (target) => {
locale = target;
};
const i18nFormat = ({ id, defaultMessage }, variables) => {
const isEmptyVariables = (variables) =>
(Array.isArray(variables) && variables.length === 0) ||
(typeof variables === "object" &&
(!variables || Object.keys(variables).length === 0));
// 按低代码规范里面的要求进行变量替换
const format = (msg, variables) =>
typeof msg === "string"
? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? "")
: msg;
const i18nFormat = ({ id, defaultMessage, fallback }, variables) => {
const msg =
(i18nConfig && i18nConfig[locale] && i18nConfig[locale][id]) ||
i18nConfig[locale]?.[id] ??
i18nConfig[locale.replace("-", "_")]?.[id] ??
defaultMessage;
if (msg == null) {
console.warn("[i18n]: unknown message id: %o (locale=%o)", id, locale);
return `${id}`;
return fallback === undefined ? `${id}` : fallback;
}
if (!variables || !variables.length) {
return msg;
return format(msg, variables);
};
const i18n = (id, params) => {
return i18nFormat({ id }, params);
};
// 将国际化的一些方法注入到目标对象&上下文中
const _inject2 = (target) => {
target.i18n = i18n;
target.getLocale = getLocale;
target.setLocale = (locale) => {
setLocale(locale);
target.forceUpdate();
};
target._i18nText = (t) => {
// 优先取直接传过来的语料
const localMsg = t[locale] ?? t[String(locale).replace("-", "_")];
if (localMsg != null) {
return format(localMsg, variables);
}
return new IntlMessageFormat(msg, locale).format(variables);
// 其次用项目级别的
const projectMsg = i18nFormat({ id: t.key, fallback: null }, t.params);
if (projectMsg != null) {
return projectMsg;
}
// 兜底用 use 指定的或默认语言的
return format(t[t.use || "zh_CN"] ?? t.en_US, t.params);
};
const i18n = (id) => {
return i18nFormat({ id });
// 注入到上下文中去
if (target._context && target._context !== target) {
Object.assign(target._context, {
i18n,
getLocale,
setLocale: target.setLocale,
});
}
};
export { getLocale, setLocale, i18n, i18nFormat };
export { getLocale, setLocale, i18n, i18nFormat, _inject2 };

View File

@ -1,3 +1,5 @@
// : "__$$" 访
// react
import React from "react";
import {
@ -25,7 +27,7 @@ import {
import utils, { RefsManager } from "../../utils";
import { i18n as _$$i18n } from "../../i18n";
import * as __$$i18n from "../../i18n";
import "./index.css";
@ -36,6 +38,8 @@ const AliAutoSearchTableDefault = AliAutoSearchTable.default;
const NextBlockCell = NextBlock.Cell;
class Test$$Page extends React.Component {
_context = this;
constructor(props, context) {
super(props);
@ -43,6 +47,8 @@ class Test$$Page extends React.Component {
this._refsManager = new RefsManager();
__$$i18n._inject2(this);
this.state = {
pkgs: [],
total: 0,
@ -79,10 +85,6 @@ class Test$$Page extends React.Component {
return this._refsManager.getAll(refName);
};
i18n = (i18nKey) => {
return _$$i18n(i18nKey);
};
componentDidUpdate(prevProps, prevState, snapshot) {}
componentWillUnmount() {}
@ -207,8 +209,8 @@ class Test$$Page extends React.Component {
}
render() {
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return (
<div
ref={this._refsManager.linkRef("outterView")}

View File

@ -0,0 +1,52 @@
{
"version": "1.0.0",
"componentsMap": [
{
"package": "react-greetings",
"version": "1.0.0",
"componentName": "Greetings",
"exportName": "Greetings",
"destructuring": true
}
],
"componentsTree": [
{
"componentName": "Page",
"id": "node_ocl137q7oc1",
"fileName": "test",
"props": { "style": {} },
"lifeCycles": {},
"dataSource": { "list": [] },
"state": {
"name": "lowcode world"
},
"methods": {},
"children": [
{
"componentName": "Greetings",
"id": "node_ocl137q7oc4",
"props": {
"content": {
"type": "i18n",
"key": "greetings.hello",
"params": {
"name": {
"type": "JSExpression",
"value": "this.state.name"
}
}
}
}
}
]
}
],
"i18n": {
"zh_CN": {
"greetings.hello": "${name}, 你好!"
},
"en_US": {
"greetings.hello": "Hello, ${name}!"
}
}
}

View File

@ -0,0 +1,54 @@
import CodeGenerator from '../../src';
import * as fs from 'fs';
import * as path from 'path';
import { ProjectSchema } from '@alilc/lowcode-types';
import { createDiskPublisher } from '../helpers/solutionHelper';
const testCaseBaseName = path.basename(__filename, '.test.ts');
const inputSchemaJsonFile = path.join(__dirname, `${testCaseBaseName}.schema.json`);
const outputDir = path.join(__dirname, `${testCaseBaseName}.generated`);
jest.setTimeout(60 * 60 * 1000);
describe(testCaseBaseName, () => {
test('default import', async () => {
await exportProject(inputSchemaJsonFile, outputDir, {});
const generatedPageFileContent = readOutputTextFile('demo-project/src/pages/Test/index.jsx');
expect(generatedPageFileContent).toContain(
`
<Greetings
content={this._i18nText({
key: "greetings.hello",
params: { name: this.state.name },
})}
/>
`.trim(),
);
});
});
function exportProject(
importPath: string,
outputPath: string,
mergeSchema?: Partial<ProjectSchema>,
) {
const schemaJsonStr = fs.readFileSync(importPath, { encoding: 'utf8' });
const schema = { ...JSON.parse(schemaJsonStr), ...mergeSchema };
const builder = CodeGenerator.solutions.icejs();
return builder.generateProject(schema).then(async (result) => {
const publisher = createDiskPublisher();
await publisher.publish({
project: result,
outputPath,
projectSlug: 'demo-project',
createProjectFolder: true,
});
return result;
});
}
function readOutputTextFile(outputFilePath: string): string {
return fs.readFileSync(path.resolve(outputDir, outputFilePath), 'utf-8');
}

View File

@ -2,6 +2,7 @@ import CodeGenerator from '../../src';
import * as fs from 'fs';
import * as path from 'path';
import { ProjectSchema } from '@alilc/lowcode-types';
import { createDiskPublisher } from '../helpers/solutionHelper';
const testCaseBaseName = path.basename(__filename, '.test.ts');
const inputSchemaJsonFile = path.join(__dirname, `${testCaseBaseName}.schema.json`);
@ -205,7 +206,7 @@ function exportProject(
return builder.generateProject(schema).then(async (result) => {
// displayResultInConsole(result);
const publisher = CodeGenerator.publishers.disk();
const publisher = createDiskPublisher();
await publisher.publish({
project: result,
outputPath,

View File

@ -1,6 +1,7 @@
import CodeGenerator from '../../src';
import * as fs from 'fs';
import * as path from 'path';
import { createDiskPublisher } from '../helpers/solutionHelper';
const testCaseBaseName = path.basename(__filename, '.test.ts');
@ -31,7 +32,7 @@ function exportProject(inputPath: string, outputPath: string) {
return builder.generateProject(newSchema).then(async (result) => {
// displayResultInConsole(result);
const publisher = CodeGenerator.publishers.disk();
const publisher = createDiskPublisher();
await publisher.publish({
project: result,
outputPath,

View File

@ -1,6 +1,7 @@
import CodeGenerator from '../../src';
import * as fs from 'fs';
import * as path from 'path';
import { createDiskPublisher } from '../helpers/solutionHelper';
const testCaseBaseName = path.basename(__filename, '.test.ts');
@ -31,7 +32,7 @@ function exportProject(inputPath: string, outputPath: string) {
return builder.generateProject(newSchema).then(async (result) => {
// displayResultInConsole(result);
const publisher = CodeGenerator.publishers.disk();
const publisher = createDiskPublisher();
await publisher.publish({
project: result,
outputPath,

View File

@ -1,6 +1,7 @@
import CodeGenerator from '../../src';
import * as fs from 'fs';
import * as path from 'path';
import { createDiskPublisher } from '../helpers/solutionHelper';
const testCaseBaseName = path.basename(__filename, '.test.ts');
@ -37,7 +38,7 @@ function exportProject(inputPath: string, outputPath: string) {
return builder.generateProject(newSchema).then(async (result) => {
// displayResultInConsole(result);
const publisher = CodeGenerator.publishers.disk();
const publisher = createDiskPublisher();
await publisher.publish({
project: result,
outputPath,

View File

@ -1,6 +1,7 @@
import CodeGenerator from '../../src';
import * as fs from 'fs';
import * as path from 'path';
import { createDiskPublisher } from '../helpers/solutionHelper';
const testCaseBaseName = path.basename(__filename, '.test.ts');
@ -25,7 +26,7 @@ function exportProject(inputPath: string, outputPath: string) {
return builder.generateProject(newSchema).then(async (result) => {
// displayResultInConsole(result);
const publisher = CodeGenerator.publishers.disk();
const publisher = createDiskPublisher();
await publisher.publish({
project: result,
outputPath,

View File

@ -1,6 +1,7 @@
import CodeGenerator from '../../src';
import * as fs from 'fs';
import * as path from 'path';
import { createDiskPublisher } from '../helpers/solutionHelper';
test('page-element1', async () => {
const inputSchemaJsonFile = path.join(__dirname, 'page-element1.schema.json');
@ -67,7 +68,7 @@ function exportProject(inputPath: string, outputPath: string) {
return builder.generateProject(newSchema).then(async (result) => {
// displayResultInConsole(result);
const publisher = CodeGenerator.publishers.disk();
const publisher = createDiskPublisher();
await publisher.publish({
project: result,
outputPath,

View File

@ -1,6 +1,7 @@
import CodeGenerator from '../../src';
import * as fs from 'fs';
import * as path from 'path';
import { createDiskPublisher } from '../helpers/solutionHelper';
test('page-element2', async () => {
const inputSchemaJsonFile = path.join(__dirname, 'page-element2.schema.json');
@ -67,7 +68,7 @@ function exportProject(inputPath: string, outputPath: string) {
return builder.generateProject(newSchema).then(async (result) => {
// displayResultInConsole(result);
const publisher = CodeGenerator.publishers.disk();
const publisher = createDiskPublisher();
await publisher.publish({
project: result,
outputPath,

View File

@ -1,6 +1,14 @@
import { run } from '../src/cli';
describe('cli', () => {
// standalone 模式下不需要测试 cli
if (process.env.TEST_TARGET === 'standalone') {
it('should ignore', () => {
expect(true).toBe(true);
});
return;
}
it('should works for the default example-schema.json', async () => {
const res = await run(['example-schema.json'], {
solution: 'icejs',

View File

@ -5,8 +5,8 @@ Object {
"chunks": Array [
Object {
"content": "
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return (this.state.otherThings).map((item, index) => ((__$$context) => (!!(__$$context.state.something) && (<Page><Text>Hello world!</Text></Page>)))(__$$createChildContext(__$$context, { item, index })));
",
"fileType": "jsx",
@ -66,8 +66,8 @@ Object {
"chunks": Array [
Object {
"content": "
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return !!(this.state.something) && (<Page><Text>Hello world!</Text></Page>);
",
"fileType": "jsx",
@ -123,8 +123,8 @@ Object {
"chunks": Array [
Object {
"content": "
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return <Page><Text>Hello world!</Text></Page>;
",
"fileType": "jsx",
@ -177,8 +177,8 @@ Object {
"chunks": Array [
Object {
"content": "
const __$$context = this;
const { state } = this;
const __$$context = this._context || this;
const { state } = __$$context;
return <Page><Text>Hello world!</Text></Page>;
",
"fileType": "jsx",

View File

@ -0,0 +1,46 @@
{
"name": ".",
"dirs": [
{
"name": "src",
"dirs": [
{
"name": "components",
"dirs": [
{
"name": "Hello",
"dirs": [],
"files": [
{
"name": "index",
"ext": "js",
"content": "export default () => <div>Hello</div>"
},
{
"name": "index",
"ext": "css",
"content": ".hello {color: red}"
}
]
}
],
"files": [
{
"name": "index",
"ext": "js",
"content": "export * from \"./Hello\";"
}
]
}
],
"files": [
{ "name": "index", "ext": "js", "content": "console.log(\"Hello\")" },
{ "name": "index", "ext": "css", "content": "html,body{ padding: 0; }" }
]
}
],
"files": [
{ "name": ".eslintrc", "ext": "", "content": "{}" },
{ "name": "package", "ext": "json", "content": "{ \"name\": \"demo\", \"version\":\"1.0.0\" }" }
]
}

View File

@ -0,0 +1,34 @@
import _ from 'lodash';
import CodeGen from '../../../src';
describe('CodeGen.utils.resultHelper.findFile', () => {
it('could package.json by "package.json"', () => {
const result = require('./example-result.json') as any;
const found = CodeGen.utils.resultHelper.findFile(result, 'package.json');
expect(found).toMatchInlineSnapshot(`
Object {
"content": "{ \\"name\\": \\"demo\\", \\"version\\":\\"1.0.0\\" }",
"ext": "json",
"name": "package",
}
`);
});
it('could find a internal component by src/components/*/index.js', () => {
const result = require('./example-result.json') as any;
const found = CodeGen.utils.resultHelper.findFile(result, 'src/components/*/index.js');
expect(found).toMatchInlineSnapshot(`
Object {
"content": "export default () => <div>Hello</div>",
"ext": "js",
"name": "index",
}
`);
});
it('could not find non-existing file', () => {
const result = require('./example-result.json') as any;
const found = CodeGen.utils.resultHelper.findFile(result, 'something-not-exist.js');
expect(found).toBeNull();
});
});

View File

@ -0,0 +1,67 @@
import _ from 'lodash';
import CodeGen from '../../../src';
describe('CodeGen.utils.resultHelper.globFiles', () => {
it('could find all files exclude dot files by **/*', () => {
const result = require('./example-result.json') as any;
const files = CodeGen.utils.resultHelper.globFiles(result, '**/*');
expect(Array.from(files).map(_.first)).toMatchInlineSnapshot(`
Array [
"package.json",
"src/index.js",
"src/index.css",
"src/components/index.js",
"src/components/Hello/index.js",
"src/components/Hello/index.css",
]
`);
});
it('could find all files by **/* with option.dot = true ', () => {
const result = require('./example-result.json') as any;
const files = CodeGen.utils.resultHelper.globFiles(result, '**/*', { dot: true });
expect(Array.from(files).map(_.first)).toMatchInlineSnapshot(`
Array [
".eslintrc",
"package.json",
"src/index.js",
"src/index.css",
"src/components/index.js",
"src/components/Hello/index.js",
"src/components/Hello/index.css",
]
`);
});
it('could find all js files by **/*.js', () => {
const result = require('./example-result.json') as any;
const files = CodeGen.utils.resultHelper.globFiles(result, '**/*.js');
expect(Array.from(files).map(_.first)).toMatchInlineSnapshot(`
Array [
"src/index.js",
"src/components/index.js",
"src/components/Hello/index.js",
]
`);
});
it('could find package.json by package.json', () => {
const result = require('./example-result.json') as any;
const files = CodeGen.utils.resultHelper.globFiles(result, 'package.json');
expect(Array.from(files).map(_.first)).toMatchInlineSnapshot(`
Array [
"package.json",
]
`);
});
it('could find all index.js in components by **/components/*/index.js', () => {
const result = require('./example-result.json') as any;
const files = CodeGen.utils.resultHelper.globFiles(result, '**/components/*/index.js');
expect(Array.from(files).map(_.first)).toMatchInlineSnapshot(`
Array [
"src/components/Hello/index.js",
]
`);
});
});

View File

@ -0,0 +1,101 @@
import type { ResultDir } from '@alilc/lowcode-types';
import _ from 'lodash';
import CodeGen from '../../../src';
const loadResult = (): ResultDir => _.cloneDeep(require('./example-result.json'));
describe('CodeGen.utils.resultHelper.removeDirsFromResult', () => {
it('could remove src by "src"', () => {
const result = loadResult();
expect(listAllDirs(result)).toMatchInlineSnapshot(`
Array [
"",
"src",
"src/components",
"src/components/Hello",
]
`);
const removed = CodeGen.utils.resultHelper.removeDirsFromResult(result, 'src');
expect(listAllDirs(result)).toMatchInlineSnapshot(`
Array [
"",
]
`);
expect(removed).toBe(1);
});
it('could remove src/components/Hello by "*/components/*"', () => {
const result = loadResult();
expect(listAllDirs(result)).toMatchInlineSnapshot(`
Array [
"",
"src",
"src/components",
"src/components/Hello",
]
`);
const removed = CodeGen.utils.resultHelper.removeDirsFromResult(result, '*/components/*');
expect(listAllDirs(result)).toMatchInlineSnapshot(`
Array [
"",
"src",
"src/components",
]
`);
expect(removed).toBe(1);
});
it('could remove all dirs by "*"', () => {
const result = loadResult();
expect(listAllDirs(result)).toMatchInlineSnapshot(`
Array [
"",
"src",
"src/components",
"src/components/Hello",
]
`);
const removed = CodeGen.utils.resultHelper.removeDirsFromResult(result, '*');
expect(listAllDirs(result)).toMatchInlineSnapshot(`
Array [
"",
]
`);
expect(removed).toBe(1);
});
it('could remove all dirs by "**"', () => {
const result = loadResult();
expect(listAllDirs(result)).toMatchInlineSnapshot(`
Array [
"",
"src",
"src/components",
"src/components/Hello",
]
`);
const removed = CodeGen.utils.resultHelper.removeDirsFromResult(result, '**');
expect(listAllDirs(result)).toMatchInlineSnapshot(`
Array [
"",
]
`);
expect(removed).toBe(3);
});
});
function listAllDirs(result: ResultDir): string[] {
return Array.from(CodeGen.utils.resultHelper.scanDirs(result)).map(([dirPath]) => dirPath);
}

View File

@ -0,0 +1,102 @@
import type { ResultDir } from '@alilc/lowcode-types';
import _ from 'lodash';
import CodeGen from '../../../src';
const loadResult = (): ResultDir => _.cloneDeep(require('./example-result.json'));
describe('CodeGen.utils.resultHelper.removeFilesFromResult', () => {
it('could remove package.json by "package.json"', () => {
const result = loadResult();
expect(listAllFiles(result)).toMatchInlineSnapshot(`
Array [
".eslintrc",
"package.json",
"src/index.js",
"src/index.css",
"src/components/index.js",
"src/components/Hello/index.js",
"src/components/Hello/index.css",
]
`);
const removed = CodeGen.utils.resultHelper.removeFilesFromResult(result, 'package.json');
expect(listAllFiles(result)).toMatchInlineSnapshot(`
Array [
".eslintrc",
"src/index.js",
"src/index.css",
"src/components/index.js",
"src/components/Hello/index.js",
"src/components/Hello/index.css",
]
`);
expect(removed).toBe(1);
});
it('could remove .eslintrc.json by ".eslintrc" with dot=true', () => {
const result = loadResult();
expect(listAllFiles(result)).toMatchInlineSnapshot(`
Array [
".eslintrc",
"package.json",
"src/index.js",
"src/index.css",
"src/components/index.js",
"src/components/Hello/index.js",
"src/components/Hello/index.css",
]
`);
const removed = CodeGen.utils.resultHelper.removeFilesFromResult(result, '.eslintrc', {
dot: true,
});
expect(listAllFiles(result)).toMatchInlineSnapshot(`
Array [
"package.json",
"src/index.js",
"src/index.css",
"src/components/index.js",
"src/components/Hello/index.js",
"src/components/Hello/index.css",
]
`);
expect(removed).toBe(1);
});
it('could remove all css files by "**/*.css"', () => {
const result = loadResult();
expect(listAllFiles(result)).toMatchInlineSnapshot(`
Array [
".eslintrc",
"package.json",
"src/index.js",
"src/index.css",
"src/components/index.js",
"src/components/Hello/index.js",
"src/components/Hello/index.css",
]
`);
const removed = CodeGen.utils.resultHelper.removeFilesFromResult(result, '**/*.css');
expect(listAllFiles(result)).toMatchInlineSnapshot(`
Array [
".eslintrc",
"package.json",
"src/index.js",
"src/components/index.js",
"src/components/Hello/index.js",
]
`);
expect(removed).toBe(2);
});
});
function listAllFiles(result: ResultDir): string[] {
return Array.from(CodeGen.utils.resultHelper.scanFiles(result)).map(([filePath]) => filePath);
}

View File

@ -0,0 +1,68 @@
import CodeGen from '../../../src';
describe('CodeGen.utils.resultHelper.scanFiles', () => {
it('should works', () => {
const result = require('./example-result.json') as any;
const files = CodeGen.utils.resultHelper.scanFiles(result);
expect(Array.from(files)).toMatchInlineSnapshot(`
Array [
Array [
".eslintrc",
Object {
"content": "{}",
"ext": "",
"name": ".eslintrc",
},
],
Array [
"package.json",
Object {
"content": "{ \\"name\\": \\"demo\\", \\"version\\":\\"1.0.0\\" }",
"ext": "json",
"name": "package",
},
],
Array [
"src/index.js",
Object {
"content": "console.log(\\"Hello\\")",
"ext": "js",
"name": "index",
},
],
Array [
"src/index.css",
Object {
"content": "html,body{ padding: 0; }",
"ext": "css",
"name": "index",
},
],
Array [
"src/components/index.js",
Object {
"content": "export * from \\"./Hello\\";",
"ext": "js",
"name": "index",
},
],
Array [
"src/components/Hello/index.js",
Object {
"content": "export default () => <div>Hello</div>",
"ext": "js",
"name": "index",
},
],
Array [
"src/components/Hello/index.css",
Object {
"content": ".hello {color: red}",
"ext": "css",
"name": "index",
},
],
]
`);
});
});