@apia/cli 4.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/cli/askQuestion.js +19 -0
- package/cli/cli.js +112 -0
- package/cli/component_base.tsx +40 -0
- package/cli/findFileInAncestors.js +33 -0
- package/cli/webpack.config.cjs +32 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/package.json +27 -0
package/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Apia Command Line
|
|
2
|
+
|
|
3
|
+
This library provides several utilities, mainly oriented to external developers consuming our development tools.
|
|
4
|
+
|
|
5
|
+
## Custom components
|
|
6
|
+
|
|
7
|
+
### `apia create component [component_name]`
|
|
8
|
+
|
|
9
|
+
Creates a boilerplate structure on `./components/[component_name]` providing the starting code for compiling custom components.
|
|
10
|
+
|
|
11
|
+
### `apia compile component [component_name] [--watch]`:
|
|
12
|
+
|
|
13
|
+
Compiles the component, provided it's located under `./components/[component_name]`. If `--watch` is passed as argument, then the compilation is made in watch mode for development purposes.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const readline = require('readline');
|
|
2
|
+
|
|
3
|
+
function askQuestion(question, defaultAnswer, defaultValue, useDefaults) {
|
|
4
|
+
if (useDefaults) return defaultValue;
|
|
5
|
+
|
|
6
|
+
const rl = readline.createInterface({
|
|
7
|
+
input: process.stdin,
|
|
8
|
+
output: process.stdout,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
return new Promise((resolve) => {
|
|
12
|
+
rl.question(`${question} [default: ${defaultAnswer}]: `, (answer) => {
|
|
13
|
+
rl.close();
|
|
14
|
+
resolve(answer || defaultValue); // Use default if no answer
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = askQuestion;
|
package/cli/cli.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { program } = require('commander');
|
|
4
|
+
const { execSync } = require('child_process');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const findFileInAncestors = require('./findFileInAncestors')
|
|
8
|
+
|
|
9
|
+
const logger = {
|
|
10
|
+
log(...what) {
|
|
11
|
+
console.log(...what);
|
|
12
|
+
},
|
|
13
|
+
error(error) {
|
|
14
|
+
console.error('[ERROR] ', error)
|
|
15
|
+
},
|
|
16
|
+
internalE(error) {
|
|
17
|
+
console.error('[INTERNAL ERROR] ', error)
|
|
18
|
+
},
|
|
19
|
+
warn(warn) {
|
|
20
|
+
console.warn('[WARNING] ', error)
|
|
21
|
+
},
|
|
22
|
+
info(info) {
|
|
23
|
+
console.info('[INFO] ', error)
|
|
24
|
+
},
|
|
25
|
+
success(success) {
|
|
26
|
+
console.log('[SUCCESS] ', success)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Starts webpack on the given component.
|
|
32
|
+
*
|
|
33
|
+
* - If --watch flag is passed, run webpack in development mode.
|
|
34
|
+
*/
|
|
35
|
+
program
|
|
36
|
+
.version('1.0.0')
|
|
37
|
+
.command('compile')
|
|
38
|
+
.argument('<component_name>', 'The name of the component to be compiled.')
|
|
39
|
+
.description('Compiles the component into the OUT_DIR declared in the .env file.')
|
|
40
|
+
.option('--watch', 'Starts the compiler in watch mode.') // Define the '--y' option
|
|
41
|
+
.action(async (componentName, { watch }) => {
|
|
42
|
+
const parsedName = componentName.charAt(0).toUpperCase() + componentName.slice(1)
|
|
43
|
+
logger.info(`Compiling ${parsedName}`);
|
|
44
|
+
if (watch) {
|
|
45
|
+
logger.info("Watch mode enabled.")
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let envFile = findFileInAncestors('.env');
|
|
49
|
+
if (envFile !== undefined) {
|
|
50
|
+
const outDir = envFile.content.match(/^ *OUT_DIR *= *([\n]+)\n/)?.[1];
|
|
51
|
+
if (outDir) {
|
|
52
|
+
const targetComponentIndex = path.resolve(`${process.cwd()}/${parsedName}/index.tsx`);
|
|
53
|
+
const defaultWebpackConfig = `${__dirname}/webpack.config.cjs`;
|
|
54
|
+
|
|
55
|
+
logger.info(`Building project with:
|
|
56
|
+
- Entry: ${targetComponentIndex}
|
|
57
|
+
- Output: ${outDir}
|
|
58
|
+
- Webpack config: ${defaultWebpackConfig}`);
|
|
59
|
+
|
|
60
|
+
// Build with the specified inputs
|
|
61
|
+
execSync(`npx webpack --config "${webpackConfig}" --entry "${targetComponentIndex}" --output-filename "${outDir}.js" ${watch ? '--watch' : ''}`, { stdio: 'inherit' });
|
|
62
|
+
|
|
63
|
+
logger.success('Build completed successfully!');
|
|
64
|
+
} else {
|
|
65
|
+
throw new Error("Cannot find OUT_DIR in " + envFile.fileName);
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
throw new Error("Cannot find .env file");
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Makes a component inside ./<component_name>/index.tsx
|
|
74
|
+
*
|
|
75
|
+
* - If the component exists, warn the user and do nothing.
|
|
76
|
+
*/
|
|
77
|
+
program
|
|
78
|
+
.command('create')
|
|
79
|
+
.argument('<component_name>', 'The name of the component to be created.')
|
|
80
|
+
.description('Creates the boilerplate for the given component name.')
|
|
81
|
+
.action((componentName) => {
|
|
82
|
+
const parsedName = componentName.charAt(0).toUpperCase() + componentName.slice(1)
|
|
83
|
+
const destinationFile = path.resolve(process.cwd(), parsedName, 'index.tsx');
|
|
84
|
+
const sourcePath = path.resolve(__dirname, 'component_base.tsx');
|
|
85
|
+
|
|
86
|
+
if (fs.existsSync(destinationFile)) {
|
|
87
|
+
logger.error(`Already exists component with name "${parsedName}" in ${destinationFile}`);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
} else {
|
|
90
|
+
|
|
91
|
+
const destinationDir = path.resolve(process.cwd(), parsedName);
|
|
92
|
+
if (!fs.existsSync(destinationDir)) {
|
|
93
|
+
fs.mkdirSync(destinationDir, { recursive: true })
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (!fs.existsSync(sourcePath)) {
|
|
97
|
+
logger.internalE(`Cannot find the template file.`);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Read the content from the source file
|
|
102
|
+
const content = fs.readFileSync(sourcePath, 'utf-8').replaceAll('__COMPONENT_NAME__', parsedName);
|
|
103
|
+
|
|
104
|
+
// Write the content to the new file
|
|
105
|
+
fs.writeFileSync(destinationFile, content);
|
|
106
|
+
|
|
107
|
+
logger.success(`Plugin created at: ${destinationFile}`);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
program.parse(process.argv);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { Plugin } from '../Plugin';
|
|
3
|
+
import { observable, makeObservable } from 'mobx';
|
|
4
|
+
import { observer } from 'mobx-react-lite';
|
|
5
|
+
|
|
6
|
+
type TState = {
|
|
7
|
+
counter: number;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
class __COMPONENT_NAME__Controller {
|
|
11
|
+
private state: TState = {
|
|
12
|
+
counter: 0,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
constructor() {
|
|
16
|
+
makeObservable<__COMPONENT_NAME__Controller, 'state'>(this, {
|
|
17
|
+
state: observable,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get count() {
|
|
22
|
+
return this.state.counter;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
sum() {
|
|
26
|
+
this.state.counter++;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const __COMPONENT_NAME__ = observer(() => {
|
|
31
|
+
const controller = useMemo(() => new __COMPONENT_NAME__Controller(), []);
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<button onClick={() => controller.sum()}>
|
|
35
|
+
Hello world {controller.count}
|
|
36
|
+
</button>
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
new Plugin('__COMPONENT_NAME__', __COMPONENT_NAME__);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Searches for the file with <fileName> in the current working directory (process.cwd()) and all its ancestors.
|
|
6
|
+
*
|
|
7
|
+
* @returns - An object { fileName: string; content: string } if found, or undefined else.
|
|
8
|
+
*/
|
|
9
|
+
function findFileInAncestors(fileName) {
|
|
10
|
+
let currentDir = path.resolve(process.cwd())
|
|
11
|
+
let searchAgain = true;
|
|
12
|
+
|
|
13
|
+
do {
|
|
14
|
+
/**
|
|
15
|
+
* Searches for the .env file in the current folder and its ancestors.
|
|
16
|
+
*/
|
|
17
|
+
const currentEnv = path.resolve(currentDir, fileName)
|
|
18
|
+
|
|
19
|
+
searchAgain = !fs.existsSync(currentEnv);
|
|
20
|
+
if (!searchAgain) {
|
|
21
|
+
return { fileName: currentEnv, content: fs.readFileSync(currentEnv) };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const aux = currentDir;
|
|
25
|
+
currentDir = path.resolve(currentDir, '..');
|
|
26
|
+
|
|
27
|
+
searchAgain = aux !== currentDir;
|
|
28
|
+
} while (searchAgain);
|
|
29
|
+
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = findFileInAncestors;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const WrapperPlugin = require('wrapper-webpack-plugin');
|
|
2
|
+
const path = require('path')
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
mode: 'production',
|
|
6
|
+
module: {
|
|
7
|
+
rules: [
|
|
8
|
+
{
|
|
9
|
+
test: /\.tsx?$/,
|
|
10
|
+
use: 'ts-loader',
|
|
11
|
+
exclude: /node_modules/,
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
externals: {
|
|
16
|
+
react: 'react'
|
|
17
|
+
},
|
|
18
|
+
resolve: {
|
|
19
|
+
extensions: ['.tsx', '.ts', '.js', '.css'],
|
|
20
|
+
},
|
|
21
|
+
output: {
|
|
22
|
+
filename: '[name].js',
|
|
23
|
+
path: path.resolve(process.cwd(), 'dist'),
|
|
24
|
+
},
|
|
25
|
+
plugins: [
|
|
26
|
+
new WrapperPlugin({
|
|
27
|
+
test: /\.js$/, // only wrap output of bundle files with '.js' extension
|
|
28
|
+
header: 'window.addEventListener("load", () => {\n',
|
|
29
|
+
footer: '\n});'
|
|
30
|
+
})
|
|
31
|
+
].filter(Boolean),
|
|
32
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { EventEmitter } from '@apia/util';
|
|
2
|
+
|
|
3
|
+
declare global {
|
|
4
|
+
interface Window {
|
|
5
|
+
dispatchComponent: EventEmitter<{
|
|
6
|
+
dispatch: any;
|
|
7
|
+
ready: null;
|
|
8
|
+
}>;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
declare class Plugin {
|
|
12
|
+
constructor(name: string, fc: any);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { Plugin };
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/Plugin.ts"],"sourcesContent":["import { EventEmitter } from '@apia/util';\r\n\r\ndeclare global {\r\n interface Window {\r\n dispatchComponent: EventEmitter<{\r\n dispatch: any;\r\n ready: null;\r\n }>;\r\n }\r\n}\r\n\r\nexport class Plugin {\r\n constructor(name: string, fc: any) {\r\n window.dispatchComponent.on('ready', () => {\r\n window.dispatchComponent.emit('dispatch', { name, fc });\r\n });\r\n }\r\n}\r\n"],"names":[],"mappings":"AAWO,MAAM,MAAO,CAAA;AAAA,EAClB,WAAA,CAAY,MAAc,EAAS,EAAA;AACjC,IAAO,MAAA,CAAA,iBAAA,CAAkB,EAAG,CAAA,OAAA,EAAS,MAAM;AACzC,MAAA,MAAA,CAAO,kBAAkB,IAAK,CAAA,UAAA,EAAY,EAAE,IAAA,EAAM,IAAI,CAAA;AAAA,KACvD,CAAA;AAAA;AAEL;;;;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@apia/cli",
|
|
3
|
+
"version": "4.0.14",
|
|
4
|
+
"sideEffects": true,
|
|
5
|
+
"author": "Alexis Leite <alexisleite@live.com>",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"typings": "dist/index.d.ts",
|
|
10
|
+
"bin": {
|
|
11
|
+
"apia": "./cli/cli.js"
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"libDev": "rollup --config ../../config/rollup.common.mjs --environment MODE:development,ENTRY:index.ts",
|
|
15
|
+
"libBuild": "rollup --config ../../config/rollup.common.mjs --environment MODE:production,ENTRY:index.ts",
|
|
16
|
+
"libWatch": "rollup --watch --config ../../config/rollup.common.mjs --environment MODE:development,ENTRY:index.ts,WATCH:true"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@apia/util": "^4.0.14",
|
|
20
|
+
"commander": "^12.0.0"
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public",
|
|
24
|
+
"registry": "https://registry.npmjs.org/"
|
|
25
|
+
},
|
|
26
|
+
"gitHead": "56fbc27ca9b878c099d501fc55c3d2b266624fbe"
|
|
27
|
+
}
|