@soleil-se/build-app 1.0.0
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 +5 -0
- package/bin/index.js +3 -0
- package/config/index.js +26 -0
- package/config.js +69 -0
- package/index.js +94 -0
- package/package.json +62 -0
- package/requests/activateAddon.js +53 -0
- package/requests/addonExists.js +13 -0
- package/requests/api/addonRequest.js +37 -0
- package/requests/api/handleError.js +23 -0
- package/requests/createAddon.js +27 -0
- package/requests/index.js +28 -0
- package/requests/signAddon.js +44 -0
- package/requests/uploadAddon.js +36 -0
- package/rollup/api/common/preprocessOptions.js +14 -0
- package/rollup/api/getAliasPlugin.js +32 -0
- package/rollup/api/getBabelPlugin.js +34 -0
- package/rollup/api/getCommonjsPlugin.js +5 -0
- package/rollup/api/getFilesizePlugin.js +5 -0
- package/rollup/api/getInsertPlugin.js +14 -0
- package/rollup/api/getNodeResolvePlugin.js +11 -0
- package/rollup/api/getPostcssPlugin.js +24 -0
- package/rollup/api/getReplacePlugin.js +19 -0
- package/rollup/api/getSveltePlugin.js +44 -0
- package/rollup/api/getTerserPlugin.js +9 -0
- package/rollup/client.js +85 -0
- package/rollup/index.js +2 -0
- package/rollup/plugins/sitevision-client.js +45 -0
- package/rollup/plugins/sitevision-server.js +81 -0
- package/rollup/server.js +76 -0
- package/rollup/utils/generateBanner.js +9 -0
- package/rollup/utils/getSitevisionClientPackages.js +7 -0
- package/rollup/utils/moveCss.js +10 -0
- package/rollup/utils/onwarn.js +15 -0
- package/utils/clean.js +5 -0
- package/utils/configFiles.js +11 -0
- package/utils/copy.js +12 -0
- package/utils/eslint.js +37 -0
- package/utils/files.js +28 -0
- package/utils/index.js +5 -0
- package/utils/zip.js +18 -0
package/README.md
ADDED
package/bin/index.js
ADDED
package/config/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { client, server } from '../rollup/index.js';
|
|
2
|
+
import copy from '../utils/copy.js';
|
|
3
|
+
import configFiles from '../utils/configFiles.js';
|
|
4
|
+
|
|
5
|
+
export default function config({ src, dest, cache }) {
|
|
6
|
+
if (src) {
|
|
7
|
+
return [
|
|
8
|
+
copy({ src: `${src}/index.html`, dest }),
|
|
9
|
+
copy({ src: `${src}/config.css`, dest }),
|
|
10
|
+
server({
|
|
11
|
+
input: `${src}/index.js`,
|
|
12
|
+
output: `${dest}/index.js`,
|
|
13
|
+
}),
|
|
14
|
+
client({
|
|
15
|
+
input: `${src}/config.js`,
|
|
16
|
+
output: `${dest}/config.js`,
|
|
17
|
+
globals: { jquery: 'jQuery' },
|
|
18
|
+
showSize: false,
|
|
19
|
+
hydratable: false,
|
|
20
|
+
cache,
|
|
21
|
+
}),
|
|
22
|
+
configFiles({ dest }),
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
package/config.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import config from '@soleil-se/build-config';
|
|
2
|
+
|
|
3
|
+
import fse from 'fs-extra';
|
|
4
|
+
import { createRequire } from 'module';
|
|
5
|
+
import { dirname } from 'path';
|
|
6
|
+
|
|
7
|
+
const require = createRequire(import.meta.url);
|
|
8
|
+
|
|
9
|
+
function readManifestFile() {
|
|
10
|
+
if (fse.existsSync('./manifest.json')) return fse.readJsonSync('./manifest.json');
|
|
11
|
+
if (fse.existsSync('./src/manifest.json')) return fse.readJsonSync('./src/manifest.json');
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function getClientInput() {
|
|
16
|
+
if (fse.existsSync('./src/main.js')) return './src/main.js';
|
|
17
|
+
if (fse.existsSync('./app_src/main.js')) return './app_src/main.js';
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getServerInput() {
|
|
22
|
+
if (fse.existsSync('./src/index.js')) return './src/index.js';
|
|
23
|
+
if (fse.existsSync('./app_src/index.js')) return './app_src/index.js';
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getHooksInput() {
|
|
28
|
+
if (fse.existsSync('./src/hooks.js')) return './src/hooks.js';
|
|
29
|
+
if (fse.existsSync('./app_src/hooks.js')) return './app_src/hooks.js';
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getConfigInput() {
|
|
34
|
+
if (fse.existsSync('./config')) return './config';
|
|
35
|
+
if (fse.existsSync('./app_config')) return './app_config';
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getGlobalConfigInput() {
|
|
40
|
+
if (fse.existsSync('./config_global')) return './config_global';
|
|
41
|
+
if (fse.existsSync('./app_config_global')) return './app_config_global';
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const { env, projectRoot, rollup } = config;
|
|
46
|
+
export const manifest = readManifestFile();
|
|
47
|
+
export const type = manifest.type.toLowerCase();
|
|
48
|
+
export const input = {
|
|
49
|
+
client: getClientInput(),
|
|
50
|
+
server: getServerInput(),
|
|
51
|
+
hooks: getHooksInput(),
|
|
52
|
+
config: getConfigInput(),
|
|
53
|
+
globalConfig: getGlobalConfigInput(),
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const folders = [
|
|
57
|
+
input.client && dirname(input.client),
|
|
58
|
+
input.server && dirname(input.server),
|
|
59
|
+
input.hooks && dirname(input.hooks),
|
|
60
|
+
input.config,
|
|
61
|
+
input.globalConfig,
|
|
62
|
+
]
|
|
63
|
+
.filter((folder) => !!folder)
|
|
64
|
+
.filter((v, i, arr) => arr.indexOf(v) === i);
|
|
65
|
+
|
|
66
|
+
export const watchPaths = folders.map((folder) => `${folder}/**/*`).concat('./manifest.json');
|
|
67
|
+
export const eslintPaths = folders.map((folder) => `${folder}/**/*.{js,svelte}`);
|
|
68
|
+
|
|
69
|
+
export const { version: buildVersion } = require('./package.json');
|
package/index.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import args from '@soleil-se/build-utils/args';
|
|
2
|
+
import runTasks from '@soleil-se/build-utils/runTasks';
|
|
3
|
+
import task from '@soleil-se/build-utils/task';
|
|
4
|
+
import watch from '@soleil-se/build-utils/watch';
|
|
5
|
+
import { getTimestamp, logError, logInfo } from '@soleil-se/build-utils/log';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
input, type, manifest, env, projectRoot, buildVersion, rollup, watchPaths, eslintPaths,
|
|
10
|
+
} from './config.js';
|
|
11
|
+
|
|
12
|
+
import { clean, copy, files, zip, eslint } from './utils/index.js';
|
|
13
|
+
import { client, server } from './rollup/index.js';
|
|
14
|
+
import { activate, upload, sign } from './requests/index.js';
|
|
15
|
+
import config from './config/index.js';
|
|
16
|
+
|
|
17
|
+
const cssOutput = type === 'webapp' ? './dist/src/css/app.css' : './dist/src/resource/client/app.css';
|
|
18
|
+
const zipPath = `./dist/${manifest.id}-${manifest.version}.zip`;
|
|
19
|
+
|
|
20
|
+
async function main() {
|
|
21
|
+
console.log(getTimestamp(), `${manifest.name} (${manifest.id})`);
|
|
22
|
+
console.log(getTimestamp(), chalk.green('Starting'), '@soleil-se/sv-app-build', chalk.green('version'), chalk.green(chalk.underline(buildVersion)));
|
|
23
|
+
logInfo(`Using ${chalk.white('project_config.json')} in ${chalk.white(projectRoot)}`);
|
|
24
|
+
const tasks = [
|
|
25
|
+
task('clean', clean({ dir: './dist' })),
|
|
26
|
+
args.eslint && task('eslint', eslint({ src: eslintPaths })),
|
|
27
|
+
task('copy', [
|
|
28
|
+
copy({ src: './manifest.json', dest: './dist/src' }),
|
|
29
|
+
copy(manifest.bundled || input.server?.startsWith('./src')
|
|
30
|
+
? { src: ['./src/manifest.json', './src/appDataDefaults.json', './src/i18n', './src/config', './src/resource'], dest: './dist/src' }
|
|
31
|
+
: { src: ['./src'], dest: './dist' }),
|
|
32
|
+
]),
|
|
33
|
+
task('server', server({
|
|
34
|
+
input: input.server,
|
|
35
|
+
output: './dist/src/index.js',
|
|
36
|
+
debug: args.debug,
|
|
37
|
+
bundled: manifest.bundled,
|
|
38
|
+
cache: args.cache,
|
|
39
|
+
cssOutput,
|
|
40
|
+
})),
|
|
41
|
+
task('client', client({
|
|
42
|
+
input: input.client,
|
|
43
|
+
output: manifest.bundled ? './dist/src/main.js' : './dist/src/resource/client/index.js',
|
|
44
|
+
bundled: manifest.bundled,
|
|
45
|
+
globals: rollup?.client?.globals,
|
|
46
|
+
debug: args.debug,
|
|
47
|
+
cache: args.cache,
|
|
48
|
+
cssOutput,
|
|
49
|
+
})),
|
|
50
|
+
task('hooks', server({
|
|
51
|
+
input: input.hooks,
|
|
52
|
+
output: './dist/src/hooks.js',
|
|
53
|
+
bundled: manifest.bundled,
|
|
54
|
+
debug: args.debug,
|
|
55
|
+
cache: args.cache,
|
|
56
|
+
cssOutput,
|
|
57
|
+
})),
|
|
58
|
+
task('config', config({ src: input.config, dest: './dist/src/config', cache: args.cache })),
|
|
59
|
+
task('globalConfig', config({ src: input.globalConfig, dest: './dist/src/config/global', cache: args.cache })),
|
|
60
|
+
task('files', files({ type: manifest.type, dest: './dist' })),
|
|
61
|
+
task('zip', zip({ src: './dist/src', dest: zipPath })),
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
if (args.sign ?? env.sign ?? env.production) {
|
|
65
|
+
tasks.push(task('sign', sign({ src: zipPath, manifest })));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (args.sync) {
|
|
69
|
+
tasks.push(task('upload', upload({
|
|
70
|
+
src: zipPath,
|
|
71
|
+
manifest,
|
|
72
|
+
force: args.force || !env.production,
|
|
73
|
+
})));
|
|
74
|
+
|
|
75
|
+
if (args.activate) {
|
|
76
|
+
tasks.push(task('activate', activate()));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (args.watch) {
|
|
81
|
+
watch(watchPaths, () => runTasks(tasks));
|
|
82
|
+
} else {
|
|
83
|
+
await runTasks(tasks);
|
|
84
|
+
}
|
|
85
|
+
if (args.run) await runTasks(tasks);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
main().catch((e) => {
|
|
89
|
+
logError(e.message);
|
|
90
|
+
logError(e.stack);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
process.on('unhandledRejection', () => {});
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@soleil-se/build-app",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"bin": {
|
|
5
|
+
"build-app": "./bin/index.js",
|
|
6
|
+
"sv-app-build": "./bin/index.js"
|
|
7
|
+
},
|
|
8
|
+
"main": "index.js",
|
|
9
|
+
"author": "Soleil AB",
|
|
10
|
+
"license": "UNLICENSED",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=14.0.0"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://docs.soleil.se/build/app",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@babel/core": "7.16.12",
|
|
18
|
+
"@babel/preset-env": "7.16.11",
|
|
19
|
+
"@rollup/plugin-alias": "3.1.9",
|
|
20
|
+
"@rollup/plugin-babel": "5.3.0",
|
|
21
|
+
"@rollup/plugin-commonjs": "21.0.1",
|
|
22
|
+
"@rollup/plugin-json": "4.1.0",
|
|
23
|
+
"@rollup/plugin-node-resolve": "13.1.3",
|
|
24
|
+
"@rollup/plugin-replace": "3.0.1",
|
|
25
|
+
"@soleil-se/build-config": "1.1.1",
|
|
26
|
+
"@soleil-se/build-utils": "1.3.0",
|
|
27
|
+
"archiver": "5.3.0",
|
|
28
|
+
"autoprefixer": "^10.4.2",
|
|
29
|
+
"babel-plugin-transform-async-to-promises": "^0.8.18",
|
|
30
|
+
"chalk": "5.0.0",
|
|
31
|
+
"find-up": "6.2.0",
|
|
32
|
+
"form-data": "4.0.0",
|
|
33
|
+
"fs-extra": "10.0.0",
|
|
34
|
+
"got": "12.0.1",
|
|
35
|
+
"lodash-es": "4.17.21",
|
|
36
|
+
"postcss": "8.4.6",
|
|
37
|
+
"postcss-discard-duplicates": "^5.0.2",
|
|
38
|
+
"postcss-pxtorem": "^6.0.0",
|
|
39
|
+
"rollup": "2.66.1",
|
|
40
|
+
"rollup-plugin-cleanup": "3.2.1",
|
|
41
|
+
"rollup-plugin-filesize": "9.1.2",
|
|
42
|
+
"rollup-plugin-insert": "^1.3.2",
|
|
43
|
+
"rollup-plugin-postcss": "4.0.2",
|
|
44
|
+
"rollup-plugin-string": "3.0.0",
|
|
45
|
+
"rollup-plugin-svelte": "7.1.0",
|
|
46
|
+
"rollup-plugin-terser": "7.0.2",
|
|
47
|
+
"sass": "1.49.7",
|
|
48
|
+
"slash": "4.0.0",
|
|
49
|
+
"svelte-preprocess": "4.10.2"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"svelte": "3.46.3"
|
|
53
|
+
},
|
|
54
|
+
"description": "Script for building WebApps, RESTApps and Widgets with Svelte in Sitevision.",
|
|
55
|
+
"keywords": [
|
|
56
|
+
"Sitevision",
|
|
57
|
+
"WebApp",
|
|
58
|
+
"RESTApp",
|
|
59
|
+
"Widget",
|
|
60
|
+
"Svelte"
|
|
61
|
+
]
|
|
62
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import fse from 'fs-extra';
|
|
3
|
+
|
|
4
|
+
import { logSuccess } from '@soleil-se/build-utils/log';
|
|
5
|
+
|
|
6
|
+
import addonRequest from './api/addonRequest.js';
|
|
7
|
+
import handleError from './api/handleError.js';
|
|
8
|
+
|
|
9
|
+
function readManifestFile() {
|
|
10
|
+
try {
|
|
11
|
+
if (fse.existsSync('./manifest.json')) {
|
|
12
|
+
return fse.readJsonSync('./manifest.json');
|
|
13
|
+
}
|
|
14
|
+
if (fse.existsSync('./src/manifest.json')) {
|
|
15
|
+
return fse.readJsonSync('./src/manifest.json');
|
|
16
|
+
}
|
|
17
|
+
throw new Error('Could not find manifest.json...');
|
|
18
|
+
} catch (e) {
|
|
19
|
+
throw new Error('Unable to parse manifest.json...');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getPropertiesUri(type, id, version) {
|
|
24
|
+
switch (type.toLowerCase()) {
|
|
25
|
+
case 'webapp':
|
|
26
|
+
return `WebApp%20Repository/${id}-${version}/properties`;
|
|
27
|
+
case 'restapp':
|
|
28
|
+
return `RestApp%20Repository/${id}-${version}/properties`;
|
|
29
|
+
default:
|
|
30
|
+
throw new Error('Unknown app type...');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default async function activateAddon() {
|
|
35
|
+
try {
|
|
36
|
+
const { id, version, name, type } = readManifestFile();
|
|
37
|
+
|
|
38
|
+
const { 'jcr:uuid': customModuleExecutableId } = await addonRequest({
|
|
39
|
+
url: getPropertiesUri(type, id, version),
|
|
40
|
+
method: 'GET',
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
await addonRequest({
|
|
44
|
+
url: `Addon%20Repository/${encodeURIComponent(name)}/activatecustommoduleexecutable`,
|
|
45
|
+
method: 'PUT',
|
|
46
|
+
searchParams: { customModuleExecutableId },
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
logSuccess(`${type} ${chalk.white(`${name} (${id}@${version})`)} activated successfully!`);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
handleError(error);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import handleError from './api/handleError.js';
|
|
2
|
+
import addonRequest from './api/addonRequest.js';
|
|
3
|
+
|
|
4
|
+
export default async function addonExists({ name }) {
|
|
5
|
+
try {
|
|
6
|
+
const addons = await addonRequest('Addon%20Repository/nodes', {
|
|
7
|
+
method: 'GET',
|
|
8
|
+
});
|
|
9
|
+
return !!addons.find((addon) => addon.name === name);
|
|
10
|
+
} catch (error) {
|
|
11
|
+
return handleError(error);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import got from 'got';
|
|
2
|
+
import config from '@soleil-se/build-config';
|
|
3
|
+
|
|
4
|
+
const { name, host, auth, acceptUnauthorizedCert } = config.env;
|
|
5
|
+
|
|
6
|
+
const [username, password] = Buffer.from(auth || '', 'base64').toString().split(':');
|
|
7
|
+
|
|
8
|
+
const options = {
|
|
9
|
+
prefixUrl: `${host}/rest-api/1/0/${encodeURI(name)}/`,
|
|
10
|
+
username,
|
|
11
|
+
password,
|
|
12
|
+
method: 'POST',
|
|
13
|
+
responseType: 'json',
|
|
14
|
+
resolveBodyOnly: true,
|
|
15
|
+
hooks: {
|
|
16
|
+
beforeError: [
|
|
17
|
+
(error) => {
|
|
18
|
+
const { response } = error;
|
|
19
|
+
if (response) {
|
|
20
|
+
const { body } = response;
|
|
21
|
+
let message = body && body.message ? body.message : body.toString();
|
|
22
|
+
if (!message && response.statusCode === 401) {
|
|
23
|
+
message = 'Unauthorized, correct username and password?';
|
|
24
|
+
}
|
|
25
|
+
return new Error(`${response.statusCode} - ${message}`);
|
|
26
|
+
}
|
|
27
|
+
return new Error(error.message);
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
if (acceptUnauthorizedCert) {
|
|
34
|
+
options.https = { rejectUnauthorized: false };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default got.extend(options);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { HTTPError } from 'got';
|
|
2
|
+
|
|
3
|
+
function handleError(error) {
|
|
4
|
+
if (error instanceof HTTPError) {
|
|
5
|
+
const { response } = error;
|
|
6
|
+
if (response.statusCode === 401) {
|
|
7
|
+
throw new Error(`${error.name}: ${response.statusCode} - Unauthorized, correct username and password?`);
|
|
8
|
+
}
|
|
9
|
+
if (response.statusCode === 500) {
|
|
10
|
+
if (response.body instanceof Buffer) {
|
|
11
|
+
const { message } = JSON.parse(response.body.toString());
|
|
12
|
+
throw new Error(`${error.name}: ${response.statusCode} - ${message}`);
|
|
13
|
+
}
|
|
14
|
+
throw new Error(`${error.name}: ${response.statusCode} - Would write some kind of proper error message if SiteVision told us what went wrong...`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (error.message === 'URI malformed') {
|
|
18
|
+
throw new Error('URI malformed - Username or password may contain special characters?');
|
|
19
|
+
}
|
|
20
|
+
throw new Error(error);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default handleError;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { logSuccess } from '@soleil-se/build-utils/log';
|
|
3
|
+
import addonRequest from './api/addonRequest.js';
|
|
4
|
+
import handleError from './api/handleError.js';
|
|
5
|
+
|
|
6
|
+
function getCreateUri(type) {
|
|
7
|
+
switch (type.toLowerCase()) {
|
|
8
|
+
case 'webapp':
|
|
9
|
+
return 'Addon%20Repository/custommodule';
|
|
10
|
+
case 'restapp':
|
|
11
|
+
return 'Addon%20Repository/headlesscustommodule';
|
|
12
|
+
default:
|
|
13
|
+
throw new Error('Unknown app type...');
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default async function createAddon({ id, name, type, category }) {
|
|
18
|
+
try {
|
|
19
|
+
await addonRequest({
|
|
20
|
+
url: getCreateUri(type),
|
|
21
|
+
searchParams: { name, category: category || 'Other' },
|
|
22
|
+
});
|
|
23
|
+
logSuccess(`${type} ${chalk.white(`${name} (${id})`)} created successfully!`);
|
|
24
|
+
} catch (error) {
|
|
25
|
+
handleError(error);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import addonExists from './addonExists.js';
|
|
2
|
+
import createAddon from './createAddon.js';
|
|
3
|
+
import uploadAddon from './uploadAddon.js';
|
|
4
|
+
import activateAddon from './activateAddon.js';
|
|
5
|
+
import signAddon from './signAddon.js';
|
|
6
|
+
|
|
7
|
+
export function upload({ src, manifest, force }) {
|
|
8
|
+
return async () => {
|
|
9
|
+
let checkIfExists = true;
|
|
10
|
+
if (checkIfExists) {
|
|
11
|
+
const exists = await addonExists(manifest);
|
|
12
|
+
if (!exists) {
|
|
13
|
+
await createAddon(manifest);
|
|
14
|
+
}
|
|
15
|
+
checkIfExists = false;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return uploadAddon({ ...manifest, src, force });
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function activate() {
|
|
23
|
+
return () => activateAddon();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function sign({ src, manifest }) {
|
|
27
|
+
return () => signAddon({ src, manifest });
|
|
28
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { basename } from 'path';
|
|
2
|
+
import fse from 'fs-extra';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import got from 'got';
|
|
5
|
+
import FormData from 'form-data';
|
|
6
|
+
import { logSuccess } from '@soleil-se/build-utils/log';
|
|
7
|
+
import config from '@soleil-se/build-config';
|
|
8
|
+
|
|
9
|
+
import handleError from './api/handleError.js';
|
|
10
|
+
|
|
11
|
+
const { certificate, auth } = config.webappSign;
|
|
12
|
+
const [username, password] = Buffer.from(auth || '', 'base64').toString().split(':');
|
|
13
|
+
|
|
14
|
+
function signRequest(path) {
|
|
15
|
+
const form = new FormData();
|
|
16
|
+
const filename = basename(path);
|
|
17
|
+
form.append('file', fse.createReadStream(path), {
|
|
18
|
+
filename,
|
|
19
|
+
contentType: 'application/octet-stream',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
return got({
|
|
23
|
+
url: 'https://developer.sitevision.se/rest-api/appsigner/signapp',
|
|
24
|
+
method: 'POST',
|
|
25
|
+
username,
|
|
26
|
+
password,
|
|
27
|
+
searchParams: { certificateName: certificate },
|
|
28
|
+
body: form,
|
|
29
|
+
responseType: 'buffer',
|
|
30
|
+
}).buffer();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default async function signAddon({ src, manifest }) {
|
|
34
|
+
try {
|
|
35
|
+
if (!fse.existsSync(src)) throw new Error(`Could not find ${src}`);
|
|
36
|
+
|
|
37
|
+
const response = await signRequest(src);
|
|
38
|
+
await fse.writeFile(src, response);
|
|
39
|
+
|
|
40
|
+
logSuccess(`${manifest.type} ${chalk.white(`${manifest.name} (${manifest.id})`)} signed successfully!`);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
handleError(error);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import fse from 'fs-extra';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import FormData from 'form-data';
|
|
4
|
+
import { logSuccess } from '@soleil-se/build-utils/log';
|
|
5
|
+
|
|
6
|
+
import handleError from './api/handleError.js';
|
|
7
|
+
import addonRequest from './api/addonRequest.js';
|
|
8
|
+
|
|
9
|
+
function getUploadUri(type, name) {
|
|
10
|
+
switch (type.toLowerCase()) {
|
|
11
|
+
case 'webapp':
|
|
12
|
+
return `Addon%20Repository/${encodeURIComponent(name)}/webAppImport`;
|
|
13
|
+
case 'restapp':
|
|
14
|
+
return `Addon%20Repository/${encodeURIComponent(name)}/restAppImport`;
|
|
15
|
+
default:
|
|
16
|
+
throw new Error('Unknown app type...');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default async function uploadAddon({ id, type, name, src, force }) {
|
|
21
|
+
try {
|
|
22
|
+
if (!fse.existsSync(src)) {
|
|
23
|
+
throw new Error(`Could not find ${src}`);
|
|
24
|
+
}
|
|
25
|
+
const form = new FormData();
|
|
26
|
+
form.append('file', fse.createReadStream(src));
|
|
27
|
+
|
|
28
|
+
await addonRequest(getUploadUri(type, name), {
|
|
29
|
+
searchParams: { force },
|
|
30
|
+
body: form,
|
|
31
|
+
});
|
|
32
|
+
logSuccess(`${type} ${chalk.white(`${name} (${id})`)} uploaded successfully!`);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
handleError(error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import config from '@soleil-se/build-config';
|
|
2
|
+
|
|
3
|
+
const sass = {
|
|
4
|
+
includePaths: [`${config.projectRoot}/client_src/sass`],
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
sass,
|
|
9
|
+
scss: sass,
|
|
10
|
+
less: {
|
|
11
|
+
paths: [`${config.projectRoot}/client_src/less`],
|
|
12
|
+
},
|
|
13
|
+
postcss: false,
|
|
14
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import alias from '@rollup/plugin-alias';
|
|
3
|
+
import config from '@soleil-se/build-config';
|
|
4
|
+
|
|
5
|
+
const resolveAlias = (root, aliases = {}) => Object.entries(aliases)
|
|
6
|
+
.reduce((acc, [key, value]) => ({
|
|
7
|
+
...acc,
|
|
8
|
+
[key]: path.resolve(root, value),
|
|
9
|
+
}), {});
|
|
10
|
+
|
|
11
|
+
const clientAlias = resolveAlias(config.projectRoot, {
|
|
12
|
+
'#api/webapps': './server_src/webapps/api',
|
|
13
|
+
'#api': './server_src/api',
|
|
14
|
+
'#components': './server_src/webapps/components',
|
|
15
|
+
...config?.rollup?.client?.alias,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export function getAliasClientPlugin() {
|
|
19
|
+
return alias({ entries: clientAlias });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const serverAlias = resolveAlias(config.projectRoot, {
|
|
23
|
+
'#api/webapps': './server_src/webapps/api',
|
|
24
|
+
'#api/restapps': './server_src/restapps/api',
|
|
25
|
+
'#api': './server_src/api',
|
|
26
|
+
'#components': './server_src/webapps/components',
|
|
27
|
+
...config?.rollup?.server?.alias,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export function getAliasServerPlugin() {
|
|
31
|
+
return alias({ entries: serverAlias });
|
|
32
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { babel } from '@rollup/plugin-babel';
|
|
2
|
+
|
|
3
|
+
const commonOptions = {
|
|
4
|
+
babelrc: false,
|
|
5
|
+
extensions: ['.js', '.mjs', '.html', '.svelte'],
|
|
6
|
+
babelHelpers: 'bundled',
|
|
7
|
+
plugins: ['babel-plugin-transform-async-to-promises'],
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export function getBabelClientPlugin() {
|
|
11
|
+
return babel({
|
|
12
|
+
...commonOptions,
|
|
13
|
+
presets: [
|
|
14
|
+
['@babel/preset-env', {
|
|
15
|
+
shippedProposals: true,
|
|
16
|
+
}],
|
|
17
|
+
],
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function getBabelServerPlugin() {
|
|
22
|
+
return babel({
|
|
23
|
+
...commonOptions,
|
|
24
|
+
presets: [
|
|
25
|
+
['@babel/preset-env', {
|
|
26
|
+
exclude: ['@babel/plugin-transform-arrow-functions'],
|
|
27
|
+
forceAllTransforms: true,
|
|
28
|
+
ignoreBrowserslistConfig: true,
|
|
29
|
+
shippedProposals: true,
|
|
30
|
+
loose: true,
|
|
31
|
+
}],
|
|
32
|
+
],
|
|
33
|
+
});
|
|
34
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { transform } from 'rollup-plugin-insert';
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import slash from 'slash';
|
|
4
|
+
import { relative, dirname } from 'path';
|
|
5
|
+
|
|
6
|
+
export default function getInsertPlugin({ input, imports }) {
|
|
7
|
+
return transform((ms, code) => {
|
|
8
|
+
const existingImports = imports
|
|
9
|
+
.filter((importee) => importee && existsSync(importee))
|
|
10
|
+
.map((importee) => slash(relative(dirname(input), importee)))
|
|
11
|
+
.map((importee) => `import './${importee}';`);
|
|
12
|
+
return `${existingImports.join('\n')}\n${code}`;
|
|
13
|
+
}, { include: input });
|
|
14
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import nodeResolve from '@rollup/plugin-node-resolve';
|
|
2
|
+
|
|
3
|
+
export default function getNodeResolvePlugin() {
|
|
4
|
+
return nodeResolve({
|
|
5
|
+
mainFields: ['module', 'browser', 'main'],
|
|
6
|
+
extensions: ['.js', '.mjs', '.json', '.svelte'],
|
|
7
|
+
dedupe(importee) {
|
|
8
|
+
return importee === 'svelte' || importee.startsWith('svelte/');
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import postcss from 'rollup-plugin-postcss';
|
|
2
|
+
|
|
3
|
+
import autoprefixer from 'autoprefixer';
|
|
4
|
+
import pxtorem from 'postcss-pxtorem';
|
|
5
|
+
import discardDuplicates from 'postcss-discard-duplicates';
|
|
6
|
+
|
|
7
|
+
import config from '@soleil-se/build-config';
|
|
8
|
+
import preprocessOptions from './common/preprocessOptions.js';
|
|
9
|
+
|
|
10
|
+
const plugins = [autoprefixer(config?.css?.plugins?.autoprefixer), discardDuplicates()];
|
|
11
|
+
|
|
12
|
+
if (config?.css?.plugins?.pxtorem) {
|
|
13
|
+
plugins.push(pxtorem(config?.css.plugins.pxtorem));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default function getPostcssPlugin({ cssOutput, debug }) {
|
|
17
|
+
return postcss({
|
|
18
|
+
plugins,
|
|
19
|
+
extract: !!cssOutput && !debug,
|
|
20
|
+
minimize: !debug ? { level: 2 } : false,
|
|
21
|
+
sourceMap: debug ? 'inline' : false,
|
|
22
|
+
use: preprocessOptions,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import replace from '@rollup/plugin-replace';
|
|
2
|
+
import config from '@soleil-se/build-config';
|
|
3
|
+
|
|
4
|
+
export function getReplaceClientPlugin() {
|
|
5
|
+
return replace({
|
|
6
|
+
'process.server': false,
|
|
7
|
+
'process.browser': true,
|
|
8
|
+
'process.env.NODE_ENV': JSON.stringify(config.env.production ? 'production' : 'development'),
|
|
9
|
+
preventAssignment: true,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function getReplaceServerPlugin() {
|
|
14
|
+
return replace({
|
|
15
|
+
'process.server': true,
|
|
16
|
+
'process.browser': false,
|
|
17
|
+
preventAssignment: true,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { dirname } from 'path';
|
|
2
|
+
import { findUpSync } from 'find-up';
|
|
3
|
+
import fse from 'fs-extra';
|
|
4
|
+
import { kebabCase } from 'lodash-es';
|
|
5
|
+
|
|
6
|
+
import preprocessOptions from './common/preprocessOptions.js';
|
|
7
|
+
|
|
8
|
+
let svelte;
|
|
9
|
+
let sveltePreprocess;
|
|
10
|
+
|
|
11
|
+
const validClassRegex = /[^a-z0-9\-_]|^[^a-z]+/gi;
|
|
12
|
+
|
|
13
|
+
const hasSvelte = (input) => {
|
|
14
|
+
const packageFile = findUpSync('package.json', { cwd: dirname(input) });
|
|
15
|
+
const { dependencies = {} } = fse.readJSONSync(packageFile);
|
|
16
|
+
return Object.keys(dependencies).includes('svelte');
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/* Custom CSS hash requires version 3.34.0 or later */
|
|
20
|
+
const cssHash = ({ hash, css, name }) => {
|
|
21
|
+
const validClass = name.replace(validClassRegex, '');
|
|
22
|
+
return `${kebabCase(validClass)}-${hash(css)}`;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default async function getSveltePlugin({
|
|
26
|
+
input, debug = false, emitCss = true, ssr, hydratable = true,
|
|
27
|
+
}) {
|
|
28
|
+
if (hasSvelte(input)) {
|
|
29
|
+
svelte = svelte || await import('rollup-plugin-svelte').then((pkg) => pkg.default);
|
|
30
|
+
sveltePreprocess = sveltePreprocess || await import('svelte-preprocess').then((pkg) => pkg.default);
|
|
31
|
+
|
|
32
|
+
return svelte({
|
|
33
|
+
preprocess: sveltePreprocess(preprocessOptions),
|
|
34
|
+
emitCss,
|
|
35
|
+
compilerOptions: {
|
|
36
|
+
generate: ssr ? 'ssr' : 'dom',
|
|
37
|
+
hydratable,
|
|
38
|
+
dev: debug,
|
|
39
|
+
cssHash,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
package/rollup/client.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { rollup } from 'rollup';
|
|
2
|
+
import json from '@rollup/plugin-json';
|
|
3
|
+
|
|
4
|
+
import fse from 'fs-extra';
|
|
5
|
+
|
|
6
|
+
import generateBanner from './utils/generateBanner.js';
|
|
7
|
+
import moveCss from './utils/moveCss.js';
|
|
8
|
+
import onwarn from './utils/onwarn.js';
|
|
9
|
+
import getSitevisionClientPackages from './utils/getSitevisionClientPackages.js';
|
|
10
|
+
|
|
11
|
+
import { getReplaceClientPlugin } from './api/getReplacePlugin.js';
|
|
12
|
+
import { getAliasClientPlugin } from './api/getAliasPlugin.js';
|
|
13
|
+
import { getBabelClientPlugin } from './api/getBabelPlugin.js';
|
|
14
|
+
import getCommonjsPlugin from './api/getCommonjsPlugin.js';
|
|
15
|
+
import getNodeResolvePlugin from './api/getNodeResolvePlugin.js';
|
|
16
|
+
import getSveltePlugin from './api/getSveltePlugin.js';
|
|
17
|
+
import getPostcssPlugin from './api/getPostcssPlugin.js';
|
|
18
|
+
import getFilesizePlugin from './api/getFilesizePlugin.js';
|
|
19
|
+
import getTerserPlugin from './api/getTerserPlugin.js';
|
|
20
|
+
import sitevision from './plugins/sitevision-client.js';
|
|
21
|
+
import getInsertPlugin from './api/getInsertPlugin.js';
|
|
22
|
+
|
|
23
|
+
export default function rollupClient({
|
|
24
|
+
debug,
|
|
25
|
+
globals = {},
|
|
26
|
+
input,
|
|
27
|
+
output,
|
|
28
|
+
cssOutput,
|
|
29
|
+
showSize = true,
|
|
30
|
+
bundled,
|
|
31
|
+
hydratable,
|
|
32
|
+
cache = true,
|
|
33
|
+
} = {}) {
|
|
34
|
+
if (!input) return false;
|
|
35
|
+
|
|
36
|
+
let bundleCache;
|
|
37
|
+
let plugins;
|
|
38
|
+
|
|
39
|
+
const external = Object.keys(globals);
|
|
40
|
+
if (bundled) external.push(...getSitevisionClientPackages());
|
|
41
|
+
|
|
42
|
+
return async () => {
|
|
43
|
+
if (!fse.existsSync(input)) return Promise.resolve();
|
|
44
|
+
|
|
45
|
+
plugins = plugins || [
|
|
46
|
+
bundled ? sitevision() : false,
|
|
47
|
+
getReplaceClientPlugin(),
|
|
48
|
+
getAliasClientPlugin(),
|
|
49
|
+
getNodeResolvePlugin(),
|
|
50
|
+
getCommonjsPlugin(),
|
|
51
|
+
getInsertPlugin({ input, imports: [cssOutput] }),
|
|
52
|
+
await getSveltePlugin({ input, debug, emitCss: !!cssOutput, hydratable }),
|
|
53
|
+
getPostcssPlugin({ cssOutput, debug }),
|
|
54
|
+
getBabelClientPlugin(),
|
|
55
|
+
json(),
|
|
56
|
+
getFilesizePlugin({ showSize }),
|
|
57
|
+
getTerserPlugin({ debug }),
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const bundle = await rollup({
|
|
62
|
+
external,
|
|
63
|
+
input,
|
|
64
|
+
plugins,
|
|
65
|
+
onwarn,
|
|
66
|
+
cache: bundleCache,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
bundleCache = cache && bundle.cache;
|
|
70
|
+
await bundle.write({
|
|
71
|
+
file: output,
|
|
72
|
+
banner: debug && generateBanner(),
|
|
73
|
+
globals,
|
|
74
|
+
format: bundled ? 'amd' : 'iife',
|
|
75
|
+
sourcemap: debug ? 'inline' : false,
|
|
76
|
+
interop: 'auto',
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
return moveCss(cssOutput, output);
|
|
80
|
+
} catch (e) {
|
|
81
|
+
bundleCache = undefined;
|
|
82
|
+
throw e;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
package/rollup/index.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export default function sitevision() {
|
|
2
|
+
const ignored = [];
|
|
3
|
+
|
|
4
|
+
function isSitevisionScope(id) {
|
|
5
|
+
return id.startsWith('@sitevision/api');
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function shouldResolve(importee) {
|
|
9
|
+
if (isSitevisionScope(importee)) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function shouldLoad(id) {
|
|
16
|
+
return !ignored.includes(id);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
name: 'sitevision-imports',
|
|
21
|
+
resolveId(importee) {
|
|
22
|
+
if (shouldResolve(importee)) {
|
|
23
|
+
// Should be handled as usual.
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
// Most likely a SiteVision dependency.
|
|
27
|
+
// Do not ask other plugins or check the file system to find it.
|
|
28
|
+
if (!ignored.includes(importee)) {
|
|
29
|
+
ignored.push(importee);
|
|
30
|
+
}
|
|
31
|
+
return importee;
|
|
32
|
+
},
|
|
33
|
+
load(id) {
|
|
34
|
+
if (shouldLoad(id)) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
// The virtual source code for the provided Sitevision dependency.
|
|
38
|
+
const pkg = id.split('/').pop();
|
|
39
|
+
return {
|
|
40
|
+
code: `export { default } from '${pkg}';`,
|
|
41
|
+
syntheticNamedExports: true,
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { camelCase } from 'lodash-es';
|
|
2
|
+
import { isAbsolute } from 'path';
|
|
3
|
+
|
|
4
|
+
const sitevisionPackages = [
|
|
5
|
+
'underscore',
|
|
6
|
+
'router',
|
|
7
|
+
'i18n',
|
|
8
|
+
'appData',
|
|
9
|
+
'globalAppData',
|
|
10
|
+
'appResource',
|
|
11
|
+
'appInfo',
|
|
12
|
+
'storage',
|
|
13
|
+
'oauth2',
|
|
14
|
+
'privileged',
|
|
15
|
+
'app',
|
|
16
|
+
'events',
|
|
17
|
+
'hooks',
|
|
18
|
+
'cache',
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export default function sitevision() {
|
|
22
|
+
const ignored = [];
|
|
23
|
+
|
|
24
|
+
function startsWithUpperCase(id) {
|
|
25
|
+
return /^[A-Z]/.test(id);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function isSitevisionPath(id) {
|
|
29
|
+
if (isAbsolute(id) && !id.startsWith('/')) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
return startsWithUpperCase(id);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function isExcluded(id) {
|
|
36
|
+
return sitevisionPackages.includes(id);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function isSitevisionScope(id) {
|
|
40
|
+
return id.startsWith('@sitevision/api');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function shouldResolve(importee) {
|
|
44
|
+
if (isSitevisionScope(importee) || isExcluded(importee) || isSitevisionPath(importee)) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function shouldLoad(id) {
|
|
51
|
+
return !ignored.includes(id);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
name: 'sitevision-imports',
|
|
56
|
+
resolveId(importee) {
|
|
57
|
+
if (shouldResolve(importee)) {
|
|
58
|
+
// Should be handled as usual.
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
// Most likely a SiteVision dependency.
|
|
62
|
+
// Do not ask other plugins or check the file system to find it.
|
|
63
|
+
if (!ignored.includes(importee)) {
|
|
64
|
+
ignored.push(importee);
|
|
65
|
+
}
|
|
66
|
+
return importee;
|
|
67
|
+
},
|
|
68
|
+
load(id) {
|
|
69
|
+
if (shouldLoad(id)) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
// The virtual source code for the provided SiteVision dependency.
|
|
73
|
+
const pkg = id.split('/').pop();
|
|
74
|
+
const name = camelCase(pkg);
|
|
75
|
+
return {
|
|
76
|
+
code: `var ${name} = require('${pkg}'); export default ${name}`,
|
|
77
|
+
syntheticNamedExports: true,
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
package/rollup/server.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { rollup } from 'rollup';
|
|
2
|
+
import json from '@rollup/plugin-json';
|
|
3
|
+
import { string } from 'rollup-plugin-string';
|
|
4
|
+
import cleanup from 'rollup-plugin-cleanup';
|
|
5
|
+
|
|
6
|
+
import fse from 'fs-extra';
|
|
7
|
+
|
|
8
|
+
import generateBanner from './utils/generateBanner.js';
|
|
9
|
+
import moveCss from './utils/moveCss.js';
|
|
10
|
+
import onwarn from './utils/onwarn.js';
|
|
11
|
+
import sitevision from './plugins/sitevision-server.js';
|
|
12
|
+
|
|
13
|
+
import { getReplaceServerPlugin } from './api/getReplacePlugin.js';
|
|
14
|
+
import { getAliasServerPlugin } from './api/getAliasPlugin.js';
|
|
15
|
+
import { getBabelServerPlugin } from './api/getBabelPlugin.js';
|
|
16
|
+
import getCommonjsPlugin from './api/getCommonjsPlugin.js';
|
|
17
|
+
import getInsertPlugin from './api/getInsertPlugin.js';
|
|
18
|
+
import getNodeResolvePlugin from './api/getNodeResolvePlugin.js';
|
|
19
|
+
import getSveltePlugin from './api/getSveltePlugin.js';
|
|
20
|
+
import getPostcssPlugin from './api/getPostcssPlugin.js';
|
|
21
|
+
import getTerserPlugin from './api/getTerserPlugin.js';
|
|
22
|
+
|
|
23
|
+
export default function rollupServer({
|
|
24
|
+
debug,
|
|
25
|
+
input,
|
|
26
|
+
output,
|
|
27
|
+
cssOutput,
|
|
28
|
+
bundled,
|
|
29
|
+
cache = true,
|
|
30
|
+
} = {}) {
|
|
31
|
+
if (!input) return false;
|
|
32
|
+
|
|
33
|
+
let bundleCache;
|
|
34
|
+
let plugins;
|
|
35
|
+
|
|
36
|
+
return async () => {
|
|
37
|
+
if (!fse.existsSync(input)) return Promise.resolve();
|
|
38
|
+
|
|
39
|
+
plugins = plugins || [
|
|
40
|
+
getReplaceServerPlugin(),
|
|
41
|
+
getAliasServerPlugin(),
|
|
42
|
+
sitevision(),
|
|
43
|
+
json(),
|
|
44
|
+
string({ include: '**/*.html' }),
|
|
45
|
+
getNodeResolvePlugin(),
|
|
46
|
+
getCommonjsPlugin(),
|
|
47
|
+
getInsertPlugin({ input, imports: [cssOutput] }),
|
|
48
|
+
await getSveltePlugin({ input, emitCss: !!cssOutput, ssr: true }),
|
|
49
|
+
getPostcssPlugin({ cssOutput, debug }),
|
|
50
|
+
getBabelServerPlugin(),
|
|
51
|
+
bundled ? getTerserPlugin({ debug }) : cleanup({ maxEmptyLines: 1 }),
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const bundle = await rollup({
|
|
56
|
+
input,
|
|
57
|
+
plugins,
|
|
58
|
+
onwarn,
|
|
59
|
+
cache: bundleCache,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
bundleCache = cache && bundle.cache;
|
|
63
|
+
await bundle.write({
|
|
64
|
+
file: output,
|
|
65
|
+
banner: debug && generateBanner(),
|
|
66
|
+
intro: 'var Promise = Promise || { resolve: () => {} };',
|
|
67
|
+
format: 'iife',
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
return moveCss(cssOutput, output);
|
|
71
|
+
} catch (e) {
|
|
72
|
+
bundleCache = undefined;
|
|
73
|
+
throw e;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { template } from 'lodash-es';
|
|
2
|
+
import fse from 'fs-extra';
|
|
3
|
+
import config from '@soleil-se/build-config';
|
|
4
|
+
|
|
5
|
+
const { name, version } = fse.readJSONSync(new URL('../../package.json', import.meta.url));
|
|
6
|
+
|
|
7
|
+
export default function generateBanner() {
|
|
8
|
+
return template(config.banner)({ date: new Date(), build: `${name} - ${version}` });
|
|
9
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { existsSync, readdirSync } from 'fs';
|
|
2
|
+
|
|
3
|
+
export default function getSitevisionClientPackages() {
|
|
4
|
+
const path = `${process.cwd()}/node_modules/@sitevision/api`;
|
|
5
|
+
if (!existsSync(path)) throw new Error('Bundled apps requires @sitevision/api to be installed.');
|
|
6
|
+
return [...readdirSync(`${path}/client`), ...readdirSync(`${path}/common`)];
|
|
7
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { logWarning } from '@soleil-se/build-utils/log';
|
|
2
|
+
|
|
3
|
+
export default function onwarn(warning) {
|
|
4
|
+
if (warning.code === 'CIRCULAR_DEPENDENCY') return;
|
|
5
|
+
|
|
6
|
+
if (warning.code === 'PLUGIN_WARNING') {
|
|
7
|
+
if (warning.pluginCode && warning.pluginCode === 'a11y-no-onchange') return;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (warning.code === 'UNRESOLVED_IMPORT') {
|
|
11
|
+
const message = warning.message.replace(' – treating it as an external dependency', '. Have you installed it?');
|
|
12
|
+
throw new Error(message);
|
|
13
|
+
}
|
|
14
|
+
logWarning(warning.message);
|
|
15
|
+
}
|
package/utils/clean.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import fse from 'fs-extra';
|
|
2
|
+
|
|
3
|
+
async function createIndexFile(path) {
|
|
4
|
+
if (!fse.existsSync(path)) {
|
|
5
|
+
await fse.writeFile(path, '<div id="app_root"></div>');
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default function files({ dest }) {
|
|
10
|
+
return () => createIndexFile(`${dest}/index.html`);
|
|
11
|
+
}
|
package/utils/copy.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import fse from 'fs-extra';
|
|
2
|
+
import { basename, join } from 'path';
|
|
3
|
+
|
|
4
|
+
export default function copy({ src, dest }) {
|
|
5
|
+
const files = Array.isArray(src) ? src : [src];
|
|
6
|
+
|
|
7
|
+
return () => Promise.all(
|
|
8
|
+
files.map((file) => (
|
|
9
|
+
fse.existsSync(file) ? fse.copy(file, join(dest, basename(file))) : Promise.resolve()
|
|
10
|
+
)),
|
|
11
|
+
);
|
|
12
|
+
}
|
package/utils/eslint.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { getTimestamp, logWarning } from '@soleil-se/build-utils/log';
|
|
3
|
+
|
|
4
|
+
const logNotInstalledWarning = () => {
|
|
5
|
+
logWarning(`ESLint is not installed, run ${chalk.white('yarn add eslint --dev')} or start with ${chalk.white('--no-eslint')} flag.`);
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
let ESLint;
|
|
9
|
+
|
|
10
|
+
export default function createESLint({ src }) {
|
|
11
|
+
return async () => {
|
|
12
|
+
try {
|
|
13
|
+
// eslint-disable-next-line import/no-extraneous-dependencies,node/no-extraneous-import
|
|
14
|
+
ESLint = ESLint || await import('eslint').then((pkg) => pkg.ESLint);
|
|
15
|
+
} catch (e) {
|
|
16
|
+
logNotInstalledWarning();
|
|
17
|
+
}
|
|
18
|
+
if (ESLint) {
|
|
19
|
+
const eslint = new ESLint();
|
|
20
|
+
const formatter = await eslint.loadFormatter();
|
|
21
|
+
const results = await eslint.lintFiles(src);
|
|
22
|
+
const errors = ESLint.getErrorResults(results);
|
|
23
|
+
const output = formatter.format(results);
|
|
24
|
+
|
|
25
|
+
if (errors.length) {
|
|
26
|
+
const error = new Error(`\n${output}`);
|
|
27
|
+
error.showStack = false;
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
if (output) {
|
|
31
|
+
console.log(`${getTimestamp()} Warning:\n${output}`);
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
logNotInstalledWarning();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
package/utils/files.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import fse from 'fs-extra';
|
|
2
|
+
|
|
3
|
+
const indexContent = `(function() {
|
|
4
|
+
'use strict';
|
|
5
|
+
var router = require('router');
|
|
6
|
+
router.get('/', function() {});
|
|
7
|
+
}());`;
|
|
8
|
+
|
|
9
|
+
async function createMain(dest) {
|
|
10
|
+
const src = `${dest}/src/main.js`;
|
|
11
|
+
if (!fse.existsSync(src)) {
|
|
12
|
+
await fse.writeFile(src, '');
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function createIndex(dest) {
|
|
17
|
+
const src = `${dest}/src/index.js`;
|
|
18
|
+
if (!fse.existsSync(src)) {
|
|
19
|
+
await fse.writeFile(src, indexContent);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default function files({ type, dest }) {
|
|
24
|
+
if (type.toLowerCase() === 'restapp') return undefined;
|
|
25
|
+
return () => Promise.all(
|
|
26
|
+
[createMain(dest), createIndex(dest)],
|
|
27
|
+
);
|
|
28
|
+
}
|
package/utils/index.js
ADDED
package/utils/zip.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import archiver from 'archiver';
|
|
2
|
+
import fse from 'fs-extra';
|
|
3
|
+
|
|
4
|
+
export default function zip({ src, dest }) {
|
|
5
|
+
return () => {
|
|
6
|
+
const archive = archiver('zip', { zlib: { level: 9 } });
|
|
7
|
+
const stream = fse.createWriteStream(dest);
|
|
8
|
+
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
archive
|
|
11
|
+
.directory(src, false)
|
|
12
|
+
.on('error', (err) => reject(err))
|
|
13
|
+
.pipe(stream);
|
|
14
|
+
stream.on('close', () => resolve());
|
|
15
|
+
archive.finalize();
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
}
|