mirror of
https://github.com/qlik-oss/nebula.js.git
synced 2025-12-19 17:58:43 -05:00
feat(cli-create): add mashup template (#372)
This commit is contained in:
@@ -80,13 +80,13 @@ jobs:
|
||||
name: Test integration
|
||||
command: APP_ID=$DOC_ID yarn run test:integration --chrome.browserWSEndpoint "ws://localhost:3000" --no-launch
|
||||
|
||||
- run:
|
||||
name: Create a hello supernova project from latest release
|
||||
command: |
|
||||
set -e
|
||||
npx nebula create temp/hello --pkgm yarn --picasso none
|
||||
cd temp/hello
|
||||
APP_ID=$DOC_ID yarn run test:integration --chrome.browserWSEndpoint "ws://localhost:3000" --no-launch
|
||||
# - run:
|
||||
# name: Create a hello supernova project from latest release
|
||||
# command: |
|
||||
# set -e
|
||||
# npx nebula create temp/hello --pkgm yarn --picasso none
|
||||
# cd temp/hello
|
||||
# APP_ID=$DOC_ID yarn run test:integration --chrome.browserWSEndpoint "ws://localhost:3000" --no-launch
|
||||
|
||||
- run:
|
||||
name: Create a picasso barchart supernova project from current commit
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
"lint": "eslint src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/cli": "7.8.3",
|
||||
"@babel/core": "7.8.3",
|
||||
"@babel/preset-env": "7.8.3",
|
||||
"@babel/cli": "7.8.4",
|
||||
"@babel/core": "7.9.0",
|
||||
"@babel/preset-env": "7.9.0",
|
||||
"@rollup/plugin-commonjs": "11.0.1",
|
||||
"@rollup/plugin-node-resolve": "7.0.0",
|
||||
"@rollup/plugin-replace": "2.3.0",
|
||||
|
||||
@@ -1,17 +1,43 @@
|
||||
#!/usr/bin/env node
|
||||
const yargs = require('yargs');
|
||||
const importCwd = require('import-cwd');
|
||||
|
||||
const build = require('@nebula.js/cli-build/command');
|
||||
const create = require('@nebula.js/cli-create/command');
|
||||
const serve = require('@nebula.js/cli-serve/command');
|
||||
const sense = require('@nebula.js/cli-sense/command');
|
||||
// const build = require('@nebula.js/cli-build/command');
|
||||
// const create = require('@nebula.js/cli-create/command');
|
||||
// const serve = require('@nebula.js/cli-serve/command');
|
||||
// const sense = require('@nebula.js/cli-sense/command');
|
||||
|
||||
yargs.usage('nebula <command> [options]');
|
||||
|
||||
const tryAddCommand = m => {
|
||||
let cmd;
|
||||
try {
|
||||
cmd = require(`${m}/command`); // eslint-disable-line
|
||||
} catch (e) {
|
||||
cmd = importCwd.silent(`${m}/command`);
|
||||
}
|
||||
|
||||
if (cmd) {
|
||||
yargs.command(cmd);
|
||||
} else {
|
||||
// add dummy command in order to instruct user how to install missing package
|
||||
const comm = m.split('-')[1];
|
||||
yargs.command({
|
||||
command: comm,
|
||||
handler() {
|
||||
throw new Error(
|
||||
`Command \x1b[36m${comm}\x1b[0m is missing, make sure to install \x1b[36m${m}\x1b[0m and then try again.`
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
['@nebula.js/cli-build', '@nebula.js/cli-create', '@nebula.js/cli-serve', '@nebula.js/cli-sense'].forEach(
|
||||
tryAddCommand
|
||||
);
|
||||
|
||||
yargs
|
||||
.usage('nebula <command> [options]')
|
||||
.command(build)
|
||||
.command(create)
|
||||
.command(serve)
|
||||
.command(sense)
|
||||
.demandCommand()
|
||||
.alias('h', 'help')
|
||||
.wrap(Math.min(80, yargs.terminalWidth())).argv;
|
||||
|
||||
@@ -21,12 +21,14 @@
|
||||
"scripts": {
|
||||
"lint": "eslint src"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nebula.js/cli-build": "^0.x",
|
||||
"@nebula.js/cli-sense": "^0.x",
|
||||
"@nebula.js/cli-serve": "^0.x"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nebula.js/cli-build": "0.2.0",
|
||||
"@nebula.js/cli-create": "0.2.0",
|
||||
"@nebula.js/cli-sense": "0.2.0",
|
||||
"@nebula.js/cli-serve": "0.2.0",
|
||||
"chalk": "3.0.0",
|
||||
"import-cwd": "3.0.0",
|
||||
"yargs": "15.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,25 @@
|
||||
const create = require('./lib/create');
|
||||
|
||||
const mashup = {
|
||||
command: 'mashup <name>',
|
||||
desc: 'Create a mashup',
|
||||
builder(yargs) {
|
||||
yargs.positional('name', {
|
||||
type: 'string',
|
||||
description: 'name of the project',
|
||||
});
|
||||
},
|
||||
handler(argv) {
|
||||
create(argv);
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
command: 'create <name>',
|
||||
desc: 'Create a supernova',
|
||||
builder(yargs) {
|
||||
yargs.command(mashup);
|
||||
|
||||
yargs.positional('name', {
|
||||
type: 'string',
|
||||
description: 'name of the project',
|
||||
|
||||
@@ -46,7 +46,7 @@ const parseAuthor = (str = '') => {
|
||||
};
|
||||
};
|
||||
|
||||
function cpy(root, destination) {
|
||||
function copyFactory(root, destination) {
|
||||
return (source, target, data) => {
|
||||
if (data) {
|
||||
const content = fs.readFileSync(path.resolve(root, ...source.split('/')), { encoding: 'utf8' });
|
||||
@@ -61,6 +61,8 @@ function cpy(root, destination) {
|
||||
const create = async argv => {
|
||||
const { name } = argv;
|
||||
|
||||
const isMashup = argv._.includes('mashup');
|
||||
|
||||
const projectFolder = name;
|
||||
const packageName = name.split('/').slice(-1)[0];
|
||||
|
||||
@@ -90,7 +92,7 @@ const create = async argv => {
|
||||
message: 'Pick a picasso template',
|
||||
default: 'none',
|
||||
choices: ['none', 'minimal', 'barchart'],
|
||||
when: !argv.picasso,
|
||||
when: !isMashup && !argv.picasso,
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -103,28 +105,30 @@ const create = async argv => {
|
||||
const { picasso } = options;
|
||||
fse.ensureDirSync(destination);
|
||||
|
||||
// ==== common files ====
|
||||
// copy raw files
|
||||
['editorconfig', 'eslintignore', 'gitignore', 'eslintrc.json'].forEach(filename =>
|
||||
fs.copyFileSync(
|
||||
path.resolve(templatesRoot, 'common', `_${filename}`), // copying dotfiles may not always work, so they are prefixed with an underline
|
||||
path.resolve(destination, `.${filename}`)
|
||||
)
|
||||
);
|
||||
|
||||
const copy = cpy(templatesRoot, destination);
|
||||
|
||||
copy('common/README.md', 'README.md', { name: packageName });
|
||||
const copy = copyFactory(templatesRoot, destination);
|
||||
|
||||
// ==== template files ====
|
||||
const folders = [];
|
||||
if (picasso !== 'none') {
|
||||
folders.push('picasso/common');
|
||||
folders.push(`picasso/${picasso}`);
|
||||
const folders = ['common'];
|
||||
if (isMashup) {
|
||||
folders.push('mashup');
|
||||
} else {
|
||||
folders.push('none');
|
||||
folders.push('sn/common');
|
||||
if (picasso !== 'none') {
|
||||
folders.push('sn/picasso/common');
|
||||
folders.push(`sn/picasso/${picasso}`);
|
||||
} else {
|
||||
folders.push('sn/none');
|
||||
}
|
||||
}
|
||||
|
||||
const data = {
|
||||
name: packageName,
|
||||
description: '',
|
||||
user: options.author.name,
|
||||
email: options.author.email,
|
||||
nebulaVersion: pkg.version,
|
||||
};
|
||||
|
||||
const traverse = (sourceFolder, targetFolder = '') => {
|
||||
const files = fs.readdirSync(path.resolve(templatesRoot, sourceFolder));
|
||||
|
||||
@@ -135,16 +139,11 @@ const create = async argv => {
|
||||
if (stats.isDirectory()) {
|
||||
fse.ensureDirSync(path.resolve(destination, next));
|
||||
traverse(p, next);
|
||||
} else if (file === '_package.json') {
|
||||
copy(`${sourceFolder}/_package.json`, 'package.json', {
|
||||
name: packageName,
|
||||
description: '',
|
||||
user: options.author.name,
|
||||
email: options.author.email,
|
||||
nebulaVersion: pkg.version,
|
||||
});
|
||||
} else if (file[0] === '_') {
|
||||
const newFileName = file === '_package.json' ? 'package.json' : `.${file.substr(1)}`;
|
||||
copy(`${sourceFolder}/${file}`, `${targetFolder}/${newFileName}`.replace(/^\//, ''), data);
|
||||
} else {
|
||||
copy(`${sourceFolder}/${file}`, next);
|
||||
copy(`${sourceFolder}/${file}`, next, data);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
19
commands/create/templates/mashup/_package.json
Normal file
19
commands/create/templates/mashup/_package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "<%= name %>",
|
||||
"version": "0.0.1",
|
||||
"author": {
|
||||
"name": "<%= user %>",
|
||||
"email": "<%= email %>"
|
||||
},
|
||||
"keywords": ["qlik", "nebula"],
|
||||
"scripts": {
|
||||
"start": "parcel src/index.html"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nebula.js/nucleus": "<%= nebulaVersion %>",
|
||||
"@nebula.js/sn-bar-chart": "^0.2.2",
|
||||
"@nebula.js/supernova": "<%= nebulaVersion %>",
|
||||
"enigma.js": "^2.6.3",
|
||||
"parcel-bundler": "^1.12.4"
|
||||
}
|
||||
}
|
||||
18
commands/create/templates/mashup/src/configure.js
Normal file
18
commands/create/templates/mashup/src/configure.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import nucleus from '@nebula.js/nucleus/dist/nucleus';
|
||||
|
||||
import barchart from '@nebula.js/sn-bar-chart';
|
||||
|
||||
const n = nucleus.createConfiguration({
|
||||
context: {
|
||||
theme: 'light',
|
||||
language: 'en-US',
|
||||
},
|
||||
types: [
|
||||
{
|
||||
name: 'barchart',
|
||||
load: () => Promise.resolve(barchart),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export default n;
|
||||
44
commands/create/templates/mashup/src/connect.js
Normal file
44
commands/create/templates/mashup/src/connect.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import enigma from 'enigma.js';
|
||||
import schema from 'enigma.js/schemas/12.170.2.json';
|
||||
|
||||
async function getQCSHeaders({ webIntegrationId, url }) {
|
||||
const response = await fetch(`${url}/api/v1/csrf-token`, {
|
||||
credentials: 'include',
|
||||
headers: { 'qlik-web-integration-id': webIntegrationId },
|
||||
});
|
||||
if (response.status === 401) {
|
||||
const loginUrl = new URL(`${url}/login`);
|
||||
loginUrl.searchParams.append('returnto', window.location.href);
|
||||
loginUrl.searchParams.append('qlik-web-integration-id', webIntegrationId);
|
||||
window.location.href = loginUrl;
|
||||
return undefined;
|
||||
}
|
||||
const csrfToken = new Map(response.headers).get('qlik-csrf-token');
|
||||
return {
|
||||
'qlik-web-integration-id': webIntegrationId,
|
||||
'qlik-csrf-token': csrfToken,
|
||||
};
|
||||
}
|
||||
|
||||
async function getEnigmaApp({ host, appId, headers }) {
|
||||
const params = Object.keys(headers)
|
||||
.map(key => `${key}=${headers[key]}`)
|
||||
.join('&');
|
||||
|
||||
const enigmaGlobal = await enigma
|
||||
.create({
|
||||
schema,
|
||||
url: `wss://${host}/app/${appId}?${params}`,
|
||||
})
|
||||
.open();
|
||||
|
||||
return enigmaGlobal.openDoc(appId);
|
||||
}
|
||||
|
||||
async function connect({ url, webIntegrationId, appId }) {
|
||||
const host = url.replace(/^https?:\/\//, '').replace(/\/?/, '');
|
||||
const headers = await getQCSHeaders({ url, webIntegrationId });
|
||||
return getEnigmaApp({ host, headers, appId });
|
||||
}
|
||||
|
||||
export default connect;
|
||||
36
commands/create/templates/mashup/src/index.html
Normal file
36
commands/create/templates/mashup/src/index.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Nebula mashup</title>
|
||||
|
||||
<style>
|
||||
body {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin: 0 auto;
|
||||
width: 80%;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.object {
|
||||
position: relative;
|
||||
height: 600px;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
margin: 12px 0px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content">
|
||||
<div class="toolbar"></div>
|
||||
<div class="object"></div>
|
||||
</div>
|
||||
|
||||
<script src="./index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
19
commands/create/templates/mashup/src/index.js
Normal file
19
commands/create/templates/mashup/src/index.js
Normal file
@@ -0,0 +1,19 @@
|
||||
/* eslint-disable */
|
||||
import nucleus from './configure';
|
||||
import connect from './connect';
|
||||
|
||||
async function run() {
|
||||
const app = await connect({
|
||||
url: '<URL>',
|
||||
webIntegrationId: '<Qlik web integration id>',
|
||||
appId: '<App id>',
|
||||
});
|
||||
|
||||
const n = nucleus(app);
|
||||
|
||||
(await n.selections()).mount(document.querySelector('.toolbar'));
|
||||
|
||||
// n.render({});
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -23,12 +23,14 @@
|
||||
"devDependencies": {
|
||||
"@after-work.js/aw": "6.0.10",
|
||||
"@nebula.js/cli": "<%= nebulaVersion %>",
|
||||
"@nebula.js/cli-build": "<%= nebulaVersion %>",
|
||||
"@nebula.js/cli-serve": "<%= nebulaVersion %>",
|
||||
"eslint": "5.12.1",
|
||||
"eslint-config-airbnb-base": "13.1.0",
|
||||
"eslint-plugin-import": "2.15.0",
|
||||
"eslint-plugin-mocha": "5.2.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nebula.js/supernova": "^0.1.0-alpha.28"
|
||||
"@nebula.js/supernova": "^0.x"
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,8 @@
|
||||
"devDependencies": {
|
||||
"@after-work.js/aw": "6.0.10",
|
||||
"@nebula.js/cli": "<%= nebulaVersion %>",
|
||||
"@nebula.js/cli-build": "<%= nebulaVersion %>",
|
||||
"@nebula.js/cli-serve": "<%= nebulaVersion %>",
|
||||
"eslint": "5.12.1",
|
||||
"eslint-config-airbnb-base": "13.1.0",
|
||||
"eslint-plugin-import": "2.15.0",
|
||||
@@ -27,9 +27,9 @@
|
||||
"lint": "eslint src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/cli": "7.8.3",
|
||||
"@babel/core": "7.8.3",
|
||||
"@babel/preset-env": "7.8.3",
|
||||
"@babel/cli": "7.8.4",
|
||||
"@babel/core": "7.9.0",
|
||||
"@babel/preset-env": "7.9.0",
|
||||
"@rollup/plugin-commonjs": "11.0.1",
|
||||
"@rollup/plugin-node-resolve": "7.0.0",
|
||||
"fs-extra": "8.1.0",
|
||||
|
||||
@@ -46,15 +46,15 @@
|
||||
"yargs": "15.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.8.3",
|
||||
"@babel/preset-env": "7.8.3",
|
||||
"@babel/preset-react": "7.8.3",
|
||||
"@babel/core": "7.9.0",
|
||||
"@babel/preset-env": "7.9.0",
|
||||
"@babel/preset-react": "7.9.1",
|
||||
"@material-ui/core": "4.9.0",
|
||||
"@nebula.js/nucleus": "0.2.0",
|
||||
"@nebula.js/supernova": "0.2.0",
|
||||
"@nebula.js/ui": "0.2.0",
|
||||
"autosuggest-highlight": "3.1.1",
|
||||
"babel-loader": "8.0.6",
|
||||
"babel-loader": "8.1.0",
|
||||
"d3-require": "1.2.4",
|
||||
"enigma.js": "2.6.3",
|
||||
"monaco-editor": "0.19.3",
|
||||
|
||||
12
package.json
12
package.json
@@ -35,12 +35,12 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@after-work.js/aw": "6.0.10",
|
||||
"@babel/cli": "7.8.3",
|
||||
"@babel/core": "7.8.3",
|
||||
"@babel/cli": "7.8.4",
|
||||
"@babel/core": "7.9.0",
|
||||
"@babel/helper-plugin-utils": "7.8.3",
|
||||
"@babel/plugin-transform-react-jsx": "7.8.3",
|
||||
"@babel/preset-env": "7.8.3",
|
||||
"@babel/preset-react": "7.8.3",
|
||||
"@babel/plugin-transform-react-jsx": "7.9.1",
|
||||
"@babel/preset-env": "7.9.0",
|
||||
"@babel/preset-react": "7.9.1",
|
||||
"@commitlint/cli": "8.3.5",
|
||||
"@commitlint/config-conventional": "8.3.4",
|
||||
"@rollup/plugin-commonjs": "11.0.1",
|
||||
@@ -50,7 +50,7 @@
|
||||
"@storybook/addon-docs": "5.3.9",
|
||||
"@storybook/addon-knobs": "5.3.9",
|
||||
"@storybook/react": "5.3.9",
|
||||
"babel-loader": "8.0.6",
|
||||
"babel-loader": "8.1.0",
|
||||
"babel-plugin-istanbul": "6.0.0",
|
||||
"body-parser": "1.19.0",
|
||||
"cross-env": "6.0.3",
|
||||
|
||||
Reference in New Issue
Block a user