mirror of
https://github.com/danielsogl/awesome-cordova-plugins.git
synced 2026-03-25 00:00:14 +08:00
fix: add strict types to build scripts and remove all any usage
Replace all implicit and explicit any types in build scripts with proper TypeScript Compiler API types (Decorator, ClassDeclaration, MethodDeclaration, Identifier, SourceFile, etc.). Add PackageJson and InjectableClassEntry interfaces. Fix return types, null checks, and type assertions throughout all transformer scripts.
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { readdirSync } from 'node:fs';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { readdirSync, readFileSync } from 'node:fs';
|
||||
import { join, resolve } from 'node:path';
|
||||
import {
|
||||
ArrayLiteralExpression,
|
||||
@@ -20,35 +19,43 @@ export const ROOT = resolve(__dirname, '../../');
|
||||
export const TS_CONFIG = JSON.parse(readFileSync(resolve(ROOT, 'tsconfig.json'), 'utf-8'));
|
||||
export const COMPILER_OPTIONS = TS_CONFIG.compilerOptions;
|
||||
export const PLUGINS_ROOT = join(ROOT, 'src/@awesome-cordova-plugins/plugins/');
|
||||
export const PLUGIN_PATHS = readdirSync(PLUGINS_ROOT).map((d) => join(PLUGINS_ROOT, d, 'index.ts'));
|
||||
export const PLUGIN_PATHS = readdirSync(PLUGINS_ROOT).map((d: string) => join(PLUGINS_ROOT, d, 'index.ts'));
|
||||
|
||||
export function getDecorator(node: Node, index = 0): Decorator {
|
||||
export function getDecorator(node: Node, index = 0): Decorator | undefined {
|
||||
const decorators = canHaveDecorators(node) ? tsGetDecorators(node) : undefined;
|
||||
if (decorators && decorators[index]) {
|
||||
return decorators[index];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function hasDecorator(decoratorName: string, node: Node): boolean {
|
||||
const decorators = canHaveDecorators(node) ? tsGetDecorators(node) : undefined;
|
||||
return decorators && decorators.length > 0 && decorators.findIndex((d) => getDecoratorName(d) === decoratorName) > -1;
|
||||
return (
|
||||
!!decorators && decorators.length > 0 && decorators.findIndex((d) => getDecoratorName(d) === decoratorName) > -1
|
||||
);
|
||||
}
|
||||
|
||||
export function getDecoratorName(decorator: any) {
|
||||
return decorator.expression.expression.text;
|
||||
export function getDecoratorName(decorator: Decorator): string {
|
||||
return (decorator.expression as unknown as { expression: { text: string } }).expression.text;
|
||||
}
|
||||
|
||||
export function getRawDecoratorArgs(decorator: any): any[] {
|
||||
if (decorator.expression.arguments.length === 0) return [];
|
||||
return decorator.expression.arguments[0].properties;
|
||||
export function getRawDecoratorArgs(
|
||||
decorator: Decorator
|
||||
): Array<{ name: { text: string }; initializer: { kind: number; text: string; elements: Array<{ text: string }> } }> {
|
||||
const expr = decorator.expression as unknown as {
|
||||
arguments: Array<{ properties: ReturnType<typeof getRawDecoratorArgs> }>;
|
||||
};
|
||||
if (expr.arguments.length === 0) return [];
|
||||
return expr.arguments[0].properties;
|
||||
}
|
||||
|
||||
export function getDecoratorArgs(decorator: any) {
|
||||
const properties: any[] = getRawDecoratorArgs(decorator);
|
||||
const args = {};
|
||||
export function getDecoratorArgs(decorator: Decorator): Record<string, string | number | boolean | string[]> {
|
||||
const properties = getRawDecoratorArgs(decorator);
|
||||
const args: Record<string, string | number | boolean | string[]> = {};
|
||||
|
||||
properties.forEach((prop) => {
|
||||
let val: number | boolean;
|
||||
let val: string | number | boolean | string[];
|
||||
|
||||
switch (prop.initializer.kind) {
|
||||
case SyntaxKind.StringLiteral:
|
||||
@@ -57,7 +64,7 @@ export function getDecoratorArgs(decorator: any) {
|
||||
break;
|
||||
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
val = prop.initializer.elements.map((e: any) => e.text);
|
||||
val = prop.initializer.elements.map((e) => e.text);
|
||||
break;
|
||||
|
||||
case SyntaxKind.TrueKeyword:
|
||||
@@ -84,17 +91,16 @@ export function getDecoratorArgs(decorator: any) {
|
||||
}
|
||||
|
||||
/**
|
||||
* FROM STENCIL
|
||||
* Convert a js value into typescript AST
|
||||
* @param val array, object, string, boolean, or number
|
||||
* @returns Typescript Object Literal, Array Literal, String Literal, Boolean Literal, Numeric Literal
|
||||
*/
|
||||
export function convertValueToLiteral(val: any) {
|
||||
export function convertValueToLiteral(
|
||||
val: string | number | boolean | string[] | Record<string, unknown> | unknown[]
|
||||
): Expression {
|
||||
if (Array.isArray(val)) {
|
||||
return arrayToArrayLiteral(val);
|
||||
}
|
||||
if (typeof val === 'object') {
|
||||
return objectToObjectLiteral(val);
|
||||
if (typeof val === 'object' && val !== null) {
|
||||
return objectToObjectLiteral(val as Record<string, unknown>);
|
||||
}
|
||||
if (typeof val === 'number') {
|
||||
return factory.createNumericLiteral(val);
|
||||
@@ -105,37 +111,26 @@ export function convertValueToLiteral(val: any) {
|
||||
if (typeof val === 'boolean') {
|
||||
return val ? factory.createTrue() : factory.createFalse();
|
||||
}
|
||||
throw new Error('Unexpected value type: ' + typeof val);
|
||||
}
|
||||
|
||||
/**
|
||||
* FROM STENCIL
|
||||
* Convert a js object into typescript AST
|
||||
* @param obj key value object
|
||||
* @returns Typescript Object Literal Expression
|
||||
*/
|
||||
function objectToObjectLiteral(obj: { [key: string]: any }): ObjectLiteralExpression {
|
||||
function objectToObjectLiteral(obj: Record<string, unknown>): ObjectLiteralExpression {
|
||||
const newProperties: ObjectLiteralElementLike[] = Object.keys(obj).map((key: string): ObjectLiteralElementLike => {
|
||||
return factory.createPropertyAssignment(
|
||||
factory.createStringLiteral(key),
|
||||
convertValueToLiteral(obj[key]) as Expression
|
||||
convertValueToLiteral(obj[key] as string | number | boolean | string[])
|
||||
);
|
||||
});
|
||||
|
||||
return factory.createObjectLiteralExpression(newProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* FROM STENCIL
|
||||
* Convert a js array into typescript AST
|
||||
* @param list arrayÏ
|
||||
* @returns Typescript Array Literal Expression
|
||||
*/
|
||||
function arrayToArrayLiteral(list: any[]): ArrayLiteralExpression {
|
||||
const newList: any[] = list.map(convertValueToLiteral);
|
||||
function arrayToArrayLiteral(list: unknown[]): ArrayLiteralExpression {
|
||||
const newList = list.map((item) => convertValueToLiteral(item as string | number | boolean));
|
||||
return factory.createArrayLiteralExpression(newList);
|
||||
}
|
||||
|
||||
export function getMethodsForDecorator(decoratorName: string) {
|
||||
export function getMethodsForDecorator(decoratorName: string): string[] {
|
||||
switch (decoratorName) {
|
||||
case 'CordovaProperty':
|
||||
return ['cordovaPropertyGet', 'cordovaPropertySet'];
|
||||
|
||||
@@ -23,7 +23,7 @@ export const EMIT_PATH = resolve(ROOT, 'injectable-classes.json');
|
||||
*/
|
||||
export function extractInjectables() {
|
||||
return (ctx: TransformationContext) => {
|
||||
return (tsSourceFile) => {
|
||||
return (tsSourceFile: any) => {
|
||||
if (tsSourceFile.fileName.indexOf('src/@awesome-cordova-plugins/plugins') > -1) {
|
||||
visitEachChild(
|
||||
tsSourceFile,
|
||||
@@ -36,7 +36,7 @@ export function extractInjectables() {
|
||||
if (isInjectable) {
|
||||
injectableClasses.push({
|
||||
file: tsSourceFile.path,
|
||||
className: (node as ClassDeclaration).name.text,
|
||||
className: (node as ClassDeclaration).name!.text,
|
||||
dirName: tsSourceFile.path.split(/[\\\/]+/).reverse()[1],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
import { factory, SourceFile, SyntaxKind, TransformationContext } from 'typescript';
|
||||
import { factory, Identifier, ImportSpecifier, SourceFile, SyntaxKind, TransformationContext } from 'typescript';
|
||||
|
||||
import { getMethodsForDecorator } from '../helpers';
|
||||
|
||||
function transformImports(file: SourceFile, ctx: TransformationContext, ngcBuild?: boolean) {
|
||||
function transformImports(file: SourceFile, _ctx: TransformationContext, ngcBuild?: boolean) {
|
||||
// remove angular imports
|
||||
if (!ngcBuild) {
|
||||
// @ts-expect-error
|
||||
file.statements = (file.statements as any).filter(
|
||||
(s: any) => !(s.kind === SyntaxKind.ImportDeclaration && s.moduleSpecifier.text === '@angular/core')
|
||||
);
|
||||
// @ts-expect-error — mutating readonly statements for transformer pipeline
|
||||
file.statements = (
|
||||
file.statements as unknown as Array<{ kind: number; moduleSpecifier?: { text: string } }>
|
||||
).filter((s) => !(s.kind === SyntaxKind.ImportDeclaration && s.moduleSpecifier?.text === '@angular/core'));
|
||||
}
|
||||
|
||||
// find the @awesome-cordova-plugins/core import statement
|
||||
const importStatement = (file.statements as any).find((s: any) => {
|
||||
return s.kind === SyntaxKind.ImportDeclaration && s.moduleSpecifier.text === '@awesome-cordova-plugins/core';
|
||||
});
|
||||
const importStatement = (file.statements as unknown as Array<Record<string, unknown>>).find((s) => {
|
||||
return (
|
||||
(s as { kind: number }).kind === SyntaxKind.ImportDeclaration &&
|
||||
(s as { moduleSpecifier: { text: string } }).moduleSpecifier.text === '@awesome-cordova-plugins/core'
|
||||
);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
}) as Record<string, any> | undefined;
|
||||
|
||||
// we're only interested in files containing @awesome-cordova-plugins/core import statement
|
||||
if (!importStatement) return file;
|
||||
@@ -27,7 +31,7 @@ function transformImports(file: SourceFile, ctx: TransformationContext, ngcBuild
|
||||
|
||||
const keep: string[] = ['getPromise', 'checkAvailability'];
|
||||
|
||||
let m;
|
||||
let m: RegExpExecArray | null;
|
||||
|
||||
while ((m = decoratorRegex.exec(file.text)) !== null) {
|
||||
if (m.index === decoratorRegex.lastIndex) {
|
||||
@@ -37,27 +41,27 @@ function transformImports(file: SourceFile, ctx: TransformationContext, ngcBuild
|
||||
}
|
||||
|
||||
if (decorators.length) {
|
||||
let methods = [];
|
||||
let methods: string[] = [];
|
||||
|
||||
decorators.forEach((d) => (methods = getMethodsForDecorator(d).concat(methods)));
|
||||
|
||||
const methodElements = methods.map((m) => factory.createIdentifier(m));
|
||||
const methodNames = methodElements.map((el) => el.escapedText);
|
||||
const methodElements = methods.map((name: string) => factory.createIdentifier(name));
|
||||
const methodNames = methodElements.map((el: Identifier) => el.escapedText);
|
||||
|
||||
importStatement.importClause.namedBindings.elements = [
|
||||
factory.createIdentifier('AwesomeCordovaNativePlugin'),
|
||||
...methodElements,
|
||||
...importStatement.importClause.namedBindings.elements.filter(
|
||||
(el) => keep.indexOf(el.name.text) !== -1 && methodNames.indexOf(el.name.text) === -1
|
||||
(el: ImportSpecifier) => keep.indexOf(el.name.text) !== -1 && methodNames.indexOf(el.name.text) === -1
|
||||
),
|
||||
];
|
||||
|
||||
if (ngcBuild) {
|
||||
importStatement.importClause.namedBindings.elements = importStatement.importClause.namedBindings.elements.map(
|
||||
(binding) => {
|
||||
(binding: Identifier & { name?: { text: string } }) => {
|
||||
if (binding.escapedText) {
|
||||
binding.name = {
|
||||
text: binding.escapedText,
|
||||
text: binding.escapedText as string,
|
||||
};
|
||||
}
|
||||
return binding;
|
||||
@@ -71,7 +75,7 @@ function transformImports(file: SourceFile, ctx: TransformationContext, ngcBuild
|
||||
|
||||
export function importsTransformer(ngcBuild?: boolean) {
|
||||
return (ctx: TransformationContext) => {
|
||||
return (tsSourceFile) => {
|
||||
return (tsSourceFile: SourceFile) => {
|
||||
return transformImports(tsSourceFile, ctx, ngcBuild);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,32 +1,45 @@
|
||||
import { canHaveDecorators, ClassDeclaration, factory, getDecorators as tsGetDecorators, SyntaxKind } from 'typescript';
|
||||
import {
|
||||
canHaveDecorators,
|
||||
ClassDeclaration,
|
||||
ClassElement,
|
||||
ConstructorDeclaration,
|
||||
factory,
|
||||
getDecorators as tsGetDecorators,
|
||||
MethodDeclaration,
|
||||
SyntaxKind,
|
||||
} from 'typescript';
|
||||
|
||||
import { transformMethod } from './methods';
|
||||
import { transformProperty } from './properties';
|
||||
|
||||
export function transformMembers(cls: ClassDeclaration) {
|
||||
export function transformMembers(cls: ClassDeclaration): ClassElement[] {
|
||||
const propertyIndices: number[] = [];
|
||||
|
||||
const members = cls.members.map((member: any, index: number) => {
|
||||
// only process decorated members
|
||||
const members = cls.members.map((member, index) => {
|
||||
const memberDecorators = canHaveDecorators(member) ? tsGetDecorators(member) : undefined;
|
||||
if (!memberDecorators || !memberDecorators.length) return member;
|
||||
|
||||
switch (member.kind) {
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
return transformMethod(member);
|
||||
return transformMethod(member as MethodDeclaration) ?? member;
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
propertyIndices.push(index);
|
||||
return member;
|
||||
case SyntaxKind.Constructor:
|
||||
return factory.createConstructorDeclaration(undefined, member.parameters, member.body);
|
||||
case SyntaxKind.Constructor: {
|
||||
const ctor = member as ConstructorDeclaration;
|
||||
return factory.createConstructorDeclaration(undefined, ctor.parameters, ctor.body);
|
||||
}
|
||||
default:
|
||||
return member; // in case anything gets here by accident...
|
||||
return member;
|
||||
}
|
||||
});
|
||||
}) as ClassElement[];
|
||||
|
||||
propertyIndices.forEach((i: number) => {
|
||||
const [getter, setter] = transformProperty(members, i) as any;
|
||||
members.push(getter, setter);
|
||||
const result = transformProperty(members, i);
|
||||
if (Array.isArray(result)) {
|
||||
const [getter, setter] = result;
|
||||
members.push(getter, setter);
|
||||
}
|
||||
});
|
||||
|
||||
propertyIndices.reverse().forEach((i) => members.splice(i, 1));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Expression, factory, MethodDeclaration, SyntaxKind } from 'typescript';
|
||||
import { Expression, factory, Identifier, MethodDeclaration, SyntaxKind } from 'typescript';
|
||||
|
||||
import { Logger } from '../../logger';
|
||||
import {
|
||||
@@ -12,9 +12,11 @@ import {
|
||||
export function transformMethod(method: MethodDeclaration) {
|
||||
if (!method) return;
|
||||
|
||||
const decorator = getDecorator(method),
|
||||
decoratorName = getDecoratorName(decorator),
|
||||
decoratorArgs = getDecoratorArgs(decorator);
|
||||
const decorator = getDecorator(method);
|
||||
if (!decorator) return;
|
||||
|
||||
const decoratorName = getDecoratorName(decorator);
|
||||
const decoratorArgs = getDecoratorArgs(decorator);
|
||||
|
||||
try {
|
||||
return factory.createMethodDeclaration(
|
||||
@@ -27,13 +29,17 @@ export function transformMethod(method: MethodDeclaration) {
|
||||
method.type,
|
||||
factory.createBlock([factory.createReturnStatement(getMethodBlock(method, decoratorName, decoratorArgs))])
|
||||
);
|
||||
} catch (e) {
|
||||
Logger.error('Error transforming method: ' + (method.name as any).text);
|
||||
Logger.error(e.message);
|
||||
} catch (e: unknown) {
|
||||
Logger.error('Error transforming method: ' + (method.name as Identifier).text);
|
||||
Logger.error(e instanceof Error ? e.message : String(e));
|
||||
}
|
||||
}
|
||||
|
||||
function getMethodBlock(method: MethodDeclaration, decoratorName: string, decoratorArgs: any): Expression {
|
||||
function getMethodBlock(
|
||||
method: MethodDeclaration,
|
||||
decoratorName: string,
|
||||
decoratorArgs: Record<string, string | number | boolean | string[]>
|
||||
): Expression {
|
||||
const decoratorMethod = getMethodsForDecorator(decoratorName)[0];
|
||||
|
||||
switch (decoratorName) {
|
||||
@@ -46,14 +52,14 @@ function getMethodBlock(method: MethodDeclaration, decoratorName: string, decora
|
||||
SyntaxKind.EqualsEqualsEqualsToken,
|
||||
factory.createTrue()
|
||||
),
|
||||
method.body
|
||||
method.body!
|
||||
),
|
||||
]);
|
||||
|
||||
default:
|
||||
return factory.createCallExpression(factory.createIdentifier(decoratorMethod), undefined, [
|
||||
factory.createThis(),
|
||||
factory.createStringLiteral(decoratorArgs?.methodName || (method.name as any).text),
|
||||
factory.createStringLiteral((decoratorArgs?.methodName as string) || (method.name as Identifier).text),
|
||||
convertValueToLiteral(decoratorArgs),
|
||||
factory.createIdentifier('arguments'),
|
||||
]);
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import {
|
||||
canHaveDecorators,
|
||||
canHaveModifiers,
|
||||
ClassDeclaration,
|
||||
Decorator,
|
||||
factory,
|
||||
getDecorators as tsGetDecorators,
|
||||
getModifiers as tsGetModifiers,
|
||||
Identifier,
|
||||
SourceFile,
|
||||
SyntaxKind,
|
||||
TransformationContext,
|
||||
@@ -16,16 +18,15 @@ import { Logger } from '../../logger';
|
||||
import { convertValueToLiteral, getDecorator, getDecoratorArgs, getDecoratorName } from '../helpers';
|
||||
import { transformMembers } from './members';
|
||||
|
||||
function transformClass(cls: any, ngcBuild?: boolean) {
|
||||
Logger.profile('transformClass: ' + cls.name.text);
|
||||
function transformClass(cls: ClassDeclaration, ngcBuild?: boolean) {
|
||||
Logger.profile('transformClass: ' + cls.name!.text);
|
||||
|
||||
const pluginStatics = [];
|
||||
const dec: Decorator = getDecorator(cls);
|
||||
const dec = getDecorator(cls);
|
||||
|
||||
if (dec) {
|
||||
const pluginDecoratorArgs = getDecoratorArgs(dec);
|
||||
|
||||
// add plugin decorator args as static properties of the plugin's class
|
||||
for (const prop in pluginDecoratorArgs) {
|
||||
pluginStatics.push(
|
||||
factory.createPropertyDeclaration(
|
||||
@@ -45,7 +46,7 @@ function transformClass(cls: any, ngcBuild?: boolean) {
|
||||
? clsDecorators.filter((d: Decorator) => getDecoratorName(d) === 'Injectable')
|
||||
: [];
|
||||
|
||||
cls = factory.createClassDeclaration(
|
||||
const result = factory.createClassDeclaration(
|
||||
[...keepDecorators, factory.createToken(SyntaxKind.ExportKeyword)],
|
||||
cls.name,
|
||||
cls.typeParameters,
|
||||
@@ -53,8 +54,8 @@ function transformClass(cls: any, ngcBuild?: boolean) {
|
||||
[...transformMembers(cls), ...pluginStatics]
|
||||
);
|
||||
|
||||
Logger.profile('transformClass: ' + cls.name.text);
|
||||
return cls;
|
||||
Logger.profile('transformClass: ' + (result.name as Identifier).text);
|
||||
return result;
|
||||
}
|
||||
|
||||
function transformClasses(file: SourceFile, ctx: TransformationContext, ngcBuild?: boolean) {
|
||||
@@ -68,7 +69,7 @@ function transformClasses(file: SourceFile, ctx: TransformationContext, ngcBuild
|
||||
) {
|
||||
return node;
|
||||
}
|
||||
return transformClass(node, ngcBuild);
|
||||
return transformClass(node as ClassDeclaration, ngcBuild);
|
||||
},
|
||||
ctx
|
||||
);
|
||||
@@ -76,7 +77,7 @@ function transformClasses(file: SourceFile, ctx: TransformationContext, ngcBuild
|
||||
|
||||
export function pluginClassTransformer(ngcBuild?: boolean): TransformerFactory<SourceFile> {
|
||||
return (ctx: TransformationContext) => {
|
||||
return (tsSourceFile) => {
|
||||
return (tsSourceFile: SourceFile) => {
|
||||
if (tsSourceFile.fileName.indexOf('src/@awesome-cordova-plugins/plugins') > -1) {
|
||||
return transformClasses(tsSourceFile, ctx, ngcBuild);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
import { factory, PropertyDeclaration } from 'typescript';
|
||||
import {
|
||||
ClassElement,
|
||||
factory,
|
||||
GetAccessorDeclaration,
|
||||
Identifier,
|
||||
PropertyDeclaration,
|
||||
SetAccessorDeclaration,
|
||||
} from 'typescript';
|
||||
|
||||
import { getDecorator, getDecoratorName } from '../helpers';
|
||||
|
||||
export function transformProperty(members: any[], index: number) {
|
||||
export function transformProperty(
|
||||
members: ClassElement[],
|
||||
index: number
|
||||
): [GetAccessorDeclaration, SetAccessorDeclaration] | PropertyDeclaration {
|
||||
const property = members[index] as PropertyDeclaration,
|
||||
decorator = getDecorator(property),
|
||||
decoratorName = getDecoratorName(decorator);
|
||||
decoratorName = decorator ? getDecoratorName(decorator) : undefined;
|
||||
|
||||
let type: 'cordova' | 'instance';
|
||||
|
||||
@@ -22,6 +32,8 @@ export function transformProperty(members: any[], index: number) {
|
||||
return property;
|
||||
}
|
||||
|
||||
const propertyName = (property.name as Identifier).text;
|
||||
|
||||
const getter = factory.createGetAccessorDeclaration(
|
||||
undefined,
|
||||
property.name,
|
||||
@@ -31,7 +43,7 @@ export function transformProperty(members: any[], index: number) {
|
||||
factory.createReturnStatement(
|
||||
factory.createCallExpression(factory.createIdentifier(type + 'PropertyGet'), undefined, [
|
||||
factory.createThis(),
|
||||
factory.createStringLiteral((property.name as any).text),
|
||||
factory.createStringLiteral(propertyName),
|
||||
])
|
||||
),
|
||||
])
|
||||
@@ -45,7 +57,7 @@ export function transformProperty(members: any[], index: number) {
|
||||
factory.createExpressionStatement(
|
||||
factory.createCallExpression(factory.createIdentifier(type + 'PropertySet'), undefined, [
|
||||
factory.createThis(),
|
||||
factory.createStringLiteral((property.name as any).text),
|
||||
factory.createStringLiteral(propertyName),
|
||||
factory.createIdentifier('value'),
|
||||
])
|
||||
),
|
||||
|
||||
@@ -2,16 +2,16 @@ import { readFileSync, writeFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
|
||||
import { PLUGIN_PATHS, ROOT } from '../build/helpers';
|
||||
import { EMIT_PATH } from '../build/transformers/extract-injectables';
|
||||
import { InjectableClassEntry, EMIT_PATH } from '../build/transformers/extract-injectables';
|
||||
import { generateDeclarations, transpile } from '../build/transpile';
|
||||
|
||||
generateDeclarations();
|
||||
transpile();
|
||||
|
||||
const outDirs = PLUGIN_PATHS.map((p) => p.replace(join(ROOT, 'src'), join(ROOT, 'dist')).replace(/[\\/]index.ts/, ''));
|
||||
const injectableClasses = JSON.parse(readFileSync(EMIT_PATH, 'utf-8'));
|
||||
const injectableClasses: InjectableClassEntry[] = JSON.parse(readFileSync(EMIT_PATH, 'utf-8'));
|
||||
|
||||
outDirs.forEach((dir) => {
|
||||
outDirs.forEach((dir: string) => {
|
||||
const classes = injectableClasses.filter((entry) => entry.dirName === dir.split(/[\\/]+/).pop());
|
||||
|
||||
let jsFile: string = readFileSync(join(dir, 'index.js'), 'utf-8'),
|
||||
|
||||
@@ -9,11 +9,28 @@ const exec = promisify(execCb);
|
||||
import { PLUGIN_PATHS, ROOT } from '../build/helpers';
|
||||
import { Logger } from '../logger';
|
||||
|
||||
interface PackageJson {
|
||||
description: string;
|
||||
type: string;
|
||||
main: string;
|
||||
module: string;
|
||||
types: string;
|
||||
exports: Record<string, { types: string; import: string; default: string } | undefined>;
|
||||
sideEffects: boolean;
|
||||
author: string;
|
||||
license: string;
|
||||
repository: { type: string; url: string };
|
||||
name?: string;
|
||||
dependencies?: Record<string, string>;
|
||||
peerDependencies?: Record<string, string>;
|
||||
version?: string;
|
||||
}
|
||||
|
||||
const MAIN_PACKAGE_JSON = JSON.parse(readFileSync(resolve(__dirname, '../../package.json'), 'utf-8'));
|
||||
const VERSION = MAIN_PACKAGE_JSON.version;
|
||||
const VERSION: string = MAIN_PACKAGE_JSON.version;
|
||||
const FLAGS = '--access public --provenance';
|
||||
|
||||
const PACKAGE_JSON_BASE = {
|
||||
const PACKAGE_JSON_BASE: PackageJson = {
|
||||
description: 'Awesome Cordova Plugins - Native plugins for ionic apps',
|
||||
type: 'module',
|
||||
main: './index.js',
|
||||
@@ -42,18 +59,22 @@ const PACKAGE_JSON_BASE = {
|
||||
|
||||
const DIST = resolve(ROOT, 'dist/@awesome-cordova-plugins');
|
||||
|
||||
const PACKAGES = [];
|
||||
const PACKAGES: string[] = [];
|
||||
|
||||
const MIN_CORE_VERSION = '^' + VERSION;
|
||||
const RXJS_VERSION = '^5.5.0 || ^6.5.0 || ^7.3.0';
|
||||
|
||||
const PLUGIN_PEER_DEPENDENCIES = {
|
||||
const PLUGIN_PEER_DEPENDENCIES: Record<string, string> = {
|
||||
'@awesome-cordova-plugins/core': MIN_CORE_VERSION,
|
||||
rxjs: RXJS_VERSION,
|
||||
};
|
||||
|
||||
function getPackageJsonContent(name: string, peerDependencies = {}, dependencies = {}) {
|
||||
const pkg = {
|
||||
function getPackageJsonContent(
|
||||
name: string,
|
||||
peerDependencies: Record<string, string> = {},
|
||||
dependencies: Record<string, string> = {}
|
||||
): PackageJson {
|
||||
const pkg: PackageJson = {
|
||||
...structuredClone(PACKAGE_JSON_BASE),
|
||||
name: '@awesome-cordova-plugins/' + name,
|
||||
dependencies,
|
||||
@@ -61,7 +82,6 @@ function getPackageJsonContent(name: string, peerDependencies = {}, dependencies
|
||||
version: VERSION,
|
||||
};
|
||||
|
||||
// Core package has no ngx subfolder
|
||||
if (name === 'core') {
|
||||
delete pkg.exports['./ngx'];
|
||||
}
|
||||
@@ -69,23 +89,23 @@ function getPackageJsonContent(name: string, peerDependencies = {}, dependencies
|
||||
return pkg;
|
||||
}
|
||||
|
||||
function writePackageJson(data: any, dir: string) {
|
||||
function writePackageJson(data: PackageJson, dir: string) {
|
||||
const filePath = resolve(dir, 'package.json');
|
||||
writeFileSync(filePath, JSON.stringify(data, null, 2));
|
||||
PACKAGES.push(dir);
|
||||
}
|
||||
function writeNGXPackageJson(data: any, dir: string) {
|
||||
|
||||
function writeNGXPackageJson(data: PackageJson, dir: string) {
|
||||
const filePath = resolve(dir, 'package.json');
|
||||
writeFileSync(filePath, JSON.stringify(data, null, 2));
|
||||
}
|
||||
|
||||
function prepare() {
|
||||
// write @awesome-cordova-plugins/core package.json
|
||||
writePackageJson(
|
||||
getPackageJsonContent('core', { rxjs: RXJS_VERSION }, { '@types/cordova': 'latest' }),
|
||||
resolve(DIST, 'core')
|
||||
);
|
||||
|
||||
// write plugin package.json files
|
||||
PLUGIN_PATHS.forEach((pluginPath: string) => {
|
||||
const pluginName = pluginPath.split(/[\/\\]+/).slice(-2)[0];
|
||||
const packageJsonContents = getPackageJsonContent(pluginName, PLUGIN_PEER_DEPENDENCIES);
|
||||
@@ -100,8 +120,9 @@ async function publishPackage(pkg: string, ignoreErrors: boolean): Promise<void>
|
||||
try {
|
||||
const { stdout } = await exec(`npm publish ${pkg} ${FLAGS}`);
|
||||
if (stdout) Logger.verbose(stdout.trim());
|
||||
} catch (err: any) {
|
||||
if (err.message?.includes('You cannot publish over the previously published version')) {
|
||||
} catch (err: unknown) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
if (message.includes('You cannot publish over the previously published version')) {
|
||||
Logger.verbose('Ignoring duplicate version error.');
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user