Skip to content

Commit

Permalink
feat: support specifying packages as real-external dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
AnYiEE committed Feb 27, 2024
1 parent 697f611 commit 9de25a3
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 42 deletions.
30 changes: 20 additions & 10 deletions .vscode/json-schemas/definition.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,6 @@
"title": "是否启用当前小工具 / Enable the current gadget or not",
"default": true
},
"excludeSites": {
"type": "array",
"title": "在给定站点上禁用当前小工具 / Disable the current gadget on given sites",
"default": [],
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"description": {
"type": "string",
"title": "“MediaWiki:Gadget-小工具名”页面中的文本,默认为当前小工具名 / The content in the page 'MediaWiki:Gadget-${gadgetName}' (default: the current gadget name)"
Expand All @@ -29,6 +19,26 @@
"examples": ["appear", "browser", "compatibility", "edit", "sysop"],
"minLength": 1
},
"excludeSites": {
"type": "array",
"title": "在给定站点上禁用当前小工具 / Disable the current gadget on given sites",
"default": [],
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"externalPackages": {
"type": "array",
"title": "除 dependencies 属性中的包之外,额外指定 esbuild 的 external 编译选项 / Specify additional esbuild external compilation options",
"default": [],
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"actions": {
"type": "array",
"default": [],
Expand Down
3 changes: 2 additions & 1 deletion scripts/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ const HEADER = `/**
*/
const DEFAULT_DEFINITION = {
enable: true,
excludeSites: [],
description: '', // 回落值为小工具名称 / Fallback value: the name of the current gadget
section: '', // 回落值为 appear / Fallback value: appear
excludeSites: [],
externalPackages: [],
actions: [],
contentModels: [],
default: false,
Expand Down
4 changes: 3 additions & 1 deletion scripts/modules/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ const build = async (): Promise<void> => {
continue;
}

const {dependencies, externalPackages} = definition;
const builtScriptFileNames: string[] = await buildFiles(gadgetName, 'script', {
dependencies,
externalPackages,
licenseText,
dependencies: definition.dependencies,
files: generateFileArray(script, scripts),
});
const scriptFileNames: string = generateFileNames(gadgetName, builtScriptFileNames);
Expand Down
6 changes: 4 additions & 2 deletions scripts/modules/formatJSON.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,15 @@ const formatJSON = async (paths: string[]): Promise<void> => {
break;
}

const {enable, excludeSites, description, section} = object as unknown as DefaultDefinition;
const {enable, description, section, excludeSites, externalPackages} =
object as unknown as DefaultDefinition;

let definitionSorted: Partial<DefaultDefinition> = {
enable,
excludeSites,
description,
section,
excludeSites,
externalPackages,
};
definitionSorted = {
...definitionSorted,
Expand Down
6 changes: 2 additions & 4 deletions scripts/modules/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ type Credentials = CredentialsOnlyOAuth | CredentialsOnlyOAuth2 | CredentialsOnl

interface DefaultDefinition {
enable: boolean;
excludeSites: string[];
description: string;
section: string;
excludeSites: string[];
externalPackages: string[];
actions: string[];
contentModels: string[];
default: boolean;
Expand All @@ -54,8 +55,6 @@ interface DefaultSectionMap {
[key: DefaultDefinition['section']]: string;
}

type Dependencies = DefaultDefinition['dependencies'];

type DeploymentDirectTargets = [string, string][];

interface DeploymentTargets {
Expand Down Expand Up @@ -95,7 +94,6 @@ export type {
CredentialsOnlyPassword,
DefaultDefinition,
DefaultSectionMap,
Dependencies,
DeploymentDirectTargets,
DeploymentTargets,
GlobalSourceFiles,
Expand Down
81 changes: 57 additions & 24 deletions scripts/modules/utils/build-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import * as PACKAGE from '../../../package.json';
import {BANNER, GLOBAL_REQUIRES_ES6, SOURCE_MAP} from '../../constant';
import {type BabelFileResult, type TransformOptions, transformAsync} from '@babel/core';
import {type BuildResult, type OutputFile, build as esbuild} from 'esbuild';
import type {BuiltFiles, Dependencies, SourceFiles} from '../types';
import type {BuiltFiles, DefaultDefinition, SourceFiles} from '../types';
import {type Path, globSync} from 'glob';
import {
__rootDir,
generateArray,
generateBannerAndFooter,
generateDefinition,
readFileContent,
Expand Down Expand Up @@ -38,17 +39,22 @@ const writeFile = (outputFilePath: string, sourceCode: string): void => {
* @private
* @param {string} inputFilePath
* @param {string} outputFilePath
* @param {Dependencies} [dependencies]
* @param {Object} object
* @param {DefaultDefinition['dependencies']|undefined} [object.dependencies]
* @param {DefaultDefinition['externalPackages']|undefined} [object.externalPackages]
* @param {string} object.licenseText
* @return {Promise<BuiltFiles>}
*/
const build = async (
inputFilePath: string,
outputFilePath: string,
{
dependencies,
externalPackages,
licenseText,
}: {
dependencies?: Dependencies | undefined;
dependencies?: DefaultDefinition['dependencies'] | undefined;
externalPackages?: DefaultDefinition['externalPackages'] | undefined;
licenseText: string | undefined;
}
): Promise<BuiltFiles> => {
Expand All @@ -60,7 +66,7 @@ const build = async (
licenseText,
isProcessJs: false,
}),
external: dependencies ?? [],
external: generateArray(dependencies, externalPackages),
entryPoints: [inputFilePath],
outfile: outputFilePath,
});
Expand All @@ -87,17 +93,22 @@ const build = async (
* @private
* @param {string} outputFilePath
* @param {string} sourceCode
* @param {Dependencies} dependencies
* @param {Object} object
* @param {DefaultDefinition['dependencies']|undefined} object.dependencies
* @param {DefaultDefinition['externalPackages']|undefined} object.externalPackages
* @param {string} object.licenseText
* @return {Promise<string>}
*/
const bundle = async (
outputFilePath: string,
sourceCode: string,
{
dependencies,
externalPackages,
licenseText,
}: {
dependencies: Dependencies | undefined;
dependencies: DefaultDefinition['dependencies'] | undefined;
externalPackages: DefaultDefinition['externalPackages'] | undefined;
licenseText: string | undefined;
}
): Promise<string> => {
Expand All @@ -106,7 +117,7 @@ const bundle = async (
...generateBannerAndFooter({
licenseText,
}),
external: dependencies ?? [],
external: generateArray(dependencies, externalPackages),
stdin: {
contents: sourceCode,
resolveDir: __rootDir,
Expand Down Expand Up @@ -220,17 +231,22 @@ const transform = async (inputFilePath: string, sourceCode: string): Promise<str
* @private
* @param {string} gadgetName
* @param {string} scriptFileName
* @param {{dependencies:Dependencies; licenseText:string|undefined}} object
* @param {Object} object
* @param {DefaultDefinition['dependencies']|undefined} object.dependencies
* @param {DefaultDefinition['externalPackages']|undefined} object.externalPackages
* @param {string} object.licenseText
* @return {Promise<string[]>}
*/
const buildScript = async (
gadgetName: string,
scriptFileName: string,
{
dependencies,
externalPackages,
licenseText,
}: {
dependencies: Dependencies | undefined;
dependencies: DefaultDefinition['dependencies'] | undefined;
externalPackages: DefaultDefinition['externalPackages'] | undefined;
licenseText: string | undefined;
}
): Promise<string[]> => {
Expand All @@ -244,6 +260,7 @@ const buildScript = async (

const builtFiles: BuiltFiles = await build(inputFilePath, outputFilePath, {
dependencies,
externalPackages,
licenseText,
});
for (const builtFile of builtFiles) {
Expand All @@ -261,6 +278,7 @@ const buildScript = async (
const transformOutput: string = await transform(inputFilePath, text);
const bundleOutput: string = await bundle(outputFilePath, transformOutput, {
dependencies,
externalPackages,
licenseText,
});
if (!bundleOutput) {
Expand Down Expand Up @@ -306,18 +324,24 @@ const buildStyle = async (
/**
* @param {string} gadgetName The gadget name
* @param {'script'|'style'} type The type of target files
* @param {{dependencies?:Dependencies; files:string[]; licenseText:string|undefined}} object The dependencies of this gadget, the array of file name for this gadget and the license file content of this gadget
* @param {Object} object
* @param {DefaultDefinition['dependencies']} [object.dependencies]
* @param {DefaultDefinition['externalPackages']} [object.externalPackages]
* @param {string[]} object.files
* @param {string} object.licenseText
* @return {Promise<string[]>} The array of built file names
*/
async function buildFiles(
gadgetName: string,
type: 'script',
{
dependencies,
externalPackages,
files,
licenseText,
}: {
dependencies: Dependencies;
dependencies: DefaultDefinition['dependencies'];
externalPackages: DefaultDefinition['externalPackages'];
files: string[];
licenseText: string | undefined;
}
Expand All @@ -339,10 +363,12 @@ async function buildFiles(
type: 'script' | 'style',
{
dependencies,
externalPackages,
files,
licenseText,
}: {
dependencies?: Dependencies;
dependencies?: DefaultDefinition['dependencies'];
externalPackages?: DefaultDefinition['externalPackages'];
files: string[];
licenseText: string | undefined;
}
Expand All @@ -355,6 +381,7 @@ async function buildFiles(
outputFileNames.push(
...(await buildScript(gadgetName, fileName, {
dependencies,
externalPackages,
licenseText,
}))
);
Expand Down Expand Up @@ -400,20 +427,25 @@ const fallbackDefinition = (sourceFiles: SourceFiles): void => {
* @param {SourceFiles} sourceFiles
*/
const filterOutInvalidDependencies = (sourceFiles: SourceFiles): void => {
for (const gadgetFiles of Object.values(sourceFiles)) {
const {
definition: {dependencies},
} = gadgetFiles;

gadgetFiles.definition.dependencies = dependencies
.filter((dependency: string): boolean => {
return typeof dependency === 'string' && !!dependency.trim();
const filter = (array: string[]): string[] => {
return array
.filter((item: string): boolean => {
return typeof item === 'string' && !!item.trim();
})
.map((dependency: string): string => {
return trim(dependency, {
.map((item: string): string => {
return trim(item, {
addNewline: false,
});
});
};

for (const gadgetFiles of Object.values(sourceFiles)) {
const {
definition: {dependencies, externalPackages},
} = gadgetFiles;

gadgetFiles.definition.dependencies = filter(dependencies);
gadgetFiles.definition.externalPackages = filter(externalPackages);
}
};

Expand Down Expand Up @@ -600,9 +632,10 @@ const generateDefinitionItem = (
[
// Keys for internal use
'enable',
'excludeSites',
'description',
'section',
'excludeSites',
'externalPackages',
// Keys that no need to be specified
'package',
'targets',
Expand Down Expand Up @@ -666,7 +699,7 @@ const generateDefinitionItem = (
* @return {string[]} The generated file name array
*/
const generateFileArray = (file: string | undefined, files: string[] | undefined): string[] => {
return file ? [file] : files ?? [];
return file ? generateArray(file) : generateArray(files);
};

/**
Expand Down
26 changes: 26 additions & 0 deletions scripts/modules/utils/general-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,31 @@ const writeFileContent = (filePath: number | string, fileContent: string): void
closeSync(fileDescriptor);
};

/**
* Generate an array and filter out null and undefined values
*
* @param {T} args The given arguments
* @return {NonNullable<T>[]} The generated array
*/
function generateArray<T extends []>(...args: (T | T[])[]): NonNullable<T>[];
function generateArray<T = unknown>(...args: (T | T[])[]): NonNullable<T>[];
// eslint-disable-next-line func-style
function generateArray<T>(...args: (T | T[])[]): T[] {
return args.flatMap((arg) => {
if (arg === null || arg === undefined) {
return [];
}

if (Array.isArray(arg)) {
return arg.filter((item): boolean => {
return item !== null && item !== undefined;
});
}

return [arg];
});
}

/**
* Sort an object
*
Expand Down Expand Up @@ -299,6 +324,7 @@ export {
exec,
readFileContent,
writeFileContent,
generateArray,
sortObject,
trim,
prompt,
Expand Down

0 comments on commit 9de25a3

Please sign in to comment.