feat(universal-xml-plugin)!: Migrate package to ESM (#22557)

BREAKING CHANGE: @appium/universal-xml-plugin is now an ESM-only package. It can no longer be loaded via CommonJS require(); consumers must use import or dynamic import(). Appium's own extension loader already loads plugins via dynamic import(), so appium plugin install/use universal-xml is unaffected. Deep imports into the package's internals are no longer possible — only the public entry point is exposed via exports.
This commit is contained in:
Mykola Mokhnach
2026-07-29 21:59:11 +02:00
committed by GitHub
parent a236fdbc97
commit 5c870329a3
12 changed files with 49 additions and 29 deletions
@@ -1,5 +1,5 @@
// uses the same format as NODE_MAP in node-map.js
import type {UniversalNameMap} from './types';
import type {UniversalNameMap} from './types.js';
export const ATTR_MAP: UniversalNameMap = {
x: {ios: 'x', android: 'x'},
+6 -5
View File
@@ -1,9 +1,10 @@
export {UniversalXMLPlugin} from './plugin';
export {transformSourceXml} from './source';
export {UniversalXMLPlugin} from './plugin.js';
export {transformSourceXml} from './source.js';
import fs from 'node:fs/promises';
import {fileURLToPath} from 'node:url';
import {UniversalXMLPlugin} from './plugin';
import {transformSourceXml} from './source';
import {UniversalXMLPlugin} from './plugin.js';
import {transformSourceXml} from './source.js';
export default UniversalXMLPlugin;
@@ -33,6 +34,6 @@ export async function main(): Promise<void> {
}
}
if (require.main === module) {
if (process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1]) {
void main();
}
@@ -6,7 +6,7 @@
* array of strings. This means that there can be a many-to-one relationship between
* platform-specific node names and universal node names.
*/
import type {UniversalNameMap} from './types';
import type {UniversalNameMap} from './types.js';
const NODE_MAP: UniversalNameMap = {
Alert: {
+5 -5
View File
@@ -1,10 +1,10 @@
import type {Element, ExternalDriver, NextPluginCallback} from '@appium/types';
import {errors} from 'appium/driver';
import {BasePlugin} from 'appium/plugin';
import {errors} from 'appium/driver.js';
import {BasePlugin} from 'appium/plugin.js';
import {transformSourceXml} from './source';
import type {TransformMetadata} from './types';
import {transformQuery} from './xpath';
import {transformSourceXml} from './source.js';
import type {TransformMetadata} from './types.js';
import {transformQuery} from './xpath.js';
export class UniversalXMLPlugin extends BasePlugin {
async getPageSource(
+4 -4
View File
@@ -1,16 +1,16 @@
import {util} from '@appium/support';
import {XMLBuilder, XMLParser} from 'fast-xml-parser';
import {ATTR_MAP, REMOVE_ATTRS} from './attr-map';
import NODE_MAP from './node-map';
import * as TRANSFORMS from './transformers';
import {ATTR_MAP, REMOVE_ATTRS} from './attr-map.js';
import NODE_MAP from './node-map.js';
import * as TRANSFORMS from './transformers.js';
import type {
NodesAndAttributes,
TransformMetadata,
TransformNodeOptions,
TransformSourceXmlOptions,
UniversalNameMap,
} from './types';
} from './types.js';
export const ATTR_PREFIX = '@_';
export const IDX_PATH_PREFIX = `${ATTR_PREFIX}indexPath`;
@@ -1,5 +1,5 @@
import {ATTR_PREFIX} from './source';
import type {TransformMetadata} from './types';
import {ATTR_PREFIX} from './source.js';
import type {TransformMetadata} from './types.js';
/**
* No-op transformer for iOS source XML.
@@ -29,8 +29,16 @@
"lib",
"tsconfig.json"
],
"type": "module",
"main": "./build/lib/index.js",
"types": "./build/lib/index.d.ts",
"exports": {
".": {
"types": "./build/lib/index.d.ts",
"import": "./build/lib/index.js"
},
"./package.json": "./package.json"
},
"publishConfig": {
"access": "public"
},
+5 -1
View File
@@ -1,7 +1,11 @@
import path from 'node:path';
import {fileURLToPath} from 'node:url';
import {node, fs, util} from '@appium/support';
const THIS_PLUGIN_DIR = node.getModuleRootSync('@appium/universal-xml-plugin', __filename)!;
const THIS_PLUGIN_DIR = node.getModuleRootSync(
'@appium/universal-xml-plugin',
fileURLToPath(import.meta.url),
)!;
const FIXTURES_DIR = path.join(THIS_PLUGIN_DIR, 'test', 'fixtures');
export const FIXTURES = {
@@ -2,11 +2,11 @@ import assert from 'node:assert/strict';
import {describe, it} from 'node:test';
import type {Constraints} from '@appium/types';
import {BaseDriver} from 'appium/driver';
import {BaseDriver} from 'appium/driver.js';
import {UniversalXMLPlugin} from '../../lib/plugin';
import {getNodeAttrVal, runQuery} from '../../lib/xpath';
import {FIXTURES, readFixture} from '../fixtures';
import {UniversalXMLPlugin} from '../../lib/plugin.js';
import {getNodeAttrVal, runQuery} from '../../lib/xpath.js';
import {FIXTURES, readFixture} from '../fixtures/index.js';
describe('UniversalXMLPlugin', function () {
let next: () => Promise<any>;
@@ -1,8 +1,8 @@
import assert from 'node:assert/strict';
import {describe, it} from 'node:test';
import {transformAttrs, transformChildNodes, transformSourceXml} from '../../lib/source';
import {FIXTURES, readFixture} from '../fixtures';
import {transformAttrs, transformChildNodes, transformSourceXml} from '../../lib/source.js';
import {FIXTURES, readFixture} from '../fixtures/index.js';
describe('source functions', function () {
describe('transformSourceXml', function () {
@@ -1,9 +1,9 @@
import assert from 'node:assert/strict';
import {describe, it} from 'node:test';
import {transformSourceXml} from '../../lib/source';
import {getNodeAttrVal, runQuery, transformQuery} from '../../lib/xpath';
import {FIXTURES, readFixture} from '../fixtures';
import {transformSourceXml} from '../../lib/source.js';
import {getNodeAttrVal, runQuery, transformQuery} from '../../lib/xpath.js';
import {FIXTURES, readFixture} from '../fixtures/index.js';
describe('xpath functions', function () {
describe('runQuery', function () {
+8 -1
View File
@@ -4,7 +4,14 @@
"outDir": "build",
"checkJs": true,
"strict": true,
"types": ["node"]
"module": "NodeNext",
"moduleResolution": "NodeNext",
"types": ["node"],
"paths": {
"appium": ["../appium"],
"appium/driver.js": ["../appium/driver.d.ts"],
"appium/plugin.js": ["../appium/plugin.d.ts"]
}
},
"extends": "@appium/tsconfig/tsconfig.plugin.json",
"include": ["lib", "test"],