fix: eslint error
This commit is contained in:
parent
f295f25176
commit
7f4eae3127
|
@ -57,6 +57,7 @@ module.exports = {
|
||||||
|
|
||||||
'no-constant-condition': 'off',
|
'no-constant-condition': 'off',
|
||||||
'no-function-declare-after-return/no-function-declare-after-return': 'error',
|
'no-function-declare-after-return/no-function-declare-after-return': 'error',
|
||||||
|
'@typescript-eslint/ban-ts-comment': 'warn'
|
||||||
},
|
},
|
||||||
globals: {
|
globals: {
|
||||||
isDev: true,
|
isDev: true,
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
||||||
|
*
|
||||||
|
* openInula is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
*
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare module 'crequire';
|
||||||
|
|
|
@ -57,7 +57,7 @@ export default (api: API) => {
|
||||||
api.applyHook({ name: 'afterStartDevServer' });
|
api.applyHook({ name: 'afterStartDevServer' });
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
api.logger.error("Can't find config");
|
api.logger.error('Can\'t find config');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'vite':
|
case 'vite':
|
||||||
|
@ -70,7 +70,7 @@ export default (api: API) => {
|
||||||
server.printUrls();
|
server.printUrls();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
api.logger.error("Can't find config");
|
api.logger.error('Can\'t find config');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -33,15 +33,17 @@ export default (api: API) => {
|
||||||
args._.shift();
|
args._.shift();
|
||||||
}
|
}
|
||||||
if (args._.length === 0) {
|
if (args._.length === 0) {
|
||||||
api.logger.warn("Can't find any generate options.");
|
api.logger.warn('Can\'t find any generate options.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (args._[0]) {
|
switch (args._[0]) {
|
||||||
case 'jest':
|
case 'jest':
|
||||||
args._.shift();
|
{
|
||||||
const isESM = api.packageJson['type'] === 'module';
|
args._.shift();
|
||||||
await generateJest(args, api.cwd, isESM);
|
const isESM = api.packageJson['type'] === 'module';
|
||||||
|
await generateJest(args, api.cwd, isESM);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
@ -50,7 +52,7 @@ export default (api: API) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateJest = async (args: yargsParser.Arguments, cwd: string, isESM: boolean) => {
|
const generateJest = async (args: yargsParser.Arguments, cwd: string, isESM: boolean) => {
|
||||||
let isTs: boolean = false;
|
let isTs = false;
|
||||||
if (args['ts']) {
|
if (args['ts']) {
|
||||||
isTs = true;
|
isTs = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -25,7 +25,7 @@ export default (api: any) => {
|
||||||
initialState: api.userConfig.remoteProxy,
|
initialState: api.userConfig.remoteProxy,
|
||||||
fn: async function (args: any, state: any) {
|
fn: async function (args: any, state: any) {
|
||||||
if (!state) {
|
if (!state) {
|
||||||
api.logger.error(`Invalid proxy config!`);
|
api.logger.error('Invalid proxy config!');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
|
@ -61,7 +61,7 @@ export default async function run() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let enableDebug: boolean = false;
|
let enableDebug = false;
|
||||||
|
|
||||||
if (process.env.DEBUG === 'true') {
|
if (process.env.DEBUG === 'true') {
|
||||||
enableDebug = true;
|
enableDebug = true;
|
||||||
|
|
|
@ -89,7 +89,7 @@ export default class Config {
|
||||||
|
|
||||||
getConfigFile(): string | null {
|
getConfigFile(): string | null {
|
||||||
const configFileList: string[] = DEFAULT_CONFIG_FILES.map(f => join(this.cwd, f));
|
const configFileList: string[] = DEFAULT_CONFIG_FILES.map(f => join(this.cwd, f));
|
||||||
for (let configFile of configFileList) {
|
for (const configFile of configFileList) {
|
||||||
if (existsSync(configFile)) {
|
if (existsSync(configFile)) {
|
||||||
return configFile;
|
return configFile;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,11 +46,11 @@ export default class Hub {
|
||||||
userConfig: UserConfig = {};
|
userConfig: UserConfig = {};
|
||||||
packageJson: PackageJSON;
|
packageJson: PackageJSON;
|
||||||
stage: ServiceStage = ServiceStage.uninitialized;
|
stage: ServiceStage = ServiceStage.uninitialized;
|
||||||
buildConfig: { name: string; config: object }[] = [];
|
buildConfig: { name: string; config: Record<string, unknown> }[] = [];
|
||||||
pluginManager: Plugin;
|
pluginManager: Plugin;
|
||||||
buildConfigPath: BuildConfig[] = [];
|
buildConfigPath: BuildConfig[] = [];
|
||||||
devBuildConfig: object = {};
|
devBuildConfig: Record<string, unknown> = {};
|
||||||
compileMode: string = '';
|
compileMode = '';
|
||||||
builtInPlugins: string[] = [];
|
builtInPlugins: string[] = [];
|
||||||
pluginPaths: string[] = [];
|
pluginPaths: string[] = [];
|
||||||
devProxy: DevProxy | null = null;
|
devProxy: DevProxy | null = null;
|
||||||
|
@ -150,14 +150,15 @@ export default class Hub {
|
||||||
|
|
||||||
async analyzeBuildConfig() {
|
async analyzeBuildConfig() {
|
||||||
if (this.userConfig.devBuildConfig) {
|
if (this.userConfig.devBuildConfig) {
|
||||||
let { name, path, env } = this.userConfig.devBuildConfig;
|
let { path } = this.userConfig.devBuildConfig;
|
||||||
|
const { env } = this.userConfig.devBuildConfig;
|
||||||
path = isAbsolute(path) ? path : join(process.cwd(), path);
|
path = isAbsolute(path) ? path : join(process.cwd(), path);
|
||||||
if (!existsSync(path)) {
|
if (!existsSync(path)) {
|
||||||
this.logger.warn(`Cant't find dev build config. Path is ${path}`);
|
this.logger.warn(`Cant't find dev build config. Path is ${path}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.logger.debug(`Find dev build config. Path is ${path}`);
|
this.logger.debug(`Find dev build config. Path is ${path}`);
|
||||||
let bc = await loadModule<object | Function>(path);
|
const bc = await loadModule<Record<string, unknown> | ((...args: any[]) => any)>(path);
|
||||||
if (bc == undefined) {
|
if (bc == undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -196,14 +197,15 @@ export default class Hub {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.buildConfigPath.forEach(async config => {
|
this.buildConfigPath.forEach(async config => {
|
||||||
let { name, path } = config;
|
let { path } = config;
|
||||||
|
const { name } = config;
|
||||||
path = isAbsolute(path) ? path : join(process.cwd(), path);
|
path = isAbsolute(path) ? path : join(process.cwd(), path);
|
||||||
if (!existsSync(path)) {
|
if (!existsSync(path)) {
|
||||||
this.logger.debug(`Cant't find build config. Path is ${path}`);
|
this.logger.debug(`Cant't find build config. Path is ${path}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.logger.debug(`Find build config. Path is ${path}`);
|
this.logger.debug(`Find build config. Path is ${path}`);
|
||||||
let bc = await loadModule<object | Function>(path);
|
const bc = await loadModule<Record<string, unknown> | ((...args: any[]) => any)>(path);
|
||||||
if (bc == undefined) {
|
if (bc == undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ export interface IPlugin {
|
||||||
id: string;
|
id: string;
|
||||||
key: string;
|
key: string;
|
||||||
path: string;
|
path: string;
|
||||||
apply: Function;
|
apply: (...args: any[]) => any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Plugin {
|
export default class Plugin {
|
||||||
|
@ -57,7 +57,7 @@ export default class Plugin {
|
||||||
} = {};
|
} = {};
|
||||||
hub: Hub;
|
hub: Hub;
|
||||||
logger: Logger;
|
logger: Logger;
|
||||||
registerFunction: Function[] = [];
|
registerFunction: ((...args: any[]) => any)[] = [];
|
||||||
// 解决调用this[props]时ts提示属性未知
|
// 解决调用this[props]时ts提示属性未知
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ export default class Plugin {
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const obj of objs) {
|
for (const obj of objs) {
|
||||||
const module: Function | undefined = await loadModule(obj.path);
|
const module: ((...args: any[]) => any) | undefined = await loadModule(obj.path);
|
||||||
if (module) {
|
if (module) {
|
||||||
try {
|
try {
|
||||||
module(obj.api);
|
module(obj.api);
|
||||||
|
|
|
@ -55,7 +55,7 @@ export default class PluginAPI {
|
||||||
this.register(hook);
|
this.register(hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
registerMethod(fn: Function) {
|
registerMethod(fn: (...args: any[]) => any) {
|
||||||
this.manager.registerFunction.push(fn);
|
this.manager.registerFunction.push(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@ import { Logger } from '../utils/logger.js';
|
||||||
import type * as http from 'http';
|
import type * as http from 'http';
|
||||||
import type * as express from 'express';
|
import type * as express from 'express';
|
||||||
|
|
||||||
interface Request extends express.Request {}
|
type Request = express.Request;
|
||||||
interface Response extends express.Response {}
|
type Response = express.Response;
|
||||||
|
|
||||||
export interface IDep {
|
export interface IDep {
|
||||||
[name: string]: string;
|
[name: string]: string;
|
||||||
|
@ -37,7 +37,7 @@ export interface IPlugin {
|
||||||
id: string;
|
id: string;
|
||||||
key: string;
|
key: string;
|
||||||
path: string;
|
path: string;
|
||||||
apply: Function;
|
apply: (...args: any[]) => any;
|
||||||
|
|
||||||
config?: IPluginConfig;
|
config?: IPluginConfig;
|
||||||
isPreset?: boolean;
|
isPreset?: boolean;
|
||||||
|
@ -45,7 +45,7 @@ export interface IPlugin {
|
||||||
|
|
||||||
export interface IPluginConfig {
|
export interface IPluginConfig {
|
||||||
default?: any;
|
default?: any;
|
||||||
onChange?: string | Function;
|
onChange?: string | ((...args: any[]) => any);
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IHook {
|
export interface IHook {
|
||||||
|
@ -94,7 +94,7 @@ export interface API {
|
||||||
(hook: IHook): void;
|
(hook: IHook): void;
|
||||||
};
|
};
|
||||||
registerMethod: {
|
registerMethod: {
|
||||||
(method: Function): void;
|
(method: (...args: any[]) => any): void;
|
||||||
};
|
};
|
||||||
applyHook: {
|
applyHook: {
|
||||||
(opts: applyHookConfig): void;
|
(opts: applyHookConfig): void;
|
||||||
|
@ -133,8 +133,8 @@ export interface MockConfig {
|
||||||
export interface DevBuildConfig {
|
export interface DevBuildConfig {
|
||||||
name: string;
|
name: string;
|
||||||
path: string;
|
path: string;
|
||||||
args?: object;
|
args?: Record<string, unknown>;
|
||||||
env?: object;
|
env?: Record<string, unknown>;
|
||||||
devProxy?: DevProxy;
|
devProxy?: DevProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,8 +147,8 @@ export interface DevProxy {
|
||||||
export interface BuildConfig {
|
export interface BuildConfig {
|
||||||
name: string;
|
name: string;
|
||||||
path: string;
|
path: string;
|
||||||
args?: object;
|
args?: Record<string, unknown>;
|
||||||
env?: object;
|
env?: Record<string, unknown>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ExportUserConfig = UserConfig | Promise<UserConfig>;
|
export type ExportUserConfig = UserConfig | Promise<UserConfig>;
|
||||||
|
|
|
@ -38,13 +38,15 @@ function getMocksFile() {
|
||||||
const mockFiles = globSync('**/*.js', {
|
const mockFiles = globSync('**/*.js', {
|
||||||
cwd: mockDir,
|
cwd: mockDir,
|
||||||
});
|
});
|
||||||
let ret = mockFiles.reduce((mocks: any, mockFile: string) => {
|
const ret = mockFiles.reduce((mocks: any, mockFile: string) => {
|
||||||
if (!mockFile.startsWith('_')) {
|
if (!mockFile.startsWith('_')) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
const file = require(join(mockDir, mockFile));
|
||||||
mocks = {
|
mocks = {
|
||||||
...mocks,
|
...mocks,
|
||||||
...require(join(mockDir, mockFile)),
|
...file,
|
||||||
};
|
};
|
||||||
console.log('mockFile', require(join(mockDir, mockFile)));
|
console.log('mockFile', file);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mocks;
|
return mocks;
|
||||||
|
@ -54,8 +56,8 @@ function getMocksFile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateRoutes(app: any) {
|
function generateRoutes(app: any) {
|
||||||
let mockStartIndex = app._router.stack.length,
|
const mockStartIndex = app._router.stack.length;
|
||||||
mocks: Mock = {};
|
let mocks: Mock = {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mocks = getMocksFile();
|
mocks = getMocksFile();
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
import { dirname } from 'path';
|
import { dirname } from 'path';
|
||||||
import { readFileSync, writeFileSync } from 'fs';
|
import { readFileSync, writeFileSync } from 'fs';
|
||||||
import resolve from 'resolve';
|
import resolve from 'resolve';
|
||||||
// @ts-ignore
|
|
||||||
import crequire from 'crequire';
|
import crequire from 'crequire';
|
||||||
import { createRequire } from 'module';
|
import { createRequire } from 'module';
|
||||||
const require = createRequire(import.meta.url);
|
const require = createRequire(import.meta.url);
|
||||||
|
|
|
@ -11,9 +11,16 @@
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
},
|
},
|
||||||
"include": ["src/**/*"],
|
"include": [
|
||||||
"exclude": ["node_modules", "**/*.spec.ts", "./src/template/**/*"],
|
"src/**/*",
|
||||||
|
"./externals.d.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"./src/template/**/*"
|
||||||
|
],
|
||||||
"ts-node": {
|
"ts-node": {
|
||||||
"esm": true,
|
"esm": true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ export class I18n extends EventDispatcher<Events> {
|
||||||
|
|
||||||
formatMessage(
|
formatMessage(
|
||||||
id: MessageDescriptor | string,
|
id: MessageDescriptor | string,
|
||||||
values: Object | undefined = {},
|
values: Record<string, unknown> | undefined = {},
|
||||||
{ message, context, formatOptions }: MessageOptions = {}
|
{ message, context, formatOptions }: MessageOptions = {}
|
||||||
) {
|
) {
|
||||||
return getFormatMessage(this, id, values, { message, context, formatOptions });
|
return getFormatMessage(this, id, values, { message, context, formatOptions });
|
||||||
|
|
|
@ -40,11 +40,11 @@ class Translation {
|
||||||
* @param values 需要替换文本占位符的值
|
* @param values 需要替换文本占位符的值
|
||||||
* @param formatOptions 需要格式化选项
|
* @param formatOptions 需要格式化选项
|
||||||
*/
|
*/
|
||||||
translate(values: object, formatOptions: FormatOptions = {}): string {
|
translate(values: Record<string, unknown>, formatOptions: FormatOptions = {}): string {
|
||||||
const createTextFormatter = (
|
const createTextFormatter = (
|
||||||
locale: Locale,
|
locale: Locale,
|
||||||
locales: Locales,
|
locales: Locales,
|
||||||
values: object,
|
values: Record<string, unknown>,
|
||||||
formatOptions: FormatOptions,
|
formatOptions: FormatOptions,
|
||||||
localeConfig: LocaleConfig
|
localeConfig: LocaleConfig
|
||||||
) => {
|
) => {
|
||||||
|
@ -66,13 +66,13 @@ class Translation {
|
||||||
return textFormatter;
|
return textFormatter;
|
||||||
};
|
};
|
||||||
|
|
||||||
let textFormatter = createTextFormatter(this.locale, this.locales, values, formatOptions, this.localeConfig);
|
const textFormatter = createTextFormatter(this.locale, this.locales, values, formatOptions, this.localeConfig);
|
||||||
// 通过递归方法formatCore进行格式化处理
|
// 通过递归方法formatCore进行格式化处理
|
||||||
const result = this.formatMessage(this.compiledMessage, textFormatter);
|
const result = this.formatMessage(this.compiledMessage, textFormatter);
|
||||||
return result; // 返回要格式化的结果
|
return result; // 返回要格式化的结果
|
||||||
}
|
}
|
||||||
|
|
||||||
formatMessage(compiledMessage: CompiledMessage, textFormatter: Function) {
|
formatMessage(compiledMessage: CompiledMessage, textFormatter: (...args: any[]) => any) {
|
||||||
if (!Array.isArray(compiledMessage)) {
|
if (!Array.isArray(compiledMessage)) {
|
||||||
return compiledMessage;
|
return compiledMessage;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,11 @@ import creatI18nCache from './cache/cache';
|
||||||
export function getFormatMessage(
|
export function getFormatMessage(
|
||||||
i18n: I18n,
|
i18n: I18n,
|
||||||
id: MessageDescriptor | string,
|
id: MessageDescriptor | string,
|
||||||
values: Object | undefined = {},
|
values: Record<string, unknown> | undefined = {},
|
||||||
options: MessageOptions = {}
|
options: MessageOptions = {}
|
||||||
) {
|
) {
|
||||||
let { message, context, formatOptions } = options;
|
let { message, context } = options;
|
||||||
|
const { formatOptions } = options;
|
||||||
const cache = i18n.cache ?? creatI18nCache();
|
const cache = i18n.cache ?? creatI18nCache();
|
||||||
if (typeof id !== 'string') {
|
if (typeof id !== 'string') {
|
||||||
values = values || id.defaultValues;
|
values = values || id.defaultValues;
|
||||||
|
|
|
@ -19,19 +19,19 @@ import { LexerInterface } from '../types/interfaces';
|
||||||
class Lexer<T> implements LexerInterface<T> {
|
class Lexer<T> implements LexerInterface<T> {
|
||||||
readonly startState: string;
|
readonly startState: string;
|
||||||
readonly states: Record<string, any>;
|
readonly states: Record<string, any>;
|
||||||
private buffer: string = '';
|
private buffer = '';
|
||||||
private stack: string[] = [];
|
private stack: string[] = [];
|
||||||
private index: number = 0;
|
private index = 0;
|
||||||
private line: number = 1;
|
private line = 1;
|
||||||
private col: number = 1;
|
private col = 1;
|
||||||
private queuedText: string = '';
|
private queuedText = '';
|
||||||
private state: string = '';
|
private state = '';
|
||||||
private groups: string[] = [];
|
private groups: string[] = [];
|
||||||
private error: Record<string, any> | undefined;
|
private error: Record<string, any> | undefined;
|
||||||
private regexp;
|
private regexp;
|
||||||
private fast: object = {};
|
private fast: Record<string, unknown> = {};
|
||||||
private queuedGroup: string | null = '';
|
private queuedGroup: string | null = '';
|
||||||
private value: string = '';
|
private value = '';
|
||||||
|
|
||||||
constructor(unionReg: Record<string, any>, startState: string) {
|
constructor(unionReg: Record<string, any>, startState: string) {
|
||||||
this.startState = startState;
|
this.startState = startState;
|
||||||
|
|
|
@ -14,11 +14,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const body: Record<string, any> = {
|
const body: Record<string, any> = {
|
||||||
doubleapos: { match: "''", value: () => "'" },
|
doubleapos: { match: '\'\'', value: () => '\'' },
|
||||||
quoted: {
|
quoted: {
|
||||||
lineBreaks: true,
|
lineBreaks: true,
|
||||||
match: /'[{}#](?:[^]*?[^'])?'(?!')/u,
|
match: /'[{}#](?:[^]*?[^'])?'(?!')/u,
|
||||||
value: src => src.slice(1, -1).replace(/''/g, "'"),
|
value: src => src.slice(1, -1).replace(/''/g, '\''),
|
||||||
},
|
},
|
||||||
argument: {
|
argument: {
|
||||||
lineBreaks: true,
|
lineBreaks: true,
|
||||||
|
|
|
@ -23,8 +23,8 @@ const defaultErrorRule = ruleUtils.getRuleOptions('error', { lineBreaks: true, s
|
||||||
// 解析规则并生成词法分析器所需的数据结构,以便进行词法分析操作
|
// 解析规则并生成词法分析器所需的数据结构,以便进行词法分析操作
|
||||||
function parseRules(rules: Record<string, any>, hasStates: boolean): Record<string, any> {
|
function parseRules(rules: Record<string, any>, hasStates: boolean): Record<string, any> {
|
||||||
let errorRule: Record<string, any> | null = null;
|
let errorRule: Record<string, any> | null = null;
|
||||||
const fast: object = {};
|
const fast: Record<string, unknown> = {};
|
||||||
let enableFast: boolean = true;
|
let enableFast = true;
|
||||||
let unicodeFlag: boolean | null = null;
|
let unicodeFlag: boolean | null = null;
|
||||||
const groups: Record<string, any>[] = [];
|
const groups: Record<string, any>[] = [];
|
||||||
const parts: string[] = [];
|
const parts: string[] = [];
|
||||||
|
@ -148,6 +148,7 @@ function parseMappingRule(mappingRule: Record<string, any>, startState?: string)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line
|
||||||
rules.splice.apply(rules, splice);
|
rules.splice.apply(rules, splice);
|
||||||
j--;
|
j--;
|
||||||
}
|
}
|
||||||
|
@ -176,7 +177,7 @@ function parseMappingRule(mappingRule: Record<string, any>, startState?: string)
|
||||||
return new Lexer(mappingAllRules, startState);
|
return new Lexer(mappingAllRules, startState);
|
||||||
}
|
}
|
||||||
|
|
||||||
function processFast(match, fast: {}, options) {
|
function processFast(match, fast: Record<string, unknown>, options) {
|
||||||
while (match.length && typeof match[0] === 'string' && match[0].length === 1) {
|
while (match.length && typeof match[0] === 'string' && match[0].length === 1) {
|
||||||
const word = match.shift();
|
const word = match.shift();
|
||||||
fast[word.charCodeAt(0)] = options;
|
fast[word.charCodeAt(0)] = options;
|
||||||
|
|
|
@ -42,7 +42,7 @@ class Parser {
|
||||||
isSelectKeyValid(token: RawToken, type: Select['type'], value: string) {
|
isSelectKeyValid(token: RawToken, type: Select['type'], value: string) {
|
||||||
if (value[0] === '=') {
|
if (value[0] === '=') {
|
||||||
if (type === 'select') {
|
if (type === 'select') {
|
||||||
throw new Error(`The key value of the select type is invalid.`);
|
throw new Error('The key value of the select type is invalid.');
|
||||||
}
|
}
|
||||||
} else if (type !== 'select') {
|
} else if (type !== 'select') {
|
||||||
const values = type === 'plural' ? this.cardinalKeys : this.ordinalKeys;
|
const values = type === 'plural' ? this.cardinalKeys : this.ordinalKeys;
|
||||||
|
@ -132,7 +132,7 @@ class Parser {
|
||||||
if (checkSelectType(nextToken.value.toLowerCase())) {
|
if (checkSelectType(nextToken.value.toLowerCase())) {
|
||||||
throw new Error(`Invalid parameter type: ${nextToken.value}`);
|
throw new Error(`Invalid parameter type: ${nextToken.value}`);
|
||||||
}
|
}
|
||||||
let param = this.parse(isPlural);
|
const param = this.parse(isPlural);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'function',
|
type: 'function',
|
||||||
|
|
|
@ -19,7 +19,7 @@ import Lexer from '../parser/Lexer';
|
||||||
|
|
||||||
// FormattedMessage的参数定义
|
// FormattedMessage的参数定义
|
||||||
export interface FormattedMessageProps extends MessageDescriptor {
|
export interface FormattedMessageProps extends MessageDescriptor {
|
||||||
values?: object;
|
values?: Record<string, unknown>;
|
||||||
tagName?: string;
|
tagName?: string;
|
||||||
|
|
||||||
children?(nodes: any[]): any;
|
children?(nodes: any[]): any;
|
||||||
|
@ -203,7 +203,7 @@ export interface InjectedIntl {
|
||||||
// 信息格式化
|
// 信息格式化
|
||||||
formatMessage(
|
formatMessage(
|
||||||
messageDescriptor: MessageDescriptor,
|
messageDescriptor: MessageDescriptor,
|
||||||
values?: object,
|
values?: Record<string, unknown>,
|
||||||
options?: MessageOptions,
|
options?: MessageOptions,
|
||||||
useMemorize?: boolean
|
useMemorize?: boolean
|
||||||
): string;
|
): string;
|
||||||
|
|
|
@ -32,7 +32,7 @@ export type Locale = string;
|
||||||
|
|
||||||
export type Locales = Locale | Locale[];
|
export type Locales = Locale | Locale[];
|
||||||
|
|
||||||
export type LocaleConfig = { plurals?: Function };
|
export type LocaleConfig = { plurals?: (...arg: any) => any };
|
||||||
|
|
||||||
export type AllLocaleConfig = Record<Locale, LocaleConfig>;
|
export type AllLocaleConfig = Record<Locale, LocaleConfig>;
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ export type Token = Content | PlainArg | FunctionArg | Select | Octothorpe;
|
||||||
|
|
||||||
export type DatePool = Date | string;
|
export type DatePool = Date | string;
|
||||||
|
|
||||||
export type SelectPool = string | object;
|
export type SelectPool = string | Record<string, unknown>;
|
||||||
|
|
||||||
export type RawToken = {
|
export type RawToken = {
|
||||||
type: string;
|
type: string;
|
||||||
|
@ -76,9 +76,9 @@ export type I18nProviderProps = I18nContextProps & configProps;
|
||||||
|
|
||||||
export type IntlType = {
|
export type IntlType = {
|
||||||
i18n: I18n;
|
i18n: I18n;
|
||||||
formatMessage: Function;
|
formatMessage: (...args: any[]) => any;
|
||||||
formatNumber: Function;
|
formatNumber: (...args: any[]) => any;
|
||||||
formatDate: Function;
|
formatDate: (...args: any[]) => any;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface InjectedIntlProps {
|
export interface InjectedIntlProps {
|
||||||
|
|
|
@ -73,7 +73,9 @@ function copyStaticProps<T, U>(targetComponent: T, sourceComponent: U): T {
|
||||||
try {
|
try {
|
||||||
// 在一个已有的targetComponent对象上增加sourceComponent的属性
|
// 在一个已有的targetComponent对象上增加sourceComponent的属性
|
||||||
Object.defineProperty(targetComponent, key, Object.getOwnPropertyDescriptor(sourceComponent, key)!);
|
Object.defineProperty(targetComponent, key, Object.getOwnPropertyDescriptor(sourceComponent, key)!);
|
||||||
} catch (e) {}
|
} catch (e) {
|
||||||
|
console.log('Error occurred while copying static props:', e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -32,12 +32,14 @@ const checkSticky = () => typeof new RegExp('')?.sticky === 'boolean';
|
||||||
|
|
||||||
// 转义正则表达式中的特殊字符
|
// 转义正则表达式中的特殊字符
|
||||||
function transferReg(s: string): string {
|
function transferReg(s: string): string {
|
||||||
|
// eslint-disable-next-line
|
||||||
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算正则表达式中捕获组的数量
|
// 计算正则表达式中捕获组的数量
|
||||||
function getRegGroups(s: string): number {
|
function getRegGroups(s: string): number {
|
||||||
const re = new RegExp('|' + s);
|
const re = new RegExp('|' + s);
|
||||||
|
// eslint-disable-next-line
|
||||||
return re.exec('')?.length! - 1;
|
return re.exec('')?.length! - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,19 +90,19 @@ describe('I18n', () => {
|
||||||
});
|
});
|
||||||
it('._ allow escaping syntax characters', () => {
|
it('._ allow escaping syntax characters', () => {
|
||||||
const messages = {
|
const messages = {
|
||||||
"My ''name'' is '{name}'": "Mi ''nombre'' es '{name}'",
|
'My \'\'name\'\' is \'{name}\'': 'Mi \'\'nombre\'\' es \'{name}\'',
|
||||||
};
|
};
|
||||||
const i18n = new I18n({
|
const i18n = new I18n({
|
||||||
locale: 'es',
|
locale: 'es',
|
||||||
messages: { es: messages },
|
messages: { es: messages },
|
||||||
});
|
});
|
||||||
expect(i18n.formatMessage("My ''name'' is '{name}'")).toEqual("Mi 'nombre' es {name}");
|
expect(i18n.formatMessage('My \'\'name\'\' is \'{name}\'')).toEqual('Mi \'nombre\' es {name}');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('._ should format message from catalog', function () {
|
it('._ should format message from catalog', function () {
|
||||||
const messages = {
|
const messages = {
|
||||||
Hello: 'Salut',
|
Hello: 'Salut',
|
||||||
id: "Je m'appelle {name}",
|
id: 'Je m\'appelle {name}',
|
||||||
};
|
};
|
||||||
const i18n = new I18n({
|
const i18n = new I18n({
|
||||||
locale: 'fr',
|
locale: 'fr',
|
||||||
|
@ -110,7 +110,7 @@ describe('I18n', () => {
|
||||||
});
|
});
|
||||||
expect(i18n.locale).toEqual('fr');
|
expect(i18n.locale).toEqual('fr');
|
||||||
expect(i18n.formatMessage('Hello')).toEqual('Salut');
|
expect(i18n.formatMessage('Hello')).toEqual('Salut');
|
||||||
expect(i18n.formatMessage('id', { name: 'Fred' })).toEqual("Je m'appelle Fred");
|
expect(i18n.formatMessage('id', { name: 'Fred' })).toEqual('Je m\'appelle Fred');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the formatted date and time', () => {
|
it('should return the formatted date and time', () => {
|
||||||
|
|
|
@ -43,7 +43,7 @@ describe('eventEmitter', () => {
|
||||||
expect(listener).not.toBeCalled();
|
expect(listener).not.toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should do nothing when even doesn't exist", () => {
|
it('should do nothing when even doesn\'t exist', () => {
|
||||||
const unknown = jest.fn();
|
const unknown = jest.fn();
|
||||||
|
|
||||||
const emitter = new EventEmitter();
|
const emitter = new EventEmitter();
|
||||||
|
|
|
@ -38,7 +38,7 @@ const useIR = <T = unknown>(
|
||||||
Inula.useEffect(() => {
|
Inula.useEffect(() => {
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
try {
|
try {
|
||||||
let result = await irClient.query(url, config, options);
|
const result = await irClient.query(url, config, options);
|
||||||
document.addEventListener('request', handleRequest(result));
|
document.addEventListener('request', handleRequest(result));
|
||||||
|
|
||||||
setData(result); // 未设置轮询查询时展示一次
|
setData(result); // 未设置轮询查询时展示一次
|
||||||
|
|
|
@ -48,7 +48,7 @@ class InterceptorManager<V> implements IrInterceptorManager<V> {
|
||||||
this.handlers = [];
|
this.handlers = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
forEach(func: Function) {
|
forEach(func: (...arg: any) => any) {
|
||||||
utils.forEach(this.handlers, function forEachHandler(h: any) {
|
utils.forEach(this.handlers, function forEachHandler(h: any) {
|
||||||
if (h !== null) {
|
if (h !== null) {
|
||||||
func(h);
|
func(h);
|
||||||
|
|
|
@ -23,7 +23,7 @@ import CancelError from '../cancel/CancelError';
|
||||||
|
|
||||||
export const fetchRequest = (config: IrRequestConfig): Promise<IrResponse> => {
|
export const fetchRequest = (config: IrRequestConfig): Promise<IrResponse> => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let {
|
const {
|
||||||
method = 'GET',
|
method = 'GET',
|
||||||
baseURL,
|
baseURL,
|
||||||
url,
|
url,
|
||||||
|
@ -40,7 +40,7 @@ export const fetchRequest = (config: IrRequestConfig): Promise<IrResponse> => {
|
||||||
signal,
|
signal,
|
||||||
} = config;
|
} = config;
|
||||||
|
|
||||||
let controller = new AbortController();
|
const controller = new AbortController();
|
||||||
if (!signal) {
|
if (!signal) {
|
||||||
signal = controller.signal;
|
signal = controller.signal;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ import { Method, ResponseType } from '../types/types';
|
||||||
|
|
||||||
export const ieFetchRequest = (config: IrRequestConfig): Promise<IrResponse> => {
|
export const ieFetchRequest = (config: IrRequestConfig): Promise<IrResponse> => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let {
|
const {
|
||||||
method = 'get',
|
method = 'get',
|
||||||
baseURL,
|
baseURL,
|
||||||
url,
|
url,
|
||||||
|
|
|
@ -231,7 +231,7 @@ export interface IrInterceptorManager<T> {
|
||||||
clear(): void;
|
clear(): void;
|
||||||
|
|
||||||
// 过滤跳过迭代器
|
// 过滤跳过迭代器
|
||||||
forEach(func: Function): void;
|
forEach(func: (...arg: any) => any): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IrErrorInterface {
|
export interface IrErrorInterface {
|
||||||
|
|
|
@ -39,7 +39,7 @@ export type IrTransformer = (data: any, headers?: IrHeaders) => any;
|
||||||
|
|
||||||
// Headers
|
// Headers
|
||||||
export type HeaderMap = Record<string, string | string[]>;
|
export type HeaderMap = Record<string, string | string[]>;
|
||||||
export type HeaderMatcher = boolean | RegExp | Function;
|
export type HeaderMatcher = boolean | RegExp | ((...args: any[]) => any);
|
||||||
|
|
||||||
// Promise 成功和拒绝类型
|
// Promise 成功和拒绝类型
|
||||||
export type FulfilledFn<T> = (value: T) => T | Promise<T>; // 泛型确保了拦截器链中各个环节之间的一致性,避免数据类型不匹配引发的错误
|
export type FulfilledFn<T> = (value: T) => T | Promise<T>; // 泛型确保了拦截器链中各个环节之间的一致性,避免数据类型不匹配引发的错误
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { Callback, FilterFunc, PropFilterFunc } from '../../types/types';
|
||||||
*
|
*
|
||||||
* @returns {any} 新的函数,当这个新的函数被调用时,它会调用 func 函数,并使用 apply() 方法将 thisArg 作为上下文对象,将传递的参数作为 func 函数的参数传递给它
|
* @returns {any} 新的函数,当这个新的函数被调用时,它会调用 func 函数,并使用 apply() 方法将 thisArg 作为上下文对象,将传递的参数作为 func 函数的参数传递给它
|
||||||
*/
|
*/
|
||||||
function bind(func: Function, thisArg: any): (...args: any[]) => any {
|
function bind(func: (...args: any[]) => any, thisArg: any): (...args: any[]) => any {
|
||||||
return (...args: any[]) => func.apply(thisArg, args);
|
return (...args: any[]) => func.apply(thisArg, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ const checkHTMLForm = createTypeChecker('HTMLFormElement');
|
||||||
*/
|
*/
|
||||||
function forEach<T>(
|
function forEach<T>(
|
||||||
input: T | T[] | Record<string, T> | null | undefined,
|
input: T | T[] | Record<string, T> | null | undefined,
|
||||||
func: Function,
|
func: (...args: any[]) => any,
|
||||||
options: { includeAll?: boolean } = {}
|
options: { includeAll?: boolean } = {}
|
||||||
): void {
|
): void {
|
||||||
if (input === null || input === undefined) {
|
if (input === null || input === undefined) {
|
||||||
|
@ -194,7 +194,7 @@ function extendObject(
|
||||||
* @returns {string[]} 所有属性名数组
|
* @returns {string[]} 所有属性名数组
|
||||||
*/
|
*/
|
||||||
function getAllPropertyNames(obj: Record<string, any>): string[] {
|
function getAllPropertyNames(obj: Record<string, any>): string[] {
|
||||||
let result: string[] = [];
|
const result: string[] = [];
|
||||||
let currentObj = obj;
|
let currentObj = obj;
|
||||||
while (currentObj) {
|
while (currentObj) {
|
||||||
const propNames = Object.getOwnPropertyNames(currentObj);
|
const propNames = Object.getOwnPropertyNames(currentObj);
|
||||||
|
@ -406,6 +406,7 @@ function objectToQueryString(obj: Record<string, any>) {
|
||||||
const all = <T>(promises: Array<Promise<T>>): Promise<T[]> => Promise.all(promises);
|
const all = <T>(promises: Array<Promise<T>>): Promise<T[]> => Promise.all(promises);
|
||||||
|
|
||||||
function spread<T>(callback: Callback<T>): (arr: any[]) => T {
|
function spread<T>(callback: Callback<T>): (arr: any[]) => T {
|
||||||
|
// eslint-disable-next-line
|
||||||
return (arr: any[]): T => callback.apply(null, arr);
|
return (arr: any[]): T => callback.apply(null, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ import IrHeaders from '../../core/IrHeaders';
|
||||||
import defaultConfig from '../../config/defaultConfig';
|
import defaultConfig from '../../config/defaultConfig';
|
||||||
import { IrRequestConfig, IrResponse } from '../../types/interfaces';
|
import { IrRequestConfig, IrResponse } from '../../types/interfaces';
|
||||||
|
|
||||||
function transformData(inputConfig: IrRequestConfig, func: Function, response?: IrResponse) {
|
function transformData(inputConfig: IrRequestConfig, func: (...arg: any) => any, response?: IrResponse) {
|
||||||
const config = inputConfig || defaultConfig;
|
const config = inputConfig || defaultConfig;
|
||||||
const context = response || config;
|
const context = response || config;
|
||||||
const headers = IrHeaders.from(context.headers);
|
const headers = IrHeaders.from(context.headers);
|
||||||
|
|
|
@ -20,9 +20,9 @@ function convertRawHeaders(rawHeaders: string): HeaderMap {
|
||||||
|
|
||||||
if (rawHeaders) {
|
if (rawHeaders) {
|
||||||
rawHeaders.split('\n').forEach((item: string) => {
|
rawHeaders.split('\n').forEach((item: string) => {
|
||||||
let i = item.indexOf(':');
|
const i = item.indexOf(':');
|
||||||
let key = item.substring(0, i).trim().toLowerCase();
|
const key = item.substring(0, i).trim().toLowerCase();
|
||||||
let val = item.substring(i + 1).trim();
|
const val = item.substring(i + 1).trim();
|
||||||
|
|
||||||
if (!key || (convertedHeaders[key] && key !== 'set-cookie')) {
|
if (!key || (convertedHeaders[key] && key !== 'set-cookie')) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -38,7 +38,7 @@ function processValueByParser(key: string, value: any, parser?: HeaderMatcher):
|
||||||
return parseKeyValuePairs(value);
|
return parseKeyValuePairs(value);
|
||||||
}
|
}
|
||||||
if (utils.checkFunction(parser)) {
|
if (utils.checkFunction(parser)) {
|
||||||
return (parser as Function)(value, key);
|
return (parser as (value: any, key: string) => any)(value, key);
|
||||||
}
|
}
|
||||||
if (utils.checkRegExp(parser)) {
|
if (utils.checkRegExp(parser)) {
|
||||||
return (parser as RegExp).exec(value)?.filter(item => item !== undefined);
|
return (parser as RegExp).exec(value)?.filter(item => item !== undefined);
|
||||||
|
|
|
@ -18,14 +18,14 @@ import { createPath } from '../utils';
|
||||||
describe('createPath', () => {
|
describe('createPath', () => {
|
||||||
describe('given only a pathname', () => {
|
describe('given only a pathname', () => {
|
||||||
it('returns the pathname unchanged', () => {
|
it('returns the pathname unchanged', () => {
|
||||||
let path = createPath({ pathname: 'https://google.com' });
|
const path = createPath({ pathname: 'https://google.com' });
|
||||||
expect(path).toBe('https://google.com');
|
expect(path).toBe('https://google.com');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('given a pathname and a search param', () => {
|
describe('given a pathname and a search param', () => {
|
||||||
it('returns the constructed pathname', () => {
|
it('returns the constructed pathname', () => {
|
||||||
let path = createPath({
|
const path = createPath({
|
||||||
pathname: 'https://google.com',
|
pathname: 'https://google.com',
|
||||||
search: '?something=cool',
|
search: '?something=cool',
|
||||||
});
|
});
|
||||||
|
@ -35,7 +35,7 @@ describe('createPath', () => {
|
||||||
|
|
||||||
describe('given a pathname and a search param without ?', () => {
|
describe('given a pathname and a search param without ?', () => {
|
||||||
it('returns the constructed pathname', () => {
|
it('returns the constructed pathname', () => {
|
||||||
let path = createPath({
|
const path = createPath({
|
||||||
pathname: 'https://google.com',
|
pathname: 'https://google.com',
|
||||||
search: 'something=cool',
|
search: 'something=cool',
|
||||||
});
|
});
|
||||||
|
@ -45,7 +45,7 @@ describe('createPath', () => {
|
||||||
|
|
||||||
describe('given a pathname and a hash param', () => {
|
describe('given a pathname and a hash param', () => {
|
||||||
it('returns the constructed pathname', () => {
|
it('returns the constructed pathname', () => {
|
||||||
let path = createPath({
|
const path = createPath({
|
||||||
pathname: 'https://google.com',
|
pathname: 'https://google.com',
|
||||||
hash: '#section-1',
|
hash: '#section-1',
|
||||||
});
|
});
|
||||||
|
@ -55,7 +55,7 @@ describe('createPath', () => {
|
||||||
|
|
||||||
describe('given a pathname and a hash param without #', () => {
|
describe('given a pathname and a hash param without #', () => {
|
||||||
it('returns the constructed pathname', () => {
|
it('returns the constructed pathname', () => {
|
||||||
let path = createPath({
|
const path = createPath({
|
||||||
pathname: 'https://google.com',
|
pathname: 'https://google.com',
|
||||||
hash: 'section-1',
|
hash: 'section-1',
|
||||||
});
|
});
|
||||||
|
@ -65,7 +65,7 @@ describe('createPath', () => {
|
||||||
|
|
||||||
describe('given a full location object', () => {
|
describe('given a full location object', () => {
|
||||||
it('returns the constructed pathname', () => {
|
it('returns the constructed pathname', () => {
|
||||||
let path = createPath({
|
const path = createPath({
|
||||||
pathname: 'https://google.com',
|
pathname: 'https://google.com',
|
||||||
search: 'something=cool',
|
search: 'something=cool',
|
||||||
hash: '#section-1',
|
hash: '#section-1',
|
||||||
|
|
|
@ -29,7 +29,7 @@ function useLocation() {
|
||||||
return useContext(RouterContext).location;
|
return useContext(RouterContext).location;
|
||||||
}
|
}
|
||||||
|
|
||||||
function useParams<P>(): Params<P> | {};
|
function useParams<P>(): Params<P> | Record<string, unknown>;
|
||||||
function useParams() {
|
function useParams() {
|
||||||
const match = useContext(RouterContext).match;
|
const match = useContext(RouterContext).match;
|
||||||
return match ? match.params : {};
|
return match ? match.params : {};
|
||||||
|
|
|
@ -38,9 +38,9 @@ describe('path lexer Test', () => {
|
||||||
expect(tokens).toStrictEqual([{ type: 'delimiter', value: '/' }]);
|
expect(tokens).toStrictEqual([{ type: 'delimiter', value: '/' }]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`don't start with a slash`, () => {
|
it('don\'t start with a slash', () => {
|
||||||
const func = () => lexer('abc.com');
|
const func = () => lexer('abc.com');
|
||||||
expect(func).toThrow(Error(`Url must start with "/".`));
|
expect(func).toThrow(Error('Url must start with "/".'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dynamic params test', () => {
|
it('dynamic params test', () => {
|
||||||
|
|
|
@ -26,9 +26,9 @@ export function lexer(path: string): Token[] {
|
||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
let urlPath = cleanPath(path);
|
const urlPath = cleanPath(path);
|
||||||
if (urlPath !== '*' && !urlPath.startsWith('/')) {
|
if (urlPath !== '*' && !urlPath.startsWith('/')) {
|
||||||
throw new Error(`Url must start with "/".`);
|
throw new Error('Url must start with "/".');
|
||||||
}
|
}
|
||||||
|
|
||||||
const getLiteral = () => {
|
const getLiteral = () => {
|
||||||
|
|
|
@ -84,7 +84,7 @@ export function createPathParser<P = unknown>(pathname: string, option: ParserOp
|
||||||
* @param currentIdx
|
* @param currentIdx
|
||||||
*/
|
*/
|
||||||
const lookToNextDelimiter = (currentIdx: number): boolean => {
|
const lookToNextDelimiter = (currentIdx: number): boolean => {
|
||||||
let hasOptionalParam: boolean = false;
|
let hasOptionalParam = false;
|
||||||
while (currentIdx < tokens.length && tokens[currentIdx].type !== TokenType.Delimiter) {
|
while (currentIdx < tokens.length && tokens[currentIdx].type !== TokenType.Delimiter) {
|
||||||
if (tokens[currentIdx].value === '?' || tokens[currentIdx].value === '*') {
|
if (tokens[currentIdx].value === '?' || tokens[currentIdx].value === '*') {
|
||||||
hasOptionalParam = true;
|
hasOptionalParam = true;
|
||||||
|
@ -98,8 +98,10 @@ export function createPathParser<P = unknown>(pathname: string, option: ParserOp
|
||||||
const nextToken = tokens[tokenIdx + 1];
|
const nextToken = tokens[tokenIdx + 1];
|
||||||
switch (token.type) {
|
switch (token.type) {
|
||||||
case TokenType.Delimiter:
|
case TokenType.Delimiter:
|
||||||
const hasOptional = lookToNextDelimiter(tokenIdx + 1);
|
{
|
||||||
pattern += `/${hasOptional ? '?' : ''}`;
|
const hasOptional = lookToNextDelimiter(tokenIdx + 1);
|
||||||
|
pattern += `/${hasOptional ? '?' : ''}`;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TokenType.Static:
|
case TokenType.Static:
|
||||||
pattern += token.value.replace(REGEX_CHARS_RE, '\\$&');
|
pattern += token.value.replace(REGEX_CHARS_RE, '\\$&');
|
||||||
|
@ -111,28 +113,30 @@ export function createPathParser<P = unknown>(pathname: string, option: ParserOp
|
||||||
scores.push(MatchScore.static);
|
scores.push(MatchScore.static);
|
||||||
break;
|
break;
|
||||||
case TokenType.Param:
|
case TokenType.Param:
|
||||||
// 动态参数支持形如/:param、/:param*、/:param?、/:param(\\d+)的形式
|
{
|
||||||
let paramRegexp = '';
|
// 动态参数支持形如/:param、/:param*、/:param?、/:param(\\d+)的形式
|
||||||
if (nextToken) {
|
let paramRegexp = '';
|
||||||
switch (nextToken.type) {
|
if (nextToken) {
|
||||||
case TokenType.LBracket:
|
switch (nextToken.type) {
|
||||||
// 跳过当前Token和左括号
|
case TokenType.LBracket:
|
||||||
tokenIdx += 2;
|
// 跳过当前Token和左括号
|
||||||
while (tokens[tokenIdx].type !== TokenType.RBracket) {
|
tokenIdx += 2;
|
||||||
paramRegexp += tokens[tokenIdx].value;
|
while (tokens[tokenIdx].type !== TokenType.RBracket) {
|
||||||
|
paramRegexp += tokens[tokenIdx].value;
|
||||||
|
tokenIdx++;
|
||||||
|
}
|
||||||
|
paramRegexp = `(${paramRegexp})`;
|
||||||
|
break;
|
||||||
|
case TokenType.Pattern:
|
||||||
tokenIdx++;
|
tokenIdx++;
|
||||||
}
|
paramRegexp += `(${nextToken.value === '*' ? '.*' : BASE_PARAM_PATTERN})${nextToken.value}`;
|
||||||
paramRegexp = `(${paramRegexp})`;
|
break;
|
||||||
break;
|
}
|
||||||
case TokenType.Pattern:
|
|
||||||
tokenIdx++;
|
|
||||||
paramRegexp += `(${nextToken.value === '*' ? '.*' : BASE_PARAM_PATTERN})${nextToken.value}`;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
pattern += paramRegexp ? `(?:${paramRegexp})` : `(${BASE_PARAM_PATTERN})`;
|
||||||
|
keys.push(token.value);
|
||||||
|
scores.push(MatchScore.param);
|
||||||
}
|
}
|
||||||
pattern += paramRegexp ? `(?:${paramRegexp})` : `(${BASE_PARAM_PATTERN})`;
|
|
||||||
keys.push(token.value);
|
|
||||||
scores.push(MatchScore.param);
|
|
||||||
break;
|
break;
|
||||||
case TokenType.WildCard:
|
case TokenType.WildCard:
|
||||||
keys.push(token.value);
|
keys.push(token.value);
|
||||||
|
@ -167,13 +171,13 @@ export function createPathParser<P = unknown>(pathname: string, option: ParserOp
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const matchedPath = reMatch[0];
|
const matchedPath = reMatch[0];
|
||||||
let params: Params<P> = {};
|
const params: Params<P> = {};
|
||||||
let parseScore: number[] = Array.from(scores);
|
const parseScore: number[] = Array.from(scores);
|
||||||
for (let i = 1; i < reMatch.length; i++) {
|
for (let i = 1; i < reMatch.length; i++) {
|
||||||
let param = reMatch[i];
|
const param = reMatch[i];
|
||||||
let key = keys[i - 1];
|
const key = keys[i - 1];
|
||||||
if (key === '*' && param) {
|
if (key === '*' && param) {
|
||||||
let value = param.split('/');
|
const value = param.split('/');
|
||||||
if (!Array.isArray(params['*'])) {
|
if (!Array.isArray(params['*'])) {
|
||||||
params['*'] = value;
|
params['*'] = value;
|
||||||
} else {
|
} else {
|
||||||
|
@ -212,11 +216,13 @@ export function createPathParser<P = unknown>(pathname: string, option: ParserOp
|
||||||
path += params[token.value];
|
path += params[token.value];
|
||||||
break;
|
break;
|
||||||
case TokenType.WildCard:
|
case TokenType.WildCard:
|
||||||
let wildCard = params['*'];
|
{
|
||||||
if (wildCard instanceof Array) {
|
const wildCard = params['*'];
|
||||||
path += wildCard.join('/');
|
if (wildCard instanceof Array) {
|
||||||
} else {
|
path += wildCard.join('/');
|
||||||
path += wildCard;
|
} else {
|
||||||
|
path += wildCard;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TokenType.Delimiter:
|
case TokenType.Delimiter:
|
||||||
|
@ -250,7 +256,7 @@ export function matchPath<P = any>(
|
||||||
const patterns = Array.isArray(pattern) ? [...pattern] : [pattern];
|
const patterns = Array.isArray(pattern) ? [...pattern] : [pattern];
|
||||||
const matchedResults: Matched<P>[] = [];
|
const matchedResults: Matched<P>[] = [];
|
||||||
for (const item of patterns) {
|
for (const item of patterns) {
|
||||||
const parser = createPathParser(item, option);
|
const parser = createPathParser<P>(item, option);
|
||||||
const matched = parser.parse(pathname);
|
const matched = parser.parse(pathname);
|
||||||
if (matched) {
|
if (matched) {
|
||||||
matchedResults.push(matched);
|
matchedResults.push(matched);
|
||||||
|
|
|
@ -56,7 +56,7 @@ type ParseParam<Param extends string> = Param extends `:${infer R}`
|
||||||
? {
|
? {
|
||||||
[K in R]: string;
|
[K in R]: string;
|
||||||
}
|
}
|
||||||
: {};
|
: Record<string, unknown>;
|
||||||
|
|
||||||
type MergeParams<OneParam extends Record<string, any>, OtherParam extends Record<string, any>> = {
|
type MergeParams<OneParam extends Record<string, any>, OtherParam extends Record<string, any>> = {
|
||||||
readonly [Key in keyof OneParam | keyof OtherParam]?: string;
|
readonly [Key in keyof OneParam | keyof OtherParam]?: string;
|
||||||
|
|
|
@ -20,10 +20,10 @@ import { createWeakMapProxy } from './WeakMapProxy';
|
||||||
import { createMapProxy } from './MapProxy';
|
import { createMapProxy } from './MapProxy';
|
||||||
|
|
||||||
export function createCollectionProxy(
|
export function createCollectionProxy(
|
||||||
rawObj: Object,
|
rawObj: Record<string, unknown>,
|
||||||
listener: { current: (...args) => any },
|
listener: { current: (...args) => any },
|
||||||
hookObserver = true
|
hookObserver = true
|
||||||
): Object {
|
): ProxyHandler<Record<string, unknown>> {
|
||||||
if (isWeakSet(rawObj)) {
|
if (isWeakSet(rawObj)) {
|
||||||
return createWeakSetProxy(rawObj, listener, hookObserver);
|
return createWeakSetProxy(rawObj, listener, hookObserver);
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,7 +311,7 @@ export function createStore<S extends Record<string, any>, A extends UserActions
|
||||||
}
|
}
|
||||||
|
|
||||||
// 函数组件中使用的hook
|
// 函数组件中使用的hook
|
||||||
export function useStore<S extends object, A extends UserActions<S>, C extends UserComputedValues<S>>(
|
export function useStore<S extends Record<string, unknown>, A extends UserActions<S>, C extends UserComputedValues<S>>(
|
||||||
id: string
|
id: string
|
||||||
): StoreObj<S, A, C> {
|
): StoreObj<S, A, C> {
|
||||||
const storeObj = storeMap.get(id);
|
const storeObj = storeMap.get(id);
|
||||||
|
|
|
@ -31,7 +31,7 @@ export interface IObserver {
|
||||||
clearByVNode: (vNode: any) => void;
|
clearByVNode: (vNode: any) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type StoreConfig<S extends object, A extends UserActions<S>, C extends UserComputedValues<S>> = {
|
export type StoreConfig<S extends Record<string, unknown>, A extends UserActions<S>, C extends UserComputedValues<S>> = {
|
||||||
id?: string;
|
id?: string;
|
||||||
state?: S;
|
state?: S;
|
||||||
actions?: A;
|
actions?: A;
|
||||||
|
@ -41,22 +41,22 @@ export type StoreConfig<S extends object, A extends UserActions<S>, C extends Us
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UserActions<S extends object> = {
|
export type UserActions<S extends Record<string, unknown>> = {
|
||||||
[K: string]: ActionFunction<S>;
|
[K: string]: ActionFunction<S>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ActionFunction<S extends object> = (this: StoreObj<S, any, any>, state: S, ...args: any[]) => any;
|
export type ActionFunction<S extends Record<string, unknown>> = (this: StoreObj<S, any, any>, state: S, ...args: any[]) => any;
|
||||||
|
|
||||||
export type StoreActions<S extends object, A extends UserActions<S>> = {
|
export type StoreActions<S extends Record<string, unknown>, A extends UserActions<S>> = {
|
||||||
[K in keyof A]: Action<A[K], S>;
|
[K in keyof A]: Action<A[K], S>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Action<T extends ActionFunction<any>, S extends object> = (
|
type Action<T extends ActionFunction<any>, S extends Record<string, unknown>> = (
|
||||||
this: StoreObj<S, any, any>,
|
this: StoreObj<S, any, any>,
|
||||||
...args: RemoveFirstFromTuple<Parameters<T>>
|
...args: RemoveFirstFromTuple<Parameters<T>>
|
||||||
) => ReturnType<T>;
|
) => ReturnType<T>;
|
||||||
|
|
||||||
export type StoreObj<S extends object, A extends UserActions<S>, C extends UserComputedValues<S>> = {
|
export type StoreObj<S extends Record<string, unknown>, A extends UserActions<S>, C extends UserComputedValues<S>> = {
|
||||||
$s: S;
|
$s: S;
|
||||||
$a: StoreActions<S, A>;
|
$a: StoreActions<S, A>;
|
||||||
$c: UserComputedValues<S>;
|
$c: UserComputedValues<S>;
|
||||||
|
@ -66,7 +66,7 @@ export type StoreObj<S extends object, A extends UserActions<S>, C extends UserC
|
||||||
$unsubscribe: (listener: (mutation) => void) => void;
|
$unsubscribe: (listener: (mutation) => void) => void;
|
||||||
} & { [K in keyof S]: S[K] } & { [K in keyof A]: Action<A[K], S> } & { [K in keyof C]: ReturnType<C[K]> };
|
} & { [K in keyof S]: S[K] } & { [K in keyof A]: Action<A[K], S> } & { [K in keyof C]: ReturnType<C[K]> };
|
||||||
|
|
||||||
export type PlannedAction<S extends object, F extends ActionFunction<S>> = {
|
export type PlannedAction<S extends Record<string, unknown>, F extends ActionFunction<S>> = {
|
||||||
action: string;
|
action: string;
|
||||||
payload: any[];
|
payload: any[];
|
||||||
resolve: ReturnType<F>;
|
resolve: ReturnType<F>;
|
||||||
|
@ -78,21 +78,21 @@ type RemoveFirstFromTuple<T extends any[]> = T['length'] extends 0
|
||||||
? I
|
? I
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
export type UserComputedValues<S extends object> = {
|
export type UserComputedValues<S extends Record<string, unknown>> = {
|
||||||
[K: string]: ComputedFunction<S>;
|
[K: string]: ComputedFunction<S>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ComputedFunction<S extends object> = (state: S) => any;
|
type ComputedFunction<S extends Record<string, unknown>> = (state: S) => any;
|
||||||
|
|
||||||
export type AsyncAction<T extends ActionFunction<any>, S extends object> = (
|
export type AsyncAction<T extends ActionFunction<any>, S extends Record<string, unknown>> = (
|
||||||
this: StoreObj<S, any, any>,
|
this: StoreObj<S, any, any>,
|
||||||
...args: RemoveFirstFromTuple<Parameters<T>>
|
...args: RemoveFirstFromTuple<Parameters<T>>
|
||||||
) => Promise<ReturnType<T>>;
|
) => Promise<ReturnType<T>>;
|
||||||
|
|
||||||
export type QueuedStoreActions<S extends object, A extends UserActions<S>> = {
|
export type QueuedStoreActions<S extends Record<string, unknown>, A extends UserActions<S>> = {
|
||||||
[K in keyof A]: AsyncAction<A[K], S>;
|
[K in keyof A]: AsyncAction<A[K], S>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ComputedValues<S extends object, C extends UserComputedValues<S>> = {
|
export type ComputedValues<S extends Record<string, unknown>, C extends UserComputedValues<S>> = {
|
||||||
[K in keyof C]: ReturnType<C[K]>;
|
[K in keyof C]: ReturnType<C[K]>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -105,25 +105,27 @@ export function handleRenderThrowError(sourceVNode: VNode, error: any) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case ClassComponent:
|
case ClassComponent:
|
||||||
const ctor = vNode.type;
|
{
|
||||||
const instance = vNode.realNode;
|
const ctor = vNode.type;
|
||||||
if (
|
const instance = vNode.realNode;
|
||||||
(vNode.flags & DidCapture) === InitFlag &&
|
if (
|
||||||
(typeof ctor.getDerivedStateFromError === 'function' ||
|
(vNode.flags & DidCapture) === InitFlag &&
|
||||||
(instance !== null && typeof instance.componentDidCatch === 'function'))
|
(typeof ctor.getDerivedStateFromError === 'function' ||
|
||||||
) {
|
(instance !== null && typeof instance.componentDidCatch === 'function'))
|
||||||
FlagUtils.markShouldCapture(vNode);
|
) {
|
||||||
|
FlagUtils.markShouldCapture(vNode);
|
||||||
|
|
||||||
// Class捕捉到异常,触发一次刷新
|
// Class捕捉到异常,触发一次刷新
|
||||||
const update = createClassErrorUpdate(vNode, error);
|
const update = createClassErrorUpdate(vNode, error);
|
||||||
pushUpdate(vNode, update);
|
pushUpdate(vNode, update);
|
||||||
|
|
||||||
launchUpdateFromVNode(vNode);
|
launchUpdateFromVNode(vNode);
|
||||||
|
|
||||||
// 有异常处理类,把抛出异常的节点的Interrupted标志去掉,继续走正常的绘制流程
|
// 有异常处理类,把抛出异常的节点的Interrupted标志去掉,继续走正常的绘制流程
|
||||||
FlagUtils.removeFlag(sourceVNode, Interrupted);
|
FlagUtils.removeFlag(sourceVNode, Interrupted);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -53,19 +53,25 @@ export function pushUpdate(vNode: VNode, update: Update) {
|
||||||
// 根据update获取新的state
|
// 根据update获取新的state
|
||||||
function calcState(vNode: VNode, update: Update, inst: any, oldState: any, props: any): any {
|
function calcState(vNode: VNode, update: Update, inst: any, oldState: any, props: any): any {
|
||||||
switch (update.type) {
|
switch (update.type) {
|
||||||
case UpdateState.Override:
|
case UpdateState.Override: {
|
||||||
const content = update.content;
|
const content = update.content;
|
||||||
return typeof content === 'function' ? content.call(inst, oldState, props) : content;
|
return typeof content === 'function' ? content.call(inst, oldState, props) : content;
|
||||||
|
}
|
||||||
case UpdateState.ForceUpdate:
|
case UpdateState.ForceUpdate:
|
||||||
vNode.isForceUpdate = true;
|
vNode.isForceUpdate = true;
|
||||||
return oldState;
|
return oldState;
|
||||||
case UpdateState.Error:
|
case UpdateState.Error: {
|
||||||
FlagUtils.removeFlag(vNode, ShouldCapture);
|
FlagUtils.removeFlag(vNode, ShouldCapture);
|
||||||
FlagUtils.markDidCapture(vNode);
|
FlagUtils.markDidCapture(vNode);
|
||||||
case UpdateState.Update:
|
|
||||||
const updateContent = update.content;
|
const updateContent = update.content;
|
||||||
const newState = typeof updateContent === 'function' ? updateContent.call(inst, oldState, props) : updateContent;
|
const newState = typeof updateContent === 'function' ? updateContent.call(inst, oldState, props) : updateContent;
|
||||||
return newState === null || newState === undefined ? oldState : { ...oldState, ...newState };
|
return newState === null || newState === undefined ? oldState : { ...oldState, ...newState };
|
||||||
|
}
|
||||||
|
case UpdateState.Update: {
|
||||||
|
const updateContent = update.content;
|
||||||
|
const newState = typeof updateContent === 'function' ? updateContent.call(inst, oldState, props) : updateContent;
|
||||||
|
return newState === null || newState === undefined ? oldState : { ...oldState, ...newState };
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return oldState;
|
return oldState;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,6 @@ function callRenderQueue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderQueue = null;
|
renderQueue = null;
|
||||||
} catch (error) {
|
|
||||||
throw error;
|
|
||||||
} finally {
|
} finally {
|
||||||
isCallingRenderQueue = false;
|
isCallingRenderQueue = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,10 +60,13 @@ function newVirtualNode(tag: VNodeTag, key?: null | string, vNodeProps?: any, re
|
||||||
return new VNode(tag, vNodeProps, key as null | string, realNode);
|
return new VNode(tag, vNodeProps, key as null | string, realNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isClassComponent(comp: Function) {
|
type FunctionType = typeof Function;
|
||||||
|
|
||||||
|
function isClassComponent(comp: FunctionType) {
|
||||||
// 如果使用 getPrototypeOf 方法获取构造函数,不能兼容业务组组件继承组件的使用方式,会误认为是函数组件
|
// 如果使用 getPrototypeOf 方法获取构造函数,不能兼容业务组组件继承组件的使用方式,会误认为是函数组件
|
||||||
// 如果使用静态属性,部分函数高阶组件会将类组件的静态属性复制到自身,导致误判为类组件
|
// 如果使用静态属性,部分函数高阶组件会将类组件的静态属性复制到自身,导致误判为类组件
|
||||||
// 既然已经兼容使用了该标识符,那么继续使用
|
// 既然已经兼容使用了该标识符,那么继续使用
|
||||||
|
// @ts-ignore
|
||||||
return comp.prototype?.isReactComponent === true;
|
return comp.prototype?.isReactComponent === true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +77,7 @@ export function getLazyVNodeTag(lazyComp: any): string {
|
||||||
} else if (lazyComp !== undefined && lazyComp !== null && typeLazyMap[lazyComp.vtype]) {
|
} else if (lazyComp !== undefined && lazyComp !== null && typeLazyMap[lazyComp.vtype]) {
|
||||||
return typeLazyMap[lazyComp.vtype];
|
return typeLazyMap[lazyComp.vtype];
|
||||||
}
|
}
|
||||||
throw Error("Inula can't resolve the content of lazy");
|
throw Error('Inula can\'t resolve the content of lazy');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建processing
|
// 创建processing
|
||||||
|
|
Loading…
Reference in New Issue