├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .gitignore
├── .npmignore
├── .npmrc
├── .nvmrc
├── .travis.yml
├── .vscode
└── settings.json
├── CHANGELOG.md
├── LICENSE
├── README.md
├── babel.config.js
├── hero.png
├── jest.config.js
├── package-lock.json
├── package.json
├── src
├── componentToReact.js
├── constants.js
└── index.js
└── test
├── index.test.js
└── pkgOverride.test.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 |
3 | root = true
4 |
5 | [*]
6 | charset = utf-8
7 | indent_style = space
8 | indent_size = 2
9 | end_of_line = lf
10 | insert_final_newline = true
11 | trim_trailing_whitespace = true
12 |
13 | [*.md]
14 | insert_final_newline = false
15 | trim_trailing_whitespace = false
16 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | dist
2 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "airbnb",
3 | "rules": {
4 | "global-require": 0,
5 | "import/no-dynamic-require": 0,
6 | "indent": 0
7 | },
8 | "env": {
9 | "jest": true
10 | },
11 | "plugins": ["jest"]
12 | }
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | coverage
2 | dist
3 | node_modules
4 | .coveralls.yml
5 | test_output/
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # Ignore Everything
2 | *
3 |
4 | # Except...
5 | !src/*.js
6 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | registry=https://registry.npmjs.org/
2 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v10.15.3
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "8"
4 | - "10"
5 | - "stable"
6 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "jest.autoEnable": false
3 | }
4 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [0.0.1-8](https://github.com/petermikitsh/stencil-react/compare/v0.0.1-7...v0.0.1-8) (2019-10-31)
2 |
3 |
4 | ### Bug Fixes
5 |
6 | * **componentToReact:** reassign properties only on change ([2f82108](https://github.com/petermikitsh/stencil-react/commit/2f82108))
7 |
8 |
9 |
10 | ## [0.0.1-7](https://github.com/petermikitsh/stencil-react/compare/v0.0.1-6...v0.0.1-7) (2019-10-28)
11 |
12 |
13 | ### Bug Fixes
14 |
15 | * always set properties (closes [#4](https://github.com/petermikitsh/stencil-react/issues/4)) ([#6](https://github.com/petermikitsh/stencil-react/issues/6)) ([7e432f2](https://github.com/petermikitsh/stencil-react/commit/7e432f2))
16 |
17 |
18 | ### Features
19 |
20 | * --packageJson and --packageJsonPath options ([8a1b0cc](https://github.com/petermikitsh/stencil-react/commit/8a1b0cc))
21 |
22 |
23 |
24 | ## [0.0.1-6](https://github.com/petermikitsh/stencil-react/compare/v0.0.1-5...v0.0.1-6) (2019-09-04)
25 |
26 |
27 | ### Bug Fixes
28 |
29 | * get class name directly from file; add d3-stencil test ([e49ecbe](https://github.com/petermikitsh/stencil-react/commit/e49ecbe))
30 |
31 |
32 |
33 | ## [0.0.1-5](https://github.com/petermikitsh/stencil-react/compare/v0.0.1-4...v0.0.1-5) (2019-09-04)
34 |
35 |
36 | ### Bug Fixes
37 |
38 | * find entry files relative to collection manifest directory ([fa7cfb1](https://github.com/petermikitsh/stencil-react/commit/fa7cfb1))
39 |
40 |
41 |
42 | ## [0.0.1-4](https://github.com/petermikitsh/stencil-react/compare/v0.0.1-3...v0.0.1-4) (2019-09-04)
43 |
44 |
45 | ### Bug Fixes
46 |
47 | * use camelCase property names instead of kebab-case ([022f50a](https://github.com/petermikitsh/stencil-react/commit/022f50a))
48 |
49 |
50 |
51 | ## [0.0.1-3](https://github.com/petermikitsh/stencil-react/compare/v0.0.1-2...v0.0.1-3) (2019-09-04)
52 |
53 |
54 | ### Bug Fixes
55 |
56 | * keep tsx files (for source map support) ([3c65bd0](https://github.com/petermikitsh/stencil-react/commit/3c65bd0))
57 |
58 |
59 |
60 | ## [0.0.1-2](https://github.com/petermikitsh/stencil-react/compare/v0.0.1-1...v0.0.1-2) (2019-09-04)
61 |
62 |
63 |
64 | ## [0.0.1-1](https://github.com/petermikitsh/stencil-react/compare/v0.0.1-0...v0.0.1-1) (2019-09-03)
65 |
66 |
67 |
68 | ## [0.0.1-0](https://github.com/petermikitsh/stencil-react/compare/fa98a4d...v0.0.1-0) (2019-09-02)
69 |
70 |
71 | ### Bug Fixes
72 |
73 | * add bracket ([6314dce](https://github.com/petermikitsh/stencil-react/commit/6314dce))
74 | * add tslib dependency to generated package.json ([65fdb87](https://github.com/petermikitsh/stencil-react/commit/65fdb87))
75 | * use React.createElement (output proper ES5) ([9cff4b4](https://github.com/petermikitsh/stencil-react/commit/9cff4b4))
76 |
77 |
78 | ### Features
79 |
80 | * add peerDependencies to generated package.json ([61e3610](https://github.com/petermikitsh/stencil-react/commit/61e3610))
81 | * generate bindings ([fa98a4d](https://github.com/petermikitsh/stencil-react/commit/fa98a4d))
82 | * generate ESM, CJS builds ([b66596f](https://github.com/petermikitsh/stencil-react/commit/b66596f))
83 | * support aria-* props ([ec853b1](https://github.com/petermikitsh/stencil-react/commit/ec853b1))
84 | * support outDir option ([e13e598](https://github.com/petermikitsh/stencil-react/commit/e13e598))
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Peter Mikitsh
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Update
2 |
3 | **Check out https://github.com/ionic-team/stencil-ds-plugins**. You may want that instead of this.
4 |
5 |
6 |
7 |
8 |
9 | # stencil-react
10 |
11 | [![npm package][npm-image]][npm-url]
12 | [![Build Status][travis-image]][travis-url]
13 | [![Coverage Status][coveralls-image]][coveralls-url]
14 | [![Dependencies Status][david-image]][david-url]
15 |
16 | Generate React Components ("bindings") from Stencil 1.x projects.
17 |
18 | ## Usage
19 |
20 | Make sure your Stencil v1 component library (e.g, `@anjuna/core`) is installed as an npm dependency.
21 |
22 | ```
23 | npm i stencil-react
24 | stencil-react @anjuna/core --outDir dist
25 | ```
26 |
27 | ### Options
28 |
29 | | Option | Description | Default Value |
30 | |---------------------|-----------------------------------------------|---------------|
31 | | `--outDir` | Output directory | `dist` |
32 | | `--packageJson` | Override output package.json fields | N/A |
33 | | `--packageJsonPath` | Override output package.json fields from file | N/A |
34 |
35 | You cannot override fields `['main', 'module', 'types', 'peerDependencies', 'dependencies']`.
36 |
37 | ### Output
38 |
39 | Your output directory will contain:
40 |
41 | - A `package.json` file with `main`, `module`, and `types` fields
42 | - An ES Module build of your React-wrapped Stencil components
43 | - A CommonJS build of your React-wrapped Stencil components
44 | - TypeScript types
45 | - Source Maps
46 |
47 | ## Usage (In React)
48 |
49 | The generated NPM package is the original, suffixed with `-react`.
50 |
51 | All your Stencil Components will be exported from the main/module entry file. E.g., if you had a `Button` component:
52 |
53 | ```jsx
54 | import { Button } from '@anjuna/core-react';
55 | ```
56 |
57 | Custom properties, custom events, synthentic React events, and aria-attributes are all supported:
58 |
59 | ```jsx
60 | import React from 'react';
61 | import ReactDOM from 'react-dom';
62 |
63 | const App = (
64 |
72 | );
73 |
74 | ReactDOM.render(, document.body);
75 | ```
76 |
77 | [npm-image]:https://img.shields.io/npm/v/stencil-react.svg
78 | [npm-url]:https://www.npmjs.com/package/stencil-react
79 | [travis-image]:https://travis-ci.org/petermikitsh/stencil-react.svg?branch=master
80 | [travis-url]:https://travis-ci.org/petermikitsh/stencil-react
81 | [david-image]:https://david-dm.org/petermikitsh/stencil-react/status.svg
82 | [david-url]:https://david-dm.org/petermikitsh/stencil-react
83 | [coveralls-image]:https://coveralls.io/repos/github/petermikitsh/stencil-react/badge.svg?branch=master
84 | [coveralls-url]:https://coveralls.io/github/petermikitsh/stencil-react?branch=master
85 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = (api) => {
2 | api.cache(false);
3 | return {
4 | plugins: [
5 | '@babel/plugin-transform-modules-commonjs',
6 | ],
7 | };
8 | };
9 |
--------------------------------------------------------------------------------
/hero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/petermikitsh/stencil-react/0322663b1c4fb61631f03fa741a94b6c01f6dec6/hero.png
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | collectCoverage: true,
3 | collectCoverageFrom: [
4 | 'src/**.js',
5 | ],
6 | coverageReporters: [
7 | 'lcov',
8 | 'text-summary',
9 | 'html',
10 | ],
11 | testEnvironment: 'jsdom',
12 | transformIgnorePatterns: [
13 | '/node_modules/(?!(@anjuna/core|d3-stencil)).+\\.js$',
14 | ],
15 | verbose: true,
16 | };
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "stencil-react",
3 | "version": "0.0.1-8",
4 | "description": "CLI tool to generate React bindings for Stencil v1 Components",
5 | "keywords": [
6 | "stencil",
7 | "react",
8 | "bindings"
9 | ],
10 | "main": "src/index.js",
11 | "scripts": {
12 | "coverage:open": "open coverage/index.html",
13 | "coverage:report": "cat ./coverage/lcov.info | coveralls",
14 | "lint": "eslint src/**/*.js",
15 | "version": "conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md",
16 | "test": "jest"
17 | },
18 | "bin": {
19 | "stencil-react": "src/index.js"
20 | },
21 | "repository": {
22 | "type": "git",
23 | "url": "git+https://github.com/petermikitsh/stencil-react.git"
24 | },
25 | "author": "Peter Mikitsh ",
26 | "license": "MIT",
27 | "bugs": {
28 | "url": "https://github.com/petermikitsh/stencil-react/issues"
29 | },
30 | "homepage": "http://blog.mikit.sh/post/React-Bindings-For-Stencil-Components/",
31 | "devDependencies": {
32 | "@anjuna/core": "1.0.0-rc.0",
33 | "@stencil/state-tunnel": "1.0.1",
34 | "@types/jest": "^24.0.18",
35 | "@types/prettier": "^1.18.2",
36 | "@types/react": "16.9.2",
37 | "conventional-changelog-cli": "2.0.23",
38 | "coveralls": "^3.0.6",
39 | "d3-stencil": "2.2.0",
40 | "eslint": "^6.1.0",
41 | "eslint-config-airbnb": "^18.0.1",
42 | "eslint-plugin-import": "^2.18.2",
43 | "eslint-plugin-jest": "^22.16.0",
44 | "eslint-plugin-jsx-a11y": "^6.2.3",
45 | "eslint-plugin-react": "^7.14.3",
46 | "eslint-plugin-react-hooks": "^1.7.0",
47 | "jest": "^24.9.0",
48 | "popper.js": "1.15.0",
49 | "react": "16.9.0",
50 | "rimraf": "^3.0.0",
51 | "tslib": "1.10.0"
52 | },
53 | "dependencies": {
54 | "@babel/core": "7.5.5",
55 | "@babel/plugin-transform-modules-commonjs": "7.5.0",
56 | "@babel/register": "7.5.5",
57 | "@stencil/core": "1.3.2",
58 | "@types/lodash": "^4.14.138",
59 | "fs-extra": "8.1.0",
60 | "lodash": "^4.17.15",
61 | "mri": "1.1.4",
62 | "outdent": "0.7.0",
63 | "prettier": "^1.18.2",
64 | "typescript": "3.6.2"
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/componentToReact.js:
--------------------------------------------------------------------------------
1 | const outdent = require('outdent');
2 |
3 | module.exports = (componentClass) => {
4 | const {
5 | is: customElementTag,
6 | properties,
7 | events,
8 | name: exportName,
9 | } = componentClass;
10 |
11 | const quote = (str) => {
12 | const hasHyphen = str.indexOf('-') > -1;
13 | if (hasHyphen) {
14 | return `'${str}'`;
15 | }
16 | return str;
17 | };
18 |
19 | const iterate = (obj, mapFn, join) => {
20 | if (!obj) {
21 | return '';
22 | }
23 | return Object.entries(obj).map(mapFn).join(join || `\n${' '.repeat(2)}`);
24 | };
25 |
26 | return outdent`
27 | import React, { Component } from 'react';
28 |
29 | interface ${exportName}Props {
30 | ${iterate(properties, ([key, prop]) => (
31 | `${quote(key)}?: ${prop.complexType.resolved.replace(/"/g, "'")};`
32 | ))}
33 | ${iterate(events, ([, prop]) => (
34 | `${quote(prop.method)}?: Function;`
35 | ))}
36 | [key: string]: any;
37 | }
38 |
39 | export class ${exportName} extends Component<${exportName}Props> {
40 | ref: React.RefObject;
41 | properties: string[];
42 | events: string[];
43 |
44 | constructor(props: ${exportName}Props) {
45 | super(props);
46 | this.ref = React.createRef();
47 | this.properties = [${iterate(
48 | properties,
49 | ([key]) => (`'${key}'`),
50 | ', ',
51 | )}];
52 | this.events = [${iterate(
53 | events,
54 | ([, { method }]) => (`'${method}'`),
55 | ', ',
56 | )}];
57 | }
58 |
59 | componentDidMount() {
60 | this.properties.forEach((property) => {
61 | const propertyValue = this.props[property];
62 | this.ref.current[property] = propertyValue;
63 | });
64 |
65 | this.events.forEach((event) => {
66 | const eventFn = this.props[event];
67 | if (eventFn) {
68 | this.ref.current.addEventListener(event, eventFn);
69 | }
70 | });
71 | }
72 |
73 | componentDidUpdate(prevProps: ${exportName}Props) {
74 | this.properties.forEach((property) => {
75 | const prevProp = prevProps[property];
76 | const currProp = this.props[property];
77 | if (prevProp !== currProp) {
78 | this.ref.current[property] = currProp;
79 | }
80 | });
81 |
82 | this.events.forEach((event) => {
83 | const prevEvent = prevProps[event];
84 | const currEvent = this.props[event];
85 | if (prevEvent !== event) {
86 | this.ref.current.removeEventListener(event, prevEvent);
87 | this.ref.current.addEventListener(event, currEvent);
88 | }
89 | });
90 | }
91 |
92 | render() {
93 | /* Pass all other props, e.g., React Synthetic Events like 'onClick'
94 | * or aria attrs like 'aria-label' to custom element
95 | */
96 | const others = Object.keys(this.props).reduce((accumulator: { [s: string]: any; }, key) => {
97 | const isAria = key.indexOf('aria-') === 0;
98 | const notCustomProperty = this.properties.indexOf(key) === -1;
99 | const notCustomEvent = this.events.indexOf(key) === -1;
100 | if (isAria || notCustomProperty && notCustomEvent) {
101 | accumulator[key] = this.props[key];
102 | }
103 | return accumulator;
104 | }, {});
105 | return <${customElementTag} ref={this.ref} {...others} />;
106 | }
107 | }
108 |
109 | `;
110 | };
111 |
--------------------------------------------------------------------------------
/src/constants.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | /**
3 | * These package.json fields are ignored and cannot be override
4 | */
5 | ignoredPkgJsonOverrideFields: [
6 | 'main',
7 | 'module',
8 | 'types',
9 | 'peerDependencies',
10 | 'dependencies',
11 | ],
12 | };
13 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const fs = require('fs-extra');
4 | const mri = require('mri');
5 | const path = require('path');
6 | const ts = require('typescript');
7 | const prettier = require('prettier');
8 | const {
9 | omit,
10 | } = require('lodash');
11 |
12 | const componentToReact = require('./componentToReact');
13 | const {
14 | ignoredPkgJsonOverrideFields,
15 | } = require('./constants');
16 |
17 | const { _: [moduleName], ...opts } = mri(process.argv.slice(2));
18 | if (!moduleName) {
19 | throw Error('No module supplied. See https://github.com/petermikitsh/stencil-react#usage');
20 | }
21 | const outDir = opts.outDir || 'dist';
22 | const pkgBasePath = path.resolve('node_modules', moduleName);
23 | const pkgJsonPath = path.resolve(pkgBasePath, 'package.json');
24 | const pkgJson = require(pkgJsonPath);
25 | // Compile stencil files so they can be read in NodeJS
26 | require('@babel/register')({
27 | only: [pkgBasePath],
28 | plugins: ['@babel/plugin-transform-modules-commonjs'],
29 | cache: false,
30 | });
31 |
32 | async function main() {
33 | const collectionPath = path.resolve(pkgBasePath, pkgJson.collection);
34 | const collectionDir = path.dirname(collectionPath);
35 | const { entries } = require(collectionPath);
36 | let indexFile = '';
37 | const relativeFiles = [];
38 |
39 | const transforms = entries.map(async (entry) => {
40 | const entryPath = path.resolve(collectionDir, entry);
41 | const componentFile = require(entryPath);
42 | const exportName = Object.keys(componentFile)[0];
43 | const componentClass = componentFile[exportName];
44 | const reactComponent = componentToReact(componentClass);
45 | const writePath = path.resolve(outDir, 'tsx', entry).replace('.js', '.tsx');
46 | const writeDir = path.dirname(writePath);
47 | const relativePath = path.relative(outDir, path.resolve(outDir, entry));
48 | const absPath = path.resolve(outDir, relativePath);
49 | relativeFiles.push(absPath);
50 | indexFile += `export { ${exportName} } from './${relativePath.replace('.js', '')}';\n`;
51 | await fs.ensureDir(writeDir);
52 | await fs.writeFile(writePath, reactComponent);
53 | });
54 |
55 | await Promise.all(transforms);
56 | const indexPath = path.resolve(outDir, 'tsx/index.ts');
57 | await fs.writeFile(indexPath, indexFile);
58 |
59 | // Typescript file generation complete.
60 | // Now to make ES Modules.
61 | const files = [indexPath, ...relativeFiles];
62 | const baseConfig = {
63 | target: ts.ScriptTarget.ES5,
64 | importHelpers: true,
65 | sourceMap: true,
66 | jsx: ts.JsxEmit.React,
67 | };
68 | const esmProgram = ts.createProgram(files, {
69 | ...baseConfig,
70 | module: ts.ModuleKind.ESNext,
71 | outDir: path.resolve(outDir, 'esm'),
72 | declaration: true,
73 | declarationDir: path.resolve(outDir, 'types'),
74 | });
75 | esmProgram.emit();
76 |
77 | // Also, make CommonJS Modules.
78 | const cjsProgram = ts.createProgram(files, {
79 | ...baseConfig,
80 | module: ts.ModuleKind.CommonJS,
81 | outDir: path.resolve(outDir, 'cjs'),
82 | });
83 | cjsProgram.emit();
84 |
85 | // Make a package.json file
86 | let jsonOverride = (() => {
87 | try {
88 | return JSON.parse(opts.packageJson || '{ }');
89 | } catch (e) {
90 | console.log('⚠️ Unable to parse --packageJson option. Ignoring input.');
91 | return {};
92 | }
93 | })();
94 |
95 | const cliPkgJsonOverridePath = opts.packageJsonPath;
96 | if (cliPkgJsonOverridePath !== undefined) {
97 | let override = { };
98 | try {
99 | override = require(path.resolve(cliPkgJsonOverridePath));
100 | } catch (e) {
101 | console.warn(e);
102 | }
103 | jsonOverride = {
104 | ...override,
105 | ...jsonOverride,
106 | };
107 | }
108 | const genPkgJsonPath = path.resolve(outDir, 'package.json');
109 | const finalPkgJsonObj = {
110 | name: `${moduleName}-react`,
111 | description: `${moduleName} Stencil Components for React`,
112 | version: `${pkgJson.version}`,
113 | main: './cjs/index.js',
114 | module: './esm/index.js',
115 | types: './types/index.d.ts',
116 | peerDependencies: {
117 | [moduleName]: `^${pkgJson.version}`,
118 | },
119 | dependencies: {
120 | tslib: `^${require('../package.json').devDependencies.tslib}`,
121 | },
122 | ...omit(
123 | jsonOverride,
124 | ...ignoredPkgJsonOverrideFields,
125 | ),
126 | };
127 | await fs.writeFile(
128 | genPkgJsonPath,
129 | prettier.format(
130 | JSON.stringify(finalPkgJsonObj),
131 | {
132 | parser: 'json',
133 | },
134 | ),
135 | );
136 | }
137 |
138 | module.exports = main();
139 |
--------------------------------------------------------------------------------
/test/index.test.js:
--------------------------------------------------------------------------------
1 | const rimraf = require('rimraf');
2 | const path = require('path');
3 |
4 | const componentToReact = require('../src/componentToReact');
5 | const testPkgOverride = require('./pkgOverride.test.json');
6 | const {
7 | ignoredPkgJsonOverrideFields,
8 | } = require('../src/constants');
9 |
10 | beforeEach(() => {
11 | jest.resetModules();
12 | });
13 |
14 | test('Generate React Component from Web Component', () => {
15 | const componentClass = {
16 | is: 'anj-button',
17 | properties: {
18 | context: {
19 | type: 'string',
20 | complexType: {
21 | original: "'primary' | 'secondary' | 'text' | 'icon' | 'free'",
22 | // eslint-disable-next-line
23 | resolved: "\"free\" | \"icon\" | \"primary\" | \"secondary\" | \"text\"",
24 | },
25 | attribute: 'context',
26 | },
27 | },
28 | events: [
29 | {
30 | method: 'anjBlur',
31 | name: 'anjBlur',
32 | complexType: {
33 | original: 'void',
34 | resolved: 'void',
35 | },
36 | },
37 | ],
38 | name: 'Button',
39 | };
40 | const result = componentToReact(componentClass);
41 | expect(typeof result).toBe('string');
42 | });
43 |
44 | describe('CLI npm package generation', () => {
45 | /**
46 | * Clean up directories
47 | *
48 | * @param {string} dirs
49 | */
50 | function cleanup(...dirs) {
51 | dirs.forEach((dir) => rimraf.sync(path.resolve(__dirname, dir)));
52 | }
53 |
54 | cleanup(
55 | '../dist',
56 | '../test_output',
57 | );
58 |
59 | it('should fail when no name supplied', async () => {
60 | try {
61 | await require('../src/index.js');
62 | } catch (e) {
63 | expect(e.message).toMatch('No module supplied.');
64 | }
65 | });
66 |
67 | it('should generate package inside /dist if no --outDir provided', async () => {
68 | jest.setTimeout(30000);
69 |
70 | process.argv.push('@anjuna/core');
71 | await require('../src/index.js');
72 | process.argv.pop();
73 |
74 | const json = require(path.resolve(__dirname, '../dist/package.json'));
75 | expect(json.name).toBe('@anjuna/core-react');
76 | });
77 |
78 | it('should generate in correct directory if --outDir provided', async () => {
79 | jest.setTimeout(30000);
80 |
81 | process.argv.push('d3-stencil', '--outDir', 'test_output/outdir');
82 | await require('../src/index.js');
83 | process.argv.splice(-3, 3);
84 |
85 | const json = require(path.resolve(__dirname, '../test_output/outdir/package.json'));
86 | expect(json.name).toBe('d3-stencil-react');
87 | });
88 |
89 | /**
90 | * Validate package.json by checking all the override fileds except ignored ones are same.
91 | *
92 | * @param {object} overrideSource The json used for override.
93 | * @param {object} outputJson The package.json output.
94 | */
95 | function compareJsonWithOverrideSource(
96 | overrideSource,
97 | outputJson,
98 | ) {
99 | Object.keys(overrideSource).forEach((key) => {
100 | if (ignoredPkgJsonOverrideFields.indexOf(key) !== -1) {
101 | expect(outputJson[key]).not.toEqual(testPkgOverride[key]);
102 | } else {
103 | expect(outputJson[key]).toEqual(testPkgOverride[key]);
104 | }
105 | });
106 | }
107 |
108 | it('should generate package with correct package.json if --packageJson provided', async () => {
109 | jest.setTimeout(30000);
110 |
111 | process.argv.push(
112 | 'd3-stencil',
113 | '--outDir',
114 | 'test_output/packageJson',
115 | '--packageJson',
116 | JSON.stringify(testPkgOverride),
117 | );
118 | await require('../src/index.js');
119 | process.argv.splice(-5, 5);
120 |
121 | const json = require(path.resolve(__dirname, '../test_output/packageJson/package.json'));
122 | compareJsonWithOverrideSource(
123 | testPkgOverride,
124 | json,
125 | );
126 | });
127 |
128 | it('should generate package with correct package.json if --packageJsonPath provided', async () => {
129 | jest.setTimeout(30000);
130 |
131 | process.argv.push(
132 | '@anjuna/core',
133 | '--outDir',
134 | 'test_output/packageJsonPath',
135 | '--packageJsonPath',
136 | './test/pkgOverride.test.json',
137 | );
138 | await require('../src/index.js');
139 | process.argv.splice(-5, 5);
140 |
141 | const json = require(path.resolve(__dirname, '../test_output/packageJsonPath/package.json'));
142 | compareJsonWithOverrideSource(
143 | testPkgOverride,
144 | json,
145 | );
146 | });
147 |
148 | it('should not apply any override to package.json if provide a non-existent --packageJsonPath', async () => {
149 | jest.setTimeout(30000);
150 |
151 | process.argv.push(
152 | '@anjuna/core',
153 | '--outDir',
154 | 'test_output/wrongPackageJsonPath',
155 | '--packageJsonPath',
156 | './test/pkgOverride.test.wrong.json',
157 | );
158 | await require('../src/index.js');
159 | process.argv.splice(-5, 5);
160 |
161 | const json = require(path.resolve(__dirname, '../test_output/wrongPackageJsonPath/package.json'));
162 | Object.keys(testPkgOverride).forEach((key) => {
163 | expect(json[key]).not.toEqual(testPkgOverride[key]);
164 | });
165 | });
166 | });
167 |
--------------------------------------------------------------------------------
/test/pkgOverride.test.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "override-package-name",
3 | "main": "./src/empty.js",
4 | "module": "./dir/index.js",
5 | "types": "./types/type.d.ts",
6 | "peerDependencies": { },
7 | "dependencies": { }
8 | }
9 |
--------------------------------------------------------------------------------