diff --git a/.changeset/lemon-bottles-act.md b/.changeset/lemon-bottles-act.md
new file mode 100644
index 0000000..7e2a9e5
--- /dev/null
+++ b/.changeset/lemon-bottles-act.md
@@ -0,0 +1,5 @@
+---
+'@chialab/plasma': minor
+---
+
+Do not require a package.json anymore.
diff --git a/README.md b/README.md
index 6187d16..216f985 100644
--- a/README.md
+++ b/README.md
@@ -18,10 +18,7 @@ Generate Custom Elements wrappers for Angular, React, Svelte and Vue.
Plasma transformations are based on [Custom Element Manifest](https://github.com/webcomponents/custom-elements-manifest) (CEM) specifications. The CEM is a JSON files that describes a Custom Element, its properties, events and slots. Plasma uses the CEM to generate wrappers for the supported frameworks.
-In order to run the `plasma` cli you need:
-
-- a `package.json` file. Plasma uses the `name` field to import the Custom Element definition and the `customElements` field to detect the CEM file;
-- a CEM file. You can generate the CEM for most of the Web Components library using this [Analyzer](https://github.com/open-wc/custom-elements-manifest/tree/master/packages/analyzer).
+You can generate the CEM for most of the Web Components library using this [Analyzer](https://github.com/open-wc/custom-elements-manifest/tree/master/packages/analyzer).
## Installation
@@ -40,19 +37,18 @@ npm run plasma
### Options
```
-npm run plasma --help
-
Usage: plasma [options]
Generate Custom Elements wrappers for Angular, React, Svelte and Vue.
Arguments:
- input source directory
+ input custom elements manifest path
Options:
-V, --version output the version number
- -f, --frameworks the framework to convert to
+ -e, --entrypoint entrypoint to the package
-o, --outdir output directory
+ -f, --frameworks the framework to convert to
-y, --yes convert all candidates to all available frameworks
-h, --help display help for command
```
diff --git a/package.json b/package.json
index c115c3d..082bf0a 100644
--- a/package.json
+++ b/package.json
@@ -40,7 +40,7 @@
"build": "yarn clear && tsc --project tsconfig.build.json && node scripts/build.js",
"lint": "prettier --check . && eslint .",
"test:manifest": "custom-elements-manifest analyze --config ./test/cem.config.mjs --outdir test",
- "test:generate": "./dist/cli.js test --outdir 'test/src/[framework]' -y",
+ "test:generate": "./dist/cli.js test --entrypoint 'plasma-test' --outdir 'test/src/[framework]' -y",
"test": "vitest",
"prepack": "yarn build && publint"
},
@@ -65,7 +65,6 @@
"eslint": "^8.0.0",
"jsdom": "^23.0.0",
"listr2": "^7.0.2",
- "package-up": "^5.0.0",
"preact": "^10.19.2",
"prettier": "^3.0.0",
"prompts": "^2.4.0",
diff --git a/src/cli.ts b/src/cli.ts
index cc18155..145fb52 100644
--- a/src/cli.ts
+++ b/src/cli.ts
@@ -5,10 +5,9 @@ import { fileURLToPath } from 'node:url';
import chalk from 'chalk';
import { program } from 'commander';
import { Listr } from 'listr2';
-import { packageUp } from 'package-up';
import prompts from 'prompts';
import { candidates, SUPPORTED, transform, UNSUPPORTED, type Frameworks } from './index';
-import { parseManifestFromPackage, parsePackageJson } from './parser';
+import { findManifest } from './utils';
const colorFramework = (framework: string) => {
switch (framework) {
@@ -35,9 +34,10 @@ program
.description(json.description)
.version(json.version)
- .argument('[input]', 'source directory')
- .option('-f, --frameworks ', 'the framework to convert to')
+ .argument('[input]', 'custom elements manifest path')
+ .requiredOption('-e, --entrypoint ', 'entrypoint to the package')
.requiredOption('-o, --outdir ', 'output directory')
+ .option('-f, --frameworks ', 'the framework to convert to')
.option('-y, --yes', 'convert all candidates to all available frameworks')
.action(
@@ -45,26 +45,20 @@ program
sourceDir,
options: {
outdir: string;
- entrypoint?: string;
+ entrypoint: string;
frameworks?: Frameworks[];
yes?: boolean;
}
) => {
sourceDir = sourceDir ? resolve(sourceDir) : process.cwd();
- const input = await packageUp({ cwd: sourceDir });
- if (!input) {
- throw new Error('No package.json found');
- }
-
- const json = await parsePackageJson(input);
- const manifest = await parseManifestFromPackage(input, json);
+ const manifest = await findManifest(sourceDir);
if (!manifest) {
throw new Error('No custom elements manifest found');
}
const yes = options.yes || !process.stdout.isTTY;
- const data = Array.from(candidates(json, manifest));
+ const data = Array.from(candidates(manifest));
if (data.length === 0) {
throw new Error('No components found');
}
@@ -135,6 +129,7 @@ program
const outDir = options.outdir.replace(/\[framework\]/g, framework);
const outFile = await transform(entry, framework, {
+ entrypoint: options.entrypoint,
outdir: outDir,
});
task.title = `Converted ${chalk.whiteBright(component)} to ${colorFramework(
diff --git a/src/parser.ts b/src/parser.ts
deleted file mode 100644
index 8386d69..0000000
--- a/src/parser.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { readFile } from 'node:fs/promises';
-import { dirname, resolve } from 'node:path';
-import type { Package } from 'custom-elements-manifest';
-import type { PackageJson as PackageJsonBase } from 'type-fest';
-
-export type PackageJson = PackageJsonBase & {
- customElements?: string;
-};
-
-export async function parseJson(fileName: string) {
- const contents = await readFile(fileName, 'utf-8');
- const json = JSON.parse(contents);
-
- return json;
-}
-
-export async function parsePackageJson(fileName: string) {
- return JSON.parse(await readFile(fileName, 'utf-8')) as PackageJson;
-}
-
-export async function parseManifestFromPackage(fileName: string, data: PackageJson) {
- if (!data.customElements) {
- return null;
- }
-
- return parseJson(resolve(dirname(fileName), data.customElements)) as Promise;
-}
diff --git a/src/preact.ts b/src/preact.ts
index 5288958..d4ca022 100644
--- a/src/preact.ts
+++ b/src/preact.ts
@@ -4,14 +4,19 @@ import { capitalize, filterPublicMemebers } from './utils';
import type { Entry } from './walker';
export interface PreactTransformOptions {
+ /**
+ * The entrypoint to the package.
+ */
+ entrypoint: string;
+
/**
* The output directory to write the converted components to.
*/
outdir: string;
}
-export function generatePreactComponent(entry: Entry) {
- const { packageJson, definition, declaration } = entry;
+export function generatePreactComponent(entry: Entry, options: PreactTransformOptions) {
+ const { definition, declaration } = entry;
const props = filterPublicMemebers(declaration).map((member) => member.name);
const eventProps =
@@ -25,7 +30,7 @@ export function generatePreactComponent(entry: Entry) {
return `import { h } from 'preact';
import { useRef, useEffect } from 'preact/hooks';
-import '${packageJson.name}';
+import '${options.entrypoint}';
const properties = ${JSON.stringify(props)};
const events = ${JSON.stringify(eventProps)};
@@ -62,11 +67,11 @@ export const ${declaration.name} = ({ children, ...props }) => {
};`;
}
-export function generatePreactTypings(entry: Entry) {
- const { packageJson, declaration } = entry;
+export function generatePreactTypings(entry: Entry, options: PreactTransformOptions) {
+ const { declaration } = entry;
const imports = `import { FunctionComponent, JSX } from 'preact';
-import { ${declaration.name} as Base${declaration.name} } from '${packageJson.name}';
+import { ${declaration.name} as Base${declaration.name} } from '${options.entrypoint}';
`;
const propertiesTypings = filterPublicMemebers(declaration).map(
@@ -95,8 +100,8 @@ export async function transformPreact(entry: Entry, options: PreactTransformOpti
recursive: true,
});
await Promise.all([
- writeFile(outFile, generatePreactComponent(entry)),
- writeFile(declFile, generatePreactTypings(entry)),
+ writeFile(outFile, generatePreactComponent(entry, options)),
+ writeFile(declFile, generatePreactTypings(entry, options)),
]);
return outFile;
diff --git a/src/react.ts b/src/react.ts
index d84cd93..263b4a8 100644
--- a/src/react.ts
+++ b/src/react.ts
@@ -4,6 +4,11 @@ import { capitalize, filterPublicMemebers } from './utils';
import type { Entry } from './walker';
export interface ReactTransformOptions {
+ /**
+ * The entrypoint to the package.
+ */
+ entrypoint: string;
+
/**
* The output directory to write the converted components to.
*/
@@ -163,8 +168,8 @@ function getAttributes(tagName: string) {
}
}
-export function generateReactComponent(entry: Entry) {
- const { packageJson, definition, declaration } = entry;
+export function generateReactComponent(entry: Entry, options: ReactTransformOptions) {
+ const { definition, declaration } = entry;
const props = filterPublicMemebers(declaration).map((member) => member.name);
const eventProps =
@@ -177,7 +182,7 @@ export function generateReactComponent(entry: Entry) {
) ?? {};
return `import React, { useRef, useEffect } from 'react';
-import '${packageJson.name}';
+import '${options.entrypoint}';
const properties = ${JSON.stringify(props)};
const events = ${JSON.stringify(eventProps)};
@@ -214,11 +219,11 @@ export const ${declaration.name} = ({ children, ...props }) => {
};`;
}
-export function generateReactTypings(entry: Entry) {
- const { packageJson, definition, declaration } = entry;
+export function generateReactTypings(entry: Entry, options: ReactTransformOptions) {
+ const { definition, declaration } = entry;
const imports = `import React from 'react';
-import { ${declaration.name} as Base${declaration.name} } from '${packageJson.name}';
+import { ${declaration.name} as Base${declaration.name} } from '${options.entrypoint}';
`;
const propertiesTypings = filterPublicMemebers(declaration).map(
@@ -250,8 +255,8 @@ export async function transformReact(entry: Entry, options: ReactTransformOption
recursive: true,
});
await Promise.all([
- writeFile(outFile, generateReactComponent(entry)),
- writeFile(declFile, generateReactTypings(entry)),
+ writeFile(outFile, generateReactComponent(entry, options)),
+ writeFile(declFile, generateReactTypings(entry, options)),
]);
return outFile;
diff --git a/src/svelte.ts b/src/svelte.ts
index c4239ec..db0400a 100644
--- a/src/svelte.ts
+++ b/src/svelte.ts
@@ -4,6 +4,11 @@ import { filterPublicMemebers } from './utils';
import type { Entry } from './walker';
export interface SvelteTransformOptions {
+ /**
+ * The entrypoint to the package.
+ */
+ entrypoint: string;
+
/**
* The output directory to write the converted components to.
*/
@@ -163,8 +168,8 @@ function getAttributes(tagName: string) {
}
}
-export function generateSvelteComponent(entry: Entry) {
- const { packageJson, definition, declaration } = entry;
+export function generateSvelteComponent(entry: Entry, options: SvelteTransformOptions) {
+ const { definition, declaration } = entry;
const props: string[] = [];
const setters: string[] = [];
@@ -196,7 +201,7 @@ export function generateSvelteComponent(entry: Entry) {
return `