From 082688b1fab518e105ffb96f4c1440d628b8d0f9 Mon Sep 17 00:00:00 2001 From: John Dillick Date: Thu, 4 May 2023 13:24:16 -1000 Subject: [PATCH] Core as module --- .core/.cli/commands/docs/actions.js | 66 -- .core/.cli/commands/docs/generator.js | 26 - .core/.cli/commands/docs/index.js | 213 ---- .core/.cli/commands/i18n/actions.js | 27 - .core/.cli/commands/i18n/generator.js | 26 - .core/.cli/commands/i18n/index.js | 170 --- .../reactium/component/componentGen.cjs | 86 -- .../reactium/component/formatDestination.cjs | 22 - .../reactium/component/formatRoute.cjs | 27 - .../.cli/commands/reactium/component/index.js | 203 ---- .../commands/reactium/component/package.json | 4 - .../reactium/component/reactium-arcli.js | 158 --- .../reactium/component/selectDestination.cjs | 14 - .../reactium/component/selectStyle.cjs | 20 - .../reactium/component/styleTypes.cjs | 34 - .../reactium/component/template/domain.hbs | 9 - .../component/template/index-functional.hbs | 29 - .../component/template/reactium-hooks.hbs | 13 - .../component/template/reactium-style.hbs | 3 - .../reactium/component/template/route.hbs | 7 - .core/.cli/commands/reactium/domain/index.js | 138 --- .../commands/reactium/domain/package.json | 4 - .../reactium/domain/reactium-arcli.js | 77 -- .core/.cli/commands/reactium/hook/index.js | 139 --- .../.cli/commands/reactium/hook/package.json | 4 - .../commands/reactium/hook/reactium-arcli.js | 77 -- .core/.cli/commands/reactium/icons/actions.js | 95 -- .../.cli/commands/reactium/icons/generator.js | 27 - .core/.cli/commands/reactium/icons/index.js | 235 ---- .../.cli/commands/reactium/icons/package.json | 9 - .../reactium/icons/template/index.hbs | 20 - .../commands/reactium/icons/template/svg.hbs | 14 - .../.cli/commands/reactium/library/actions.js | 98 -- .../commands/reactium/library/generator.js | 26 - .core/.cli/commands/reactium/library/index.js | 506 -------- .../commands/reactium/plugin/eject/actions.js | 87 -- .../reactium/plugin/eject/generator.js | 29 - .../commands/reactium/plugin/eject/index.js | 424 ------- .core/.cli/commands/reactium/plugin/index.js | 46 - .../commands/reactium/plugin/local/actions.js | 41 - .../reactium/plugin/local/generator.js | 29 - .../commands/reactium/plugin/local/index.js | 224 ---- .../reactium/plugin/module/actions.js | 124 -- .../reactium/plugin/module/generator.js | 29 - .../commands/reactium/plugin/module/index.js | 295 ----- .../reactium/plugin/module/template/index.hbs | 9 - .../plugin/module/template/reactium-boot.hbs | 16 - .../plugin/module/template/reactium-hooks.hbs | 25 - .../module/template/reactium-hooks.json | 3 - .../reactium/plugin/module/template/style.hbs | 17 - .../plugin/module/template/umd-config.hbs | 3 - .../reactium/plugin/module/template/umd.hbs | 8 - .../commands/reactium/plugin/zones/actions.js | 179 --- .../reactium/plugin/zones/generator.js | 89 -- .../commands/reactium/plugin/zones/index.js | 440 ------- .../reactium/plugin/zones/manifest.js | 16 - .core/.cli/commands/reactium/route/index.js | 144 --- .../.cli/commands/reactium/route/package.json | 4 - .../commands/reactium/route/reactium-arcli.js | 93 -- .../.cli/commands/reactium/server/actions.js | 50 - .../commands/reactium/server/generator.js | 26 - .core/.cli/commands/reactium/server/index.js | 265 ----- .core/.cli/commands/reactium/style/index.js | 142 --- .../.cli/commands/reactium/style/package.json | 4 - .../commands/reactium/style/reactium-arcli.js | 90 -- .core/.cli/commands/reactium/test/actions.js | 47 - .../.cli/commands/reactium/test/generator.js | 26 - .core/.cli/commands/reactium/test/index.js | 293 ----- .../commands/reactium/test/template/test.hbs | 9 - .core/.cli/commands/reactium/version/index.js | 36 - .core/.cli/config.json | 6 - .core/app.js | 1 - .core/app/index.js | 185 --- .core/app/reactium-hooks.js | 172 --- .core/app/shell.js | 39 - .core/assets/images/a11y/a11y.svg | 77 -- .core/babel.config.js | 212 ---- .core/boot-hooks.mjs | 46 - .core/components/DevTools/index.js | 7 - .core/components/Loading/domain.js | 9 - .core/components/Loading/index.js | 146 --- .core/components/Loading/reactium-hooks.js | 12 - .core/components/NotFound/index.js | 24 - .core/components/Plugable/Plugins.js | 5 - .core/components/Plugable/index.js | 6 - .core/components/Plugable/reducers.js | 30 - .core/components/Plugable/state.js | 1 - .core/components/Router/RoutedContent.js | 38 - .core/components/Router/index.js | 14 - .core/components/Router/reactium-hooks.js | 68 -- .core/components/WindowProvider/index.js | 7 - .core/dependencies/getComponents.js | 8 - .core/dependencies/index.js | 161 --- .core/easy-connect.js | 6 - .core/enzyme.js | 7 - .core/get-task.js | 8 - .core/globby-patch.js | 15 - .core/gulp.bootup.js | 74 -- .core/gulp.config.js | 173 --- .core/gulp.tasks.js | 963 ---------------- .core/gulp.watch.js | 28 - .core/gulpfile.js | 1 - .core/index.mjs | 371 ------ .core/manifest/manifest-tools.js | 245 ---- .core/manifest/processors/domains.js | 27 - .core/manifest/processors/externals.js | 30 - .core/manifest/processors/manifest.js | 63 - .core/manifest/processors/umd.js | 76 -- .core/manifest/templates/domains.hbs | 6 - .core/manifest/templates/externals.hbs | 14 - .core/manifest/templates/manifest.hbs | 62 - .core/manifest/templates/umd.hbs | 1 - .core/reactium-config.js | 379 ------ .core/reactium.log.cjs | 76 -- .core/sdk/i18n/index.js | 61 - .core/sdk/index.js | 68 -- .core/sdk/named-exports/app-context.js | 76 -- .core/sdk/named-exports/capability.js | 61 - .core/sdk/named-exports/hookable-component.js | 6 - .core/sdk/named-exports/i18n.js | 47 - .core/sdk/named-exports/index.js | 8 - .core/sdk/named-exports/roles.js | 30 - .core/sdk/named-exports/routing.js | 57 - .core/sdk/named-exports/setting.js | 104 -- .core/sdk/named-exports/useDispatcher.js | 46 - .core/sdk/named-exports/window.js | 222 ---- .core/sdk/reactium-hooks.js | 23 - .core/sdk/routing/index.js | 477 -------- .core/server-globals.mjs | 44 - .core/server/placeholder/reactium-boot.js | 110 -- .core/server/renderer/feo.js | 1 - .core/server/renderer/index.mjs | 638 ---------- .core/server/router.mjs | 94 -- .core/server/template/feo.js | 25 - .core/umd.webpack.config.js | 95 -- .core/webpack.config.js | 152 --- .core/webpack.sdk.js | 385 ------- Dockerfile | 7 +- babel.config.js | 2 +- gulpfile.js | 6 +- package-lock.json | 1024 +++++++++-------- package.json | 122 +- src/app/main.js | 21 +- 143 files changed, 543 insertions(+), 13356 deletions(-) delete mode 100644 .core/.cli/commands/docs/actions.js delete mode 100644 .core/.cli/commands/docs/generator.js delete mode 100644 .core/.cli/commands/docs/index.js delete mode 100644 .core/.cli/commands/i18n/actions.js delete mode 100644 .core/.cli/commands/i18n/generator.js delete mode 100644 .core/.cli/commands/i18n/index.js delete mode 100644 .core/.cli/commands/reactium/component/componentGen.cjs delete mode 100644 .core/.cli/commands/reactium/component/formatDestination.cjs delete mode 100644 .core/.cli/commands/reactium/component/formatRoute.cjs delete mode 100644 .core/.cli/commands/reactium/component/index.js delete mode 100644 .core/.cli/commands/reactium/component/package.json delete mode 100644 .core/.cli/commands/reactium/component/reactium-arcli.js delete mode 100644 .core/.cli/commands/reactium/component/selectDestination.cjs delete mode 100644 .core/.cli/commands/reactium/component/selectStyle.cjs delete mode 100644 .core/.cli/commands/reactium/component/styleTypes.cjs delete mode 100644 .core/.cli/commands/reactium/component/template/domain.hbs delete mode 100644 .core/.cli/commands/reactium/component/template/index-functional.hbs delete mode 100644 .core/.cli/commands/reactium/component/template/reactium-hooks.hbs delete mode 100644 .core/.cli/commands/reactium/component/template/reactium-style.hbs delete mode 100644 .core/.cli/commands/reactium/component/template/route.hbs delete mode 100644 .core/.cli/commands/reactium/domain/index.js delete mode 100644 .core/.cli/commands/reactium/domain/package.json delete mode 100644 .core/.cli/commands/reactium/domain/reactium-arcli.js delete mode 100644 .core/.cli/commands/reactium/hook/index.js delete mode 100644 .core/.cli/commands/reactium/hook/package.json delete mode 100644 .core/.cli/commands/reactium/hook/reactium-arcli.js delete mode 100644 .core/.cli/commands/reactium/icons/actions.js delete mode 100644 .core/.cli/commands/reactium/icons/generator.js delete mode 100644 .core/.cli/commands/reactium/icons/index.js delete mode 100644 .core/.cli/commands/reactium/icons/package.json delete mode 100644 .core/.cli/commands/reactium/icons/template/index.hbs delete mode 100644 .core/.cli/commands/reactium/icons/template/svg.hbs delete mode 100644 .core/.cli/commands/reactium/library/actions.js delete mode 100644 .core/.cli/commands/reactium/library/generator.js delete mode 100644 .core/.cli/commands/reactium/library/index.js delete mode 100644 .core/.cli/commands/reactium/plugin/eject/actions.js delete mode 100644 .core/.cli/commands/reactium/plugin/eject/generator.js delete mode 100644 .core/.cli/commands/reactium/plugin/eject/index.js delete mode 100644 .core/.cli/commands/reactium/plugin/index.js delete mode 100644 .core/.cli/commands/reactium/plugin/local/actions.js delete mode 100644 .core/.cli/commands/reactium/plugin/local/generator.js delete mode 100644 .core/.cli/commands/reactium/plugin/local/index.js delete mode 100644 .core/.cli/commands/reactium/plugin/module/actions.js delete mode 100644 .core/.cli/commands/reactium/plugin/module/generator.js delete mode 100644 .core/.cli/commands/reactium/plugin/module/index.js delete mode 100644 .core/.cli/commands/reactium/plugin/module/template/index.hbs delete mode 100644 .core/.cli/commands/reactium/plugin/module/template/reactium-boot.hbs delete mode 100644 .core/.cli/commands/reactium/plugin/module/template/reactium-hooks.hbs delete mode 100644 .core/.cli/commands/reactium/plugin/module/template/reactium-hooks.json delete mode 100644 .core/.cli/commands/reactium/plugin/module/template/style.hbs delete mode 100644 .core/.cli/commands/reactium/plugin/module/template/umd-config.hbs delete mode 100644 .core/.cli/commands/reactium/plugin/module/template/umd.hbs delete mode 100644 .core/.cli/commands/reactium/plugin/zones/actions.js delete mode 100644 .core/.cli/commands/reactium/plugin/zones/generator.js delete mode 100644 .core/.cli/commands/reactium/plugin/zones/index.js delete mode 100644 .core/.cli/commands/reactium/plugin/zones/manifest.js delete mode 100644 .core/.cli/commands/reactium/route/index.js delete mode 100644 .core/.cli/commands/reactium/route/package.json delete mode 100644 .core/.cli/commands/reactium/route/reactium-arcli.js delete mode 100644 .core/.cli/commands/reactium/server/actions.js delete mode 100644 .core/.cli/commands/reactium/server/generator.js delete mode 100644 .core/.cli/commands/reactium/server/index.js delete mode 100644 .core/.cli/commands/reactium/style/index.js delete mode 100644 .core/.cli/commands/reactium/style/package.json delete mode 100644 .core/.cli/commands/reactium/style/reactium-arcli.js delete mode 100644 .core/.cli/commands/reactium/test/actions.js delete mode 100644 .core/.cli/commands/reactium/test/generator.js delete mode 100644 .core/.cli/commands/reactium/test/index.js delete mode 100644 .core/.cli/commands/reactium/test/template/test.hbs delete mode 100644 .core/.cli/commands/reactium/version/index.js delete mode 100644 .core/.cli/config.json delete mode 100644 .core/app.js delete mode 100644 .core/app/index.js delete mode 100644 .core/app/reactium-hooks.js delete mode 100644 .core/app/shell.js delete mode 100644 .core/assets/images/a11y/a11y.svg delete mode 100644 .core/babel.config.js delete mode 100644 .core/boot-hooks.mjs delete mode 100644 .core/components/DevTools/index.js delete mode 100644 .core/components/Loading/domain.js delete mode 100644 .core/components/Loading/index.js delete mode 100644 .core/components/Loading/reactium-hooks.js delete mode 100644 .core/components/NotFound/index.js delete mode 100644 .core/components/Plugable/Plugins.js delete mode 100644 .core/components/Plugable/index.js delete mode 100644 .core/components/Plugable/reducers.js delete mode 100644 .core/components/Plugable/state.js delete mode 100644 .core/components/Router/RoutedContent.js delete mode 100644 .core/components/Router/index.js delete mode 100644 .core/components/Router/reactium-hooks.js delete mode 100644 .core/components/WindowProvider/index.js delete mode 100644 .core/dependencies/getComponents.js delete mode 100644 .core/dependencies/index.js delete mode 100644 .core/easy-connect.js delete mode 100644 .core/enzyme.js delete mode 100644 .core/get-task.js delete mode 100644 .core/globby-patch.js delete mode 100644 .core/gulp.bootup.js delete mode 100644 .core/gulp.config.js delete mode 100644 .core/gulp.tasks.js delete mode 100644 .core/gulp.watch.js delete mode 100644 .core/gulpfile.js delete mode 100644 .core/index.mjs delete mode 100644 .core/manifest/manifest-tools.js delete mode 100644 .core/manifest/processors/domains.js delete mode 100644 .core/manifest/processors/externals.js delete mode 100644 .core/manifest/processors/manifest.js delete mode 100644 .core/manifest/processors/umd.js delete mode 100644 .core/manifest/templates/domains.hbs delete mode 100644 .core/manifest/templates/externals.hbs delete mode 100644 .core/manifest/templates/manifest.hbs delete mode 100644 .core/manifest/templates/umd.hbs delete mode 100644 .core/reactium-config.js delete mode 100644 .core/reactium.log.cjs delete mode 100644 .core/sdk/i18n/index.js delete mode 100644 .core/sdk/index.js delete mode 100644 .core/sdk/named-exports/app-context.js delete mode 100644 .core/sdk/named-exports/capability.js delete mode 100644 .core/sdk/named-exports/hookable-component.js delete mode 100644 .core/sdk/named-exports/i18n.js delete mode 100644 .core/sdk/named-exports/index.js delete mode 100644 .core/sdk/named-exports/roles.js delete mode 100644 .core/sdk/named-exports/routing.js delete mode 100644 .core/sdk/named-exports/setting.js delete mode 100644 .core/sdk/named-exports/useDispatcher.js delete mode 100644 .core/sdk/named-exports/window.js delete mode 100644 .core/sdk/reactium-hooks.js delete mode 100644 .core/sdk/routing/index.js delete mode 100644 .core/server-globals.mjs delete mode 100644 .core/server/placeholder/reactium-boot.js delete mode 100644 .core/server/renderer/feo.js delete mode 100644 .core/server/renderer/index.mjs delete mode 100644 .core/server/router.mjs delete mode 100644 .core/server/template/feo.js delete mode 100644 .core/umd.webpack.config.js delete mode 100644 .core/webpack.config.js delete mode 100644 .core/webpack.sdk.js diff --git a/.core/.cli/commands/docs/actions.js b/.core/.cli/commands/docs/actions.js deleted file mode 100644 index 799e5ebe..00000000 --- a/.core/.cli/commands/docs/actions.js +++ /dev/null @@ -1,66 +0,0 @@ -const path = require('path'); -const chalk = require('chalk'); -const fs = require('fs-extra'); -const _ = require('underscore'); -const op = require('object-path'); -const { createDoc } = require('apidoc'); -const globby = require('globby'); - -module.exports = spinner => { - const message = text => { - if (spinner) { - spinner.text = text; - } - }; - - return { - create: async ({ action, params, props }) => { - message(`Creating ${chalk.cyan('docs')}...`); - - let { src, dest, verbose } = params; - - src = _.flatten( - src.map(search => { - if (search === 'node_modules/@atomic-reactor') { - const globRoot = path - .resolve(process.cwd(), search) - .replace(/\\/g, '/'); - - const globs = [ - `${globRoot}/**/src/*.js`, - `${globRoot}/**/lib/*.js`, - `!${globRoot}/**/node_modules/**/*`, - `!${globRoot}/cli/**/*`, - ]; - - return _.uniq( - globby - .sync(globs) - .map(fn => - path.dirname(fn).replace(globRoot, ''), - ), - ).map(p => `${search}${p}`); - } - return search; - }), - ); - - dest = String(dest) - .replace(/ /gi, '') - .split(','); - dest = _.flatten([dest]); - - dest.forEach(d => { - createDoc({ - src, - dest: d, - lineEnding: '\n', - debug: verbose, - verbose, - }); - }); - - return Promise.resolve({ action, status: 200 }); - }, - }; -}; diff --git a/.core/.cli/commands/docs/generator.js b/.core/.cli/commands/docs/generator.js deleted file mode 100644 index 08288f91..00000000 --- a/.core/.cli/commands/docs/generator.js +++ /dev/null @@ -1,26 +0,0 @@ -const ora = require('ora'); -const ActionSequence = require('action-sequence'); - -module.exports = ({ params, props }) => { - const spinner = ora({ - spinner: 'dots', - color: 'cyan', - }); - - spinner.start(); - - const actions = require('./actions')(spinner); - - return ActionSequence({ - actions, - options: { params, props }, - }) - .then(success => { - spinner.succeed('complete!'); - return success; - }) - .catch(error => { - spinner.fail('error!'); - return error; - }); -}; diff --git a/.core/.cli/commands/docs/index.js b/.core/.cli/commands/docs/index.js deleted file mode 100644 index db82a006..00000000 --- a/.core/.cli/commands/docs/index.js +++ /dev/null @@ -1,213 +0,0 @@ -/** - * ----------------------------------------------------------------------------- - * Imports - * ----------------------------------------------------------------------------- - */ - -const chalk = require('chalk'); -const generator = require('./generator'); -const prettier = require('prettier'); -const path = require('path'); -const op = require('object-path'); -const { error, message } = arcli; - -/** - * NAME String - * @description Constant defined as the command name. Value passed to the commander.command() function. - * @example $ arcli docs - * @see https://www.npmjs.com/package/commander#command-specific-options - * @since 2.0.0 - */ -const NAME = 'docs'; - -/** - * DESC String - * @description Constant defined as the command description. Value passed to - * the commander.desc() function. This string is also used in the --help flag output. - * @see https://www.npmjs.com/package/commander#automated---help - * @since 2.0.0 - */ -const DESC = 'Generate docs'; - -/** - * CANCELED String - * @description Message sent when the command is canceled - * @since 2.0.0 - */ -const CANCELED = 'Action canceled!'; - -/** - * conform(input:Object) Function - * @description Reduces the input object. - * @param input Object The key value pairs to reduce. - * @since 2.0.0 - */ -const CONFORM = ({ input, props }) => - Object.keys(input).reduce((obj, key) => { - const { cwd } = props; - let val = input[key]; - switch (key) { - case 'src': { - const paths = val.split(',').map(srcDir => { - srcDir = path.normalize(srcDir); - if (/^[\/\\]{1}/.test(srcDir)) { - srcDir = path.relative(cwd, srcDir); - } - return srcDir; - }); - obj.src = paths; - break; - } - case 'dest': { - let dest = path.normalize(val); - if (/^[\/\\]{1}/.test(dest)) { - dest = path.relative(cwd, dest); - } - obj.dest = dest; - break; - } - default: - obj[key] = val; - break; - } - - if (!('verbose' in obj)) obj.verbose = false; - else obj.verbose = !!obj.verbose; - - return obj; - }, {}); - -/** - * HELP Function - * @description Function called in the commander.on('--help', callback) callback. - * @see https://www.npmjs.com/package/commander#automated---help - * @since 2.0.0 - */ -const HELP = () => - console.log(` -Example: - $ arcli docs -h -`); - -/** - * FLAGS - * @description Array of flags passed from the commander options. - * @since 2.0.18 - */ -const FLAGS = ['src', 'dest', 'verbose']; - -/** - * FLAGS_TO_PARAMS Function - * @description Create an object used by the prompt.override property. - * @since 2.0.18 - */ -const FLAGS_TO_PARAMS = ({ opt = {} }) => - FLAGS.reduce((obj, key) => { - let val = opt[key]; - val = typeof val === 'function' ? undefined : val; - - if (val) { - obj[key] = val; - } - - return obj; - }, {}); - -/** - * SCHEMA Function - * @description used to describe the input for the prompt function. - * @see https://www.npmjs.com/package/prompt - * @since 2.0.0 - */ -const SCHEMA = ({ props }) => { - const { prompt } = props; - - return { - properties: { - src: { - description: chalk.white( - 'Source directories, comma separated:', - ), - required: true, - default: 'src,.core', - }, - dest: { - description: chalk.white('Documentation destination:'), - required: true, - default: 'public/apidocs', - }, - }, - }; -}; - -/** - * ACTION Function - * @description Function used as the commander.action() callback. - * @see https://www.npmjs.com/package/commander - * @param opt Object The commander options passed into the function. - * @param props Object The CLI props passed from the calling class `orcli.js`. - * @since 2.0.0 - */ -const ACTION = ({ opt, props }) => { - console.log(''); - - const { cwd, prompt } = props; - const schema = SCHEMA({ props }); - const ovr = FLAGS_TO_PARAMS({ opt }); - - prompt.override = ovr; - prompt.start(); - - return new Promise((resolve, reject) => { - prompt.get(schema, (err, input = {}) => { - if (err) { - prompt.stop(); - reject(`${NAME} ${err.message}`); - return; - } - - input = { ...ovr, ...input }; - - resolve(CONFORM({ input, props })); - }); - }) - .then(async params => { - console.log(''); - await generator({ params, props }); - console.log(''); - }) - .then(() => prompt.stop()) - .catch(err => { - prompt.stop(); - message(op.get(err, 'message', CANCELED)); - }); -}; - -/** - * COMMAND Function - * @description Function that executes program.command() - */ -const COMMAND = ({ program, props }) => - program - .command(NAME) - .description(DESC) - .action(opt => ACTION({ opt, props })) - .option('-s, --src [src]', 'Comma separated src directories to scan.') - .option( - '-d, --dest [dest]', - 'Dest directories to output documentation.', - ) - .option('-V, --verbose', 'Verbose logging during generation.') - .on('--help', HELP); - -/** - * Module Constructor - * @description Internal constructor of the module that is being exported. - * @param program Class Commander.program reference. - * @param props Object The CLI props passed from the calling class `arcli.js`. - * @since 2.0.0 - */ -module.exports = { - COMMAND, - NAME, -}; diff --git a/.core/.cli/commands/i18n/actions.js b/.core/.cli/commands/i18n/actions.js deleted file mode 100644 index c06e63db..00000000 --- a/.core/.cli/commands/i18n/actions.js +++ /dev/null @@ -1,27 +0,0 @@ -const path = require('path'); -const chalk = require('chalk'); -const fs = require('fs-extra'); -const _ = require('underscore'); -const op = require('object-path'); -const ShowConfigCli = require('gettext-extract'); - -module.exports = spinner => { - const message = text => { - if (spinner) { - spinner.text = text; - } - }; - - return { - generate: async ({ action, params, props }) => { - const generator = new ShowConfigCli([]); - message(`Generating ${chalk.cyan('POT file')}...`); - try { - generator.run(); - } catch (error) { - console.log(error); - } - return Promise.resolve({ action, status: 200 }); - }, - }; -}; diff --git a/.core/.cli/commands/i18n/generator.js b/.core/.cli/commands/i18n/generator.js deleted file mode 100644 index 08288f91..00000000 --- a/.core/.cli/commands/i18n/generator.js +++ /dev/null @@ -1,26 +0,0 @@ -const ora = require('ora'); -const ActionSequence = require('action-sequence'); - -module.exports = ({ params, props }) => { - const spinner = ora({ - spinner: 'dots', - color: 'cyan', - }); - - spinner.start(); - - const actions = require('./actions')(spinner); - - return ActionSequence({ - actions, - options: { params, props }, - }) - .then(success => { - spinner.succeed('complete!'); - return success; - }) - .catch(error => { - spinner.fail('error!'); - return error; - }); -}; diff --git a/.core/.cli/commands/i18n/index.js b/.core/.cli/commands/i18n/index.js deleted file mode 100644 index 22ef9b83..00000000 --- a/.core/.cli/commands/i18n/index.js +++ /dev/null @@ -1,170 +0,0 @@ -/** - * ----------------------------------------------------------------------------- - * Imports - * ----------------------------------------------------------------------------- - */ - -const chalk = require('chalk'); -const generator = require('./generator'); -const prettier = require('prettier'); -const path = require('path'); -const op = require('object-path'); -const { error, message } = arcli; - -/** - * NAME String - * @description Constant defined as the command name. Value passed to the commander.command() function. - * @example $ arcli docs - * @see https://www.npmjs.com/package/commander#command-specific-options - * @since 2.0.0 - */ -const NAME = 'i18n'; - -/** - * DESC String - * @description Constant defined as the command description. Value passed to - * the commander.desc() function. This string is also used in the --help flag output. - * @see https://www.npmjs.com/package/commander#automated---help - * @since 2.0.0 - */ -const DESC = 'Generate POT file.'; - -/** - * CANCELED String - * @description Message sent when the command is canceled - * @since 2.0.0 - */ -const CANCELED = 'Action canceled!'; - -/** - * conform(input:Object) Function - * @description Reduces the input object. - * @param input Object The key value pairs to reduce. - * @since 2.0.0 - */ -const CONFORM = ({ input, props }) => - Object.keys(input).reduce((obj, key) => { - const { cwd } = props; - let val = input[key]; - switch (key) { - default: - obj[key] = val; - break; - } - - return obj; - }, {}); - -/** - * HELP Function - * @description Function called in the commander.on('--help', callback) callback. - * @see https://www.npmjs.com/package/commander#automated---help - * @since 2.0.0 - */ -const HELP = () => - console.log(` -Example: - $ arcli i18n -h -`); - -/** - * FLAGS - * @description Array of flags passed from the commander options. - * @since 2.0.18 - */ -const FLAGS = []; - -/** - * FLAGS_TO_PARAMS Function - * @description Create an object used by the prompt.override property. - * @since 2.0.18 - */ -const FLAGS_TO_PARAMS = ({ opt = {} }) => - FLAGS.reduce((obj, key) => { - let val = opt[key]; - val = typeof val === 'function' ? undefined : val; - - if (val) { - obj[key] = val; - } - - return obj; - }, {}); - -/** - * SCHEMA Function - * @description used to describe the input for the prompt function. - * @see https://www.npmjs.com/package/prompt - * @since 2.0.0 - */ -const SCHEMA = ({ props }) => { - const { prompt } = props; - - return { - properties: {}, - }; -}; - -/** - * ACTION Function - * @description Function used as the commander.action() callback. - * @see https://www.npmjs.com/package/commander - * @param opt Object The commander options passed into the function. - * @param props Object The CLI props passed from the calling class `orcli.js`. - * @since 2.0.0 - */ -const ACTION = ({ opt, props }) => { - const { cwd, prompt } = props; - const schema = SCHEMA({ props }); - const ovr = FLAGS_TO_PARAMS({ opt }); - - prompt.override = ovr; - prompt.start(); - - return new Promise((resolve, reject) => { - prompt.get(schema, (err, input = {}) => { - if (err) { - prompt.stop(); - reject(`${NAME} ${err.message}`); - return; - } - - input = { ...ovr, ...input }; - - resolve(CONFORM({ input, props })); - }); - }) - .then(async () => { - console.log(''); - await generator({ props }); - console.log(''); - }) - .then(() => prompt.stop()) - .catch(err => { - prompt.stop(); - message(op.get(err, 'message', CANCELED)); - }); -}; - -/** - * COMMAND Function - * @description Function that executes program.command() - */ -const COMMAND = ({ program, props }) => - program - .command(NAME) - .description(DESC) - .action(opt => ACTION({ opt, props })) - .on('--help', HELP); - -/** - * Module Constructor - * @description Internal constructor of the module that is being exported. - * @param program Class Commander.program reference. - * @param props Object The CLI props passed from the calling class `arcli.js`. - * @since 2.0.0 - */ -module.exports = { - COMMAND, - NAME, -}; diff --git a/.core/.cli/commands/reactium/component/componentGen.cjs b/.core/.cli/commands/reactium/component/componentGen.cjs deleted file mode 100644 index e997e87b..00000000 --- a/.core/.cli/commands/reactium/component/componentGen.cjs +++ /dev/null @@ -1,86 +0,0 @@ -const { fs, chalk, Reactium } = arcli; -const handlebars = require('handlebars'); - -const componentGen = async props => { - const { params, spinner } = props; - - const templateDir = arcli.normalizePath(__dirname, 'template'); - - const templates = { - hooks: { - file: 'reactium-hooks.js', - template: 'reactium-hooks.hbs', - create: params.hooks, - }, - component: { - file: 'index.js', - template: 'index-functional.hbs', - create: params.index, - }, - domain: { - file: 'domain.js', - template: 'domain.hbs', - create: params.domain, - }, - route: { - file: 'route.js', - template: 'route.hbs', - create: typeof params.route === 'string', - }, - style: { - file: params.styleType || '_reactium-style.scss', - template: params.className ? 'reactium-style.hbs' : undefined, - create: params.style, - }, - }; - - // Create component directory: - fs.ensureDirSync(params.destination); - - // Create component files: - for (const item of Object.values(templates)) { - if (!item.create) continue; - - const filePath = arcli.normalizePath(params.destination, item.file); - - if (fs.existsSync(filePath) && !params.unattended) { - const { overwrite } = await arcli.props.inquirer.prompt([ - { - default: false, - type: 'confirm', - name: 'overwrite', - message: `Overwrite existing ${item.file} file?`, - prefix: arcli.prefix, - suffix: chalk.magenta(': '), - }, - ]); - if (!overwrite) continue; - } - - if (!item.template) { - fs.ensureFileSync(filePath); - continue; - } - - const templateFilePath = arcli.normalizePath( - templateDir, - item.template, - ); - - let fileContent = handlebars.compile( - fs.readFileSync(templateFilePath, 'utf-8'), - )(params); - - try { - await Reactium.Hook.run('arcli-file-gen', fileContent, props); - } catch (err) { - spinner.stop(); - console.log(err); - spinner.start(); - } - - fs.writeFileSync(filePath, fileContent); - } -}; - -module.exports = componentGen; diff --git a/.core/.cli/commands/reactium/component/formatDestination.cjs b/.core/.cli/commands/reactium/component/formatDestination.cjs deleted file mode 100644 index 1b806698..00000000 --- a/.core/.cli/commands/reactium/component/formatDestination.cjs +++ /dev/null @@ -1,22 +0,0 @@ -const formatDestination = val => { - const { cwd } = arcli.props; - - val = arcli.normalizePath(val); - val = String(val).replace(/^~\/|^\/cwd\/|^cwd\/|^cwd$/i, `${cwd}/`); - val = String(val).replace( - /^\/core\/|^core\/|^core/i, - `${cwd}/.core/components/`, - ); - val = String(val).replace( - /^\/components\/|^components\/|^components$/i, - `${cwd}/src/app/components/`, - ); - val = String(val).replace( - /^\/common-ui\/|^common-ui\/|^common-ui$/i, - `${cwd}/src/app/components/common-ui/`, - ); - - return arcli.normalizePath(val); -}; - -module.exports = formatDestination; diff --git a/.core/.cli/commands/reactium/component/formatRoute.cjs b/.core/.cli/commands/reactium/component/formatRoute.cjs deleted file mode 100644 index b9c2caf1..00000000 --- a/.core/.cli/commands/reactium/component/formatRoute.cjs +++ /dev/null @@ -1,27 +0,0 @@ -const { _ } = arcli; - -const formatRoute = route => { - const inputToArray = str => { - str = String(str) - .replace(/,/g, ' ') - .replace(/\s\s+/g, ' '); - - return _.compact(str.split(' ')).map(item => { - if (String(item).substring(0, 1) !== '/') { - item = `/${item}`; - } - - return item; - }); - }; - - return JSON.stringify( - inputToArray(route) - .sort() - .reverse(), - ) - .replace(/\"/g, "'") - .replace(/,/g, ', '); -}; - -module.exports = formatRoute; diff --git a/.core/.cli/commands/reactium/component/index.js b/.core/.cli/commands/reactium/component/index.js deleted file mode 100644 index 9a3230dc..00000000 --- a/.core/.cli/commands/reactium/component/index.js +++ /dev/null @@ -1,203 +0,0 @@ -import Reactium from '@atomic-reactor/reactium-sdk-core'; - -arcli.Reactium = Reactium; - -const { ActionSequence, ora, path } = arcli; - -const ENUMS = { - CANCELED: 'component canceled!', - DESC: 'Reactium: Create or replace a component', - FLAGS: { - destination: { - flag: '-d, --destination [destination]', - desc: 'Component parent directory', - }, - name: { - flag: '-n, --name [name]', - desc: 'String used when importing', - }, - route: { - flag: '-r, --route [route]', - desc: 'Direct routes to the component', - }, - hooks: { - flag: '-H, --hooks [hooks]', - desc: - 'Create Reactium hooks file and register component for useHookComponent() usage', - }, - style: { - flag: '-s, --style [style]', - desc: 'Create a stylesheet file', - }, - domain: { - flag: '-D, --domain [domain]', - desc: 'Create domain.js file', - }, - unattended: { - flag: '-u, --unattended [unattended]', - desc: 'Bypass the preflight confirmation and any input prompts', - }, - }, - NAME: 'component', -}; - -export const NAME = ENUMS.NAME; - -// prettier-ignore -const HELP = () => console.log(` -Example: - $ arcli component -h - - $ arcli component -n Test - - $ arcli component -s atoms - - $ arcli component -r "/route-1, /route-1/:param" -`); - -const ACTION = async ({ opt, props }) => { - // load hooks - for (const file of arcli.globby( - [ - './.core/**/reactium-arcli.js', - './src/**/reactium-arcli.js', - './reactium_modules/**/reactium-arcli.js', - './node_modules/**/reactium-arcli.js', - ], - { - dot: true, - }, - )) { - await import(path.resolve(file)); - } - - let params = arcli.flagsToParams({ opt, flags: Object.keys(ENUMS.FLAGS) }); - - try { - await Reactium.Hook.run('arcli-component-init', { - ...props, - params, - ENUMS, - }); - } catch (err) { - console.log(err); - process.exit(); - } - - try { - await Reactium.Hook.run('arcli-component-enums', { - ...props, - params, - ENUMS, - }); - } catch (err) { - console.log(err); - process.exit(); - } - - if (params.unattended !== true) { - try { - await Reactium.Hook.run('arcli-component-input', { - ...props, - params, - ENUMS, - }); - } catch (err) { - console.log(err); - process.exit(); - } - } - - try { - await Reactium.Hook.run('arcli-component-conform', { - ...props, - params, - ENUMS, - }); - } catch (err) { - console.log(err); - process.exit(); - } - - if (params.unattended !== true) { - try { - await Reactium.Hook.run('arcli-component-preflight', { - ...props, - params, - }); - } catch (err) { - console.log(err); - process.exit(); - } - - try { - await Reactium.Hook.run('arcli-component-confirm', { - ...props, - params, - ENUMS, - }); - } catch (err) { - console.log(err); - process.exit(); - } - - if (params.confirm !== true) { - arcli.message(ENUMS.CANCELED); - return; - } - } - - console.log(''); - - // Start the spinner - - const spinner = ora({ spinner: 'dots', color: 'cyan' }); - spinner.start(); - - let actions = {}; - try { - await Reactium.Hook.run('arcli-component-actions', { - ...props, - params, - actions, - spinner, - ENUMS, - }); - } catch (err) { - console.log(err); - process.exit(); - } - - return ActionSequence({ - actions, - options: { params, props, spinner }, - }) - .then(success => { - spinner.succeed('complete!'); - console.log(''); - return success; - }) - .catch(error => { - spinner.fail('error!'); - console.error(error); - return error; - }); -}; - -export const COMMAND = ({ program, props }) => { - program - .command(ENUMS.NAME) - .description(ENUMS.DESC) - .on('--help', HELP) - .action(opt => ACTION({ opt, props, program })); - - program.commands - .filter(cmd => Boolean(cmd._name === ENUMS.NAME)) - .forEach(cmd => - Object.values(ENUMS.FLAGS).forEach(({ flag, desc }) => - cmd.option(flag, desc), - ), - ); - - return program; -}; diff --git a/.core/.cli/commands/reactium/component/package.json b/.core/.cli/commands/reactium/component/package.json deleted file mode 100644 index 03017e42..00000000 --- a/.core/.cli/commands/reactium/component/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "reactium-component-cmd", - "type": "module" -} \ No newline at end of file diff --git a/.core/.cli/commands/reactium/component/reactium-arcli.js b/.core/.cli/commands/reactium/component/reactium-arcli.js deleted file mode 100644 index ff85d549..00000000 --- a/.core/.cli/commands/reactium/component/reactium-arcli.js +++ /dev/null @@ -1,158 +0,0 @@ -import formatRoute from './formatRoute.cjs'; -import componentGen from './componentGen.cjs'; -import formatDestination from './formatDestination.cjs'; -import selectDestination from './selectDestination.cjs'; -import selectStyleDefault from './selectStyle.cjs'; -import camelcase from 'camelcase'; - -const { selectStyle, styleTypes } = selectStyleDefault; -const { _, chalk, prefix, Reactium } = arcli; - -const cc = str => camelcase(str, { pascalCase: true }); -const suffix = chalk.magenta(': '); - -const PREFLIGHT = ({ msg, params }) => { - arcli.message(msg || 'Preflight checklist:'); - console.log(JSON.stringify(params, null, 2)); - console.log(''); -}; - -const INPUT = async ({ inquirer, params }) => { - const input = await inquirer.prompt( - [ - selectDestination(), - { - prefix, - suffix, - type: 'input', - name: 'name', - message: 'Component Name', - }, - { - prefix, - suffix, - type: 'input', - name: 'route', - message: 'Route', - }, - { - prefix, - suffix, - default: true, - type: 'confirm', - name: 'hooks', - message: 'Reactium Hooks?', - }, - { - prefix, - suffix, - default: true, - type: 'confirm', - name: 'domain', - message: 'Domain file?', - }, - { - prefix, - suffix, - default: false, - type: 'confirm', - name: 'style', - message: 'Stylesheet?', - }, - selectStyle({ - name: 'styleType', - when: answers => answers.style === true, - }), - ], - params, - ); - - Object.entries(input).forEach(([key, val]) => (params[key] = val)); -}; - -const CONFIRM = async ({ inquirer, params }) => { - if (params.unattended) return; - - const input = await inquirer.prompt([ - { - prefix, - suffix, - default: false, - type: 'confirm', - name: 'confirm', - message: 'Proceed?', - }, - ]); - - Object.entries(input).forEach(([key, val]) => (params[key] = val)); -}; - -const CONFORM = async ({ params }) => { - params.destination = formatDestination(params.destination); - - if (typeof params.name === 'string') { - params.className = String(params.name).toLowerCase(); - params.name = cc(params.name); - params.index = true; - - if (!String(params.destination).endsWith(params.name)) { - params.destination = arcli.normalizePath( - params.destination, - params.name, - ); - } - } - - if (typeof params.style === 'string') { - params.styleType = params.style; - params.style = true; - } - - if (params.style === true) { - const styleType = - _.findWhere(styleTypes, { name: params.styleType }) || - _.first(styleTypes); - - params.styleType = styleType.value; - } - - if (typeof params.route === 'string') { - params.route = formatRoute(params.route); - } -}; - -// Register default hooks -Reactium.Hook.register( - 'arcli-component-input', - INPUT, - Reactium.Enums.priority.highest, - 'arcli-component-input', -); - -Reactium.Hook.register( - 'arcli-component-confirm', - CONFIRM, - Reactium.Enums.priority.highest, - 'arcli-component-confirm', -); - -Reactium.Hook.register( - 'arcli-component-conform', - CONFORM, - Reactium.Enums.priority.highest, - 'arcli-component-conform', -); - -Reactium.Hook.register( - 'arcli-component-preflight', - PREFLIGHT, - Reactium.Enums.priority.highest, - 'arcli-component-preflight', -); - -Reactium.Hook.register( - 'arcli-component-actions', - ({ actions }) => (actions['component'] = componentGen), - Reactium.Enums.priority.highest, - 'arcli-component-actions', -); diff --git a/.core/.cli/commands/reactium/component/selectDestination.cjs b/.core/.cli/commands/reactium/component/selectDestination.cjs deleted file mode 100644 index 1ee4b469..00000000 --- a/.core/.cli/commands/reactium/component/selectDestination.cjs +++ /dev/null @@ -1,14 +0,0 @@ -const { prefix, chalk } = arcli; -const suffix = chalk.magenta(': '); - -module.exports = () => ({ - prefix, - suffix, - type: 'fuzzypath', - name: 'destination', - itemType: 'directory', - message: 'Select directory', - excludeFilter: nodePath => nodePath == '.' || nodePath.startsWith('.'), - excludePath: nodePath => - nodePath.startsWith('build/') || nodePath.startsWith('node_modules'), -}); diff --git a/.core/.cli/commands/reactium/component/selectStyle.cjs b/.core/.cli/commands/reactium/component/selectStyle.cjs deleted file mode 100644 index 4132fdc8..00000000 --- a/.core/.cli/commands/reactium/component/selectStyle.cjs +++ /dev/null @@ -1,20 +0,0 @@ -const { _, chalk, prefix } = arcli; -const suffix = chalk.magenta(': '); -const styleTypes = require('./styleTypes.cjs'); - -const selectStyle = props => ({ - prefix, - suffix, - default: _.first(styleTypes).name, - type: 'list', - name: 'styleType', - choices: _.pluck(styleTypes, 'name'), - message: 'Select stylesheet type', - ...props, -}); - -module.exports = { - selectStyle, - styleTypes, - default: selectStyle, -}; diff --git a/.core/.cli/commands/reactium/component/styleTypes.cjs b/.core/.cli/commands/reactium/component/styleTypes.cjs deleted file mode 100644 index 99cc2ae4..00000000 --- a/.core/.cli/commands/reactium/component/styleTypes.cjs +++ /dev/null @@ -1,34 +0,0 @@ -module.exports = [ - { - name: 'default', - value: '_reactium-style.scss', - }, - { - name: 'mixins', - value: '_reactium-style-mixins.scss', - }, - { - name: 'variables', - value: '_reactium-style-variables.scss', - }, - { - name: 'base', - value: '_reactium-style-base.scss', - }, - { - name: 'atoms', - value: '_reactium-style-atoms.scss', - }, - { - name: 'molecules', - value: '_reactium-style-molecules.scss', - }, - { - name: 'organisms', - value: '_reactium-style-organisms.scss', - }, - { - name: 'overrides', - value: '_reactium-style-overrides.scss', - }, -]; diff --git a/.core/.cli/commands/reactium/component/template/domain.hbs b/.core/.cli/commands/reactium/component/template/domain.hbs deleted file mode 100644 index f9c5b525..00000000 --- a/.core/.cli/commands/reactium/component/template/domain.hbs +++ /dev/null @@ -1,9 +0,0 @@ -/** - * ----------------------------------------------------------------------------- - * DDD Domain {{name}} - Change name to place domain artifacts in this directory - * in a different domain. - * ----------------------------------------------------------------------------- - */ -module.exports = { - name: '{{name}}', -}; diff --git a/.core/.cli/commands/reactium/component/template/index-functional.hbs b/.core/.cli/commands/reactium/component/template/index-functional.hbs deleted file mode 100644 index 0aa112a0..00000000 --- a/.core/.cli/commands/reactium/component/template/index-functional.hbs +++ /dev/null @@ -1,29 +0,0 @@ -import PropTypes from 'prop-types'; -import { useSyncState } from 'reactium-core/sdk'; -import React, { forwardRef, useImperativeHandle } from 'react'; - -/** - * ----------------------------------------------------------------------------- - * Functional Component: {{name}} - * ----------------------------------------------------------------------------- - */ -let {{name}} = ({ className }, ref) => { - - const state = useSyncState({}); - - useImperativeHandle(ref, () => state); - - return
{{name}}
; -}; - -{{name}} = forwardRef({{name}}); - -{{name}}.propTypes = { - className: PropTypes.string, -}; - -{{name}}.defaultProps = { - className: '{{className}}' -}; - -export default {{name}}; diff --git a/.core/.cli/commands/reactium/component/template/reactium-hooks.hbs b/.core/.cli/commands/reactium/component/template/reactium-hooks.hbs deleted file mode 100644 index 749b27e3..00000000 --- a/.core/.cli/commands/reactium/component/template/reactium-hooks.hbs +++ /dev/null @@ -1,13 +0,0 @@ -/** - * ----------------------------------------------------------------------------- - * Reactium Plugin {{name}} - * ----------------------------------------------------------------------------- - */ - -import Component from './index'; -import Reactium from 'reactium-core/sdk'; - -(async () => { - await Reactium.Plugin.register('{{name}}'); - Reactium.Component.register('{{name}}', Component); -})(); diff --git a/.core/.cli/commands/reactium/component/template/reactium-style.hbs b/.core/.cli/commands/reactium/component/template/reactium-style.hbs deleted file mode 100644 index 59eaa27a..00000000 --- a/.core/.cli/commands/reactium/component/template/reactium-style.hbs +++ /dev/null @@ -1,3 +0,0 @@ -.{{className}} { - -} diff --git a/.core/.cli/commands/reactium/component/template/route.hbs b/.core/.cli/commands/reactium/component/template/route.hbs deleted file mode 100644 index 844bbfd7..00000000 --- a/.core/.cli/commands/reactium/component/template/route.hbs +++ /dev/null @@ -1,7 +0,0 @@ -import Component from './index'; - -export default { - exact: true, - component: Component, - path: {{{route}}}, -}; diff --git a/.core/.cli/commands/reactium/domain/index.js b/.core/.cli/commands/reactium/domain/index.js deleted file mode 100644 index 694d618d..00000000 --- a/.core/.cli/commands/reactium/domain/index.js +++ /dev/null @@ -1,138 +0,0 @@ -import Reactium from '@atomic-reactor/reactium-sdk-core'; -const { ActionSequence, ora, path } = arcli; - -const ENUMS = { - CANCELED: 'domain canceled!', - DESC: 'Reactium: Create or replace a component domain file', - FLAGS: { - destination: { - flag: '-d, --destination [destination]', - desc: 'Directory to save the file', - }, - unattended: { - flag: '-u, --unattended [unattended]', - desc: 'Bypass the preflight confirmation and any input prompts', - }, - }, - NAME: 'domain', -}; - -// prettier-ignore -const HELP = () => console.log(` -Example: - $ arcli domain -h -`); - -const ACTION = async ({ opt, props }) => { - // load hooks - for (const file of arcli.globby( - [ - './.core/**/reactium-arcli.js', - './src/**/reactium-arcli.js', - './reactium_modules/**/reactium-arcli.js', - './node_modules/**/reactium-arcli.js', - ], - { - dot: true, - }, - )) { - await import(path.resolve(file)); - } - - let params = arcli.flagsToParams({ opt, flags: Object.keys(ENUMS.FLAGS) }); - - await Reactium.Hook.run('arcli-domain-init', { - ...props, - params, - ENUMS, - }); - - await Reactium.Hook.run('arcli-domain-enums', { - ...props, - params, - ENUMS, - }); - - if (params.unattended !== true) { - await Reactium.Hook.run('arcli-domain-input', { - ...props, - params, - ENUMS, - }); - } - - await Reactium.Hook.run('arcli-domain-conform', { - ...props, - params, - ENUMS, - }); - - if (params.unattended !== true) { - await Reactium.Hook.run('arcli-domain-preflight', { - ...props, - params, - }); - - await Reactium.Hook.run('arcli-domain-confirm', { - ...props, - params, - ENUMS, - }); - - if (params.confirm !== true) { - arcli.message(ENUMS.CANCELED); - return; - } - } - - console.log(''); - - // Start the spinner - - const spinner = ora({ spinner: 'dots', color: 'cyan' }); - spinner.start(); - - let actions = {}; - await Reactium.Hook.run('arcli-domain-actions', { - ...props, - params, - actions, - spinner, - ENUMS, - }); - - return ActionSequence({ - actions, - options: { params, props, spinner }, - }) - .then(success => { - spinner.succeed('complete!'); - console.log(''); - return success; - }) - .catch(error => { - spinner.fail('error!'); - console.error(error); - return error; - }); -}; - -export const COMMAND = ({ program, props }) => { - program - .command(ENUMS.NAME) - .description(ENUMS.DESC) - .on('--help', HELP) - .action(opt => ACTION({ opt, props, program })); - - program.commands - .filter(cmd => Boolean(cmd._name === ENUMS.NAME)) - .forEach(cmd => - Object.values(ENUMS.FLAGS).forEach(({ flag, desc }) => - cmd.option(flag, desc), - ), - ); - - return program; -}; - -export const NAME = ENUMS.NAME; diff --git a/.core/.cli/commands/reactium/domain/package.json b/.core/.cli/commands/reactium/domain/package.json deleted file mode 100644 index 5f0121e9..00000000 --- a/.core/.cli/commands/reactium/domain/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "reactium-domain-cmd", - "type": "module" -} \ No newline at end of file diff --git a/.core/.cli/commands/reactium/domain/reactium-arcli.js b/.core/.cli/commands/reactium/domain/reactium-arcli.js deleted file mode 100644 index 848c48ce..00000000 --- a/.core/.cli/commands/reactium/domain/reactium-arcli.js +++ /dev/null @@ -1,77 +0,0 @@ -import componentGen from '../component/componentGen.cjs'; -import formatDestination from '../component/formatDestination.cjs'; -import selectDestination from '../component/selectDestination.cjs'; - -const { _, chalk, path, prefix, Reactium } = arcli; - -const suffix = chalk.magenta(': '); - -const PREFLIGHT = ({ msg, params }) => { - arcli.message(msg || 'Preflight checklist:'); - console.log(JSON.stringify(params, null, 2)); - console.log(''); -}; - -const INPUT = async ({ inquirer, params }) => { - const input = await inquirer.prompt([selectDestination()], params); - Object.entries(input).forEach(([key, val]) => (params[key] = val)); -}; - -const CONFIRM = async ({ inquirer, params }) => { - if (params.unattended) return; - - const input = await inquirer.prompt([ - { - prefix, - suffix, - default: false, - type: 'confirm', - name: 'confirm', - message: 'Proceed?', - }, - ]); - - Object.entries(input).forEach(([key, val]) => (params[key] = val)); -}; - -const CONFORM = async ({ params }) => { - params.domain = true; - params.destination = formatDestination(params.destination); - params.name = path.basename(params.destination); -}; - -// Register default hooks -Reactium.Hook.register( - 'arcli-domain-input', - INPUT, - Reactium.Enums.priority.highest, - 'arcli-domain-input', -); - -Reactium.Hook.register( - 'arcli-domain-confirm', - CONFIRM, - Reactium.Enums.priority.highest, - 'arcli-domain-confirm', -); - -Reactium.Hook.register( - 'arcli-domain-conform', - CONFORM, - Reactium.Enums.priority.highest, - 'arcli-domain-conform', -); - -Reactium.Hook.register( - 'arcli-domain-preflight', - PREFLIGHT, - Reactium.Enums.priority.highest, - 'arcli-domain-preflight', -); - -Reactium.Hook.register( - 'arcli-domain-actions', - ({ actions }) => (actions['component'] = componentGen), - Reactium.Enums.priority.highest, - 'arcli-domain-actions', -); diff --git a/.core/.cli/commands/reactium/hook/index.js b/.core/.cli/commands/reactium/hook/index.js deleted file mode 100644 index ed5c8529..00000000 --- a/.core/.cli/commands/reactium/hook/index.js +++ /dev/null @@ -1,139 +0,0 @@ -import Reactium from '@atomic-reactor/reactium-sdk-core'; - -const { ActionSequence, ora, path } = arcli; - -const ENUMS = { - CANCELED: 'hook canceled!', - DESC: 'Reactium: Create or replace a component hooks file', - FLAGS: { - destination: { - flag: '-d, --destination [destination]', - desc: 'Directory to save the file', - }, - unattended: { - flag: '-u, --unattended [unattended]', - desc: 'Bypass the preflight confirmation and any input prompts', - }, - }, - NAME: 'hook', -}; - -// prettier-ignore -const HELP = () => console.log(` -Example: - $ arcli hook -h -`); - -const ACTION = async ({ opt, props }) => { - // load hooks - for (const file of arcli.globby( - [ - './.core/**/reactium-arcli.js', - './src/**/reactium-arcli.js', - './reactium_modules/**/reactium-arcli.js', - './node_modules/**/reactium-arcli.js', - ], - { - dot: true, - }, - )) { - await import(path.resolve(file)); - } - - let params = arcli.flagsToParams({ opt, flags: Object.keys(ENUMS.FLAGS) }); - - await Reactium.Hook.run('arcli-hook-init', { - ...props, - params, - ENUMS, - }); - - await Reactium.Hook.run('arcli-hook-enums', { - ...props, - params, - ENUMS, - }); - - if (params.unattended !== true) { - await Reactium.Hook.run('arcli-hook-input', { - ...props, - params, - ENUMS, - }); - } - - await Reactium.Hook.run('arcli-hook-conform', { - ...props, - params, - ENUMS, - }); - - if (params.unattended !== true) { - await Reactium.Hook.run('arcli-hook-preflight', { - ...props, - params, - }); - - await Reactium.Hook.run('arcli-hook-confirm', { - ...props, - params, - ENUMS, - }); - - if (params.confirm !== true) { - arcli.message(ENUMS.CANCELED); - return; - } - } - - console.log(''); - - // Start the spinner - - const spinner = ora({ spinner: 'dots', color: 'cyan' }); - spinner.start(); - - let actions = {}; - await Reactium.Hook.run('arcli-hook-actions', { - ...props, - params, - actions, - spinner, - ENUMS, - }); - - return ActionSequence({ - actions, - options: { params, props, spinner }, - }) - .then(success => { - spinner.succeed('complete!'); - console.log(''); - return success; - }) - .catch(error => { - spinner.fail('error!'); - console.error(error); - return error; - }); -}; - -export const COMMAND = ({ program, props }) => { - program - .command(ENUMS.NAME) - .description(ENUMS.DESC) - .on('--help', HELP) - .action(opt => ACTION({ opt, props, program })); - - program.commands - .filter(cmd => Boolean(cmd._name === ENUMS.NAME)) - .forEach(cmd => - Object.values(ENUMS.FLAGS).forEach(({ flag, desc }) => - cmd.option(flag, desc), - ), - ); - - return program; -}; - -export const NAME = ENUMS.NAME; diff --git a/.core/.cli/commands/reactium/hook/package.json b/.core/.cli/commands/reactium/hook/package.json deleted file mode 100644 index 6dc5c9ca..00000000 --- a/.core/.cli/commands/reactium/hook/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "reactium-hook-cmd", - "type": "module" -} \ No newline at end of file diff --git a/.core/.cli/commands/reactium/hook/reactium-arcli.js b/.core/.cli/commands/reactium/hook/reactium-arcli.js deleted file mode 100644 index 19c0fb89..00000000 --- a/.core/.cli/commands/reactium/hook/reactium-arcli.js +++ /dev/null @@ -1,77 +0,0 @@ -import componentGen from '../component/componentGen.cjs'; -import formatDestination from '../component/formatDestination.cjs'; -import selectDestination from '../component/selectDestination.cjs'; - -const { _, chalk, path, prefix, Reactium } = arcli; - -const suffix = chalk.magenta(': '); - -const PREFLIGHT = ({ msg, params }) => { - arcli.message(msg || 'Preflight checklist:'); - console.log(JSON.stringify(params, null, 2)); - console.log(''); -}; - -const INPUT = async ({ inquirer, params }) => { - const input = await inquirer.prompt([selectDestination()], params); - Object.entries(input).forEach(([key, val]) => (params[key] = val)); -}; - -const CONFIRM = async ({ inquirer, params }) => { - if (params.unattended) return; - - const input = await inquirer.prompt([ - { - prefix, - suffix, - default: false, - type: 'confirm', - name: 'confirm', - message: 'Proceed?', - }, - ]); - - Object.entries(input).forEach(([key, val]) => (params[key] = val)); -}; - -const CONFORM = async ({ params }) => { - params.hooks = true; - params.name = path.basename(params.destination); - params.destination = formatDestination(params.destination); -}; - -// Register default hooks -Reactium.Hook.register( - 'arcli-hook-input', - INPUT, - Reactium.Enums.priority.highest, - 'arcli-hook-input', -); - -Reactium.Hook.register( - 'arcli-hook-confirm', - CONFIRM, - Reactium.Enums.priority.highest, - 'arcli-hook-confirm', -); - -Reactium.Hook.register( - 'arcli-hook-conform', - CONFORM, - Reactium.Enums.priority.highest, - 'arcli-hook-conform', -); - -Reactium.Hook.register( - 'arcli-hook-preflight', - PREFLIGHT, - Reactium.Enums.priority.highest, - 'arcli-hook-preflight', -); - -Reactium.Hook.register( - 'arcli-hook-actions', - ({ actions }) => (actions['component'] = componentGen), - Reactium.Enums.priority.highest, - 'arcli-hook-actions', -); diff --git a/.core/.cli/commands/reactium/icons/actions.js b/.core/.cli/commands/reactium/icons/actions.js deleted file mode 100644 index d2c1b661..00000000 --- a/.core/.cli/commands/reactium/icons/actions.js +++ /dev/null @@ -1,95 +0,0 @@ -import chalk from 'chalk'; -import fs from 'fs-extra'; -import hb from 'handlebars'; -import cc from 'camelcase'; -import op from 'object-path'; -import path from 'node:path'; -import { dirname } from '@atomic-reactor/dirname'; - -const __dirname = dirname(import.meta.url); - -const handlebars = hb.compile; - -export default spinner => { - const message = text => { - if (spinner) { - spinner.text = text; - } - }; - - let svgs = {}; - - return { - scan: async ({ action, params }) => { - const { source } = params; - - message( - `Scanning icon file ${chalk.cyan(path.basename(source))}...`, - ); - - const filePath = path.normalize(source); - const { icons } = await import(filePath); - - svgs = icons.reduce((obj, item) => { - const id = cc(op.get(item, 'properties.name'), { - pascalCase: true, - }); - obj[id] = { paths: op.get(item, 'icon.paths'), id }; - - return obj; - }, {}); - - return Promise.resolve({ action, status: 200 }); - }, - - create: ({ action, params }) => { - const { destination, name } = params; - const dir = path.normalize(path.join(destination, 'svg')); - - message(`Creating ${chalk.cyan('icons')}...`); - - // Template content - const template = path.normalize(`${__dirname}/template/svg.hbs`); - - Object.values(svgs).forEach(({ id, paths }) => { - const content = handlebars(fs.readFileSync(template, 'utf8'))({ - name, - paths, - id, - }); - - const filepath = path.join(dir, `${id}.js`); - - fs.ensureFileSync(filepath); - fs.writeFileSync(filepath, content); - }); - - return Promise.resolve({ action, status: 200 }); - }, - - index: ({ action, params }) => { - const { destination, name } = params; - const dir = path.normalize(path.join(destination, name)); - - message(`Indexing ${chalk.cyan(name)}...`); - - // Template content - const template = path.normalize(`${__dirname}/template/index.hbs`); - - const icons = Object.keys(svgs).map(name => { - return { id: name, path: `./svgs/${name}` }; - }); - - const content = handlebars(fs.readFileSync(template, 'utf8'))({ - icons, - }); - - const filepath = path.normalize(path.join(dir, 'index.js')); - - fs.ensureFileSync(filepath); - fs.writeFileSync(filepath, content); - - return Promise.resolve({ action, status: 200 }); - }, - }; -}; diff --git a/.core/.cli/commands/reactium/icons/generator.js b/.core/.cli/commands/reactium/icons/generator.js deleted file mode 100644 index c23d977b..00000000 --- a/.core/.cli/commands/reactium/icons/generator.js +++ /dev/null @@ -1,27 +0,0 @@ -import ora from 'ora'; -import ACTIONS from './actions.js'; -import ActionSequence from 'action-sequence'; - -export default async ({ params, props }) => { - const spinner = ora({ - spinner: 'dots', - color: 'cyan', - }); - - spinner.start(); - - const actions = ACTIONS(spinner); - - return ActionSequence({ - actions, - options: { params, props }, - }) - .then(success => { - spinner.succeed('complete!'); - return success; - }) - .catch(error => { - spinner.fail('error!'); - return error; - }); -}; diff --git a/.core/.cli/commands/reactium/icons/index.js b/.core/.cli/commands/reactium/icons/index.js deleted file mode 100644 index aebff781..00000000 --- a/.core/.cli/commands/reactium/icons/index.js +++ /dev/null @@ -1,235 +0,0 @@ -/** - * ----------------------------------------------------------------------------- - * Imports - * ----------------------------------------------------------------------------- - */ - -import generator from './generator.js'; -import { fileURLToPath } from 'node:url'; - -const { _, fs, chalk, op, camelcase, message, path, prettier } = arcli; - -const __dirname = path.dirname(fileURLToPath(import.meta.url)); - -const pkg = JSON.parse( - fs.readFileSync(path.normalize(`${__dirname}/package.json`)), -); - -const formatDestination = (val, props) => { - const { cwd } = props; - - val = path.normalize(val); - - val = String(val).replace(/^\/cwd\/|^cwd\/|^cwd$/i, `${cwd}/`); - val = String(val).replace( - /^\/icon|^\/icon\/|^icon\/|^icon$/i, - `${cwd}/src/app/components/common-ui/Icon/`, - ); - val = String(val).replace( - /^\/components\/|^components\/|^components$/i, - `${cwd}/src/app/components/`, - ); - val = String(val).replace( - /^\/common-ui\/|^common-ui\/|^common-ui$/i, - `${cwd}/src/app/components/common-ui/`, - ); - - return path.normalize(val); -}; - -const NAME = 'icons'; - -const DESC = pkg.description; - -const CANCELED = 'Action canceled!'; - -const CONFORM = ({ input, props }) => - Object.keys(input).reduce((obj, key) => { - let val = input[key]; - switch (key) { - case 'destination': - val = path.join( - val, - camelcase(input.name, { pascalCase: true }), - ); - obj[key] = formatDestination(val, props); - break; - - case 'source': - obj[key] = formatDestination(val, props); - break; - - default: - obj[key] = val; - break; - } - - return obj; - }, {}); - -const CONFIRM = ({ props, params, msg }) => { - const { prompt } = props; - - msg = msg || chalk.white('Proceed?'); - - return new Promise((resolve, reject) => { - prompt.get( - { - properties: { - confirmed: { - description: `${msg} ${chalk.cyan('(Y/N):')}`, - type: 'string', - required: true, - pattern: /^y|n|Y|N/, - message: ' ', - before: val => { - return String(val).toLowerCase() === 'y'; - }, - }, - }, - }, - (error, input = {}) => { - const confirmed = op.get(input, 'confirmed', false); - if (error || confirmed === false) { - console.log(''); - reject(error); - } else { - params['confirmed'] = true; - console.log(''); - resolve(params); - } - }, - ); - }); -}; - -const HELP = props => - console.log(` -Example: - $ arcli icon-import -d common-ui/Icon/icons.js - -When specifying the [${chalk.cyan('-d')}, ${chalk.cyan( - '--destination', - )}] or [${chalk.cyan('-s')}, ${chalk.cyan( - '--source', - )}] value you can use the following short cuts: - ${chalk.cyan('components')} ${chalk.magenta('→')} ${chalk.cyan( - path.normalize(props.cwd + '/src/app/components'), - )} directory. - ${chalk.cyan('common-ui ')} ${chalk.magenta('→')} ${chalk.cyan( - path.normalize(props.cwd + '/src/app/components/common-ui'), - )} directory. - ${chalk.cyan('icon ')} ${chalk.magenta('→')} ${chalk.cyan( - path.normalize(props.cwd + '/src/app/components/common-ui/Icon'), - )} directory. - ${chalk.cyan('cwd ')} ${chalk.magenta('→')} ${chalk.cyan( - path.normalize(props.cwd), - )} directory. -`); - -const FLAGS = ['destination', 'name', 'source']; - -const FLAGS_TO_PARAMS = ({ opt = {} }) => - FLAGS.reduce((obj, key) => { - let val = opt[key]; - val = typeof val === 'function' ? undefined : val; - - if (val) { - obj[key] = val; - } - - return obj; - }, {}); - -const PREFLIGHT = ({ params }) => { - const msg = - 'A new icon package will be create witht the following options:'; - const preflight = _.pick(params, ...Object.keys(params).sort()); - - message(msg); - - console.log( - prettier.format(JSON.stringify(preflight), { - parser: 'json-stringify', - }), - ); -}; - -const SCHEMA = () => { - return { - properties: { - name: { - required: true, - message: ' Name is required', - description: chalk.white('Name:'), - }, - destination: { - required: true, - message: ' Destination is required', - description: chalk.white('Destination:'), - default: '/icon', - }, - source: { - required: true, - message: ' Source is required', - description: chalk.white('Source:'), - }, - }, - }; -}; - -const ACTION = ({ opt, props }) => { - let params; - const { prompt } = props; - const schema = SCHEMA({ props }); - const ovr = FLAGS_TO_PARAMS({ opt }); - - prompt.override = ovr; - prompt.start(); - - return new Promise((resolve, reject) => { - prompt.get(schema, (err, input = {}) => { - if (err) { - prompt.stop(); - reject(`${NAME} ${err.message}`); - return; - } - - input = { ...ovr, ...input }; - params = CONFORM({ input, props }); - - PREFLIGHT({ params, props }); - - resolve(params); - }); - }) - .then(params => CONFIRM({ props, params })) - .then(async () => { - console.log(''); - await generator({ params, props }); - console.log(''); - }) - .then(() => prompt.stop()) - .catch(err => { - prompt.stop(); - message(op.get(err, 'message', CANCELED)); - }); -}; - -const COMMAND = ({ program, props }) => - program - .command(NAME) - .description(DESC) - .action(opt => ACTION({ opt, props })) - .option( - '-d, --destination [destination]', - 'Destination. Example: /common-ui/Icon', - ) - .option( - '-s, --source [source]', - 'Source File. Example: /cwd/icons.json', - ) - .option('-n, --name [name]', 'Name of the icon package.') - .on('--help', () => HELP(props)); - -export { COMMAND, NAME }; diff --git a/.core/.cli/commands/reactium/icons/package.json b/.core/.cli/commands/reactium/icons/package.json deleted file mode 100644 index 54b7d018..00000000 --- a/.core/.cli/commands/reactium/icons/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "module", - "name": "icon-generator", - "version": "0.0.1", - "description": "Reactium: Import icons from an Icomoon selection file.", - "main": "index.js", - "author": "Reactium LLC", - "license": "MIT" -} diff --git a/.core/.cli/commands/reactium/icons/template/index.hbs b/.core/.cli/commands/reactium/icons/template/index.hbs deleted file mode 100644 index a42747c6..00000000 --- a/.core/.cli/commands/reactium/icons/template/index.hbs +++ /dev/null @@ -1,20 +0,0 @@ - -// THIS FILE IS GENERATED BY THE `$ arcli icons` command -// DO NOT DIRECTLY EDIT !!!!!!!!!!!!!!!! - -{{#each icons}} -import {{id}} from '{{path}}'; -{{/each}} - -const icons = { -{{#each icons}} - {{id}}, -{{/each}} -}; - -export { - icons as default, - {{#each icons}} - {{id}}, - {{/each}} -}; diff --git a/.core/.cli/commands/reactium/icons/template/svg.hbs b/.core/.cli/commands/reactium/icons/template/svg.hbs deleted file mode 100644 index 1375172d..00000000 --- a/.core/.cli/commands/reactium/icons/template/svg.hbs +++ /dev/null @@ -1,14 +0,0 @@ -// Icon: {{name}}.{{id}} - -import React from 'react'; -import defaultProps from 'components/common-ui/Icon/defaultProps'; - -export default props => ( - - - {{#each paths}} - - {{/each}} - - -); diff --git a/.core/.cli/commands/reactium/library/actions.js b/.core/.cli/commands/reactium/library/actions.js deleted file mode 100644 index 8373bdd9..00000000 --- a/.core/.cli/commands/reactium/library/actions.js +++ /dev/null @@ -1,98 +0,0 @@ -const path = require('path'); -const chalk = require('chalk'); -const fs = require('fs-extra'); -const _ = require('underscore'); -const run = require('@atomic-reactor/gulp-run'); -const globby = require('globby'); -const op = require('object-path'); -const prettier = require('prettier'); -const del = require('del'); - -module.exports = spinner => { - const message = text => { - if (spinner) { - spinner.text = text; - } - }; - - return { - no_node_modules: async ({ action, params, props }) => { - const { source } = params; - - if (!fs.existsSync(path.resolve(source, 'node_modules'))) return; - - message(`Removing node_modules from source directory...`); - - return del(path.resolve(source, 'node_modules')); - }, - - clean: async ({ action, params, props }) => { - const { destination } = params; - - message( - `Cleanup destination directory ${chalk.cyan(destination)}...`, - ); - - return del(destination); - }, - buildPackage: ({ action, params, props }) => { - const { destination, newPackage, source } = params; - - const fpath = path.join(source, 'package.json'); - const dpath = path.join(destination, 'package.json'); - - let pkg; - - try { - message(`Updating ${chalk.cyan('package.json')}...`); - pkg = require(fpath); - } catch (err) { - message(`Creating ${chalk.cyan('package.json')}...`); - pkg = {}; - } - - pkg = { ...pkg, ...newPackage }; - - const content = prettier.format(JSON.stringify(pkg), { - parser: 'json-stringify', - }); - - fs.writeFileSync(fpath, content); - fs.ensureDirSync(destination); - fs.copySync(fpath, dpath); - }, - assets: ({ action, params, props }) => { - const { destination, source } = params; - const globs = [path.join(source, '**'), '!{*.js}']; - - const files = globby - .sync(globs) - .filter(file => - Boolean( - file.substr(-3) !== '.js' && file.substr(-3) !== 'jsx', - ), - ); - - files.forEach(file => { - let src = path.join(source, '/'); - const dpath = file.replace(src, destination); - fs.ensureFileSync(dpath); - fs.copySync(file, dpath); - }); - }, - create: async ({ action, params, props }) => { - const { source, destination, verbosity = 0 } = params; - - message( - `Creating library from ${chalk.cyan(path.basename(source))}...`, - ); - - const babel = new run.Command( - `cross-env NODE_ENV=library babel "${source}" --out-dir "${destination}"`, - { verbosity }, - ); - - return new Promise(resolve => babel.exec(null, () => resolve())); - }, - }; -}; diff --git a/.core/.cli/commands/reactium/library/generator.js b/.core/.cli/commands/reactium/library/generator.js deleted file mode 100644 index 1abcc105..00000000 --- a/.core/.cli/commands/reactium/library/generator.js +++ /dev/null @@ -1,26 +0,0 @@ -const ora = require('ora'); -const ActionSequence = require('action-sequence'); - -module.exports = ({ action, params, props }) => { - const spinner = ora({ - spinner: 'dots', - color: 'cyan', - }); - - spinner.start(); - - const actions = require('./actions')(spinner); - - return ActionSequence({ - actions, - options: { params, props }, - }) - .then(success => { - spinner.succeed('complete!'); - return success; - }) - .catch(error => { - spinner.fail('error!'); - return error; - }); -}; diff --git a/.core/.cli/commands/reactium/library/index.js b/.core/.cli/commands/reactium/library/index.js deleted file mode 100644 index de2ad90a..00000000 --- a/.core/.cli/commands/reactium/library/index.js +++ /dev/null @@ -1,506 +0,0 @@ -/** - * ----------------------------------------------------------------------------- - * Imports - * ----------------------------------------------------------------------------- - */ - -const chalk = require('chalk'); -const generator = require('./generator'); -const prettier = require('prettier'); -const path = require('path'); -const op = require('object-path'); -const { error, message } = arcli; -const _ = require('underscore'); - -const formatsource = (val, props) => { - const { cwd } = props; - - val = path.normalize(val); - val = String(val).replace( - /^\/components\/|^components\/|^components$/i, - `${cwd}/src/app/components/`, - ); - val = String(val).replace( - /^\/common-ui\/|^common-ui\/|^common-ui$/i, - `${cwd}/src/app/components/common-ui/`, - ); - val = String(val).replace(/^\/cwd\/|^cwd\/|^cwd/i, `${cwd}/`); - val = val.substr(-1) !== '/' ? val + '/' : val; - - return path.normalize(val); -}; - -/** - * NAME String - * @description Constant defined as the command name. Value passed to the commander.command() function. - * @example $ arcli library - * @see https://www.npmjs.com/package/commander#command-specific-options - * @since 2.0.0 - */ -const NAME = 'library'; - -/** - * DESC String - * @description Constant defined as the command description. Value passed to - * the commander.desc() function. This string is also used in the --help flag output. - * @see https://www.npmjs.com/package/commander#automated---help - * @since 2.0.0 - */ -const DESC = - 'Reactium: Generate a component library from the specified source directory.'; - -/** - * CANCELED String - * @description Message sent when the command is canceled - * @since 2.0.0 - */ -const CANCELED = 'Action canceled!'; - -/** - * confirm({ props:Object, params:Object }) Function - * @description Prompts the user to confirm the operation - * @since 2.0.0 - */ -const CONFIRM = ({ props, params, msg }) => { - const { prompt } = props; - - msg = msg || chalk.white('Proceed?'); - - return new Promise((resolve, reject) => { - prompt.get( - { - properties: { - confirmed: { - description: `${msg} ${chalk.cyan('(Y/N):')}`, - type: 'string', - required: true, - pattern: /^y|n|Y|N/, - message: ` `, - before: val => { - return String(val).toUpperCase() === 'Y'; - }, - }, - }, - }, - (error, input = {}) => { - const confirmed = op.get(input, 'confirmed', false); - if (error || confirmed === false) { - reject(error); - } else { - resolve(params); - } - }, - ); - }); -}; - -/** - * conform(input:Object) Function - * @description Reduces the input object. - * @param input Object The key value pairs to reduce. - * @since 2.0.0 - */ -const CONFORM = ({ input, props }) => { - const packageJSON = require(`${props.cwd}/package.json`); - - return Object.keys(input).reduce((output, key) => { - let val = input[key]; - const pkg = op.get(output, 'newPackage', {}); - - switch (key) { - case 'verbosity': - output[key] = Math.max(Math.min(parseInt(val), 3), 0) || 0; - break; - case 'destination': - case 'source': - output[key] = formatsource(val, props); - break; - - case 'name': - case 'version': - case 'main': - case 'author': - if (val != '') { - pkg[key] = val; - output['newPackage'] = pkg; - } - break; - - case 'dependencies': - case 'devDependencies': - if (typeof val === 'string') { - val = val.replace(/\,/g, ''); - val = val.replace(/\s\s+/g, ' ').trim(); - val = _.compact(val.split(' ')); - } - - if (Array.isArray(val)) { - if (val.length > 0) { - const deplist = { - ...packageJSON.dependencies, - ...packageJSON.devDependencies, - }; - pkg[key] = val.reduce((obj, dep) => { - const v = op.get(deplist, dep); - if (v) { - obj[dep] = v; - } - return obj; - }, {}); - - output['newPackage'] = pkg; - } - } - - break; - - case 'repo': - op.set(pkg, 'repository.url', val); - output['newPackage'] = pkg; - break; - - case 'repoType': - op.set(pkg, 'repository.type', val); - output['newPackage'] = pkg; - break; - - case 'keywords': - if (typeof val === 'string') { - val = val.replace(/\,/g, ''); - val = val.replace(/\s\s+/g, ' ').trim(); - val = _.compact(val.split(' ')); - } - - if (Array.isArray(val)) { - if (val.length > 0) { - pkg[key] = val; - output['newPackage'] = pkg; - } - } - - break; - - default: - output[key] = val; - break; - } - - return output; - }, {}); -}; - -/** - * HELP Function - * @description Function called in the commander.on('--help', callback) callback. - * @see https://www.npmjs.com/package/commander#automated---help - * @since 2.0.0 - */ -const HELP = () => - console.log(` - Example: - $ arcli library -s components/MyComponentLibrary -d cwd/lib -n MyComponentLibrary - - When specifying the source [-d, --source] the following shortcuts are available: - ${chalk.cyan('components/')} The /.src/app/components source. - ${chalk.cyan('common-ui/')} The /.src/app/components/common-ui source. - `); - -/** - * FLAGS - * @description Array of flags passed from the commander options. - * @since 2.0.18 - */ -const FLAGS = [ - 'name', - 'source', - 'destination', - 'version', - 'verbosity', - 'main', - 'author', - 'dependencies', - 'devDependencies', - 'keywords', - 'repo', - 'repoType', -]; - -/** - * FLAGS_TO_PARAMS Function - * @description Create an object used by the prompt.override property. - * @since 2.0.18 - */ -const FLAGS_TO_PARAMS = ({ opt = {} }) => - FLAGS.reduce((obj, key) => { - let val = opt[key]; - val = typeof val === 'function' ? undefined : val; - - if (val) { - obj[key] = val; - } - - return obj; - }, {}); - -/** - * PREFLIGHT Function - */ -const PREFLIGHT = ({ msg, params, props }) => { - msg = - msg || - `A new ${chalk.cyan( - 'library', - )} will be generated with the following options:`; - - message(msg); - - // Transform the preflight object instead of the params object - const preflight = { ...params }; - - console.log( - prettier.format(JSON.stringify(preflight), { - parser: 'json-stringify', - }), - ); -}; - -const SCHEMA_SOURCE = ({ params, props }) => { - const name = op.get(params, 'package.name', ''); - - return { - properties: { - source: { - description: chalk.white('Source:'), - message: `Enter the ${chalk.cyan('Source directory')}`, - required: true, - }, - destination: { - description: chalk.white('Destination:'), - default: path.join('cwd', 'lib', name), - }, - verbosity: { - description: chalk.white('Verbosity [0-3] (0):'), - default: 0, - required: false, - }, - }, - }; -}; - -const SCHEMA_NAME = ({ params, props }) => { - let pkg; - let p = path.join(params.source, 'package.json'); - - try { - pkg = require(p); - } catch (err) { - pkg = {}; - } - - const schema = { - properties: { - name: { - description: chalk.white('Name:'), - message: `Enter the ${chalk.cyan('Library name')}`, - default: op.get(pkg, 'name'), - required: true, - }, - }, - }; - - if (op.has(pkg, 'name')) { - op.set(schema, 'properties.name.default', pkg.name); - } - - return schema; -}; - -/** - * SCHEMA Function - * @description used to describe the input for the prompt function. - * @see https://www.npmjs.com/package/prompt - * @since 2.0.0 - */ -const SCHEMA = ({ params, props }) => { - let pkg; - - try { - pkg = require(`${params.source}/package.json`); - } catch (err) { - pkg = {}; - } - - const { prompt } = props; - - const schema = { - properties: { - version: { - description: chalk.white('Version:'), - default: op.get(pkg, 'version', '0.0.1'), - }, - main: { - description: chalk.white('Main js file:'), - default: op.get(pkg, 'main', 'index.js'), - }, - author: { - description: chalk.white('NPM Package Author:'), - default: op.get(pkg, 'author', undefined), - }, - dependencies: { - description: chalk.white('NPM Dependencies:'), - default: op.has(pkg, 'dependencies') - ? Object.keys(pkg.dependencies).join(', ') - : undefined, - }, - devDependencies: { - description: chalk.white('NPM Dev. Dependencies:'), - default: op.has(pkg, 'devDependencies') - ? Object.keys(pkg.devDependencies).join(', ') - : undefined, - }, - repo: { - description: chalk.white('Repository:'), - default: op.get(pkg, 'repository.url', undefined), - }, - repoType: { - description: chalk.white('Repository Type:'), - default: op.get(pkg, 'repository.type', 'git'), - ask: () => !!prompt.history('repo'), - }, - keywords: { - description: chalk.white('NPM Keywords:'), - default: op.has(pkg, 'keywords') - ? pkg.keywords.join(', ') - : undefined, - }, - }, - }; - - return schema; -}; - -/** - * ACTION Function - * @description Function used as the commander.action() callback. - * @see https://www.npmjs.com/package/commander - * @param opt Object The commander options passed into the function. - * @param props Object The CLI props passed from the calling class `orcli.js`. - * @since 2.0.0 - */ -const ACTION = ({ opt, props }) => { - const { cwd, prompt } = props; - const ovr = FLAGS_TO_PARAMS({ opt }); - - prompt.override = ovr; - prompt.start(); - - let params = CONFORM({ input: ovr, props }); - - return new Promise((resolve, reject) => { - prompt.get(SCHEMA_NAME({ params, props }), (err, input = {}) => { - if (err) { - prompt.stop(); - reject(`${NAME} ${err.message} 386`); - return; - } - - input = { ...ovr, ...input }; - params = CONFORM({ input, props }); - - resolve(params); - }); - }) - .then( - () => - new Promise((resolve, reject) => { - prompt.get( - SCHEMA_SOURCE({ params, props }), - (err, input = {}) => { - if (err) { - prompt.stop(); - reject(`${NAME} ${err.message}`); - return; - } - - input = { ...ovr, ...params, ...input }; - params = CONFORM({ input, props }); - - resolve(params); - }, - ); - }), - ) - .then( - () => - new Promise((resolve, reject) => { - prompt.get(SCHEMA({ params, props }), (err, input = {}) => { - if (err) { - prompt.stop(); - reject(`${NAME} ${err.message}`); - return; - } - - input = { ...ovr, ...params, ...input }; - params = CONFORM({ input, props }); - - PREFLIGHT({ params, props }); - - resolve(params); - }); - }), - ) - .then(() => { - return CONFIRM({ props, params }); - }) - .then(async () => { - console.log(''); - await generator({ params, props }); - console.log(''); - }) - .then(() => prompt.stop()) - .catch(err => { - prompt.stop(); - message(op.get(err, 'message', CANCELED)); - }); -}; - -/** - * COMMAND Function - * @description Function that executes program.command() - */ -const COMMAND = ({ program, props }) => - program - .command(NAME) - .description(DESC) - .action(opt => ACTION({ opt, props })) - .option('-n, --name [name]', 'Library name.') - .option('-s, --source [source]', 'The library source.') - .option('-d, --destination [destination]', 'The library destination.') - .option('-V, --ver [version]', 'The version of the library.') - .option( - '-T, --verbosity [verbosity]', - 'The 0-3 verbosity of output. Default 0.', - ) - .option('-m, --main [main]', 'The library entry point or main js file.') - .option('-a, --author [author]', 'The library author.') - .option('--dependencies [dependencies]', 'The library dependencies.') - .option( - '--devDependencies [devDependencies]', - 'The library devDependencies', - ) - .option('--repo [repo]', 'The repo url.') - .option('--repoType [repoType]', 'The repo type.') - .option('--keywords [keywords]', 'The NPM keywords.') - .on('--help', HELP); - -/** - * Module Constructor - * @description Internal constructor of the module that is being exported. - * @param program Class Commander.program reference. - * @param props Object The CLI props passed from the calling class `arcli.js`. - * @since 2.0.0 - */ -module.exports = { - COMMAND, - NAME, -}; diff --git a/.core/.cli/commands/reactium/plugin/eject/actions.js b/.core/.cli/commands/reactium/plugin/eject/actions.js deleted file mode 100644 index 488a0a93..00000000 --- a/.core/.cli/commands/reactium/plugin/eject/actions.js +++ /dev/null @@ -1,87 +0,0 @@ -const path = require('path'); -const chalk = require('chalk'); -const fs = require('fs-extra'); -const _ = require('underscore'); -const op = require('object-path'); -const globby = require('globby').sync; -const { spawn } = require('child_process'); -const labelGenerator = require('@atomic-reactor/cli/commands/config/set/generator'); - -const command = (cmd, args = [], done) => { - const ps = spawn(cmd, args, { - env: { - PATH: process.env.PATH, - NODE_ENV: 'production', - }, - }); - - ps.stdout.pipe(process.stdout, { end: false }); - ps.stderr.pipe(process.stderr, { end: false }); - process.stdin.resume(); - process.stdin.pipe(ps.stdin, { end: false }); - ps.on('close', code => { - if (code !== 0) console.log(`Error executing ${cmd}`); - done(); - }); -}; - -module.exports = spinner => { - const message = text => { - if (spinner) { - spinner.text = text; - } - }; - - return { - build: async ({ action, params, props }) => { - const { offerBuild } = params; - - if (offerBuild) { - message(`Building ${chalk.cyan('Reactium manifest')}...`); - await new Promise((resolve, reject) => { - command('gulp', ['manifest'], resolve); - }); - - message(`Building ${chalk.cyan('Reactium umd libraries')}...`); - await new Promise((resolve, reject) => { - command('gulp', ['umdLibraries'], resolve); - }); - message(`Building ${chalk.cyan('Reactium styles')}...`); - await new Promise((resolve, reject) => { - command('gulp', ['styles'], resolve); - }); - } - }, - ejectAssets: async ({ action, params, props }) => { - const { plugin, targetPath } = params; - const { cwd } = props; - - const assets = globby([ - `${cwd}/public/assets/js/umd/${plugin}/${plugin}.js`, - `${cwd}/public/assets/style/${plugin}-plugin.css`, - ]); - - if (assets.length < 1) throw 'No assets to eject.'; - const assetsDir = path.resolve(targetPath, 'plugin-assets'); - message(`Copying ${chalk.cyan(`${plugin} assets`)}...`); - - fs.ensureDirSync(assetsDir); - for (let asset of assets) { - message(`Copying ${chalk.cyan(`${path.basename(asset)}`)}...`); - fs.copySync( - asset, - path.resolve(assetsDir, path.basename(asset)), - ); - } - }, - - addLabel: async ({ action, params, props }) => { - const { plugin, targetPath, targetLabel, newConfig } = params; - const { cwd } = props; - - if (targetLabel && newConfig) { - await labelGenerator({ params, props }); - } - }, - }; -}; diff --git a/.core/.cli/commands/reactium/plugin/eject/generator.js b/.core/.cli/commands/reactium/plugin/eject/generator.js deleted file mode 100644 index 1bbad523..00000000 --- a/.core/.cli/commands/reactium/plugin/eject/generator.js +++ /dev/null @@ -1,29 +0,0 @@ -const ora = require('ora'); -const ActionSequence = require('action-sequence'); - -module.exports = ({ params, props }) => { - console.log(''); - const spinner = ora({ - spinner: 'dots', - color: 'cyan', - }); - - spinner.start(); - - const actions = require('./actions')(spinner); - - return ActionSequence({ - actions, - options: { params, props }, - }) - .then(success => { - spinner.succeed('complete!'); - console.log(''); - return success; - }) - .catch(error => { - spinner.fail('error!'); - console.log(error); - return error; - }); -}; diff --git a/.core/.cli/commands/reactium/plugin/eject/index.js b/.core/.cli/commands/reactium/plugin/eject/index.js deleted file mode 100644 index c0e15441..00000000 --- a/.core/.cli/commands/reactium/plugin/eject/index.js +++ /dev/null @@ -1,424 +0,0 @@ -/** - * ----------------------------------------------------------------------------- - * Imports - * ----------------------------------------------------------------------------- - */ - -const chalk = require('chalk'); -const prettier = require('prettier'); -const path = require('path'); -const op = require('object-path'); -const { error, message } = arcli; -const GENERATOR = require('./generator'); -const globby = require('globby').sync; -const fs = require('fs-extra'); -const slugify = require('slugify'); - -/** - * NAME String - * @description Constant defined as the command name. Value passed to the commander.command() function. - * @example $ arcli eject - * @see https://www.npmjs.com/package/commander#command-specific-options - * @since 2.0.0 - */ -const NAME = 'plugin '; - -/** - * DESC String - * @description Constant defined as the command description. Value passed to - * the commander.desc() function. This string is also used in the --help flag output. - * @see https://www.npmjs.com/package/commander#automated---help - * @since 2.0.0 - */ -const DESC = - 'Compile a runtime plugin to a UMD asset and eject the asset into a publishing directory.'; - -/** - * CANCELED String - * @description Message sent when the command is canceled - * @since 2.0.0 - */ -const CANCELED = 'Action canceled!'; - -/** - * confirm({ props:Object, params:Object }) Function - * @description Prompts the user to confirm the operation - * @since 2.0.0 - */ -const CONFIRM = ({ props, params, msg }) => { - const { prompt } = props; - - msg = msg || chalk.white('Proceed?'); - - return new Promise((resolve, reject) => { - prompt.get( - { - properties: { - confirmed: { - description: `${msg} ${chalk.cyan('(Y/N):')}`, - type: 'string', - required: true, - pattern: /^y|n|Y|N/, - message: ' ', - before: val => { - return String(val).toUpperCase() === 'Y'; - }, - }, - }, - }, - (error, input = {}) => { - const confirmed = op.get(input, 'confirmed', false); - if (error || confirmed === false) { - reject(error); - } else { - params['confirmed'] = true; - resolve(params); - } - }, - ); - }); -}; - -/** - * conform(input:Object) Function - * @description Reduces the input object. - * @param input Object The key value pairs to reduce. - * @since 2.0.0 - */ -const CONFORM = ({ input, props, params }) => - Object.keys(input).reduce((obj, key) => { - let val = input[key]; - switch (key) { - default: - obj[key] = val; - break; - } - return obj; - }, params); - -/** - * HELP Function - * @description Function called in the commander.on('--help', callback) callback. - * @see https://www.npmjs.com/package/commander#automated---help - * @since 2.0.0 - */ -const HELP = () => - console.log(` -Example: - # Follow the prompts - $ arcli eject -`); - -/** - * PREFLIGHT Function - */ -const PREFLIGHT = ({ msg, params, props }) => { - msg = msg || 'Preflight checklist:'; - - message(msg); - - const { plugin, targetPath, targetLabel, offerBuild, assets } = params; - - console.log(chalk.white('Plugin:'), chalk.cyan(plugin)); - console.log( - chalk.white('Running build:'), - chalk.cyan(offerBuild ? 'Y' : 'N'), - ); - if (assets && assets.length > 0) { - console.log(chalk.white('Copying assets:')); - assets.forEach(asset => console.log(chalk.white(` - ${asset}`))); - } - console.log(chalk.white('Target path:'), chalk.cyan(targetPath)); - if (targetLabel) - console.log( - chalk.white('New target path label:'), - chalk.cyan(targetLabel), - ); -}; - -const descriptionList = (list = []) => { - return ( - list.reduce((description, plugin, index) => { - description += ` ${chalk.cyan(index + 1)}: ${plugin}\n\r`; - return description; - }, '') + '\n\r' - ); -}; - -/** - * SCHEMA Function - * @description used to describe the input for the prompt function. - * @see https://www.npmjs.com/package/prompt - * @since 2.0.0 - */ -const SCHEMA_CHOOSE_PLUGIN = ({ props, plugins }) => { - return { - properties: { - plugin: { - description: - chalk.white('Choose plugin:\n\r') + - descriptionList(plugins), - required: true, - message: - plugins.length > 1 - ? chalk.white(`Select 1 to ${plugins.length}`) - : chalk.white('1 is only option.'), - before: val => op.get(plugins, Number(val) - 1), - conform: val => op.has(plugins, Number(val) - 1), - default: 1, - }, - }, - }; -}; - -/** - * SCHEMA Function - * @description used to describe the input for the prompt function. - * @see https://www.npmjs.com/package/prompt - * @since 2.0.0 - */ -const SCHEMA_CHOOSE_TARGET = ({ props, actiniumPlugins }) => { - const pluginKeys = Object.keys(actiniumPlugins); - - const { cwd, prompt } = props; - const schema = { - properties: { - targetPath: { - description: - pluginKeys.length > 0 - ? chalk.white( - 'Choose target actinium plugin (select from below or type path to target directory):\n\r', - ) + descriptionList(pluginKeys) - : chalk.white('Target actinium plugin directory:'), - required: true, - message: - pluginKeys.length > 1 - ? chalk.white( - `Select 1 to ${pluginKeys.length} or a valid path`, - ) - : chalk.white('Select a valid path'), - before: val => { - const selected = op.has(pluginKeys, Number(val) - 1); - if (selected) - return actiniumPlugins[ - op.get(pluginKeys, Number(val) - 1) - ]; - - const potentialPath = path.resolve(path.relative(cwd, val)); - if (fs.existsSync(potentialPath)) return potentialPath; - }, - conform: val => { - const selected = op.has(pluginKeys, Number(val) - 1); - if (selected) return true; - - const potentialPath = path.resolve(path.relative(cwd, val)); - return fs.existsSync(potentialPath); - }, - }, - offerLabel: { - description: `${chalk.white( - 'This path does not have a label, provide one?', - )} ${chalk.cyan('(Y/N):')}`, - type: 'string', - required: true, - pattern: /^y|n|Y|N/, - message: ' ', - before: val => { - return String(val).toUpperCase() === 'Y'; - }, - ask: () => { - const targetPath = op.get( - prompt.history('targetPath'), - 'value', - ); - - return !Object.values(actiniumPlugins).includes(targetPath); - }, - }, - targetLabel: { - description: chalk.white('Label for target directory:'), - type: 'string', - required: true, - pattern: /^[a-zA-Z_\-0-9]{4,}$/, - message: chalk.white('Invalid label'), - before: val => { - return `actinium-plugins.${slugify(String(val))}`; - }, - ask: () => op.get(prompt.history('offerLabel'), 'value', false), - }, - }, - }; - - if (actiniumPlugins.length > 0) - op.set(schema, 'properties.targetPath.default', 1); - - return schema; -}; - -/** - * ACTION Function - * @description Function used as the commander.action() callback. - * @see https://www.npmjs.com/package/commander - * @param opt Object The commander options passed into the function. - * @param props Object The CLI props passed from the calling class `arcli.js`. - * @since 2.0.0 - */ -const ACTION = ({ opt, props }) => { - const { cwd, prompt, config } = props; - const plugins = globby( - path - .resolve(cwd, 'src/app/components/plugin-src/**/umd.js') - .split(/[\\\/]/g) - .join(path.posix.sep), - ).map(mod => path.basename(path.dirname(mod))); - - prompt.start(); - - let params = {}; - - return new Promise((resolve, reject) => { - if (plugins.length < 1) { - message( - chalk.magenta( - 'No plugins found in src/app/components/plugin-src.', - chalk.white( - `Use ${chalk.cyan( - '`arcli plugin module`', - )} to create one.`, - ), - ), - ); - reject(); - return; - } - - prompt.get( - SCHEMA_CHOOSE_PLUGIN({ props, plugins }), - (err, input = {}) => { - if (err) { - prompt.stop(); - reject(`${NAME} ${err.message}`); - return; - } - - params = CONFORM({ input, props, params }); - - resolve(); - }, - ); - }) - .then(() => { - const actiniumPlugins = op.get(config, 'actinium-plugins', {}); - return new Promise((resolve, reject) => { - prompt.get( - SCHEMA_CHOOSE_TARGET({ - props, - actiniumPlugins, - }), - (err, input = {}) => { - if (err) { - prompt.stop(); - reject(`${NAME} ${err.message}`); - return; - } - - params = CONFORM({ input, props, params }); - if (op.has(params, 'targetLabel')) { - params.newConfig = { ...config }; - op.set( - params.newConfig, - op.get(params, 'targetLabel'), - op.get(params, 'targetPath'), - ); - } - - resolve(); - }, - ); - }); - }) - .then(() => { - const { plugin } = params; - const assets = globby([ - `${cwd}/public/assets/js/umd/${plugin}/${plugin}.js`, - `${cwd}/public/assets/style/${plugin}-plugin.css`, - ]); - - return new Promise((resolve, reject) => { - prompt.get( - { - properties: { - offerBuild: { - description: `${ - assets.length < 1 - ? chalk.white( - `No assets appear for plugin ${params.plugin}. Run build?`, - ) - : chalk.white('Run build?') - } ${chalk.cyan('(Y/N):')}`, - type: 'string', - required: true, - pattern: /^y|n|Y|N/, - message: ' ', - before: val => { - return String(val).toUpperCase() === 'Y'; - }, - }, - }, - }, - (err, input = {}) => { - if (err) { - prompt.stop(); - reject(`${NAME} ${err.message}`); - return; - } - - params = CONFORM({ input, props, params }); - const { offerBuild } = params; - if (assets.length < 1 && !offerBuild) { - reject('No assets to eject'); - return; - } else { - params.assets = assets; - } - - resolve(); - }, - ); - }); - }) - .then(() => PREFLIGHT({ params, props })) - .then(() => CONFIRM({ props, params })) - .then(() => GENERATOR({ params, props })) - .then(() => prompt.stop()) - .then(results => { - console.log(''); - }) - .catch(err => { - prompt.stop(); - message(op.get(err, 'message', CANCELED)); - }); -}; - -/** - * COMMAND Function - * @description Function that executes program.command() - */ -const COMMAND = ({ program, props }) => - program - .command(NAME) - .description(DESC) - .action(opt => ACTION({ opt, props })) - .on('--help', HELP); - -/** - * Module Constructor - * @description Internal constructor of the module that is being exported. - * @param program Class Commander.program reference. - * @param props Object The CLI props passed from the calling class `arcli.js`. - * @since 2.0.0 - */ -module.exports = { - COMMAND, - ID: NAME, -}; diff --git a/.core/.cli/commands/reactium/plugin/index.js b/.core/.cli/commands/reactium/plugin/index.js deleted file mode 100644 index 99d773c7..00000000 --- a/.core/.cli/commands/reactium/plugin/index.js +++ /dev/null @@ -1,46 +0,0 @@ -const chalk = require('chalk'); -const op = require('object-path'); - -const NAME = 'plugin'; -const DESC = 'Reactium: Commands used to help manage plugins.'; - -const HELP = props => { - const actions = Object.keys(props.subcommands[NAME]); - actions.sort(); - - console.log(''); - console.log('Actions:'); - console.log(' ', actions.map(act => chalk.cyan(act)).join(', ')); - console.log(''); - console.log('Example:'); - actions.forEach(act => - console.log(` $ arcli`, chalk.magenta(NAME), chalk.cyan(act), '-h'), - ); - console.log(''); -}; - -const COMMAND = ({ program, props }) => { - const ACT = props.args[3]; - const { subcommands = {} } = props; - - if (NAME === props.args[2] && ACT) { - if (!op.has(subcommands, `${NAME}.${ACT}`)) { - console.log(''); - console.log(chalk.red('Invalid command:'), NAME, chalk.cyan(ACT)); - console.log(''); - process.exit(); - } - return subcommands[NAME][ACT]['COMMAND']({ program, props }); - } else { - return program - .command(`${NAME} `) - .description(DESC) - .action((action, opt) => {}) - .on('--help', () => HELP(props)); - } -}; - -module.exports = { - COMMAND, - NAME, -}; diff --git a/.core/.cli/commands/reactium/plugin/local/actions.js b/.core/.cli/commands/reactium/plugin/local/actions.js deleted file mode 100644 index 1dab981b..00000000 --- a/.core/.cli/commands/reactium/plugin/local/actions.js +++ /dev/null @@ -1,41 +0,0 @@ -const path = require('path'); -const chalk = require('chalk'); -const fs = require('fs-extra'); -const _ = require('underscore'); -const op = require('object-path'); -const globby = require('globby').sync; -const { spawn } = require('child_process'); -const labelGenerator = require('@atomic-reactor/cli/commands/config/set/generator'); - -module.exports = spinner => { - const message = text => { - if (spinner) { - spinner.text = text; - } - }; - - return { - toggle: async ({ action, params, props }) => { - const { plugin } = params; - message( - `Toggling ${chalk.cyan(plugin.name)} ${chalk.cyan( - !plugin.development ? 'on' : 'off', - )}...`, - ); - - let conf = {}; - if (fs.existsSync(plugin.confPath)) { - try { - conf = JSON.parse(fs.readFileSync(plugin.confPath, 'utf8')); - } catch (err) {} - } - - conf.development = !op.get(plugin, 'development', false); - fs.writeFileSync( - plugin.confPath, - JSON.stringify(conf, null, 2), - 'utf8', - ); - }, - }; -}; diff --git a/.core/.cli/commands/reactium/plugin/local/generator.js b/.core/.cli/commands/reactium/plugin/local/generator.js deleted file mode 100644 index 1bbad523..00000000 --- a/.core/.cli/commands/reactium/plugin/local/generator.js +++ /dev/null @@ -1,29 +0,0 @@ -const ora = require('ora'); -const ActionSequence = require('action-sequence'); - -module.exports = ({ params, props }) => { - console.log(''); - const spinner = ora({ - spinner: 'dots', - color: 'cyan', - }); - - spinner.start(); - - const actions = require('./actions')(spinner); - - return ActionSequence({ - actions, - options: { params, props }, - }) - .then(success => { - spinner.succeed('complete!'); - console.log(''); - return success; - }) - .catch(error => { - spinner.fail('error!'); - console.log(error); - return error; - }); -}; diff --git a/.core/.cli/commands/reactium/plugin/local/index.js b/.core/.cli/commands/reactium/plugin/local/index.js deleted file mode 100644 index 6556a229..00000000 --- a/.core/.cli/commands/reactium/plugin/local/index.js +++ /dev/null @@ -1,224 +0,0 @@ -/** - * ----------------------------------------------------------------------------- - * Imports - * ----------------------------------------------------------------------------- - */ - -const chalk = require('chalk'); -const prettier = require('prettier'); -const path = require('path'); -const op = require('object-path'); -const { error, message } = arcli; -const GENERATOR = require('./generator'); -const globby = require('globby').sync; -const fs = require('fs-extra'); -const slugify = require('slugify'); - -/** - * NAME String - * @description Constant defined as the command name. Value passed to the commander.command() function. - * @example $ arcli local - * @see https://www.npmjs.com/package/commander#command-specific-options - * @since 2.0.0 - */ -const NAME = 'plugin '; - -/** - * DESC String - * @description Constant defined as the command description. Value passed to - * the commander.desc() function. This string is also used in the --help flag output. - * @see https://www.npmjs.com/package/commander#automated---help - * @since 2.0.0 - */ -const DESC = 'Toggle local development mode for a runtime plugin.'; - -/** - * CANCELED String - * @description Message sent when the command is canceled - * @since 2.0.0 - */ -const CANCELED = 'Action canceled!'; - -/** - * HELP Function - * @description Function called in the commander.on('--help', callback) callback. - * @see https://www.npmjs.com/package/commander#automated---help - * @since 2.0.0 - */ -const HELP = () => - console.log(` -Example: - # Follow the prompts - $ arcli local -`); - -/** - * PREFLIGHT Function - */ -const PREFLIGHT = ({ msg, params, props }) => { - const { plugin } = params; - - msg = - msg || - `${chalk.white('Toggle Local Development for Plugin:')} ${chalk.cyan( - plugin.name, - )} ${plugin.development ? chalk.cyan('off') : chalk.cyan('on')}`; - - message(msg); -}; - -const descriptionList = (list = []) => { - return ( - list.reduce((description, plugin, index) => { - description += ` ${chalk.cyan(index + 1)}: ${ - plugin.name - } ${chalk.cyan(plugin.development ? '(on)' : '(off)')}\n\r`; - return description; - }, '') + '\n\r' - ); -}; - -/** - * SCHEMA Function - * @description used to describe the input for the prompt function. - * @see https://www.npmjs.com/package/prompt - * @since 2.0.0 - */ -const SCHEMA_CHOOSE_PLUGIN = ({ props, plugins }) => { - return { - properties: { - plugin: { - description: - chalk.white('Choose plugin:\n\r') + - descriptionList(plugins), - required: true, - message: - plugins.length > 1 - ? chalk.white(`Select 1 to ${plugins.length}`) - : chalk.white('1 is only option.'), - conform: val => op.has(plugins, [Number(val) - 1]), - default: 1, - }, - }, - }; -}; - -/** - * ACTION Function - * @description Function used as the commander.action() callback. - * @see https://www.npmjs.com/package/commander - * @param opt Object The commander options passed into the function. - * @param props Object The CLI props passed from the calling class `arcli.js`. - * @since 2.0.0 - */ -const ACTION = ({ opt, props }) => { - const { cwd, prompt, config } = props; - const umds = globby( - path - .resolve(cwd, 'src/app/components/plugin-src/**/umd.js') - .split(/[\\\/]/g) - .join(path.posix.sep), - ); - - const plugins = umds.map(mod => { - const dir = path.dirname(mod); - const name = path.basename(dir); - const confPath = path.resolve(dir, 'reactium-hooks.json'); - - let development = false; - if (fs.existsSync(confPath)) { - try { - development = op.get( - JSON.parse(fs.readFileSync(confPath, 'utf8')), - 'development', - false, - ); - } catch (err) {} - } - - console.log({ name, dir, confPath, development }); - - return { - name, - dir, - confPath, - development, - }; - }); - - prompt.start(); - - let params = {}; - - return new Promise((resolve, reject) => { - if (plugins.length < 1) { - message( - chalk.magenta( - 'No plugins found in src/app/components/plugin-src.', - chalk.white( - `Use ${chalk.cyan( - '`arcli plugin module`', - )} to create one.`, - ), - ), - ); - reject(); - return; - } - - prompt.get( - SCHEMA_CHOOSE_PLUGIN({ props, plugins }), - (err, input = {}) => { - if (err) { - prompt.stop(); - reject(`${NAME} ${err.message}`); - return; - } - - let pluginIndex = Number(op.get(input, 'plugin', 1)) - 1; - pluginIndex = Math.max( - 0, - Math.min(pluginIndex, plugins.length - 1), - ); - - op.set(params, 'plugins', plugins); - op.set(params, 'plugin', op.get(plugins, pluginIndex)); - - resolve(); - }, - ); - }) - .then(() => PREFLIGHT({ params, props })) - .then(() => GENERATOR({ params, props })) - .then(() => prompt.stop()) - .then(results => { - console.log(''); - }) - .catch(err => { - prompt.stop(); - message(op.get(err, 'message', CANCELED)); - }); -}; - -/** - * COMMAND Function - * @description Function that executes program.command() - */ -const COMMAND = ({ program, props }) => - program - .command(NAME) - .description(DESC) - .action(opt => ACTION({ opt, props })) - .on('--help', HELP); - -/** - * Module Constructor - * @description Internal constructor of the module that is being exported. - * @param program Class Commander.program reference. - * @param props Object The CLI props passed from the calling class `arcli.js`. - * @since 2.0.0 - */ -module.exports = { - COMMAND, - ID: NAME, -}; diff --git a/.core/.cli/commands/reactium/plugin/module/actions.js b/.core/.cli/commands/reactium/plugin/module/actions.js deleted file mode 100644 index 5337b76e..00000000 --- a/.core/.cli/commands/reactium/plugin/module/actions.js +++ /dev/null @@ -1,124 +0,0 @@ -const path = require('path'); -const chalk = require('chalk'); -const fs = require('fs-extra'); -const _ = require('underscore'); -const op = require('object-path'); -const handlebars = require('handlebars').compile; - -module.exports = spinner => { - const message = text => { - if (spinner) { - spinner.text = text; - } - }; - - return { - create: async ({ action, params, props }) => { - const { cwd } = props; - const { plugin } = params; - const pluginPath = path.resolve( - cwd, - 'src/app/components/plugin-src/', - plugin, - ); - message(`Creating ${chalk.cyan(`plugin ${plugin}`)}...`); - - fs.ensureDirSync(pluginPath); - - message('Writing index.js'); - const index = handlebars( - fs.readFileSync( - path.resolve(__dirname, 'template/index.hbs'), - 'utf8', - ), - ); - fs.writeFileSync( - path.resolve(pluginPath, 'index.js'), - index({ NAME: plugin }), - 'utf8', - ); - - message('Writing reactium-hooks.js'); - const hooks = handlebars( - fs.readFileSync( - path.resolve(__dirname, 'template/reactium-hooks.hbs'), - 'utf8', - ), - ); - fs.writeFileSync( - path.resolve(pluginPath, 'reactium-hooks.js'), - hooks({ NAME: plugin }), - 'utf8', - ); - - message('Writing reactium-hooks.json'); - const hooksJson = fs.readFileSync( - path.resolve(__dirname, 'template/reactium-hooks.json'), - 'utf8', - ); - fs.writeFileSync( - path.resolve(pluginPath, 'reactium-hooks.json'), - hooksJson, - 'utf8', - ); - - message('Writing umd.js'); - const umd = handlebars( - fs.readFileSync( - path.resolve(__dirname, 'template/umd.hbs'), - 'utf8', - ), - ); - fs.writeFileSync( - path.resolve(pluginPath, 'umd.js'), - umd({ NAME: plugin }), - 'utf8', - ); - - message('Writing umd-config.json'); - const config = handlebars( - fs.readFileSync( - path.resolve(__dirname, 'template/umd-config.hbs'), - 'utf8', - ), - ); - fs.writeFileSync( - path.resolve(pluginPath, 'umd-config.json'), - config({ NAME: plugin }), - 'utf8', - ); - - fs.ensureDirSync(path.resolve(pluginPath, 'assets/style')); - message(`${plugin}-plugin.scss`); - const style = handlebars( - fs.readFileSync( - path.resolve(__dirname, 'template/style.hbs'), - 'utf8', - ), - ); - fs.writeFileSync( - path.resolve( - pluginPath, - 'assets/style', - `${plugin}-plugin.scss`, - ), - style({ NAME: plugin }), - 'utf8', - ); - - message('Writing reactium-boot.js'); - const bootJs = handlebars( - fs.readFileSync( - path.resolve(__dirname, 'template/reactium-boot.hbs'), - 'utf8', - ), - ); - - fs.writeFileSync( - path.resolve(pluginPath, 'reactium-boot.js'), - bootJs({ FILENAME: `/assets/style/${plugin}-plugin.css` }), - 'utf8', - ); - }, - }; -}; diff --git a/.core/.cli/commands/reactium/plugin/module/generator.js b/.core/.cli/commands/reactium/plugin/module/generator.js deleted file mode 100644 index fa4c35b7..00000000 --- a/.core/.cli/commands/reactium/plugin/module/generator.js +++ /dev/null @@ -1,29 +0,0 @@ -const ora = require('ora'); -const ActionSequence = require('action-sequence'); - -module.exports = ({ params, props }) => { - console.log(''); - const spinner = ora({ - spinner: 'dots', - color: 'cyan', - }); - - spinner.start(); - - const actions = require('./actions')(spinner); - - return ActionSequence({ - actions, - options: { params, props }, - }) - .then(success => { - spinner.succeed('complete!'); - console.log(''); - return success; - }) - .catch(error => { - spinner.fail('error!'); - console.log({ error }); - return error; - }); -}; diff --git a/.core/.cli/commands/reactium/plugin/module/index.js b/.core/.cli/commands/reactium/plugin/module/index.js deleted file mode 100644 index 4bf82b3f..00000000 --- a/.core/.cli/commands/reactium/plugin/module/index.js +++ /dev/null @@ -1,295 +0,0 @@ -/** - * ----------------------------------------------------------------------------- - * Imports - * ----------------------------------------------------------------------------- - */ - -const chalk = require('chalk'); -const prettier = require('prettier'); -const path = require('path'); -const fs = require('fs-extra'); -const op = require('object-path'); -const { error, message } = arcli; -const GENERATOR = require('./generator'); -const slugify = require('slugify'); - -/** - * NAME String - * @description Constant defined as the command name. Value passed to the commander.command() function. - * @example $ arcli module - * @see https://www.npmjs.com/package/commander#command-specific-options - * @since 2.0.0 - */ -const NAME = 'plugin '; - -/** - * DESC String - * @description Constant defined as the command description. Value passed to - * the commander.desc() function. This string is also used in the --help flag output. - * @see https://www.npmjs.com/package/commander#automated---help - * @since 2.0.0 - */ -const DESC = 'Create exportable plugin module.'; - -/** - * CANCELED String - * @description Message sent when the command is canceled - * @since 2.0.0 - */ -const CANCELED = 'Action canceled!'; - -/** - * confirm({ props:Object, params:Object }) Function - * @description Prompts the user to confirm the operation - * @since 2.0.0 - */ -const CONFIRM = ({ props, params, msg }) => { - const { prompt, cwd } = props; - const { plugin } = params; - - msg = msg || chalk.white('Proceed?'); - - return new Promise((resolve, reject) => { - prompt.get( - { - properties: { - confirmed: { - description: `${msg} ${chalk.cyan('(Y/N):')}`, - type: 'string', - required: true, - pattern: /^y|n|Y|N/, - message: ` `, - before: val => { - return String(val).toUpperCase() === 'Y'; - }, - }, - }, - }, - (error, input = {}) => { - const confirmed = op.get(input, 'confirmed', false); - if (error || confirmed === false) { - reject(error); - } else { - params['confirmed'] = true; - resolve(params); - } - }, - ); - }); -}; - -/** - * conform(input:Object) Function - * @description Reduces the input object. - * @param input Object The key value pairs to reduce. - * @since 2.0.0 - */ -const CONFORM = ({ input, props }) => - Object.keys(input).reduce((obj, key) => { - let val = input[key]; - switch (key) { - case 'overwrite': - if (String(val).toUpperCase() === 'Y' || val === true) - obj[key] = true; - if (String(val).toUpperCase() === 'N' || val === false) - obj[key] = false; - break; - default: - obj[key] = val; - break; - } - return obj; - }, {}); - -/** - * HELP Function - * @description Function called in the commander.on('--help', callback) callback. - * @see https://www.npmjs.com/package/commander#automated---help - * @since 2.0.0 - */ -const HELP = () => - console.log(` -Example: - # results in plugin named my-neato-functions - $ arcli module --name "My Neato Functions Plugin" -`); - -/** - * FLAGS - * @description Array of flags passed from the commander options. - * @since 2.0.18 - */ -const FLAGS = ['plugin', 'overwrite']; - -/** - * FLAGS_TO_PARAMS Function - * @description Create an object used by the prompt.override property. - * @since 2.0.18 - */ -const FLAGS_TO_PARAMS = ({ opt = {} }) => - FLAGS.reduce((obj, key) => { - let val = opt[key]; - val = typeof val === 'function' ? undefined : val; - - if (key === 'plugin') obj[key] = nameToPluginName(val); - if (key === 'overwrite' && val === true) obj.overwrite = true; - - return obj; - }, {}); - -/** - * PREFLIGHT Function - */ -const PREFLIGHT = ({ msg, params, props }) => { - msg = msg || 'Preflight checklist:'; - - message(msg); - - const { prompt, cwd } = props; - const { plugin } = params; - - message( - `Reactium Plugin module will be created at ${chalk.cyan( - path.relative(cwd, getPluginPath(plugin, cwd)), - )}`, - ); -}; - -const nameToPluginName = (name = '') => { - // remove redundant plugin word from plugin - const lower = String(name) - .toLowerCase() - .replace('plugin', ''); - return slugify(lower); -}; - -const getPluginPath = (name, cwd) => - path.resolve(cwd, 'src/app/components/plugin-src', name); -const pluginPathExists = (name, cwd) => { - const pluginPath = getPluginPath(name, cwd); - return fs.existsSync(pluginPath); -}; - -/** - * SCHEMA Function - * @description used to describe the input for the prompt function. - * @see https://www.npmjs.com/package/prompt - * @since 2.0.0 - */ -const SCHEMA = ({ props }) => { - const { cwd, prompt } = props; - return { - properties: { - plugin: { - description: 'Plugin name:', - required: true, - before: nameToPluginName, - message: chalk.cyan( - 'Plugin name invalid. Must be at least 4 characters, and not include the word "plugin"', - ), - conform: name => { - const check = nameToPluginName(name); - return String(check).length >= 4; - }, - }, - overwrite: { - pattern: /^y|n|Y|N/, - default: 'N', - description: 'Plugin exists. Overwrite? (y/N):', - ask: () => { - const name = op.get( - prompt.history('plugin'), - 'value', - op.get(prompt, 'override.plugin'), - ); - return ( - pluginPathExists(name, cwd) && - !op.get(prompt, 'override.overwrite', false) - ); - }, - message: ` `, - }, - }, - }; -}; - -/** - * ACTION Function - * @description Function used as the commander.action() callback. - * @see https://www.npmjs.com/package/commander - * @param opt Object The commander options passed into the function. - * @param props Object The CLI props passed from the calling class `orcli.js`. - * @since 2.0.0 - */ -const ACTION = ({ opt, props }) => { - const { cwd, prompt } = props; - const schema = SCHEMA({ props }); - const ovr = FLAGS_TO_PARAMS({ opt }); - - prompt.override = ovr; - prompt.start(); - - let params = {}; - - return new Promise((resolve, reject) => { - prompt.get(schema, (err, input = {}) => { - if (err) { - prompt.stop(); - reject(`${NAME} ${err.message}`); - return; - } - - input = { ...ovr, ...input }; - params = CONFORM({ input, props }); - - const { plugin, overwrite } = params; - // Cancel if existing and not overwriting - if (pluginPathExists(plugin, cwd) && !overwrite) { - reject(); - return; - } - - PREFLIGHT({ params, props }); - - resolve(); - }); - }) - .then(() => CONFIRM({ props, params })) - .then(() => GENERATOR({ params, props })) - .then(() => prompt.stop()) - .then(results => { - console.log(''); - }) - .catch(err => { - prompt.stop(); - message(op.get(err, 'message', CANCELED)); - }); -}; - -/** - * COMMAND Function - * @description Function that executes program.command() - */ -const COMMAND = ({ program, props }) => - program - .command(NAME) - .description(DESC) - .action((action, opt) => ACTION({ opt, props })) - .option( - '-o, --overwrite [overwrite]', - 'Allow overwrite of existing plugin.', - ) - .option('-p, --plugin [plugin]', 'Reactium plugin module name.') - .on('--help', HELP); - -/** - * Module Constructor - * @description Internal constructor of the module that is being exported. - * @param program Class Commander.program reference. - * @param props Object The CLI props passed from the calling class `arcli.js`. - * @since 2.0.0 - */ -module.exports = { - COMMAND, - ID: NAME, -}; diff --git a/.core/.cli/commands/reactium/plugin/module/template/index.hbs b/.core/.cli/commands/reactium/plugin/module/template/index.hbs deleted file mode 100644 index 1707b4e3..00000000 --- a/.core/.cli/commands/reactium/plugin/module/template/index.hbs +++ /dev/null @@ -1,9 +0,0 @@ -import Reactium from 'reactium-core/sdk'; - -const registerPlugin = async () => { - await Reactium.Plugin.register('{{NAME}}'); - - // Reactium SDK calls here -}; - -registerPlugin(); diff --git a/.core/.cli/commands/reactium/plugin/module/template/reactium-boot.hbs b/.core/.cli/commands/reactium/plugin/module/template/reactium-boot.hbs deleted file mode 100644 index 01631919..00000000 --- a/.core/.cli/commands/reactium/plugin/module/template/reactium-boot.hbs +++ /dev/null @@ -1,16 +0,0 @@ -/** - * reactium-boot.js file generated by arcli for your runtime plugin. - * Use `arcli plugin local` to toggle local development on and off - */ -const { development } = require('./reactium-hooks.json'); - -(async () => { - ReactiumBoot.Hook.registerSync('Server.AppStyleSheets', (req, AppStyleSheets) => { - if (development === true) { - AppStyleSheets.register('site-plugin', { - path: '{{FILENAME}}', - order: SDK.Enums.priority.normal, - }); - } - }); -})(); diff --git a/.core/.cli/commands/reactium/plugin/module/template/reactium-hooks.hbs b/.core/.cli/commands/reactium/plugin/module/template/reactium-hooks.hbs deleted file mode 100644 index 0de2820d..00000000 --- a/.core/.cli/commands/reactium/plugin/module/template/reactium-hooks.hbs +++ /dev/null @@ -1,25 +0,0 @@ -/** - * reactium-hooks.js file generated by arcli. - * To develop this plugin, make your development changes to './index.js', not here. - * Use `arcli plugin local` to activate local development, and `arcli plugin eject` - */ - -import Reactium from 'reactium-core/sdk'; -import op from 'object-path'; - -(async () => { - Reactium.Hook.register( - 'plugin-dependencies', - async () => { - const runtime = require('./reactium-hooks.json'); - - if (op.get(runtime, 'development', false)) { - Reactium.Plugin.unregister('{{NAME}}'); - - // make your edits to index.js, not here - require('./index'); - } - }, - Reactium.Enums.priority.highest, - ); -})(); diff --git a/.core/.cli/commands/reactium/plugin/module/template/reactium-hooks.json b/.core/.cli/commands/reactium/plugin/module/template/reactium-hooks.json deleted file mode 100644 index c8345979..00000000 --- a/.core/.cli/commands/reactium/plugin/module/template/reactium-hooks.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "development": true -} diff --git a/.core/.cli/commands/reactium/plugin/module/template/style.hbs b/.core/.cli/commands/reactium/plugin/module/template/style.hbs deleted file mode 100644 index 58cebdff..00000000 --- a/.core/.cli/commands/reactium/plugin/module/template/style.hbs +++ /dev/null @@ -1,17 +0,0 @@ -// Generated by arcli -// If you wish to use images in your styles, add a plugin-assets.json to this directory, with assets pathed relative to this directory. -// -// e.g. Given a "src/app/components/plugin-src/{{NAME}}/assets/images/logo.png" file, your plugin-assets.json would look like: -// { -// "my-logo": "../images/logo.png" -// } -// -// This will produce a partial "_plugin-assets.scss" that will contain an map $assets, containing the data uri for this asset. -// Do not hard-code paths to assets relative to your stylesheet, or they will not work when you export your css to another location (such as CDN) -// -// Example usage: -// -// @import './plugin-assets'; -// .my-logo { -// background: url(map-get($assets, 'my-logo')); -// } diff --git a/.core/.cli/commands/reactium/plugin/module/template/umd-config.hbs b/.core/.cli/commands/reactium/plugin/module/template/umd-config.hbs deleted file mode 100644 index 39a8311f..00000000 --- a/.core/.cli/commands/reactium/plugin/module/template/umd-config.hbs +++ /dev/null @@ -1,3 +0,0 @@ -{ - "libraryName": "{{NAME}}" -} diff --git a/.core/.cli/commands/reactium/plugin/module/template/umd.hbs b/.core/.cli/commands/reactium/plugin/module/template/umd.hbs deleted file mode 100644 index 4afbccb9..00000000 --- a/.core/.cli/commands/reactium/plugin/module/template/umd.hbs +++ /dev/null @@ -1,8 +0,0 @@ -/** - * This file was generated by arcli. This file when found in your Reactium - * instance, will produce a UMD (Universal Module Definition) module, - * named {{NAME}}.js, produced in public/assets/js/umd/{{NAME}} by default. - * - * To develop this plugin, make your development changes to index.js, not here. - */ -require('./index'); diff --git a/.core/.cli/commands/reactium/plugin/zones/actions.js b/.core/.cli/commands/reactium/plugin/zones/actions.js deleted file mode 100644 index 7003c943..00000000 --- a/.core/.cli/commands/reactium/plugin/zones/actions.js +++ /dev/null @@ -1,179 +0,0 @@ -const path = require('path'); -const chalk = require('chalk'); -const fs = require('fs-extra'); -const _ = require('underscore'); -const op = require('object-path'); -const prettier = require('prettier'); -const globby = require('globby'); - -const pad = arlci.pad; - -module.exports = spinner => { - const message = text => { - if (spinner) { - spinner.text = text; - } - }; - - const M = require('./manifest')(); - - const results = { action: 'result', zones: { ...M }, status: 200 }; - - const zoneList = () => - Object.keys(M) - .map((zone, index) => { - index += 1; - const len = String(Object.keys(M).length).length; - const i = chalk.cyan(pad(index, len) + '.'); - return ` ${i} ${zone}`; - }) - .join('\n'); - - const list = ({ action, params, props }) => { - const l = zoneList(); - - if (l.length > 0) { - console.log(chalk.cyan(' Zones:')); - console.log(zoneList()); - } else { - console.log( - ` ${chalk.red('No zones found!')}\n\n Run:\n${chalk.cyan( - ' $ arcli zones scan', - )}\n\n or:\n${chalk.cyan(' $ arcli zones add')}`, - ); - } - return Promise.resolve({ action, status: 200 }); - }; - - const object = ({ action, params, props }) => { - console.log( - '\n', - prettier - .format(JSON.stringify(results.zones), { - parser: 'json-stringify', - }) - .replace(/\"(.*?)\": \{/g, `"${chalk.cyan('$1')}": {`) - .replace(/\"(.*?)\": \"/g, `"${chalk.green('$1')}": "`) - .replace(/\n/g, `\n `), - ); - - return Promise.resolve({ action, status: 200 }); - }; - - const scan = ({ action, params, props }) => { - message( - `Scanning for plugin ${chalk.cyan( - 'zones', - )}. This may take awhile...`, - ); - - const { cwd = process.cwd() } = props; - const globs = []; - - if (op.get(params, 'source') === true) { - globs.push(path.normalize(`${cwd}/src/**/*.js*`)); - } - - if (op.get(params, 'node') === true) { - globs.push(path.normalize(`${cwd}/node_modules/**/*.js*`)); - } - - if (globs.length < 1) { - return Promise.resolve({ action, status: 200 }); - } - - const quick_scan = /\ { - const zones = files.reduce((z, file) => { - const contents = fs.readFileSync(file); - if (!quick_scan.test(contents)) { - return z; - } - - const reg_find = //gm; - const matches = String(fs.readFileSync(file)) - .replace(/["'\s+]/g, ' ') - .match(reg_find); - - if (matches) { - matches.forEach(match => { - const zone = String(match).match(/zone= (.*?) /i); - if (Array.isArray(zone) && zone.length > 1) { - const id = zone[1]; - if (op.has(M, id)) { - return z; - } - - z[id] = { - file, - description: `Plugin zone found in: ${file.replace( - path.normalize(cwd), - '', - )}`, - }; - } - }); - } - - return z; - }, {}); - - if (action) { - results['zones'] = { ...zones, ...M }; - } - - return { action, status: 200 }; - }); - }; - - const create = ({ action, params, props }) => { - const { description, id } = params; - - results.zones = { ...M }; - results.zones[id] = { description }; - - return Promise.resolve({ action, status: 200 }); - }; - - const remove = ({ action, params, props }) => { - const { id } = params; - - delete results.zones[id]; - - return Promise.resolve({ action, status: 200 }); - }; - - const purge = ({ action, params, props }) => { - results.zones = {}; - return Promise.resolve({ action, status: 200 }); - }; - - const cache = ({ action, params, props }) => { - message(`Caching plugin ${chalk.cyan('zones')}...`); - - const { cwd = process.cwd() } = props; - const cont = prettier.format(JSON.stringify(results.zones), { - parser: 'json-stringify', - }); - - const filePath = path.normalize(`${cwd}/.cli-cache/plugin-zones.json`); - fs.ensureFileSync(filePath); - fs.writeFileSync(filePath, cont); - - return Promise.resolve({ action, status: 200 }); - }; - - const result = () => Promise.resolve(results); - - return { - list, - object, - scan, - create, - purge, - cache, - remove, - result, - }; -}; diff --git a/.core/.cli/commands/reactium/plugin/zones/generator.js b/.core/.cli/commands/reactium/plugin/zones/generator.js deleted file mode 100644 index 55dcedc3..00000000 --- a/.core/.cli/commands/reactium/plugin/zones/generator.js +++ /dev/null @@ -1,89 +0,0 @@ -const ActionSequence = require('action-sequence'); -const prettier = require('prettier'); -const op = require('object-path'); -const _ = require('underscore'); - -module.exports = ({ action, params, props }) => { - const { activity, cache } = params; - - const spinner = activity - ? require('ora')({ - spinner: 'dots', - color: 'cyan', - }) - : null; - - const allActions = require('./actions')(spinner); - - if (spinner) { - spinner.start(); - } - - let acts = []; - switch (action) { - case 'list': - if (op.has(params, 'json')) { - acts.push('object'); - } else { - acts.push('list'); - } - break; - - case 'add': - case 'update': - acts.push('create'); - if (cache) { - acts.push('cache'); - } - break; - - case 'remove': - acts.push('remove'); - if (cache) { - acts.push('cache'); - } - break; - - case 'purge': - acts.push('purge'); - if (cache) { - acts.push('cache'); - } - break; - - case 'scan': - acts.push('scan'); - if (cache) { - acts.push('cache'); - } - break; - } - - if (acts.length < 1) { - return Promise.resolve([]); - } - - acts.push('result'); - const actions = _.pick(allActions, ...acts); - - if (actions.length < 1) { - return Promise.resolve([]); - } - - return ActionSequence({ - actions, - options: { params, props }, - }) - .then(success => { - if (spinner) { - spinner.succeed(`${action} complete!`); - } - return success; - }) - .catch(error => { - if (spinner) { - spinner.fail('error!'); - } - return error; - }); -}; diff --git a/.core/.cli/commands/reactium/plugin/zones/index.js b/.core/.cli/commands/reactium/plugin/zones/index.js deleted file mode 100644 index 27f37710..00000000 --- a/.core/.cli/commands/reactium/plugin/zones/index.js +++ /dev/null @@ -1,440 +0,0 @@ -/** - * ----------------------------------------------------------------------------- - * Imports - * ----------------------------------------------------------------------------- - */ -const path = require('path'); -const chalk = require('chalk'); -const generator = require('./generator'); -const prettier = require('prettier'); -const _ = require('underscore'); -const op = require('object-path'); -const { error, message, pad } = arcli; -const M = require('./manifest')(); - -const NAME = 'plugin '; - -const DESC = 'Reactium: Manage the current project Plugin Zones'; - -const ZONE_LIST = () => - Object.keys(M).map((zone, index) => { - index += 1; - const len = String(Object.keys(M).length).length; - const i = chalk.cyan(pad(index, len) + '.'); - return ` ${i} ${zone}`; - }); - -const GET_ZONE = index => { - return !isNaN(Number(index)) ? Object.keys(M)[index - 1] : index; -}; - -const FLAGS = [ - 'id', - 'description', - 'node', - 'cache', - 'activity', - 'source', - 'zone', - 'json', -]; - -const FLAGS_TO_PARAMS = ({ opt = {} }) => - FLAGS.reduce((obj, key) => { - let val = opt[key]; - val = typeof val === 'function' ? undefined : val; - - if (val) { - obj[key] = val; - } - - return obj; - }, {}); - -const CANCELED = 'plugin zones ACTION canceled'; - -const CONFIRM = ({ props, params, msg = 'Proceed?' }) => { - const { prompt } = props; - - return new Promise((resolve, reject) => { - prompt.get( - { - properties: { - confirmed: { - description: `${chalk.white(msg)} ${chalk.cyan( - '(Y/N):', - )}`, - type: 'string', - required: true, - pattern: /^y|n|Y|N/, - message: ' ', - before: val => { - return String(val).toLowerCase() === 'y'; - }, - }, - }, - }, - (error, input = {}) => { - if (error || !op.get(input, 'confirmed')) { - reject(error); - } else { - resolve(params); - } - }, - ); - }); -}; - -const CONFORM = ({ action, input, props }) => { - let output = {}; - - Object.entries(input).forEach(([key, val]) => { - switch (key) { - default: - output[key] = val; - break; - } - }); - - if (action === 'scan') { - delete output.id; - delete output.description; - } - - if (action === 'list') { - delete output.activity; - } - - return output; -}; - -const HELP = () => - console.log(` - -Available values: -${chalk.cyan('list')} | ${chalk.cyan('scan')} | ${chalk.cyan( - 'add', - )} | ${chalk.cyan('update')} | ${chalk.cyan('remove')} | ${chalk.cyan( - 'purge', - )} - -<${chalk.cyan('list')}> - Output the plugin zones: - $ arcli plugin zones ${chalk.cyan('list')} - - Output the plugin zones as JSON - $ arcli plugin zones ${chalk.cyan('list')} --json - $ arcli plugin zones ${chalk.cyan('list')} -j - - ${chalk.magenta( - '* Note:', - )} if a zone is found in more than one location, the first occurance is added to the manifest. - -<${chalk.cyan('scan')}> - Scan the '~/src' directory only, omiting the 'node_modules' directory: - $ arcli plugin zones ${chalk.cyan('scan')} --no-node - $ arcli plugin zones ${chalk.cyan('scan')} -N - - ${chalk.magenta( - '* Note:', - )} if a zone already exists in the manifest, it is skipped. - -<${chalk.cyan('add')}> | <${chalk.cyan('update')}> - Add a plugin zone to the manifest: - $ arcli plugin zones ${chalk.cyan( - 'add', - )} --id "my-plugin-zone" --description "My awesome plugins go here!" - $ arcli plugin zones ${chalk.cyan( - 'add', - )} -i "my-plugin-zone" -d "My awesome plugins go here!" - - ${chalk.magenta( - '* Note:', - )} if a zone already exists in the manifest, it will be updated. - -<${chalk.cyan('remove')}> - Remove a plugin zone from the manifest: - $ arcli plugin zones ${chalk.cyan('remove')} --id "my-plugin-zone" - -<${chalk.cyan('purge')}> - Clear all entries from the plugin zone manifest: - $ arcli plugin zones ${chalk.cyan('purge')} - - ${chalk.magenta( - '* Note:', - )} Purging can not be undone. You can run ${chalk.cyan( - '$ arcli plugin zones scan', - )} to regenerate the default manifest. - -`); - -const SCHEMA = ({ action, props, zone = {} }) => { - const { prompt } = props; - - const output = { - properties: { - id: { - required: true, - description: chalk.white('Zone:'), - message: ' Plugin zone is required', - default: op.get(zone, 'id'), - ask: () => { - if (action === 'update') { - return true; - } - - if (!op.has(prompt, 'override.id')) { - return ['add', 'remove', 'update'].includes(action); - } else { - return false; - } - }, - }, - description: { - required: true, - description: chalk.white('Description:'), - message: ' Plugin description is required', - default: op.get(zone, 'description'), - ask: () => { - if (action === 'update') { - return true; - } - - if (!op.has(prompt, 'override.description')) { - return ['add', 'update'].includes(action); - } else { - return false; - } - }, - }, - }, - }; - - return output; -}; - -const SCHEMA_SELECT = ({ action, opt, props }) => { - const { prompt } = props; - const zones = ZONE_LIST(); - return { - properties: { - id: { - description: `${chalk.white('Zone:')}\n\t ${zones.join( - '\n\t ', - )}\n ${chalk.white('Select:')}`, - type: 'string', - required: true, - message: ' select a zone', - ask: () => { - return !op.has(prompt, 'override.id'); - }, - before: val => { - val = val.replace(/[^\w-_]/g, ''); - return !isNaN(val) && val > zones.length - ? null - : GET_ZONE(val) || val; - }, - }, - }, - }; -}; - -const PREFLIGHT = ({ action, params }) => { - let msg; - switch (action) { - case 'add': - console.log( - '\n', - 'A plugin zone will be created with the following options:', - ); - console.log(''); - console.log( - prettier.format( - JSON.stringify(_.pick(params, 'id', 'description')), - { - parser: 'json-stringify', - }, - ), - ); - break; - - case 'update': - console.log( - '\n', - `The plugin zone ${chalk.cyan( - op.get(params, 'id'), - )} will be updated with the following options:`, - ); - console.log(''); - console.log( - prettier.format( - JSON.stringify(_.pick(params, 'id', 'description')), - { - parser: 'json-stringify', - }, - ), - ); - break; - - case 'remove': - msg = `Are you sure you want to remove the ${chalk.cyan( - op.get(params, 'id'), - )} zone?`; - break; - - case 'purge': - msg = 'Purging can not be undone. Are you sure?'; - break; - } - - return msg; -}; - -const ACTION = ({ action, opt, props, zone, foo }) => { - const id = op.get(opt, 'id'); - - if (['update', 'remove'].includes(action) && !id) { - ACTION_SELECT({ action, opt, props }); - return; - } - - if (id && !op.has(M, id)) { - action = 'add'; - } - - const { prompt } = props; - - const flags = FLAGS_TO_PARAMS({ opt }); - - if (action !== 'update') { - prompt.override = flags; - } else if (id && !zone) { - zone = { ...op.get(M, GET_ZONE(id), {}), id }; - } - - let schema; - - switch (action) { - default: - schema = SCHEMA({ action, props, zone }); - } - - console.log(''); - prompt.start(); - prompt.get(schema, (err, input) => { - if (err) { - prompt.stop(); - error(`${NAME} ${err.message}`); - return; - } - - // Reduce the input - input = { ...flags, ...input }; - const params = CONFORM({ action, input, props }); - - // Preflight - const msg = PREFLIGHT({ action, params }); - - const promise = ['scan', 'list'].includes(action) - ? Promise.resolve(params) - : CONFIRM({ props, params, msg }); - - promise - .then(async () => { - console.log(''); - await generator({ action, params, props }); - console.log(''); - }) - .then(() => prompt.stop()) - .catch(err => { - prompt.stop(); - if (err) { - error(err); - } else { - error(CANCELED.replace('ACTION', action)); - } - }); - }); -}; - -const ACTION_SELECT = ({ action, opt, props }) => { - if (Object.keys(M).length < 1) { - return error( - `no zones found.\n\nRun:\n${chalk.cyan( - ' $ arcli plugin zones scan', - )}\n or:\n${chalk.cyan(' $ arcli plugin zones add')}`, - ); - } - - const { prompt } = props; - const flags = FLAGS_TO_PARAMS({ opt }); - - prompt.override = flags; - const schema = SCHEMA_SELECT({ action, opt, props }); - - prompt.start(); - prompt.get(schema, (err, input) => { - if (err) { - prompt.stop(); - error(`${NAME} ${err.message}`); - return; - } - - const zone = { - id: input.id, - description: op.get(M, `${input.id}.description`), - }; - - opt = { ...opt, ...input }; - - ACTION({ action, opt, props, zone }); - }); -}; - -const COMMAND = ({ program, props }) => - program - .command(`${NAME} `) - .description(DESC) - .action((action, subaction, opt) => - ACTION({ action: subaction, opt, props }), - ) - .option( - '-i, --id ', - 'The plugin zone id. Used when the is add, update, or remove.', - ) - .option( - '-d, --description ', - 'The description of the plugin zone. Used when the is add or update.', - ) - .option( - '-j, --json [json]', - 'Output the plugin zones as a JSON object. Used when calling the action.', - ) - .option( - '-N, --no-node [node]', - 'Excludes the `node_modules` directory when scanning the source code.', - ) - .option('-C, --no-cache [cache]', 'Do not cache the --scan results.') - .option( - '-A, --no-activity [activity]', - 'Do not show the activity spinner.', - ) - .option( - '-S, --no-source [source]', - 'Exclude the `src` directory when scanning the source code.', - ) - .on('--help', HELP); - -/** - * Module Constructor - * @description Internal constructor of the module that is being exported. - * @param program Class Commander.program reference. - * @param props Object The CLI props passed from the calling class `arcli.js`. - * @since 2.0.0 - */ -module.exports = { - ACTION, - CONFORM, - COMMAND, - ID: NAME, -}; diff --git a/.core/.cli/commands/reactium/plugin/zones/manifest.js b/.core/.cli/commands/reactium/plugin/zones/manifest.js deleted file mode 100644 index 9b84b0fe..00000000 --- a/.core/.cli/commands/reactium/plugin/zones/manifest.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Return the output of the 'plugin-manifest.json' file if it exists. - */ -const fs = require('fs-extra'); -const path = require('path'); - -module.exports = () => { - const cwd = process.cwd(); - const dir = path.normalize(`${cwd}/.cli-cache`); - const manifestFile = path.normalize(`${dir}/plugin-zones.json`); - - // Create the cli-cache directory - fs.ensureDirSync(dir); - - return fs.existsSync(manifestFile) ? require(manifestFile) : {}; -}; diff --git a/.core/.cli/commands/reactium/route/index.js b/.core/.cli/commands/reactium/route/index.js deleted file mode 100644 index d31eee19..00000000 --- a/.core/.cli/commands/reactium/route/index.js +++ /dev/null @@ -1,144 +0,0 @@ -import Reactium from '@atomic-reactor/reactium-sdk-core'; - -const { ActionSequence, ora, path } = arcli; - -const ENUMS = { - CANCELED: 'route canceled!', - DESC: 'Reactium: Create or replace a component route file', - FLAGS: { - destination: { - flag: '-d, --destination [destination]', - desc: 'Directory to save the file', - }, - route: { - flag: '-r, --route [route]', - desc: - 'Add routes to the component. /route-1, /route-2, /route/with/:param', - }, - unattended: { - flag: '-u, --unattended [unattended]', - desc: 'Bypass the preflight confirmation and any input prompts', - }, - }, - NAME: 'route', -}; - -// prettier-ignore -const HELP = () => console.log(` -Example: - $ arcli route -h -`); - -const ACTION = async ({ opt, props }) => { - // load hooks - for (const file of arcli.globby( - [ - './.core/**/reactium-arcli.js', - './src/**/reactium-arcli.js', - './reactium_modules/**/reactium-arcli.js', - './node_modules/**/reactium-arcli.js', - ], - { - dot: true, - }, - )) { - await import(path.resolve(file)); - } - - let params = arcli.flagsToParams({ opt, flags: Object.keys(ENUMS.FLAGS) }); - - await Reactium.Hook.run('arcli-route-init', { - ...props, - params, - ENUMS, - }); - - await Reactium.Hook.run('arcli-route-enums', { - ...props, - params, - ENUMS, - }); - - if (params.unattended !== true) { - await Reactium.Hook.run('arcli-route-input', { - ...props, - params, - ENUMS, - }); - } - - await Reactium.Hook.run('arcli-route-conform', { - ...props, - params, - ENUMS, - }); - - if (params.unattended !== true) { - await Reactium.Hook.run('arcli-route-preflight', { - ...props, - params, - }); - - await Reactium.Hook.run('arcli-route-confirm', { - ...props, - params, - ENUMS, - }); - - if (params.confirm !== true) { - arcli.message(ENUMS.CANCELED); - return; - } - } - - console.log(''); - - // Start the spinner - - const spinner = ora({ spinner: 'dots', color: 'cyan' }); - spinner.start(); - - let actions = {}; - await Reactium.Hook.run('arcli-route-actions', { - ...props, - params, - actions, - spinner, - ENUMS, - }); - - return ActionSequence({ - actions, - options: { params, props, spinner }, - }) - .then(success => { - spinner.succeed('complete!'); - console.log(''); - return success; - }) - .catch(error => { - spinner.fail('error!'); - console.error(error); - return error; - }); -}; - -export const COMMAND = ({ program, props }) => { - program - .command(ENUMS.NAME) - .description(ENUMS.DESC) - .on('--help', HELP) - .action(opt => ACTION({ opt, props, program })); - - program.commands - .filter(cmd => Boolean(cmd._name === ENUMS.NAME)) - .forEach(cmd => - Object.values(ENUMS.FLAGS).forEach(({ flag, desc }) => - cmd.option(flag, desc), - ), - ); - - return program; -}; - -export const NAME = ENUMS.NAME; diff --git a/.core/.cli/commands/reactium/route/package.json b/.core/.cli/commands/reactium/route/package.json deleted file mode 100644 index 33983ed7..00000000 --- a/.core/.cli/commands/reactium/route/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "reactium-route-cmd", - "type": "module" -} \ No newline at end of file diff --git a/.core/.cli/commands/reactium/route/reactium-arcli.js b/.core/.cli/commands/reactium/route/reactium-arcli.js deleted file mode 100644 index fcc249f2..00000000 --- a/.core/.cli/commands/reactium/route/reactium-arcli.js +++ /dev/null @@ -1,93 +0,0 @@ -import componentGen from '../component/componentGen.cjs'; -import formatDestination from '../component/formatDestination.cjs'; -import selectDestination from '../component/selectDestination.cjs'; -import formatRoute from '../component/formatRoute.cjs'; - -const { _, chalk, prefix, Reactium } = arcli; - -const suffix = chalk.magenta(': '); - -const PREFLIGHT = ({ msg, params }) => { - arcli.message(msg || 'Preflight checklist:'); - console.log(JSON.stringify(params, null, 2)); - console.log(''); -}; - -const INPUT = async ({ inquirer, params }) => { - const input = await inquirer.prompt( - [ - selectDestination(), - { - prefix, - suffix, - type: 'input', - name: 'route', - message: 'Route', - }, - ], - params, - ); - - Object.entries(input).forEach(([key, val]) => (params[key] = val)); -}; - -const CONFIRM = async ({ inquirer, params }) => { - if (params.unattended) return; - - const input = await inquirer.prompt([ - { - prefix, - suffix, - default: false, - type: 'confirm', - name: 'confirm', - message: 'Proceed?', - }, - ]); - - Object.entries(input).forEach(([key, val]) => (params[key] = val)); -}; - -const CONFORM = async ({ params }) => { - params.destination = formatDestination(params.destination); - - if (typeof params.route === 'string') { - params.route = formatRoute(params.route); - } -}; - -// Register default hooks -Reactium.Hook.register( - 'arcli-route-input', - INPUT, - Reactium.Enums.priority.highest, - 'arcli-route-input', -); - -Reactium.Hook.register( - 'arcli-route-confirm', - CONFIRM, - Reactium.Enums.priority.highest, - 'arcli-route-confirm', -); - -Reactium.Hook.register( - 'arcli-route-conform', - CONFORM, - Reactium.Enums.priority.highest, - 'arcli-route-conform', -); - -Reactium.Hook.register( - 'arcli-route-preflight', - PREFLIGHT, - Reactium.Enums.priority.highest, - 'arcli-route-preflight', -); - -Reactium.Hook.register( - 'arcli-route-actions', - ({ actions }) => (actions['component'] = componentGen), - Reactium.Enums.priority.highest, - 'arcli-route-actions', -); diff --git a/.core/.cli/commands/reactium/server/actions.js b/.core/.cli/commands/reactium/server/actions.js deleted file mode 100644 index d4e07886..00000000 --- a/.core/.cli/commands/reactium/server/actions.js +++ /dev/null @@ -1,50 +0,0 @@ -const path = require('path'); -const chalk = require('chalk'); -const fs = require('fs-extra'); -const _ = require('underscore'); -const op = require('object-path'); - -module.exports = spinner => { - const message = text => { - if (spinner) { - spinner.text = text; - } - }; - - return { - create: ({ action, params, props }) => { - message(`Creating ${chalk.cyan('templates')}...`); - - const { cwd } = props; - const { feo } = params; - - const reactium = require(path.normalize( - `${cwd}/.core/reactium-config`, - )); - const template = {}; - const tmpath = path.normalize(`${cwd}/`); - const ver = op.get(reactium, 'version', '2.3.15'); - - if (feo) { - template['feo'] = fs.readFileSync( - path.normalize(`${cwd}/.core/server/template/feo.js`), - ); - template['feo'] = String(template.feo).replace( - /\%TEMPLATE_VERSION\%/gi, - ver, - ); - } - - Object.entries(template).forEach(([type, content]) => { - const p = path.normalize( - `${cwd}/src/app/server/template/${type}.js`, - ); - - fs.ensureFileSync(p); - fs.writeFileSync(p, content); - }); - - return Promise.resolve({ action, status: 200 }); - }, - }; -}; diff --git a/.core/.cli/commands/reactium/server/generator.js b/.core/.cli/commands/reactium/server/generator.js deleted file mode 100644 index 1abcc105..00000000 --- a/.core/.cli/commands/reactium/server/generator.js +++ /dev/null @@ -1,26 +0,0 @@ -const ora = require('ora'); -const ActionSequence = require('action-sequence'); - -module.exports = ({ action, params, props }) => { - const spinner = ora({ - spinner: 'dots', - color: 'cyan', - }); - - spinner.start(); - - const actions = require('./actions')(spinner); - - return ActionSequence({ - actions, - options: { params, props }, - }) - .then(success => { - spinner.succeed('complete!'); - return success; - }) - .catch(error => { - spinner.fail('error!'); - return error; - }); -}; diff --git a/.core/.cli/commands/reactium/server/index.js b/.core/.cli/commands/reactium/server/index.js deleted file mode 100644 index ac8c650b..00000000 --- a/.core/.cli/commands/reactium/server/index.js +++ /dev/null @@ -1,265 +0,0 @@ -/** - * ----------------------------------------------------------------------------- - * Imports - * ----------------------------------------------------------------------------- - */ - -const fs = require('fs-extra'); -const chalk = require('chalk'); -const generator = require('./generator'); -const prettier = require('prettier'); -const path = require('path'); -const op = require('object-path'); -const { error, message } = arcli; - -/** - * NAME String - * @description Constant defined as the command name. Value passed to the commander.command() function. - * @example $ arcli server template - * @see https://www.npmjs.com/package/commander#command-specific-options - * @since 2.0.0 - */ -const NAME = 'server '; - -/** - * DESC String - * @description Constant defined as the command description. Value passed to - * the commander.desc() function. This string is also used in the --help flag output. - * @see https://www.npmjs.com/package/commander#automated---help - * @since 2.0.0 - */ -const DESC = 'Reactium: Create a custom server template.'; - -/** - * CANCELED String - * @description Message sent when the command is canceled - * @since 2.0.0 - */ -const CANCELED = 'Action canceled!'; - -/** - * TYPES - * @description types of server templates that can be created - */ -const TYPES = ['feo']; - -/** - * confirm({ props:Object, params:Object }) Function - * @description Prompts the user to confirm the operation - * @since 2.0.0 - */ -const CONFIRM = ({ props, params, msg }) => { - const { prompt } = props; - - msg = msg || chalk.white('Proceed?'); - - return new Promise((resolve, reject) => { - prompt.get( - { - properties: { - confirmed: { - description: `${msg} ${chalk.cyan('(Y/N):')}`, - type: 'string', - required: true, - pattern: /^y|n|Y|N/, - message: ' ', - before: val => { - return String(val).toUpperCase() === 'Y'; - }, - }, - }, - }, - (error, input = {}) => { - const confirmed = op.get(input, 'confirmed', false); - if (error || confirmed === false) { - reject(error); - } else { - params['confirmed'] = true; - resolve(params); - } - }, - ); - }); -}; - -/** - * conform(input:Object) Function - * @description Reduces the input object. - * @param input Object The key value pairs to reduce. - * @since 2.0.0 - */ -const CONFORM = ({ input, props }) => { - const output = Object.keys(input).reduce((obj, key) => { - let val = input[key]; - switch (key) { - case 'type': - val = String(val).toLowerCase(); - val = TYPES.includes(val) ? val : 'all'; - obj[key] = val; - break; - - default: - obj[key] = val; - break; - } - - return obj; - }, {}); - - return output; -}; - -/** - * HELP Function - * @description Function called in the commander.on('--help', callback) callback. - * @see https://www.npmjs.com/package/commander#automated---help - * @since 2.0.0 - */ -const HELP = () => - console.log(` -Example: - $ arcli server template - -Exclude the front-end template: - $ arcli server template --no-feo - -Overwrite existing server templates - $ arcli server template --overwrite -`); - -/** - * FLAGS - * @description Array of flags passed from the commander options. - * @since 2.0.18 - */ -const FLAGS = ['feo', 'overwrite']; - -/** - * FLAGS_TO_PARAMS Function - * @description Create an object used by the prompt.override property. - * @since 2.0.18 - */ -const FLAGS_TO_PARAMS = ({ opt = {} }) => - FLAGS.reduce((obj, key) => { - let val = opt[key]; - val = typeof val === 'function' ? undefined : val; - - if (val) { - obj[key] = val; - } - - return obj; - }, {}); - -const isTemplate = cwd => { - const destFEO = fs.existsSync( - path.normalize(`${cwd}/src/app/server/template/feo.js`), - ); - - return destFEO; -}; - -/** - * SCHEMA Function - * @description used to describe the input for the prompt function. - * @see https://www.npmjs.com/package/prompt - * @since 2.0.0 - */ -const SCHEMA = ({ props }) => { - const { cwd } = props; - - return { - properties: { - overwrite: { - required: true, - pattern: /^y|n|Y|N/, - message: '', - description: `${chalk.white( - 'Overwrite existing template?', - )} ${chalk.cyan('(Y/N):')}`, - ask: () => isTemplate(cwd), - before: val => Boolean(String(val).toUpperCase() === 'Y'), - }, - }, - }; -}; - -/** - * ACTION Function - * @description Function used as the commander.action() callback. - * @see https://www.npmjs.com/package/commander - * @param opt Object The commander options passed into the function. - * @param props Object The CLI props passed from the calling class `orcli.js`. - * @since 2.0.0 - */ -const ACTION = ({ action, opt, props }) => { - const { cwd, prompt } = props; - const schema = SCHEMA({ props }); - const ovr = FLAGS_TO_PARAMS({ opt }); - - prompt.override = ovr; - prompt.start(); - - return new Promise((resolve, reject) => { - prompt.get(schema, (err, input = {}) => { - if (err) { - prompt.stop(); - reject(`${NAME} ${err.message}`); - return; - } - - input = { ...ovr, ...input }; - params = CONFORM({ input, props }); - - const { feo } = params; - - if (!op.has(params, 'overwrite') || !feo) { - reject(CANCELED); - return; - } - - resolve(params); - }); - }) - .then(() => { - return CONFIRM({ props, params }); - }) - .then(async () => { - console.log(''); - await generator({ params, props }); - console.log(''); - }) - .then(() => prompt.stop()) - .catch(err => { - prompt.stop(); - message(op.get(err, 'message', CANCELED)); - }); -}; - -/** - * COMMAND Function - * @description Function that executes program.command() - */ -const COMMAND = ({ program, props }) => - program - .command(NAME) - .description(DESC) - .action((action, opt) => ACTION({ action, opt, props })) - .option('-F, --no-feo [feo]', 'Front-end template.') - .option( - '-o, --overwrite [overwrite]', - 'Overwrite existing template files.', - ) - .on('--help', HELP); - -/** - * Module Constructor - * @description Internal constructor of the module that is being exported. - * @param program Class Commander.program reference. - * @param props Object The CLI props passed from the calling class `arcli.js`. - * @since 2.0.0 - */ -module.exports = { - COMMAND, - NAME, -}; diff --git a/.core/.cli/commands/reactium/style/index.js b/.core/.cli/commands/reactium/style/index.js deleted file mode 100644 index f36e757d..00000000 --- a/.core/.cli/commands/reactium/style/index.js +++ /dev/null @@ -1,142 +0,0 @@ -import Reactium from '@atomic-reactor/reactium-sdk-core'; - -const { ActionSequence, ora, path } = arcli; - -const ENUMS = { - CANCELED: 'style canceled!', - DESC: 'Reactium: Create or replace a component stylesheet', - FLAGS: { - destination: { - flag: '-d, --destination [destination]', - desc: 'Directory to save stylesheet', - }, - type: { - flag: '-t, --type [type]', - desc: 'Stylesheet type', - }, - unattended: { - flag: '-u, --unattended [unattended]', - desc: 'Bypass the preflight confirmation and any input prompts', - }, - }, - NAME: 'style', -}; - -// prettier-ignore -const HELP = () => console.log(` -Example: - $ arcli style -h -`); - -const ACTION = async ({ opt, props }) => { - // load hooks - for (const file of arcli.globby( - [ - './.core/**/reactium-arcli.js', - './src/**/reactium-arcli.js', - './reactium_modules/**/reactium-arcli.js', - './node_modules/**/reactium-arcli.js', - ], - { - dot: true, - }, - )) { - await import(path.resolve(file)); - } - - let params = arcli.flagsToParams({ opt, flags: Object.keys(ENUMS.FLAGS) }); - - await Reactium.Hook.run('arcli-style-init', { - ...props, - params, - ENUMS, - }); - - await Reactium.Hook.run('arcli-style-enums', { - ...props, - params, - ENUMS, - }); - - if (params.unattended !== true) { - await Reactium.Hook.run('arcli-style-input', { - ...props, - params, - ENUMS, - }); - } - - await Reactium.Hook.run('arcli-style-conform', { - ...props, - params, - ENUMS, - }); - - if (params.unattended !== true) { - await Reactium.Hook.run('arcli-style-preflight', { - ...props, - params, - }); - - await Reactium.Hook.run('arcli-style-confirm', { - ...props, - params, - ENUMS, - }); - - if (params.confirm !== true) { - arcli.message(ENUMS.CANCELED); - return; - } - } - - console.log(''); - - // Start the spinner - - const spinner = ora({ spinner: 'dots', color: 'cyan' }); - spinner.start(); - - let actions = {}; - await Reactium.Hook.run('arcli-style-actions', { - ...props, - params, - actions, - ENUMS, - }); - - return ActionSequence({ - actions, - options: { params, props, spinner }, - }) - .then(success => { - spinner.succeed('complete!'); - console.log(''); - return success; - }) - .catch(error => { - spinner.fail('error!'); - console.error(error); - return error; - }); -}; - -export const COMMAND = ({ program, props }) => { - program - .command(ENUMS.NAME) - .description(ENUMS.DESC) - .on('--help', HELP) - .action(opt => ACTION({ opt, props, program })); - - program.commands - .filter(cmd => Boolean(cmd._name === ENUMS.NAME)) - .forEach(cmd => - Object.values(ENUMS.FLAGS).forEach(({ flag, desc }) => - cmd.option(flag, desc), - ), - ); - - return program; -}; - -export const NAME = ENUMS.NAME; diff --git a/.core/.cli/commands/reactium/style/package.json b/.core/.cli/commands/reactium/style/package.json deleted file mode 100644 index 70094079..00000000 --- a/.core/.cli/commands/reactium/style/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "reactium-style-cmd", - "type": "module" -} \ No newline at end of file diff --git a/.core/.cli/commands/reactium/style/reactium-arcli.js b/.core/.cli/commands/reactium/style/reactium-arcli.js deleted file mode 100644 index 6eb789d6..00000000 --- a/.core/.cli/commands/reactium/style/reactium-arcli.js +++ /dev/null @@ -1,90 +0,0 @@ -import componentGen from '../component/componentGen.cjs'; -import formatDestination from '../component/formatDestination.cjs'; -import selectDestination from '../component/selectDestination.cjs'; -import selectStyleDefault from '../component/selectStyle.cjs'; - -const { _, chalk, Reactium } = arcli; - -const { selectStyle, styleTypes } = selectStyleDefault; - -const PREFLIGHT = ({ msg, params }) => { - arcli.message(msg || 'Preflight checklist:'); - console.log(JSON.stringify(params, null, 2)); - console.log(''); -}; - -const INPUT = async ({ inquirer, params }) => { - const input = await inquirer.prompt( - [selectDestination(), selectStyle({ name: 'type' })], - params, - ); - - Object.entries(input).forEach(([key, val]) => (params[key] = val)); -}; - -const CONFIRM = async ({ inquirer, params }) => { - if (params.unattended) return; - - const input = await inquirer.prompt([ - { - default: false, - type: 'confirm', - name: 'confirm', - message: 'Proceed?', - prefix: arcli.prefix, - suffix: chalk.magenta(': '), - }, - ]); - - Object.entries(input).forEach(([key, val]) => (params[key] = val)); -}; - -const CONFORM = async ({ params }) => { - params.style = true; - params.destination = formatDestination(params.destination); - - if (typeof params.type === 'string') { - const styleType = - _.findWhere(styleTypes, { name: params.type }) || - _.first(styleTypes); - - params.styleType = styleType.value; - delete params.type; - } -}; - -// Register default hooks -Reactium.Hook.register( - 'arcli-style-input', - INPUT, - Reactium.Enums.priority.highest, - 'arcli-style-input', -); - -Reactium.Hook.register( - 'arcli-style-confirm', - CONFIRM, - Reactium.Enums.priority.highest, - 'arcli-style-confirm', -); - -Reactium.Hook.register( - 'arcli-style-conform', - CONFORM, - Reactium.Enums.priority.highest, - 'arcli-style-conform', -); - -Reactium.Hook.register( - 'arcli-style-preflight', - PREFLIGHT, - Reactium.Enums.priority.highest, - 'arcli-style-preflight', -); - -Reactium.Hook.register( - 'arcli-style-actions', - ({ actions }) => (actions['component'] = componentGen), - Reactium.Enums.priority.highest, - 'arcli-style-actions', -); diff --git a/.core/.cli/commands/reactium/test/actions.js b/.core/.cli/commands/reactium/test/actions.js deleted file mode 100644 index 1402e934..00000000 --- a/.core/.cli/commands/reactium/test/actions.js +++ /dev/null @@ -1,47 +0,0 @@ -const path = require('path'); -const chalk = require('chalk'); -const fs = require('fs-extra'); -const _ = require('underscore'); -const op = require('object-path'); -const handlebars = require('handlebars').compile; - -module.exports = spinner => { - const message = text => { - if (spinner) { - spinner.text = text; - } - }; - - return { - create: ({ action, params, props }) => { - const { cwd } = props; - const { destination, component } = params; - - message( - `Creating ${chalk.white(component)} ${chalk.cyan( - 'test.js', - )}...`, - ); - - const filepath = path.normalize(path.join(destination, 'test.js')); - - fs.ensureDirSync(path.normalize(destination)); - - const template = path.normalize(`${__dirname}/template/test.hbs`); - - const content = handlebars(fs.readFileSync(template, 'utf-8'))( - params, - ); - - return new Promise((resolve, reject) => { - fs.writeFile(filepath, content, error => { - if (error) { - reject(error.Error); - } else { - setTimeout(resolve, 1000, { action, status: 200 }); - } - }); - }); - }, - }; -}; diff --git a/.core/.cli/commands/reactium/test/generator.js b/.core/.cli/commands/reactium/test/generator.js deleted file mode 100644 index 1abcc105..00000000 --- a/.core/.cli/commands/reactium/test/generator.js +++ /dev/null @@ -1,26 +0,0 @@ -const ora = require('ora'); -const ActionSequence = require('action-sequence'); - -module.exports = ({ action, params, props }) => { - const spinner = ora({ - spinner: 'dots', - color: 'cyan', - }); - - spinner.start(); - - const actions = require('./actions')(spinner); - - return ActionSequence({ - actions, - options: { params, props }, - }) - .then(success => { - spinner.succeed('complete!'); - return success; - }) - .catch(error => { - spinner.fail('error!'); - return error; - }); -}; diff --git a/.core/.cli/commands/reactium/test/index.js b/.core/.cli/commands/reactium/test/index.js deleted file mode 100644 index c21d4340..00000000 --- a/.core/.cli/commands/reactium/test/index.js +++ /dev/null @@ -1,293 +0,0 @@ -/** - * ----------------------------------------------------------------------------- - * Imports - * ----------------------------------------------------------------------------- - */ - -const chalk = require('chalk'); -const generator = require('./generator'); -const prettier = require('prettier'); -const path = require('path'); -const op = require('object-path'); -const { error, message } = arcli; - -const formatDestination = (val, props) => { - const { cwd } = props; - - val = path.normalize(val); - val = String(val).replace( - /^\/components\/|^components\/|^components$/i, - `${cwd}/src/app/components/`, - ); - val = String(val).replace( - /^\/common-ui\/|^common-ui\/|^common-ui$/i, - `${cwd}/src/app/components/common-ui/`, - ); - - return path.normalize(val); -}; - -/** - * NAME String - * @description Constant defined as the command name. Value passed to the commander.command() function. - * @example $ arcli test - * @see https://www.npmjs.com/package/commander#command-specific-options - * @since 2.0.0 - */ -const NAME = 'test'; - -/** - * DESC String - * @description Constant defined as the command description. Value passed to - * the commander.desc() function. This string is also used in the --help flag output. - * @see https://www.npmjs.com/package/commander#automated---help - * @since 2.0.0 - */ -const DESC = 'Reactium: Add a jest/enzyme test to your component.'; - -/** - * CANCELED String - * @description Message sent when the command is canceled - * @since 2.0.0 - */ -const CANCELED = 'Action canceled!'; - -/** - * confirm({ props:Object, params:Object }) Function - * @description Prompts the user to confirm the operation - * @since 2.0.0 - */ -const CONFIRM = ({ props, params, msg }) => { - const { prompt } = props; - - msg = msg || chalk.white('Proceed?'); - - return new Promise((resolve, reject) => { - prompt.get( - { - properties: { - confirmed: { - description: `${msg} ${chalk.cyan('(Y/N):')}`, - type: 'string', - required: true, - pattern: /^y|n|Y|N/, - message: ` `, - before: val => { - return String(val).toUpperCase() === 'Y'; - }, - }, - }, - }, - (error, input = {}) => { - const confirmed = op.get(input, 'confirmed', false); - if (error || confirmed === false) { - reject(error); - } else { - params['confirmed'] = true; - resolve(params); - } - }, - ); - }); -}; - -/** - * conform(input:Object) Function - * @description Reduces the input object. - * @param input Object The key value pairs to reduce. - * @since 2.0.0 - */ -const CONFORM = ({ input, props }) => - Object.keys(input).reduce((output, key) => { - let val = input[key]; - switch (key) { - case 'destination': - output[key] = formatDestination(val, props); - break; - - default: - output[key] = val; - break; - } - - return output; - }, {}); - -/** - * HELP Function - * @description Function called in the commander.on('--help', callback) callback. - * @see https://www.npmjs.com/package/commander#automated---help - * @since 2.0.0 - */ -const HELP = () => - console.log(` -Example: - $ arcli test -d components/MyComponent - $ arcli test -d common-ui/MyCommonUiComponent - -When specifying the destination [-d, --destination] the following shortcuts are available: - ${chalk.cyan('components/')} The /.src/app/components directory. - ${chalk.cyan('common-ui/')} The /.src/app/components/common-ui directory. -`); - -/** - * FLAGS - * @description Array of flags passed from the commander options. - * @since 2.0.18 - */ -const FLAGS = ['component', 'destination', 'from', 'overwrite']; - -/** - * FLAGS_TO_PARAMS Function - * @description Create an object used by the prompt.override property. - * @since 2.0.18 - */ -const FLAGS_TO_PARAMS = ({ opt = {} }) => - FLAGS.reduce((obj, key) => { - let val = opt[key]; - val = typeof val === 'function' ? undefined : val; - - if (val) { - obj[key] = val; - } - - return obj; - }, {}); - -/** - * PREFLIGHT Function - */ -const PREFLIGHT = ({ msg, params, props }) => { - msg = - msg || - `A new ${chalk.cyan( - 'test.js', - )} file will be generated with the following options:`; - - message(msg); - - // Transform the preflight object instead of the params object - const preflight = { ...params }; - - console.log( - prettier.format(JSON.stringify(preflight), { - parser: 'json-stringify', - }), - ); -}; - -/** - * SCHEMA Function - * @description used to describe the input for the prompt function. - * @see https://www.npmjs.com/package/prompt - * @since 2.0.0 - */ -const SCHEMA = ({ props }) => { - return { - properties: { - destination: { - description: chalk.white('Destination:'), - message: `Enter the ${chalk.cyan('Destination')}`, - required: true, - }, - component: { - description: chalk.white('Component:'), - message: `Enter the ${chalk.cyan('Component')} name`, - required: true, - }, - from: { - description: chalk.white('Import from:'), - default: './index', - required: true, - }, - }, - }; -}; - -/** - * ACTION Function - * @description Function used as the commander.action() callback. - * @see https://www.npmjs.com/package/commander - * @param opt Object The commander options passed into the function. - * @param props Object The CLI props passed from the calling class `orcli.js`. - * @since 2.0.0 - */ -const ACTION = ({ opt, props }) => { - const { cwd, prompt } = props; - const schema = SCHEMA({ props }); - const ovr = FLAGS_TO_PARAMS({ opt }); - - if (op.has(opt, 'destination') && !op.has(opt, 'component')) { - if (String(opt.destination).split('/').length > 1) { - const comp = String(opt.destination) - .split('/') - .pop(); - if (comp) { - ovr['component'] = comp; - } - } - } - - prompt.override = ovr; - prompt.start(); - - return new Promise((resolve, reject) => { - prompt.get(schema, (err, input = {}) => { - if (err) { - prompt.stop(); - reject(`${NAME} ${err.message}`); - return; - } - - input = { ...ovr, ...input }; - params = CONFORM({ input, props }); - - PREFLIGHT({ params, props }); - - resolve(params); - }); - }) - .then(() => CONFIRM({ props, params })) - .then(async () => { - console.log(''); - await generator({ params, props }); - console.log(''); - }) - .then(() => prompt.stop()) - .catch(err => { - prompt.stop(); - message(op.get(err, 'message', CANCELED)); - }); -}; - -/** - * COMMAND Function - * @description Function that executes program.command() - */ -const COMMAND = ({ program, props }) => - program - .command(NAME) - .description(DESC) - .action(opt => ACTION({ opt, props })) - .option('-d, --destination [destination]', 'The component directory.') - .option('-c, --component [component]', 'The component name.') - .option('-o, --overwrite [overwrite]', 'Overwrite existing test file.') - .option( - '-f, --from [from]', - `The component import path relative to the ${chalk.cyan( - 'test.js', - )} file. Default: ${chalk.cyan('./index')}`, - ) - .on('--help', HELP); - -/** - * Module Constructor - * @description Internal constructor of the module that is being exported. - * @param program Class Commander.program reference. - * @param props Object The CLI props passed from the calling class `arcli.js`. - * @since 2.0.0 - */ -module.exports = { - COMMAND, - NAME, -}; diff --git a/.core/.cli/commands/reactium/test/template/test.hbs b/.core/.cli/commands/reactium/test/template/test.hbs deleted file mode 100644 index 2b4f581d..00000000 --- a/.core/.cli/commands/reactium/test/template/test.hbs +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -import {{component}} from '{{from}}'; -import { shallow } from 'reactium-core/enzyme'; - -test('<{{component}} />', () => { - const component = shallow(<{{component}} />); - - expect(component.html().length).toBeGreaterThan(0); -}); diff --git a/.core/.cli/commands/reactium/version/index.js b/.core/.cli/commands/reactium/version/index.js deleted file mode 100644 index 56ea45f9..00000000 --- a/.core/.cli/commands/reactium/version/index.js +++ /dev/null @@ -1,36 +0,0 @@ -const chalk = require('chalk'); -const path = require('path'); -const op = require('object-path'); - -const NAME = 'version'; -const DESC = 'The current Reactium Core version'; - -const ACTION = ({ opt, props }) => { - const configPath = path.normalize( - path.join(props.cwd, '/.core', 'reactium-config'), - ); - const reactiumConfig = require(configPath); - console.log(chalk.cyan('Reactium:')); - console.log( - ' ', - 'Version:', - chalk.magenta(op.get(actiniumConfig, 'version')), - ); - console.log( - ' ', - 'Semver: ', - chalk.magenta(op.get(actiniumConfig, 'semver')), - ); - console.log(''); -}; - -const COMMAND = ({ program, props }) => - program - .command(NAME) - .description(DESC) - .action(opt => ACTION({ opt, props })); - -module.exports = { - COMMAND, - NAME, -}; diff --git a/.core/.cli/config.json b/.core/.cli/config.json deleted file mode 100644 index b81b8d84..00000000 --- a/.core/.cli/config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "reactium": { - "repo": "https://github.com/Atomic-Reactor/Reactium/archive/master.zip", - "types": ["class", "functional", "hook"] - } -} diff --git a/.core/app.js b/.core/app.js deleted file mode 100644 index d72209f5..00000000 --- a/.core/app.js +++ /dev/null @@ -1 +0,0 @@ -export * from './app/index'; diff --git a/.core/app/index.js b/.core/app/index.js deleted file mode 100644 index a43b6485..00000000 --- a/.core/app/index.js +++ /dev/null @@ -1,185 +0,0 @@ -/** - * ----------------------------------------------------------------------------- - * Includes - * ----------------------------------------------------------------------------- - */ -import React from 'react'; -import _ from 'underscore'; -import deps from 'dependencies'; -import 'externals'; - -const loadFramework = async () => { - console.log('Loading Core SDK'); - const { default: Reactium } = await import('reactium-core/sdk'); - - console.log('Initializing Application Hooks'); - - await deps().loadAll('allHooks'); - - /** - * @api {Hook} sdk-init sdk-init - * @apiName sdk-init - * @apiDescription Called after reactium-hooks.js DDD artifacts are loaded, to allow - * the Reactium SDK singleton to be extended before the init hook. - * @apiGroup Hooks - */ - await Reactium.Hook.run('sdk-init', Reactium); - Reactium.Hook.runSync('sdk-init', Reactium); - - /** - * @api {Hook} init init - * @apiName init - * @apiDescription Called before all other hooks on Reactium application startup. async only - used in - front-end - * @apiGroup Hooks - */ - await Reactium.Hook.run('init'); - - /** - * @api {Hook} dependencies-load dependencies-load - * @apiName dependencies-load - * @apiDescription Called after init to give an application a change to load - async dependencies. Many Domain Driven Design (DDD) artifacts from generated src/manifest.js are loaded on this hook - async only - used in front-end - * @apiGroup Hooks - */ - await Reactium.Hook.run('dependencies-load'); - - /** - * @api {Hook} zone-defaults zone-defaults - * @apiName zone-defaults - * @apiDescription Called after dependencies-load by Reactium.Zone.init() for - loading default component rendering Zone controls and components. - async only - used in front-end - * @apiParam {Object} context used to create initial controls and components. - controls.filter for default filtering, controls.sort for default sorting, controls.mapper for default mapping - and controls.components for initial registered components. zone.js Domain Driven Design (DDD) artifacts from generated src/manifest.js - are registered with Reactium.Zone at this time. See Reactium.Zone SDK for runtime operations. - * @apiGroup Hooks - */ - // Note: zone-defaults is run from @atomic-reactor/reactium-sdk-core inside Zone.init() - await Reactium.Zone.init(); - - /** - * @api {Hook} plugin-dependencies plugin-dependencies - * @apiName plugin-dependencies - * @apiDescription Called to indicate all bootstrap dependencies should now be loaded, but before application routes have been initialized. - There are 2 default registered callback in Reactium core on this hook. - 1. (Highest Priority): The generated src/manifest.js dependencies are attached - to this hook context (as context.deps). - 2. (High Priority): `plugin-init` hook will be invoked, at which point all Reactium.Plugin registrations will be called. - - Any hooks that registered after Reactium.Plugin will only be useful if they happen to be invoked during the normal runtime operations of the application. - An important exception to this is `routes-init`, which is deferred until after plugins initialize so they may dynamically add routes before Reactium hands off - control to the Router. - async only - used in front-end - * @apiParam {Object} context Core attaches generated manifest loaded dependencies to context.deps - * @apiGroup Hooks - */ - await Reactium.Hook.run('plugin-dependencies'); - await Reactium.Routing.load(); - - /** - * @api {Hook} plugin-ready plugin-ready - * @apiName plugin-ready - * @apiDescription Called after all plugin registration callbacks have completed and routes have loaded. - * @apiGroup Hooks - */ - await Reactium.Hook.run('plugin-ready'); -}; - -/** - * ----------------------------------------------------------------------------- - * @function App() - * @description Scan DOM for elements and render React components - * inside of them. - * ----------------------------------------------------------------------------- - */ -export const App = async () => { - const { - default: Reactium, - hookableComponent, - Zone, - AppContexts, - } = await import('reactium-core/sdk'); - - await loadFramework(); - - /** - * @api {Hook} component-bindings component-bindings - * @apiName component-bindings - * @apiDescription Called after plugin and routing initialization to define element and dynamic component for - one-off component bindings to the DOM. e.g. In development mode, used to render Redux Dev tools. - async only - used in front-end application only - * @apiParam {Object} context context.bindPoints MUST be an array of binding objects after this hook is called - * @apiParam (binding) {HTMLElement} the DOM element to bind to (e.g. document.getElementById('my-element')) - * @apiParam (binding) {String} string matching a React component module in one of the Reactium built-in webpack contexts - (src/app/components or src/app/components/common-ui) e.g. 'DevTools' maps to src/app/components/DevTools - * @apiGroup Hooks - */ - const { bindPoints } = await Reactium.Hook.run('component-bindings'); - - /** - * @api {Hook} app-context-provider app-context-provider - * @apiName app-context-provider - * @apiDescription Called after app-bindpoint to define any React context providers, using the [Reactium.AppContext](#api-Reactium-Reactium.AppContext) registry. - * @apiGroup Hooks - */ - await Reactium.Hook.run('app-context-provider'); - - // Render the React Components - if (bindPoints.length > 0) { - const { createRoot } = await import('react-dom/client'); - - console.log('Binding components.'); - for (const { type, Component, Element } of bindPoints) { - if (type === 'App') { - /** - * @api {Hook} app-router app-router - * @apiName app-router - * @apiDescription Called after app-context-provider to define the registered Router component (i.e. `Reactium.Component.register('Router'...)`). - After this hook, the ReactDOM bindings will actually take place. - async only - used in front-end application only - * @apiGroup Hooks - */ - await Reactium.Hook.run('app-router'); - - const Router = hookableComponent('Router'); - const { message = [] } = await Reactium.Hook.run( - 'app-boot-message', - ); - - console.log(...message); - - createRoot(Element).render( - - - - - , - ); - - /** - * @api {Hook} app-ready app-ready - * @apiDescription The final hook run after the front-end application has bee bound or hydrated. After this point, - the all hooks are runtime hooks. - * @apiName app-ready - * @apiGroup Hooks - */ - } else { - // createRoot(Element).render(); - createRoot(Element).render( - - - , - ); - } - } - - _.defer(() => Reactium.Hook.run('app-ready')); - } -}; - -export const AppError = async error => { - console.error(error); -}; diff --git a/.core/app/reactium-hooks.js b/.core/app/reactium-hooks.js deleted file mode 100644 index 4bd9ff55..00000000 --- a/.core/app/reactium-hooks.js +++ /dev/null @@ -1,172 +0,0 @@ -import 'reactium-core/components/Router/reactium-hooks'; -import op from 'object-path'; -import _ from 'underscore'; -import deps from 'dependencies'; - -import('reactium-core/sdk').then( - async ({ default: Reactium, ReactiumSyncState }) => { - Reactium.Hook.register( - 'component-bindings', - async context => { - const { hookableComponent } = await import('reactium-core/sdk'); - - // Placeholder for the bindable elements - const bindPoints = []; - - const elements = Array.from( - document.querySelectorAll('[data-reactium-bind]'), - ); - - if (elements.length > 0) { - let types = []; - for (const Element of elements) { - const type = Element.getAttribute('data-reactium-bind'); - const Component = hookableComponent(type); - bindPoints.push({ type, Element, Component }); - } - } - - context.bindPoints = bindPoints; - return Promise.resolve(); - }, - Reactium.Enums.priority.highest, - 'REACTIUM_COMPONENT_BINDINGS', - ); - - Reactium.Hook.register( - 'plugin-dependencies', - context => { - // Setup plugin registration - context.deps = deps(); - - console.log('Plugin dependencies.'); - return Promise.resolve(); - }, - Reactium.Enums.priority.highest, - 'REACTIUM_PLUGIN_DEPENDENCIES', - ); - - Reactium.Hook.register( - 'app-bindpoint', - context => { - context.appElement = document.getElementById('router'); - return Promise.resolve(); - }, - Reactium.Enums.priority.highest, - 'REACTIUM_APP_BINDPOINT', - ); - - const getSaneZoneComponents = () => { - return ( - // allow array of DDD zone components - _.flatten(_.compact(Object.values(deps().plugins)), true) - // remove DDD zone components missing zones - .filter(({ zone }) => { - if (!zone) return false; - if (Array.isArray(zone) && zone.length < 1) - return false; - return true; - }) - // normalize zone property - .map(component => { - let { zone } = component; - if (!Array.isArray(zone)) { - zone = [zone]; - } - return { - ...component, - zone, - }; - }) - ); - }; - - Reactium.Hook.register( - 'zone-defaults', - async context => { - op.set(context, 'controls', deps().plugableConfig); - op.set(context, 'components', getSaneZoneComponents()); - console.log('Initializing Content Zones'); - }, - Reactium.Enums.priority.highest, - 'REACTIUM_ZONE_DEFAULTS', - ); - - Reactium.Hook.register( - 'app-router', - async () => { - const { Router } = await import( - 'reactium-core/components/Router' - ); - Reactium.Component.register('Router', Router); - console.log('Defining Router.'); - }, - Reactium.Enums.priority.highest, - 'REACTIUM_APP_ROUTER', - ); - - Reactium.Hook.register( - 'app-boot-message', - context => { - context.message = [ - `%c [Reactium] %c⚡💡 %cBinding Reactium. %c⚡💡 `, - 'font-size: 16px; color: #fff; background-color: #4F82BA', - 'font-size: 16px; color: #F4F19C; background-color: #4F82BA', - 'font-size: 16px; color: #fff; background-color: #4F82BA', - 'font-size: 16px; color: #F4F19C; background-color: #4F82BA', - ]; - - return Promise.resolve(); - }, - Reactium.Enums.priority.highest, - 'REACTIUM_APP_BOOT_MESSAGE', - ); - - Reactium.Hook.register( - 'sdk-init', - async Reactium => { - Reactium.State = new ReactiumSyncState( - op.get(window, 'state', {}), - ); - }, - Reactium.Enums.priority.highest, - 'REACTIUM_STATE_INIT', - ); - }, -); - -/** - * @api {Hook} dependencies-load dependencies-load - * @apiName dependencies-load - * @apiDescription Called after init to give an application a change to load - async dependencies. Many Domain Driven Design (DDD) artifacts from generated src/manifest.js are loaded on this hook - async only - used in front-end - * @apiGroup Hooks - */ - -/** - * @api {Hook} Hooks Hooks - * @apiName Hooks - * @apiDescription Here are the standard hooks that fire (in order) on the bootstrap of your Reactium application. - | Hook | Description | -| :---- | :----- | -| init | Called before all other hooks on startup. | -| dependencies-load | Called while application dependencies are loaded. | -| service-worker-init | Called while service worker is loaded. | -| zone-defaults | Called while rendering zone default components are loaded. | -| store-create | Called while Redux store is being created. | -| store-created | Called after Redux store is created. | -| plugin-dependencies | Called before loading runtime plugins. | -| plugin-init | Called to initiate plugin registration. | -| routes-init | Called to initiaze React router | -| register-route | Called for each route that is registered | -| data-loaded | Called on route load to pre-load data | -| plugin-ready | Called after all plugins registration callbacks have completed | -| component-bindings | Called to sibling React components and their DOM element bindings | -| app-bindpoint | Called to define the main application bind point. | -| app-context-provider | Called to define React application-wrapping context providers, such as Redux / Theme, etc. | -| app-router | Called to provide the React router component | -| app-boot-message | Called to define the javascript console boot message | -| app-ready | Called when the application is being bound or hydrated by ReactDOM | - * @apiGroup Hooks - */ diff --git a/.core/app/shell.js b/.core/app/shell.js deleted file mode 100644 index 30885194..00000000 --- a/.core/app/shell.js +++ /dev/null @@ -1,39 +0,0 @@ -const onLoaded = () => { - if ( - window.LoadingRef && - window.LoadingRef.current && - typeof window.LoadingRef.current.setVisible == 'function' - ) { - window.LoadingRef.current.setVisible(false); - } -}; - -export const Shell = async ( - LoadingComponent, - loadCb = onLoaded, - delay = 250, -) => { - const { default: React, useRef } = await import('react'); - const { createRoot } = await import('react-dom/client'); - - let Loading; - if (LoadingComponent) Loading = LoadingComponent; - else { - const mod = await import('../components/Loading'); - Loading = mod.Loading; - } - - const Shell = () => { - window.LoadingRef = useRef(); - return ; - }; - - const something = createRoot( - document.body.appendChild(document.createElement('div')), - ).render(); - - const { App } = await import('./index'); - await App(); - - setTimeout(loadCb, delay); -}; diff --git a/.core/assets/images/a11y/a11y.svg b/.core/assets/images/a11y/a11y.svg deleted file mode 100644 index bbc0754b..00000000 --- a/.core/assets/images/a11y/a11y.svg +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.core/babel.config.js b/.core/babel.config.js deleted file mode 100644 index baef3bd6..00000000 --- a/.core/babel.config.js +++ /dev/null @@ -1,212 +0,0 @@ -const ReactiumBabel = require('@atomic-reactor/reactium-sdk-core').default; -const fs = require('fs'); -const path = require('path'); -const globby = require('./globby-patch').sync; -const rootPath = path.resolve(__dirname, '..'); -const chalk = require('chalk'); -const semver = require('semver'); -const op = require('object-path'); -const babelCoreVersion = op.get( - require(path.resolve( - path.dirname(require.resolve('@babel/core')), - '../package.json', - )), - 'version', -); -const coreJsVersion = op.get( - require(path.resolve( - path.dirname(require.resolve('core-js')), - 'package.json', - )), - 'version', -); - -let corejs; -// annoying warning starts with @babel/core 7.4.0 -if (semver.satisfies(semver.coerce(babelCoreVersion), '^7.4.0')) { - if (semver.satisfies(semver.coerce(coreJsVersion), '>=2.0.0')) { - corejs = '2'; - } - if (semver.satisfies(semver.coerce(coreJsVersion), '>=3.0.0')) { - corejs = '3'; - } -} - -require('./reactium.log.cjs'); - -global.ReactiumBabel = ReactiumBabel; - -// Load reactium-gulp DDD artifact from plugin sources -globby([ - `${rootPath}/.core/**/reactium-babel.js`, - `${rootPath}/src/**/reactium-babel.js`, - `${rootPath}/reactium_modules/**/reactium-babel.js`, - `${rootPath}/node_modules/**/reactium-plugin/**/reactium-babel.js`, -]).forEach(item => { - const p = path.normalize(item); - try { - require(p); - } catch (error) { - console.error(chalk.red(`Error loading ${p}:`)); - console.error(error); - } -}); - -/** - * Babel Module Aliases - for babel-plugin-module-resolver - */ -ReactiumBabel.ModuleAliases = ReactiumBabel.Utils.registryFactory( - 'BabelAliases', - 'alias', - ReactiumBabel.Utils.Registry.MODES.CLEAN, -); -ReactiumBabel.ModuleAliases.register('externals', { - path: './src/externals-manifest', -}); -ReactiumBabel.ModuleAliases.register('manifest', { - path: './src/manifest', -}); -ReactiumBabel.ModuleAliases.register('appdir', { path: './src/app' }); -ReactiumBabel.ModuleAliases.register('components', { - path: './src/app/components', -}); -ReactiumBabel.ModuleAliases.register('reactium-core', { - path: './.core', -}); -ReactiumBabel.ModuleAliases.register('reactium_modules', { - path: './reactium_modules', -}); -ReactiumBabel.ModuleAliases.register('dependencies', { - path: './.core/dependencies', -}); -ReactiumBabel.ModuleAliases.register('toolkit', { - path: './src/app/toolkit', -}); -ReactiumBabel.ModuleAliases.register('reactium-translations', { - path: './src/reactium-translations', -}); - -ReactiumBabel.Hook.runSync('aliases', ReactiumBabel.ModuleAliases); - -/** - * @babel/env configuration - */ -ReactiumBabel.env = { - ...(corejs ? { corejs } : {}), - useBuiltIns: 'usage', - debug: false, - targets: { - browsers: ['> 1%', 'IE 11'], - }, -}; - -if (!global.ReactiumWebpack) ReactiumBabel.env.targets = { node: '18' }; - -ReactiumBabel.Hook.runSync('env', ReactiumBabel.env); - -/** - * Babel Presets - */ -ReactiumBabel.Presets = ReactiumBabel.Utils.registryFactory( - 'BabelPreset', - 'name', - ReactiumBabel.Utils.Registry.MODES.CLEAN, -); -ReactiumBabel.Presets.register('@babel/react', { - preset: '@babel/react', - envs: ['default', 'test', 'library'], -}); -ReactiumBabel.Presets.register('@babel/env', { - preset: ['@babel/env', ReactiumBabel.env], - envs: ['default', 'test', 'library'], -}); - -ReactiumBabel.Hook.runSync('presets', ReactiumBabel.Presets); - -/** - * Babel Plugins - */ -ReactiumBabel.Plugins = ReactiumBabel.Utils.registryFactory( - 'BabelPlugins', - 'name', - ReactiumBabel.Utils.Registry.MODES.CLEAN, -); - -ReactiumBabel.Plugins.register('@babel/plugin-syntax-dynamic-import', { - plugin: ['@babel/plugin-syntax-dynamic-import'], - envs: ['default', 'test', 'library'], -}); - -ReactiumBabel.Plugins.register('module-resolver', { - plugin: [ - 'module-resolver', - { - cwd: rootPath, - alias: ReactiumBabel.ModuleAliases.list.reduce( - (aliases, { alias, path }) => { - aliases[alias] = path; - return aliases; - }, - {}, - ), - }, - ], - envs: ['default', 'test', 'library'], -}); - -ReactiumBabel.Plugins.register('@babel/plugin-proposal-class-properties', { - plugin: ['@babel/plugin-proposal-class-properties', { loose: true }], - envs: ['default', 'test', 'library'], -}); - -ReactiumBabel.Plugins.register('@babel/plugin-proposal-export-default-from', { - plugin: ['@babel/plugin-proposal-export-default-from'], - envs: ['default', 'test', 'library'], -}); - -ReactiumBabel.Plugins.register('@babel/plugin-proposal-private-methods', { - plugin: ['@babel/plugin-proposal-private-methods', { loose: true }], - envs: ['default', 'test', 'library'], -}); - -ReactiumBabel.Plugins.register( - '@babel/plugin-proposal-private-property-in-object', - { - plugin: [ - '@babel/plugin-proposal-private-property-in-object', - { loose: true }, - ], - envs: ['default', 'test', 'library'], - }, -); - -ReactiumBabel.Hook.runSync('plugins', ReactiumBabel.Plugins); - -ReactiumBabel.envs = ['default', 'test', 'library']; -ReactiumBabel.Hook.runSync('envs', ReactiumBabel.envs); - -const config = { - presets: ReactiumBabel.Presets.list - .filter(preset => op.get(preset, 'envs', []).includes('default')) - .map(({ preset }) => preset), - plugins: ReactiumBabel.Plugins.list - .filter(plugin => op.get(plugin, 'envs', []).includes('default')) - .map(({ plugin }) => plugin), - env: ReactiumBabel.envs - .filter(env => env !== 'default') - .reduce((envs, env) => { - envs[env] = { - presets: ReactiumBabel.Presets.list - .filter(preset => op.get(preset, 'envs', []).includes(env)) - .map(({ preset }) => preset), - plugins: ReactiumBabel.Plugins.list - .filter(plugin => op.get(plugin, 'envs', []).includes(env)) - .map(({ plugin }) => plugin), - }; - return envs; - }, {}), -}; - -ReactiumBabel.Hook.runSync('config', config); - -module.exports = config; diff --git a/.core/boot-hooks.mjs b/.core/boot-hooks.mjs deleted file mode 100644 index 79000b19..00000000 --- a/.core/boot-hooks.mjs +++ /dev/null @@ -1,46 +0,0 @@ -import _ from 'underscore'; -import path from 'node:path'; -import globbyPatched from './globby-patch.js' -import { dirname } from '@atomic-reactor/dirname'; - -const __dirname = dirname(import.meta.url); -const globby = globbyPatched.sync; - -global.rootPath = path.resolve(__dirname, '..'); - -export default async () => { - // include boot DDD artifacts - if (!global.bootHooks) { - global.bootHooks = globby([ - `${rootPath}/.core/**/reactium-boot.js`, - `${rootPath}/.core/**/reactium-boot.mjs`, - `${rootPath}/.core/**/reactium-boot.cjs`, - `${rootPath}/src/**/reactium-boot.js`, - `${rootPath}/src/**/reactium-boot.mjs`, - `${rootPath}/src/**/reactium-boot.cjs`, - `${rootPath}/reactium_modules/**/reactium-boot.js`, - `${rootPath}/reactium_modules/**/reactium-boot.mjs`, - `${rootPath}/reactium_modules/**/reactium-boot.cjs`, - `${rootPath}/node_modules/**/reactium-plugin/**/reactium-boot.js`, - `${rootPath}/node_modules/**/reactium-plugin/**/reactium-boot.mjs`, - `${rootPath}/node_modules/**/reactium-plugin/**/reactium-boot.cjs`, - ]); - } - - if (!global.bootHookLoaded) { - DEBUG('Loading boot hooks.'); - global.bootHookLoaded = []; - for (const item of global.bootHooks) { - if (!bootHookLoaded.includes(item)) { - const p = path.normalize(item); - await import(p); - bootHookLoaded.push(item); - } - } - - ReactiumBoot.Hook.runSync('sdk-init', ReactiumBoot); - await ReactiumBoot.Hook.run('sdk-init', ReactiumBoot); - } else { - DEBUG('Boot hooks already loaded.'); - } -}; diff --git a/.core/components/DevTools/index.js b/.core/components/DevTools/index.js deleted file mode 100644 index ad0e2a8c..00000000 --- a/.core/components/DevTools/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react'; -import { useHookComponent } from 'reactium-core/sdk'; - -export default () => { - const DevTools = useHookComponent('DevTools'); - return ; -}; diff --git a/.core/components/Loading/domain.js b/.core/components/Loading/domain.js deleted file mode 100644 index b5caa9e5..00000000 --- a/.core/components/Loading/domain.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * ----------------------------------------------------------------------------- - * DDD Domain Loading - Change name to place domain artifacts in this directory - * in a different domain. - * ----------------------------------------------------------------------------- - */ -module.exports = { - name: 'LoadingSpinner', -}; diff --git a/.core/components/Loading/index.js b/.core/components/Loading/index.js deleted file mode 100644 index 4c92f215..00000000 --- a/.core/components/Loading/index.js +++ /dev/null @@ -1,146 +0,0 @@ -import op from 'object-path'; -import ReactDom from 'react-dom'; -import PropTypes from 'prop-types'; - -import React, { - forwardRef, - useEffect, - useImperativeHandle, - useRef, - useState, -} from 'react'; - -/** - * ----------------------------------------------------------------------------- - * Functional Component: Loading - * ----------------------------------------------------------------------------- - */ -let Loading = ( - { controlled, visible: initVisible, style: initStyle, ...props }, - ref, -) => { - const containerRef = useRef(); - const ival = useRef(); - const opacity = useRef(initVisible === true ? 1 : 0); - - const [visible, setVisible] = useState(initVisible); - - const [init, setInit] = useState(false); - - const [style, setStyle] = useState({ - ...initStyle, - display: opacity.current === 1 ? null : 'none', - opacity: opacity.current, - }); - - const show = () => { - let i = ival.current; - if (i) clearInterval(i); - - const cont = containerRef.current; - if (cont) { - cont.style.display = null; - if (init !== true) { - cont.style.opacity = 0; - } - } - - i = setInterval(() => { - opacity.current = opacity.current + 0.0125; - opacity.current = Math.min(opacity.current, 1); - - if (cont) cont.style.opacity = opacity.current; - - if (opacity.current === 1) { - clearInterval(i); - setStyle({ ...style, display: null }); - } - }, 1); - - ival.current = i; - }; - - const hide = () => { - let i = ival.current; - if (i) clearInterval(i); - const cont = containerRef.current; - - i = setInterval(() => { - opacity.current = opacity.current - 0.0125; - opacity.current = Math.max(opacity.current, 0); - - if (cont) cont.style.opacity = opacity.current; - - if (opacity.current === 0) { - cont.style.display = 'none'; - clearInterval(i); - setStyle({ ...style, opacity: null }); - } - }, 1); - - ival.current = i; - }; - - useImperativeHandle( - ref, - () => ({ - ...props, - hide, - show, - containerRef, - visible, - setStyle, - setVisible, - }), - [visible], - ); - - useEffect(() => { - if (controlled === true) { - const val = op.get(props, 'visible'); - if (val !== visible) setVisible(val); - } - }, [controlled, initVisible]); - - useEffect(() => { - if (controlled === true) { - const val = op.get(props, 'style'); - if (val !== style) setStyle(val); - } - }, [controlled, initStyle]); - - useEffect(() => { - if (visible === true) { - show(); - } else { - hide(); - } - }, [visible]); - - useEffect(() => { - setInit(true); - }, []); - - return ReactDom.createPortal( -
, - document.body, - ); -}; - -Loading = forwardRef(Loading); - -Loading.propTypes = { - className: PropTypes.string, - controlled: PropTypes.bool, - style: PropTypes.object, - visible: PropTypes.bool, -}; - -Loading.defaultProps = { - className: 'reactium-loading', - controlled: false, - style: {}, - visible: true, -}; - -export { Loading }; diff --git a/.core/components/Loading/reactium-hooks.js b/.core/components/Loading/reactium-hooks.js deleted file mode 100644 index f334759f..00000000 --- a/.core/components/Loading/reactium-hooks.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * ----------------------------------------------------------------------------- - * Reactium Plugin Loading - * ----------------------------------------------------------------------------- - */ - -import { Loading } from './index'; -import Reactium from 'reactium-core/sdk'; - -(async () => { - Reactium.Component.register('Loading', Loading); -})(); diff --git a/.core/components/NotFound/index.js b/.core/components/NotFound/index.js deleted file mode 100644 index 43625600..00000000 --- a/.core/components/NotFound/index.js +++ /dev/null @@ -1,24 +0,0 @@ -import React, { useEffect } from 'react'; -import Reactium, { __, Zone } from 'reactium-core/sdk'; - -const DefaultComponent = () => { - const comps = Reactium.Zone.getZoneComponents('not-found'); - - if (comps.length < 1) { - Reactium.Zone.addComponent({ - zone: 'not-found', - id: 'NOT_FOUND_DEFAULT', - component: () => __('PAGE NOT FOUND'), - order: Reactium.Enums.priority.highest, - }); - - return () => { - Reactium.Zone.removeComponent('NOT_FOUND_DEFAULT'); - }; - } -}; - -export default () => { - useEffect(DefaultComponent, []); - return ; -}; diff --git a/.core/components/Plugable/Plugins.js b/.core/components/Plugable/Plugins.js deleted file mode 100644 index 29142484..00000000 --- a/.core/components/Plugable/Plugins.js +++ /dev/null @@ -1,5 +0,0 @@ -export { Zone as default } from '@atomic-reactor/reactium-sdk-core'; - -console.log( - "You imported from reactium-core/components/Plugable/Plugins which is deprecated. Use useHookComponent('Zone') instead, or import from reactium-core/components/Plugable/Zone", -); diff --git a/.core/components/Plugable/index.js b/.core/components/Plugable/index.js deleted file mode 100644 index c4d91fa2..00000000 --- a/.core/components/Plugable/index.js +++ /dev/null @@ -1,6 +0,0 @@ -export { Zone as Plugins } from '@atomic-reactor/reactium-sdk-core'; -export { Zone } from '@atomic-reactor/reactium-sdk-core'; - -console.log( - "You imported from reactium-core/components/Plugable which is deprecated. Use useHookComponent('Zone') instead, or import { Zone } from reactium-core/sdk", -); diff --git a/.core/components/Plugable/reducers.js b/.core/components/Plugable/reducers.js deleted file mode 100644 index 121deb15..00000000 --- a/.core/components/Plugable/reducers.js +++ /dev/null @@ -1,30 +0,0 @@ -export default (state = {}, action) => { - switch (action.type) { - case 'ADD_PLUGIN': - case 'UPDATE_PLUGIN': - case 'REMOVE_PLUGIN': - case 'ADD_PLUGIN_CONTROLS': - case 'REMOVE_PLUGIN_CONTROLS': - console.log( - `action ${action.type} is no longer used. See one of the following Reactium.Zone SDK functions.`, - ); - console.log( - `Use Reactium.Zone.addComponent() instead of dispatching the ADD_PLUGIN action type.`, - ); - console.log( - `Use Reactium.Zone.removeComponent() instead of dispatching the REMOVE_PLUGIN action type.`, - ); - console.log( - `Use Reactium.Zone.addFilter() to add a filter function to a zone where your component is rendered.`, - ); - console.log( - `Use Reactium.Zone.addMap() to add a mapping function to a zone where your component is rendered.`, - ); - console.log( - `Use Reactium.Zone.addSort() to add sortBy criteria to a zone where your component is rendered.`, - ); - default: - return state; - } - return state; -}; diff --git a/.core/components/Plugable/state.js b/.core/components/Plugable/state.js deleted file mode 100644 index ff8b4c56..00000000 --- a/.core/components/Plugable/state.js +++ /dev/null @@ -1 +0,0 @@ -export default {}; diff --git a/.core/components/Router/RoutedContent.js b/.core/components/Router/RoutedContent.js deleted file mode 100644 index eb0be9d7..00000000 --- a/.core/components/Router/RoutedContent.js +++ /dev/null @@ -1,38 +0,0 @@ -import React, { useEffect } from 'react'; -import Reactium, { useRouting, useSyncState } from 'reactium-core/sdk'; -import { Route } from 'react-router'; -import op from 'object-path'; - -const useRoutes = () => { - const routeState = useSyncState(Reactium.Routing.get()); - const setState = () => { - routeState.set(Reactium.Routing.get()); - }; - - useEffect(() => { - setState(); - return Reactium.Routing.subscribe(setState); - }, []); - - return routeState; -}; - -const RoutedContent = () => { - // cause rerender if routes are added/removed at runtime - useRoutes(); - const routing = useRouting(); - const route = routing.get('active.match.route'); - const Component = routing.get('active.match.route.component'); - - // if we have a route with no component, let react-router handle it however it will - return Component ? ( - - ) : ( - - ); -}; - -export default RoutedContent; diff --git a/.core/components/Router/index.js b/.core/components/Router/index.js deleted file mode 100644 index dab11474..00000000 --- a/.core/components/Router/index.js +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import { Router as Dom, Switch } from 'react-router-dom'; -import { useHookComponent } from 'reactium-core/sdk'; - -export const Router = ({ history }) => { - const RoutedContent = useHookComponent('RoutedContent'); - return ( - - - - - - ); -}; diff --git a/.core/components/Router/reactium-hooks.js b/.core/components/Router/reactium-hooks.js deleted file mode 100644 index f34c7218..00000000 --- a/.core/components/Router/reactium-hooks.js +++ /dev/null @@ -1,68 +0,0 @@ -import Reactium, { - hookableComponent, - isBrowserWindow, -} from 'reactium-core/sdk'; -import _ from 'underscore'; -import RoutedContent from './RoutedContent'; -import deps from 'dependencies'; - -Reactium.Hook.register( - 'routes-init', - async Routing => { - const allRoutes = await deps().loadAllDefaults('allRoutes'); - if (!Object.values(allRoutes || {}).length) { - return []; - } - - let globalRoutes = []; - if (isBrowserWindow()) { - if ('routes' in window && Array.isArray(window.routes)) { - globalRoutes = window.routes; - } - } else { - if ('routes' in global && Array.isArray(global.routes)) { - globalRoutes = global.routes; - } - } - - const combinedRoutes = _.chain( - Object.values(allRoutes || {}) - .concat(globalRoutes) - .filter(route => route) - .map(route => _.flatten([route])), - ) - .flatten() - .compact() - .value(); - - for (const route of combinedRoutes) { - const paths = _.compact(_.flatten([route.path])); - for (const path of paths) { - await Reactium.Routing.register( - { - ...route, - path, - }, - false, - ); - } - } - }, - Reactium.Enums.priority.highest, - 'REACTIUM_ROUTES_INIT', -); - -Reactium.Hook.register( - 'register-route', - async route => { - if (typeof route.component === 'string') { - route.component = hookableComponent(route.component); - } - - return route; - }, - Reactium.Enums.priority.highest, - 'REACTIUM_REGISTER_ROUTE', -); - -Reactium.Component.register('RoutedContent', RoutedContent); diff --git a/.core/components/WindowProvider/index.js b/.core/components/WindowProvider/index.js deleted file mode 100644 index 7c40ca5a..00000000 --- a/.core/components/WindowProvider/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import { createContext } from 'react'; -import { isBrowserWindow } from '@atomic-reactor/reactium-sdk-core'; - -export const Context = createContext({ - iWindow: isBrowserWindow() ? window : undefined, - iDocument: isBrowserWindow() ? document : undefined, -}); diff --git a/.core/dependencies/getComponents.js b/.core/dependencies/getComponents.js deleted file mode 100644 index d8b3117e..00000000 --- a/.core/dependencies/getComponents.js +++ /dev/null @@ -1,8 +0,0 @@ -import { hookableComponent } from '../sdk/named-exports'; - -export default (elms = []) => - elms.reduce((cmps, { type, path }) => { - if (path) console.warn('path no longer supported in getComponents'); - cmps[type] = hookableComponent(type); - return cmps; - }, {}); diff --git a/.core/dependencies/index.js b/.core/dependencies/index.js deleted file mode 100644 index 7ed0e898..00000000 --- a/.core/dependencies/index.js +++ /dev/null @@ -1,161 +0,0 @@ -import op from 'object-path'; -import _ from 'underscore'; -import Reactium, { isBrowserWindow } from 'reactium-core/sdk'; -import manifestLoader from 'manifest'; - -class ReactiumDependencies { - constructor() { - this.loaded = false; - this.loadedModules = {}; - this.services = {}; - this.plugins = {}; - this.plugableConfig = {}; - - // Just used to determine if is a custom type - this.coreTypes = ['allServices', 'allPlugins', 'allHooks']; - - // Things to be mapped on deps now - this.coreTypeMap = { - allServices: 'services', - allPlugins: 'plugins', - }; - } - - async loadAllMerged(type) { - const all = await this.loadAll(type); - - return all.reduce( - (merged, current) => ({ - ...merged, - [current.domain]: current.module.default, - }), - {}, - ); - } - - async loadAllDefaults(type) { - return (await this.loadAll(type)).map(dep => { - return dep.module.default; - }); - } - - async loadAll(type) { - return _.compact( - await Promise.all( - op.get(this.manifest, [type], []).map(async dep => { - try { - const { name, domain, loader } = dep; - const { load = true } = await Reactium.Hook.run( - 'load-dependency', - { name, domain, module }, - Reactium.Enums.priority.highest, - 'REACTIUM-DEP-MODULE-LOAD', - ); - - if (load) { - if (op.has(this, ['loadedModules', name, domain])) { - const loadedModule = op.get(this, [ - 'loadedModules', - name, - domain, - ]); - - return loadedModule; - } else { - const loadedModule = await loader(); - const { name, domain } = loadedModule; - - op.set( - this, - ['loadedModules', name, domain], - loadedModule, - ); - - return loadedModule; - } - } - } catch (error) { - console.error('loadAll error', error); - return Promise.resolve(undefined); - } - - return; - }), - ), - ); - } - - async load() { - if (!this.loaded) { - console.log('Loading core dependencies.'); - for (const depType of Object.keys(this.manifest)) { - if ( - depType in this.coreTypeMap || - !this.coreTypes.includes(depType) - ) { - const binding = op.get( - this.coreTypeMap, - [depType], - depType, - ); - for (const { name, domain, module } of await this.loadAll( - depType, - )) { - op.set(this, [binding, domain], module.default); - if (binding === 'actionTypes') { - for (const [key, value] of Object.entries( - module.default, - )) { - op.set(this, [binding, key], value); - } - } else { - op.set(this, [binding, domain], module.default); - } - } - } - } - - try { - let plugableConfig = await import('appdir/plugable'); - if ('default' in plugableConfig) { - plugableConfig = plugableConfig.default; - } - this.plugableConfig = plugableConfig; - } catch (error) {} - - this.loaded = true; - } - - return Promise.resolve(this); - } -} - -const dependencies = new ReactiumDependencies(); - -export default () => dependencies; - -export const restHeaders = () => { - return {}; -}; - -// File scoped -try { - dependencies.manifest = manifestLoader.get(); -} catch (error) { - if (isBrowserWindow()) { - console.error('Error loading dependencies from manifest.', error); - } else { - console.error( - 'Error loading dependencies from manifest on server.', - error, - ); - } -} - -export const manifest = dependencies.manifest; - -Reactium.Hook.register( - 'dependencies-load', - dependencies.load.bind(dependencies), - Reactium.Enums.priority.highest, -); diff --git a/.core/easy-connect.js b/.core/easy-connect.js deleted file mode 100644 index 4d5c6043..00000000 --- a/.core/easy-connect.js +++ /dev/null @@ -1,6 +0,0 @@ -export * from 'reactium-core/sdk'; - -console.log( - '%cImporting from `reactium-core/easy-connect` is deprecated. Import from `reactium-core/sdk` instead.', - 'font-size: 12px; color: #F4F19C; background-color: #4F82BA', -); diff --git a/.core/enzyme.js b/.core/enzyme.js deleted file mode 100644 index 7c60d45f..00000000 --- a/.core/enzyme.js +++ /dev/null @@ -1,7 +0,0 @@ -import Enzyme, { configure, shallow, mount, render } from 'enzyme'; -import Adapter from 'enzyme-adapter-react-16'; - -configure({ adapter: new Adapter() }); - -export { shallow, mount, render }; -export default Enzyme; diff --git a/.core/get-task.js b/.core/get-task.js deleted file mode 100644 index 1606ba39..00000000 --- a/.core/get-task.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = gulp => name => { - const func = function(done) { - return gulp.task(name)(done); - }; - func.displayName = name; - - return func; -}; diff --git a/.core/globby-patch.js b/.core/globby-patch.js deleted file mode 100644 index a478b34c..00000000 --- a/.core/globby-patch.js +++ /dev/null @@ -1,15 +0,0 @@ -const globby = require('globby'); -const path = require('path'); -const _ = require('underscore'); - -const sync = globby.sync; -globby.sync = (patterns, options) => { - return sync( - _.compact(_.flatten([patterns])).map(pattern => - pattern.split(/[\\\/]/g).join(path.posix.sep), - ), - options, - ); -}; - -module.exports = globby; diff --git a/.core/gulp.bootup.js b/.core/gulp.bootup.js deleted file mode 100644 index 48bf17dd..00000000 --- a/.core/gulp.bootup.js +++ /dev/null @@ -1,74 +0,0 @@ -const ReactiumGulp = require('@atomic-reactor/reactium-sdk-core').default; -const fs = require('fs'); -const path = require('path'); -const gulp = require('gulp'); -const globby = require('./globby-patch').sync; -const rootPath = path.resolve(__dirname, '..'); -const config = require('./gulp.config'); -const webpackConfig = require('./webpack.config')(config); -const chalk = require('chalk'); - -require('./reactium.log.cjs'); - -global.ReactiumGulp = ReactiumGulp; - -ReactiumGulp.Enums.style = { - MIXINS: -1000, - VARIABLES: -900, - BASE: -800, - ATOMS: 0, - MOLECULES: 800, - ORGANISMS: 900, - OVERRIDES: 1000, -}; - -// Load reactium-gulp DDD artifact from plugin sources -globby([ - `${rootPath}/.core/**/reactium-gulp.js`, - `${rootPath}/src/**/reactium-gulp.js`, - `${rootPath}/reactium_modules/**/reactium-gulp.js`, - `${rootPath}/node_modules/**/reactium-plugin/**/reactium-gulp.js`, -]).forEach(item => { - const p = path.normalize(item); - try { - require(p); - } catch (error) { - console.error(chalk.red(`Error loading ${p}:`)); - console.error(error); - } -}); - -ReactiumGulp.Hook.runSync('config', config, webpackConfig); - -const tasks = require('./gulp.tasks')(gulp, config, webpackConfig); -const taskPlaceholder = require('./get-task')(gulp); - -const GulpRegistry = ReactiumGulp.Utils.registryFactory( - 'GulpTasks', - 'name', - ReactiumGulp.Utils.Registry.MODES.CLEAN, -); - -GulpRegistry.unregister = name => { - GulpRegistry.register(name, { - name, - task: () => Promise.resolve(), - }); -}; - -Object.entries(tasks).forEach(([name, task]) => { - GulpRegistry.register(name, { - name, - task, - }); -}); - -ReactiumGulp.Hook.runSync( - 'tasks', - GulpRegistry, - config, - webpackConfig, - taskPlaceholder, -); - -GulpRegistry.list.forEach(({ name, task }) => gulp.task(name, task)); diff --git a/.core/gulp.config.js b/.core/gulp.config.js deleted file mode 100644 index f8e8af1a..00000000 --- a/.core/gulp.config.js +++ /dev/null @@ -1,173 +0,0 @@ -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const globby = require('./globby-patch'); -const rootPath = path.resolve(__dirname, '..'); - -const defaultConfig = { - rootPath, - entries: globby - .sync('./src/app/*.js') - .map(p => path.resolve(p)) - .reduce((entries, entry) => { - entries[path.parse(entry).name] = entry; - return entries; - }, {}), - defines: {}, - browsers: 'last 1 version', - port: { - browsersync: 3000, - proxy: 3030, - }, - serverRetries: 4, - serverRetryDelay: 2000, - open: true, - watch: { - js: ['src/app/**/*', 'reactium_modules/**/*'], - markup: ['src/**/*.html', 'src/**/*.css', 'reactium_modules/**/*.css'], - colors: ['src/**/*/colors*.json', 'reactium_modules/**/*/colors*.json'], - pluginAssets: [ - 'src/app/**/plugin-assets.json', - 'src/**/style-assets.json', - '.core/**/style-assets.json', - 'reactium_modules/**/style-assets.json', - ], - restartWatches: [ - 'src/**/assets/style/*.scss', - '!src/**/assets/style/_*.scss', - ], - style: [ - 'src/**/*.scss', - '.core/**/*.scss', - 'reactium_modules/**/*.scss', - '!{src/**/assets/style/*.scss}', - '!{reactium_modules/**/assets/style/*.scss}', - ], - assets: [ - 'src/**/assets/**/*', - 'src/assets/**/*', - 'reactium_modules/**/assets/**/*', - '!{src/**/*/assets/style,src/**/*/assets/style/**,reactium_modules/**/assets/style/**}', - '!{src/**/*/assets/js,src/**/*/assets/js/**,reactium_modules/**/assets/js/**}', - '!{src/assets/style,src/assets/style/**}', - '!{src/assets/js,src/assets/js/**}', - ], - server: ['src/index.js', 'src/server/**/*.js'], - templates: ['src/server/**/*.hbs'], - }, - src: { - app: 'src', - colors: ['src/**/*/colors*.json', 'reactium_modules/**/*/colors*.json'], - pluginAssets: [ - 'src/app/**/plugin-assets.json', - 'src/**/style-assets.json', - '.core/**/style-assets.json', - 'reactium_modules/**/style-assets.json', - ], - js: ['src/app/**/*'], - json: ['src/**/*.json'], - markup: ['src/**/*.html', 'src/**/*.css', 'reactium_modules/**/*.css'], - style: [ - 'src/**/*.scss', - '.core/**/*.scss', - 'reactium_modules/**/*.scss', - '!{src/**/_*.scss}', - '!{.core/**/_*.scss}', - '!{reactium_modules/**/_*.scss}', - ], - styleDDD: [ - 'src/**/*/_reactium-style*.scss', - 'reactium_modules/**/*/_reactium-style*.scss', - ], - assets: [ - '.core/assets/**/*', - 'src/**/assets/**/*', - 'reactium_modules/**/assets/**/*', - 'src/assets/**/*', - '!{src/**/*/assets/style,src/**/*/assets/style/**,reactium_modules/**/assets/style/**}', - '!{src/**/*/assets/js,src/**/*/assets/js/**,reactium_modules/**/assets/js/**}', - '!{src/assets/style,src/assets/style/**}', - '!{src/assets/js,src/assets/js/**}', - ], - compress: [ - 'public/assets/**/*', - 'public/assets/js/sw/**/*', - '!public/assets/js/*.js', - '!public/assets/**/*.gz', - ], - includes: ['./node_modules'], - appdir: path.resolve(__dirname, 'src/app'), - rootdir: path.resolve(__dirname), - domainManifest: path.normalize(`${rootPath}/src/domains.js`), - manifest: path.normalize(`${rootPath}/src/manifest.js`), - externalsManifest: path.normalize( - `${rootPath}/src/externals-manifest.js`, - ), - reactiumModules: path.normalize(`${rootPath}/reactium_modules`), - }, - dest: { - dist: 'public', - js: '../public/assets/js', - markup: 'public', - style: 'public/assets/style', - assets: 'public/assets', - static: 'dist', - library: 'lib', - build: 'build/src', - buildCore: 'build/core', - colors: 'src/assets/style/_scss/_colors.scss', - modulesPartial: 'src/assets/style/_scss/_reactium-modules.scss', - startPath: '/', - }, - umd: { - defaultWorker: path.resolve( - __dirname, - '../public/assets/js/umd/service-worker/service-worker.js', - ), - manifest: path.normalize(`${rootPath}/.tmp/umd-manifest.json`), - outputPath: path.resolve(__dirname, '../public/assets/js/umd'), - }, - sw: { - globDirectory: 'public', - globPatterns: ['**/*.{html,js,css,js.gz,css.gz}'], - globIgnores: ['**/index-static.html', 'docs/**/*', 'assets/js/sw/**/*'], - swDest: 'public/assets/js/sw/sw.js', - modifyURLPrefix: { - assets: '/assets', - }, - }, - docs: { - src: '.core,src/app,node_modules/@atomic-reactor', - dest: ['public/docs', 'docs'], - verbose: false, - }, - buildTasks: [ - 'preBuild', - 'ensureReactiumModules', - 'clean', - 'manifest', - ['markup', 'json'], - ['assets', 'styles'], - 'scripts', - 'umdLibraries', - 'serviceWorker', - 'compress', - 'postBuild', - ], -}; - -const overrides = config => { - globby - .sync([ - './gulp.config.override.js', - './node_modules/**/reactium-plugin/gulp.config.override.js', - './src/**/gulp.config.override.js', - './reactium_modules/**/gulp.config.override.js', - ]) - .forEach(file => require(path.resolve(file))(config)); - - return config; -}; - -module.exports = overrides(defaultConfig); diff --git a/.core/gulp.tasks.js b/.core/gulp.tasks.js deleted file mode 100644 index 239ed1b3..00000000 --- a/.core/gulp.tasks.js +++ /dev/null @@ -1,963 +0,0 @@ -'use strict'; - -const del = require('del'); -const fs = require('fs-extra'); -const op = require('object-path'); -const path = require('node:path'); -const globby = require('./globby-patch'); -const webpack = require('webpack'); -const browserSync = require('browser-sync'); -const gulpif = require('gulp-if'); -const gulpwatch = require('@atomic-reactor/gulp-watch'); -const prefix = require('gulp-autoprefixer'); -const sass = require('gulp-sass')(require('sass-embedded')); -const gzip = require('gulp-gzip'); -const reactiumImporter = require('@atomic-reactor/node-sass-reactium-importer'); -const cleanCSS = require('gulp-clean-css'); -const sourcemaps = require('gulp-sourcemaps'); -const rename = require('gulp-rename'); -const chalk = require('chalk'); -const reactiumConfig = require('./reactium-config'); -const { regenManifest } = require('./manifest/manifest-tools'); -const umdWebpackGenerator = require('./umd.webpack.config'); -const rootPath = path.resolve(__dirname, '..'); -const { fork, spawn, execSync } = require('child_process'); -const { File, FileReader } = require('file-api'); -const handlebars = require('handlebars'); -const { resolve } = require('path'); -const axios = require('axios'); -const axiosRetry = require('axios-retry'); -const _ = require('underscore'); - -// For backward compatibility with gulp override tasks using run-sequence module -// make compatible with gulp4 -require('module-alias').addAlias('run-sequence', 'gulp4-run-sequence'); - -const reactium = (gulp, config, webpackConfig) => { - axiosRetry(axios, { - retries: config.serverRetries, - retryDelay: retryCount => { - console.log(`retry attempt: ${retryCount}`); - return retryCount * config.serverRetryDelay; // time interval between retries - }, - }); - - const task = require('./get-task')(gulp); - - const env = process.env.NODE_ENV || 'development'; - const isDev = env === 'development'; - - const assetPath = p => { - p.dirname = p.dirname.split('assets').pop(); - }; - const markupPath = p => { - if (p.extname === '.css') { - p.dirname = config.dest.style.split(config.dest.markup).pop(); - } - }; - - // PORT setup: - let port = config.port.proxy; - - let node_env = process.env.hasOwnProperty('NODE_ENV') - ? process.env.NODE_ENV - : 'development'; - - const PORT_VAR = op.get(process.env, 'PORT_VAR', 'APP_PORT'); - if (PORT_VAR && op.has(process.env, [PORT_VAR])) { - port = op.get(process.env, [PORT_VAR], port); - } else { - port = op.get(process.env, ['PORT'], port); - } - - port = parseInt(port); - - // Update config from environment variables - config.port.proxy = port; - - // Update config from environment variables - config.port.browsersync = Number( - op.get(process.env, 'BROWSERSYNC_PORT', config.port.browsersync), - ); - - const noop = done => done(); - - const watcher = e => { - let src = path.relative(path.resolve(__dirname), e.path); - let ePathRelative = path.relative(path.resolve(config.src.app), e.path); - let fpath = path.resolve( - rootPath, - `${config.dest.dist}/${ePathRelative.replace( - /^.*?\/assets/, - 'assets', - )}`, - ); - - let displaySrc = path.relative(rootPath, e.path); - let displayDest = path.relative(rootPath, fpath); - - if (fs.existsSync(fpath)) { - del.sync([fpath]); - } - - if (e.event !== 'unlink') { - const destPath = path.dirname(fpath); - if (!fs.existsSync(destPath)) { - fs.mkdirSync(destPath, { recursive: true }); - } - - fs.createReadStream(e.path) - .pipe(fs.createWriteStream(fpath)) - .on('error', error => console.error(error)); - } - - console.log(`File ${e.event}: ${displaySrc} -> ${displayDest}`); - }; - - const _opnWrapperMonkeyPatch = open => - function(url, name, bs) { - const app = op.get( - process.env, - 'BROWERSYNC_OPEN_BROWSER', - 'chrome', - ); - let browser = open.apps.chrome; - if (app in open.apps) browser = open.apps[app]; - - open(url, { app: { name: browser } }).catch(function(error) { - bs.events.emit('browser:error'); - }); - }; - - const serve = ({ open } = { open: config.open }) => done => { - const proxy = `127.0.0.1:${config.port.proxy}`; - - // monkey-path opnWrapper for linux support - const open = require('open'); - const utils = require('browser-sync/dist/utils'); - utils.opnWrapper = _opnWrapperMonkeyPatch(open); - - axios.get(`http://${proxy}`).then(() => { - browserSync({ - notify: false, - timestamps: false, - port: config.port.browsersync, - ui: { port: config.port.browsersync + 1 }, - proxy, - open: open, - ghostMode: false, - startPath: config.dest.startPath, - ws: true, - }); - - done(); - }); - }; - - const watch = (done, restart = false) => { - let watchProcess = fork(path.resolve(__dirname, './gulp.watch.js'), { - env: process.env, - stdio: ['inherit', 'inherit', 'inherit', 'ipc'], - }); - watchProcess.send({ config, webpackConfig, restart }); - watchProcess.on('message', message => { - switch (message) { - case 'build-started': { - console.log("Starting 'build'..."); - done(); - return; - } - case 'restart-watches': { - console.log('Waiting for server...'); - new Promise(resolve => - setTimeout(resolve, config.serverRetryDelay), - ) - .then(() => { - const proxy = `127.0.0.1:${config.port.proxy}`; - return axios.get(`http://${proxy}`); - }) - .then(() => { - console.log("Restarting 'watch'..."); - watchProcess.kill(); - watch(_ => _, true); - }) - .catch(error => console.error(error)); - return; - } - } - }); - }; - - const command = ( - cmd, - args = [], - done, - { stdin = 'ignore', stdout = 'inherit', stderr = 'inherit' } = {}, - ) => { - const ps = spawn(cmd, args, { stdio: [stdin, stdout, stderr] }); - ps.on('close', code => { - if (code !== 0) console.log(`Error executing ${cmd}`); - done(); - }); - - return ps; - }; - - const local = async done => { - const crossEnvModulePath = path.resolve( - path.dirname(require.resolve('cross-env')), - '..', - ); - const crossEnvPackage = require(path.resolve( - crossEnvModulePath, - 'package.json', - )); - const crossEnvBin = path.resolve( - crossEnvModulePath, - crossEnvPackage.bin['cross-env'], - ); - - await gulp.task('domainsManifest')(() => Promise.resolve()); - await gulp.task('mainManifest')(() => Promise.resolve()); - - command('node', [crossEnvBin, 'NODE_ENV=development', 'gulp'], done); - - command( - 'node', - [ - crossEnvBin, - 'NODE_ENV=development', - 'nodemon', - './.core/index.mjs', - ], - done, - { stdin: 'inherit' }, - ); - }; - - const assets = () => - gulp - .src(config.src.assets) - .pipe(rename(assetPath)) - .pipe(gulp.dest(config.dest.assets)); - - const generateParallel = (arr = []) => { - return gulp.parallel( - ...arr.map(t => { - if (typeof t === 'string') { - return task(t); - } else if (Array.isArray(t)) { - return generateSeries(t); - } - }), - ); - }; - - const generateSeries = (arr = []) => { - return gulp.series( - ...arr.map(t => { - if (typeof t === 'string') { - return task(t); - } else if (Array.isArray(t)) { - return generateParallel(t); - } - }), - ); - }; - - const build = cfg => { - const series = cfg.buildTasks || [ - 'preBuild', - 'ensureReactiumModules', - 'clean', - 'manifest', - ['markup', 'json'], - ['assets', 'styles'], - 'scripts', - 'umdLibraries', - 'serviceWorker', - 'compress', - 'postBuild', - ]; - - ReactiumGulp.Hook.runSync('build-series', series); - - return generateSeries(series); - }; - - const apidocs = done => { - if (!isDev) done(); - - const arcliBin = path.resolve( - path.dirname(require.resolve('@atomic-reactor/cli')), - 'arcli.js', - ); - const args = [ - arcliBin, - 'docs', - '-s', - config.docs.src, - '-d', - config.docs.dest, - ]; - - const verbose = config.docs.verbose || process.env.VERBOSE_API_DOCS; - if (verbose) args.push('-V'); - command('node', args, done); - }; - - const clean = done => { - // Remove build files - del.sync([config.dest.dist]); - done(); - }; - - const ensureReactiumModules = done => { - fs.ensureDirSync(config.src.reactiumModules); - done(); - }; - - const defaultTask = env === 'development' ? task('watch') : task('build'); - - const json = () => - gulp.src(config.src.json).pipe(gulp.dest(config.dest.build)); - - const manifest = gulp.series( - gulp.parallel( - gulp.series(task('domainsManifest'), task('mainManifest')), - task('externalsManifest'), - task('umdManifest'), - ), - ); - - const umd = gulp.series(task('umdManifest'), task('umdLibraries')); - - const sw = gulp.series(task('umd'), task('serviceWorker')); - - const domainsManifest = done => { - // Generate domains.js file - regenManifest({ - manifestFilePath: config.src.domainManifest, - manifestConfig: reactiumConfig.manifest.domains, - manifestTemplateFilePath: path.resolve( - __dirname, - 'manifest/templates/domains.hbs', - ), - manifestProcessor: require('./manifest/processors/domains'), - }); - - done(); - }; - - const mainManifest = done => { - // Generate manifest.js file - regenManifest({ - manifestFilePath: config.src.manifest, - manifestConfig: reactiumConfig.manifest, - manifestTemplateFilePath: path.resolve( - __dirname, - 'manifest/templates/manifest.hbs', - ), - manifestProcessor: require('./manifest/processors/manifest'), - }); - - done(); - }; - - const externalsManifest = done => { - // Generate manifest.js file - regenManifest({ - manifestFilePath: config.src.externalsManifest, - manifestConfig: reactiumConfig.manifest, - manifestTemplateFilePath: path.resolve( - __dirname, - 'manifest/templates/externals.hbs', - ), - manifestProcessor: require('./manifest/processors/externals'), - }); - done(); - }; - - const umdManifest = done => { - // Generate manifest all all umd libraries - regenManifest({ - manifestFilePath: config.umd.manifest, - manifestConfig: reactiumConfig.manifest.umd, - manifestTemplateFilePath: path.resolve( - __dirname, - 'manifest/templates/umd.hbs', - ), - manifestProcessor: require('./manifest/processors/umd'), - }); - done(); - }; - - const markup = () => - gulp - .src(config.src.markup) - .pipe(rename(markupPath)) - .pipe(gulp.dest(config.dest.markup)); - - const scripts = done => { - // Compile js - if (!isDev || process.env.MANUAL_DEV_BUILD === 'true') { - webpack(webpackConfig, (err, stats) => { - if (err) { - console.error(err.stack || err); - if (err.details) { - console.error(err.details); - } - - done(); - return; - } - - const info = stats.toJson(); - if (stats.hasErrors()) { - console.error(info.errors); - done(); - return; - } - - if (stats.hasWarnings()) { - if (process.env.DEBUG === 'on') console.warn(info.warnings); - } - - const mainEntryAssets = _.pluck( - info.namedChunkGroups.main.assets, - 'name', - ); - ReactiumGulp.Hook.runSync( - 'main-webpack-assets', - mainEntryAssets, - info, - stats, - ); - const serverAppPath = path.resolve(rootPath, 'src/app/server'); - - fs.ensureDirSync(serverAppPath); - fs.writeFileSync( - path.resolve(serverAppPath, 'webpack-manifest.json'), - JSON.stringify(mainEntryAssets), - 'utf-8', - ); - - done(); - }); - } else { - done(); - } - }; - - const umdLibraries = async done => { - let umdConfigs = []; - try { - umdConfigs = JSON.parse( - fs.readFileSync(config.umd.manifest, 'utf8'), - ); - } catch (error) { - console.log(error); - } - - for (let umd of umdConfigs) { - try { - console.log(`Generating UMD library ${umd.libraryName}`); - await new Promise((resolve, reject) => { - webpack(umdWebpackGenerator(umd), (err, stats) => { - if (err) { - reject(err); - return; - } - - let result = stats.toJson(); - if (result.errors.length > 0) { - result.errors.forEach(error => { - console.log(error); - }); - - reject(result.errors); - return; - } - - resolve(); - }); - }); - } catch (error) { - console.log('error', error); - } - } - - done(); - }; - - // Stub serviceWorker task. Implementation moved to @atomic-reactor/reactium-service-worker plugin - const serviceWorker = () => Promise.resolve(); - - const staticTask = task('static:copy'); - - const staticCopy = done => { - // Copy static files - fs.copySync(config.dest.dist, config.dest.static); - done(); - }; - - const fileReader = file => { - return new Promise((resolve, reject) => { - const reader = new FileReader(); - - reader.onerror = () => { - reader.abort(); - reject(); - }; - - reader.onload = () => resolve(reader.result); - reader.readAsDataURL(file); - }); - }; - - const pluginAssetsTemplate = data => { - const template = handlebars.compile(` -// -// DO NOT EDIT! -// This file is generated by gulp styles:pluginAssets task. -// -@use "sass:map"; - -$assets: () !default; - -{{#each this}} -$assets: map.set($assets, "{{key}}", "{{{dataURL}}}"); -{{/each}} -`); - - return template(data); - }; - - const pluginAssets = async done => { - const files = globby.sync(config.src.pluginAssets); - for (const file of files) { - const manifest = path.resolve(file); - const base = path.dirname(manifest); - try { - let assets = fs.readFileSync(manifest); - assets = JSON.parse(assets); - - const entries = Object.entries(assets); - const mappings = []; - for (const entry of entries) { - const [key, fileName] = entry; - const dataURL = await fileReader( - new File(path.resolve(base, fileName)), - ); - mappings.push({ key, dataURL }); - } - - fs.writeFileSync( - path.resolve(base, '_reactium-style-variables.scss'), - pluginAssetsTemplate(mappings), - 'utf8', - ); - } catch (error) { - console.error( - 'error generating sass partial _reactium-style-variables.scss in ' + - base, - error, - ); - } - } - - done(); - }; - - const sassPartialPreRegistrations = SassPartial => { - SassPartial.register('mixins-dir', { - pattern: /mixins\/_reactium-style/, - exclude: false, - priority: ReactiumGulp.Enums.style.MIXINS, - }); - - SassPartial.register('mixins-ddd', { - pattern: /_reactium-style-mixins/, - exclude: false, - priority: ReactiumGulp.Enums.style.MIXINS, - }); - - SassPartial.register('variables-dir', { - pattern: /variables\/_reactium-style/, - exclude: false, - priority: ReactiumGulp.Enums.style.VARIABLES, - }); - - SassPartial.register('variables-ddd', { - pattern: /_reactium-style-variables/, - exclude: false, - priority: ReactiumGulp.Enums.style.VARIABLES, - }); - - SassPartial.register('base-dir', { - pattern: /base\/_reactium-style/, - exclude: false, - priority: ReactiumGulp.Enums.style.BASE, - }); - - SassPartial.register('base-ddd', { - pattern: /_reactium-style-base/, - exclude: false, - priority: ReactiumGulp.Enums.style.BASE, - }); - - SassPartial.register('atoms-dir', { - pattern: /atoms\/_reactium-style/, - exclude: false, - priority: ReactiumGulp.Enums.style.ATOMS, - }); - - SassPartial.register('atoms-ddd', { - pattern: /_reactium-style-atoms/, - exclude: false, - priority: ReactiumGulp.Enums.style.ATOMS, - }); - - SassPartial.register('molecules-dir', { - pattern: /molecules\/_reactium-style/, - exclude: false, - priority: ReactiumGulp.Enums.style.MOLECULES, - }); - - SassPartial.register('molecules-ddd', { - pattern: /_reactium-style-molecules/, - exclude: false, - priority: ReactiumGulp.Enums.style.MOLECULES, - }); - - SassPartial.register('organisms-dir', { - pattern: /organisms\/_reactium-style/, - exclude: false, - priority: ReactiumGulp.Enums.style.ORGANISMS, - }); - - SassPartial.register('organisms-ddd', { - pattern: /_reactium-style-organisms/, - exclude: false, - priority: ReactiumGulp.Enums.style.ORGANISMS, - }); - - SassPartial.register('overrides-dir', { - pattern: /overrides\/_reactium-style/, - exclude: false, - priority: ReactiumGulp.Enums.style.OVERRIDES, - }); - - SassPartial.register('overrides-ddd', { - pattern: /_reactium-style-overrides/, - exclude: false, - priority: ReactiumGulp.Enums.style.OVERRIDES, - }); - }; - - const dddStylesPartial = done => { - const currentPartial = - fs.existsSync(config.dest.modulesPartial) && - fs.readFileSync(config.dest.modulesPartial, 'utf8'); - const SassPartialRegistry = ReactiumGulp.Utils.registryFactory( - 'SassPartialRegistry', - 'id', - ReactiumGulp.Utils.Registry.MODES.CLEAN, - ); - - sassPartialPreRegistrations(SassPartialRegistry); - ReactiumGulp.Hook.runSync('ddd-styles-partial', SassPartialRegistry); - - const stylePartials = globby - .sync(config.src.styleDDD) - .map(partial => { - if (/^reactium_modules\//.test(partial)) { - return partial.replace('reactium_modules/', '+'); - } - - return path - .relative( - path.dirname(config.dest.modulesPartial), - path.resolve(rootPath, partial), - ) - .split(/[\\\/]/g) - .join(path.posix.sep); - }) - .map(partial => partial.replace(/\.scss$/, '')) - // sort by directory basename - .sort((a, b) => { - const aBase = path - .basename(path.dirname(a)) - .toLocaleLowerCase(); - const bBase = path - .basename(path.dirname(b)) - .toLocaleLowerCase(); - if (aBase > bBase) return 1; - if (aBase < bBase) return -1; - return 0; - }) - // sort by file basename - .sort((a, b) => { - const aBase = path.basename(a).toLocaleLowerCase(); - const bBase = path.basename(b).toLocaleLowerCase(); - if (aBase > bBase) return 1; - if (aBase < bBase) return -1; - return 0; - }) - // sort by priority - .sort((a, b) => { - const aMatch = - SassPartialRegistry.list.find(({ pattern }) => - pattern.test(a), - ) || {}; - const bMatch = - SassPartialRegistry.list.find(({ pattern }) => - pattern.test(b), - ) || {}; - - const aPriority = op.get( - aMatch, - 'priority', - ReactiumGulp.Enums.style.ORGANISMS, - ); - const bPriority = op.get( - bMatch, - 'priority', - ReactiumGulp.Enums.style.ORGANISMS, - ); - - if (aPriority > bPriority) return 1; - else if (bPriority > aPriority) return -1; - return 0; - }) - .filter(partial => { - const match = - SassPartialRegistry.list.find(({ pattern }) => - pattern.test(partial), - ) || {}; - return !match || op.get(match, 'exclude', false) !== true; - }); - - const template = handlebars.compile(` -// WARNING: Do not directly edit this file !!!! -// File generated by gulp styles:partials task - -{{#each this}} -@import '{{ this }}'; -{{/each}} -`); - - const newPartial = template(stylePartials); - if (currentPartial !== newPartial) { - fs.ensureFileSync(config.dest.modulesPartial); - fs.writeFileSync( - config.dest.modulesPartial, - template(stylePartials), - 'utf8', - ); - } - done(); - }; - - const colorTemplate = (data, src) => { - const template = handlebars.compile(` -// -// DO NOT EDIT! -// This file is generated by gulp styles:colors task. -// Modify ${src} in this directory to effect this file. -// -@use "sass:map"; - -{{#each this}} -\${{{ key }}}: {{{value}}} !default; -{{/each}} - -$color: () !default; - -{{#each this}} -$color: map.set($color, "{{key}}", \${{{ key }}}); -{{/each}} -`); - return template(data); - }; - - const stylesColors = done => { - const colorProfiles = globby.sync(config.src.colors); - - if (colorProfiles.length > 0) { - colorProfiles.forEach(filePath => { - const profile = fs.readJsonSync(path.resolve(filePath)); - const location = path.dirname(filePath); - const { name } = path.parse(path.basename(filePath)); - let [, prefix = 'variables', ...suffixParts] = name.split('-'); - - const prefixes = [ - 'mixins', - 'variables', - 'base', - 'atoms', - 'molecules', - 'organisms', - 'overrides', - ]; - ReactiumGulp.Hook.runSync('color-profile-prefixes', prefixes); - - if (!prefixes.includes(prefix)) { - suffixParts = [prefix].concat(suffixParts); - prefix = 'variables'; - } - - const suffix = suffixParts.join('-'); - const outputFileName = `_reactium-style-${prefix}-colors${ - suffix.length > 0 ? `-${suffix}` : '' - }.scss`; - const outputPath = path.resolve(location, outputFileName); - - const colorFileContents = colorTemplate( - Object.entries(profile).map(([key, value]) => ({ - key, - value, - })), - path.basename(filePath), - ); - - fs.writeFileSync(outputPath, colorFileContents, 'utf8'); - }); - } - - done(); - }; - - const stylesCompile = () => { - return gulp - .src(config.src.style) - .pipe(gulpif(isDev, sourcemaps.init())) - .pipe( - sass({ - importer: reactiumImporter, - includePaths: config.src.includes, - }).on('error', sass.logError), - ) - .pipe(prefix(config.browsers)) - .pipe(gulpif(!isDev, cleanCSS())) - .pipe(gulpif(isDev, sourcemaps.write())) - .pipe(rename({ dirname: '' })) - .pipe(gulp.dest(config.dest.style)) - .pipe(gulpif(isDev, browserSync.stream())); - }; - - const getStyleSeries = () => { - const series = [ - 'styles:colors', - 'styles:pluginAssets', - 'styles:partials', - 'styles:compile', - ]; - - ReactiumGulp.Hook.runSync('style-series', series); - - return series; - }; - - const styles = generateSeries(getStyleSeries()); - - const compress = done => - isDev - ? done() - : gulp - .src(config.src.compress) - .pipe(gzip()) - .pipe(gulp.dest(config.dest.assets)); - - const watchFork = done => { - const watchers = {}; - - // Watch for file changes - watchers['manifest'] = gulp.watch( - config.watch.js, - gulp.parallel(task('manifest')), - ); - - watchers['styles:colors'] = gulp.watch( - config.watch.colors, - gulp.task('styles:colors'), - ); - watchers['styles:pluginAssets'] = gulp.watch( - config.watch.pluginAssets, - gulp.task('styles:pluginAssets'), - ); - watchers['styles:compile'] = gulp.watch( - config.watch.style, - gulp.task('styles:compile'), - ); - watchers['styles:partials'] = gulp.watch( - config.src.styleDDD, - gulp.task('styles:partials'), - ); - gulpwatch(config.watch.markup, watcher); - gulpwatch(config.watch.assets, watcher); - - watchLogger(watchers); - done(); - }; - - const watchLogger = watchers => { - Object.entries(watchers).forEach(([type, watcher]) => { - [ - ['change', chalk.green(`[${type} change]`)], - ['add', chalk.green(`[${type} add]`)], - ['unlink', chalk.green(`[${type} delete]`)], - ].forEach(([eventName, label]) => { - watcher.on(eventName, changed => { - console.log(label, changed); - }); - }); - }); - }; - - const tasks = { - apidocs, - local, - assets, - preBuild: noop, - build: build(config), - compress, - postBuild: noop, - postServe: noop, - clean, - ensureReactiumModules, - default: defaultTask, - json, - manifest, - domainsManifest, - mainManifest, - externalsManifest, - umd, - umdManifest, - umdLibraries, - markup, - scripts, - serve: serve(), - 'serve-restart': serve({ open: false }), - serviceWorker, - sw, - static: staticTask, - 'static:copy': staticCopy, - 'styles:partials': dddStylesPartial, - 'styles:pluginAssets': pluginAssets, - 'styles:colors': stylesColors, - 'styles:compile': stylesCompile, - styles, - watch, - watchFork, - }; - - let tasksOverride = _ => _; - if (fs.existsSync(`${rootPath}/gulp.tasks.override.js`)) { - tasksOverride = require(`${rootPath}/gulp.tasks.override.js`); - } - - return tasksOverride(tasks, config); -}; - -module.exports = reactium; diff --git a/.core/gulp.watch.js b/.core/gulp.watch.js deleted file mode 100644 index 58a0e391..00000000 --- a/.core/gulp.watch.js +++ /dev/null @@ -1,28 +0,0 @@ -const gulp = require('gulp'); -const gulpTasks = require('./gulp.tasks'); -const gulpwatch = require('@atomic-reactor/gulp-watch'); -const task = require('./get-task')(gulp); - -process.on('message', ({ config, webpackConfig, restart }) => { - require('./gulp.bootup'); - - const asyncDone = done => { - process.send('build-started'); - done(); - }; - - const asyncBuild = gulp.series( - task('build'), - task('watchFork'), - restart ? task('serve-restart') : task('serve'), - task('postServe'), - asyncDone, - ); - - gulp.task('asyncBuild', asyncBuild); - gulp.task('asyncBuild')(); - - gulpwatch(config.watch.restartWatches, () => { - process.send('restart-watches'); - }); -}); diff --git a/.core/gulpfile.js b/.core/gulpfile.js deleted file mode 100644 index 95086808..00000000 --- a/.core/gulpfile.js +++ /dev/null @@ -1 +0,0 @@ -require('./gulp.bootup'); diff --git a/.core/index.mjs b/.core/index.mjs deleted file mode 100644 index f892d303..00000000 --- a/.core/index.mjs +++ /dev/null @@ -1,371 +0,0 @@ -//------------------------------------------------------------------------------ -// Reactium Server -//------------------------------------------------------------------------------ - -import cors from 'cors'; -import express from 'express'; -import bodyParser from 'body-parser'; -import cookieParser from 'cookie-parser'; -import cookieSession from 'cookie-session'; -import morgan from 'morgan'; -import op from 'object-path'; -import _ from 'underscore'; -import staticGzip from 'express-static-gzip'; -import chalk from 'chalk'; -import globals from './server-globals.mjs'; -import path from 'node:path'; -import fs from 'fs-extra'; -import globbyPatched from './globby-patch.js'; -import router from './server/router.mjs'; -import { dirname } from '@atomic-reactor/dirname'; - -const __dirname = dirname(import.meta.url); -const globby = globbyPatched.sync; - -global.rootPath = path.resolve(__dirname, '..'); - -global.app = express(); - -const registeredMiddleware = async () => { - const { Enums } = ReactiumBoot; - - // express middlewares - if (LOG_LEVEL >= LOG_LEVELS.INFO) { - ReactiumBoot.Server.Middleware.register('logging', { - name: 'logging', - use: morgan('combined'), - order: Enums.priority.highest, - }); - } - - ReactiumBoot.Server.Middleware.register('cors', { - name: 'cors', - use: cors(), - order: Enums.priority.highest, - }); - - // parsers - ReactiumBoot.Server.Middleware.register('jsonParser', { - name: 'jsonParser', - use: bodyParser.json(), - order: Enums.priority.high, - }); - - ReactiumBoot.Server.Middleware.register('urlEncoded', { - name: 'urlEncoded', - use: bodyParser.urlencoded({ extended: true }), - order: Enums.priority.high, - }); - - // cookies - ReactiumBoot.Server.Middleware.register('cookieParser', { - name: 'cookieParser', - use: cookieParser(), - order: Enums.priority.high, - }); - - ReactiumBoot.Server.Middleware.register('cookieSession', { - name: 'cookieSession', - use: cookieSession({ - name: op.get(process.env, 'COOKIE_SESSION_NAME', 'aljtka4'), - keys: JSON.parse( - op.get( - process.env, - 'COOKIE_SESSION_KEYS', - JSON.stringify([ - 'Q2FtZXJvbiBSdWxlcw', - 'vT3GtyZKbnoNSdWxlcw', - ]), - ), - ), - order: Enums.priority.high, - }), - }); - - // serve the static files out of ./public or specified directory - global.staticAssets = - process.env.PUBLIC_DIRECTORY || path.resolve(process.cwd(), 'public'); - - global.staticHTML = - process.env.PUBLIC_HTML || - path.resolve(process.cwd(), 'public/static-html'); - - ReactiumBoot.Server.Middleware.register('static', { - name: 'static', - use: staticGzip(staticAssets), - order: Enums.priority.neutral, - }); - - ReactiumBoot.Server.Middleware.register('static-html', { - name: 'static-html', - use: staticGzip(staticHTML), - order: Enums.priority.neutral, - }); - - const reactiumModules = Object.keys( - op.get( - fs.readJsonSync(path.resolve(process.cwd(), 'package.json')), - 'reactiumDependencies', - {}, - ), - ); - - reactiumModules.forEach(mod => { - const modStaticPath = path.resolve( - process.cwd(), - 'reactium_modules', - mod, - '_static', - ); - if (fs.existsSync(modStaticPath)) { - ReactiumBoot.Server.Middleware.register(`static.${mod}`, { - use: staticGzip(modStaticPath), - order: Enums.priority.neutral, - }); - } - }); - - // default route handler - ReactiumBoot.Server.Middleware.register('service-worker-allowed', { - name: 'service-worker-allowed', - use: async (req, res, next) => { - const responseHeaders = { - 'Service-Worker-Allowed': '/', - }; - - /** - * @api {Hook} Server.ServiceWorkerAllowed Server.ServiceWorkerAllowed - * @apiDescription Called on server-side during service-worker-allowed middleware. - Used to define the HTTP response header "Service-Worker-Allowed". - By default, this header will allow the document root, "/". - Both sync and async version called. - * @apiParam {Object} responseHeader with property 'Service-Worker-Allowed' (case sensitive) and its value. - * @apiParam {Object} req Node/Express request object - * @apiParam {Object} res Node/Express response object - * @apiName Server.ServiceWorkerAllowed - * @apiGroup Hooks - */ - ReactiumBoot.Hook.runSync( - 'Server.ServiceWorkerAllowed', - responseHeaders, - req, - res, - ); - await ReactiumBoot.Hook.run( - 'Server.ServiceWorkerAllowed', - responseHeaders, - req, - res, - ); - - if (op.has(responseHeaders, 'Service-Worker-Allowed')) { - res.set( - 'Service-Worker-Allowed', - op.get(responseHeaders, 'Service-Worker-Allowed'), - ); - } - - next(); - }, - order: Enums.priority.high, - }); - - // default route handler - ReactiumBoot.Server.Middleware.register('router', { - name: 'router', - use: router, - order: Enums.priority.neutral, - }); -}; - -const registeredDevMiddleware = async () => { - const { Enums } = ReactiumBoot; - - // set app variables - app.set('x-powered-by', false); - - // development mode - if (process.env.NODE_ENV === 'development') { - const { default: webpack } = await import('webpack'); - const { default: gulpConfig } = await import('./gulp.config.js'); - const { default: webpackConfigFactory } = await import( - './webpack.config.js' - ); - const webpackConfig = webpackConfigFactory(gulpConfig); - const { default: wpMiddleware } = await import('webpack-dev-middleware'); - const { default: wpHotMiddleware } = await import( - 'webpack-hot-middleware' - ); - const publicPath = `http://localhost:${PORT}/`; - - // local development overrides for webpack config - webpackConfig.entry.main = [ - 'webpack-hot-middleware/client?path=/__webpack_hmr&quiet=true', - webpackConfig.entry.main, - ]; - webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin()); - webpackConfig.output.publicPath = publicPath; - - const compiler = webpack(webpackConfig); - - ReactiumBoot.Server.Middleware.register('webpack', { - name: 'webpack', - use: wpMiddleware(compiler, { - serverSideRender: true, - publicPath, - }), - order: Enums.priority.high, - }); - - ReactiumBoot.Server.Middleware.register('hmr', { - name: 'hmr', - use: wpHotMiddleware(compiler, { - reload: true, - }), - order: Enums.priority.high, - }); - } -}; - -const startServer = async () => { - await registeredMiddleware(); - await registeredDevMiddleware(); - - /** - * @api {Hook} Server.Middleware Server.Middleware - * @apiName Server.Middleware - * @apiDescription Used to register or unregister express middleware. - * @apiParam {Object} Middleware Server express middleware registry object. - * @apiParam (middleware) {String} name Name of the middleware. - * @apiParam (middlware) {Function} use the express middleware function. - * @apiParam (middlware) {Number} order the loading order of the middleware - * @apiExample reactium-boot.js - const express = require('express'); - const router = express.Router(); - const axios = require('axios'); - - // register a new backend route /foo with express - router.get('/', (req, res) => { - res.send('Foo!!') - }); - - ReactiumBoot.Hook.registerSync('Server.Middleware', Middleware => { - Middleware.register('foo-page', { - name: 'foo-page', - use: router, - order: ReactiumBoot.Enums.priority.highest, - }) - }); - - ReactiumBoot.Hook.registerSync('Server.Middleware', Middleware => { - const intercept = express.Router(); - intercept.post('/api*', (req, res) => { - res.json({ - foo: 'bar' - }); - }); - - // check api health every 90 seconds and intercept api if it goes down - Middleware.register('downapi', { - name: 'downapi', - use: async (res, req, next) => { - try { - let healthy = ReactiumBoot.Cache.get('health-check'); - if (healthy === undefined) { - const response = await axios.get(process.env.REST_API_URI + '/healthcheck'); - healthy = response.data; - ReactiumBoot.Cache.set('health-check', healthy, 1000 * 90); - } - } catch (error) { - console.error(error); - ReactiumBoot.Cache.set('health-check', false, 1000 * 90); - healthy = false; - } - - if (healthy === true) next(); - return intercept(req, req, next); - }, - order: ReactiumBoot.Enums.priority.highest, - }) - }); - * @apiGroup Hooks - */ - ReactiumBoot.Hook.runSync( - 'Server.Middleware', - ReactiumBoot.Server.Middleware, - ); - await ReactiumBoot.Hook.run( - 'Server.Middleware', - ReactiumBoot.Server.Middleware, - ); - - let middlewares = Object.values(ReactiumBoot.Server.Middleware.list); - // Deprecated: Give app an opportunity to change middlewares - if (fs.existsSync(`${rootPath}/src/app/server/middleware.js`)) { - ERROR( - 'src/app/server/middleware.js has been discontinued. Use reactium-boot.js register to register or deregister express middleware.', - ); - } - - _.sortBy(_.compact(middlewares), 'order').forEach(({ use }) => { - if (Array.isArray(use)) { - app.use(...use); - } else { - app.use(use); - } - }); - - // start server on the specified port and binding host - app.listen(PORT, '0.0.0.0', function() { - BOOT( - `Reactium Server running ${chalk.red( - 'PLAIN', - )} on port '${PORT}'...`, - ); - }); - - if (process.env.REACTIUM_TLS_MODE === 'on') { - const spdy = await import('spdy'); - const options = { - key: fs.readFileSync( - op.get( - process.env, - 'REACTIUM_TLS_KEY', - path.resolve(__dirname, '../src', 'server.key'), - ), - ), - cert: fs.readFileSync( - op.get( - process.env, - 'REACTIUM_TLS_CERT', - path.resolve(__dirname, '../src', 'server.crt'), - ), - ), - }; - await ReactiumBoot.Hook.run('spdy-options', options); - - spdy.createServer(options, app).listen(TLS_PORT, error => { - if (error) { - ERROR(error); - process.exit(1); - } - BOOT( - `Reactium Server running ${chalk.green( - 'TLS', - )} on port '${TLS_PORT}'...`, - ); - }); - } -}; - -const bootup = async () => { - const logger = console; - try { - await globals(); - await startServer(); - } catch (error) { - console.error('Error on server startup:', error); - } -}; - -bootup(); diff --git a/.core/manifest/manifest-tools.js b/.core/manifest/manifest-tools.js deleted file mode 100644 index 1741e6b7..00000000 --- a/.core/manifest/manifest-tools.js +++ /dev/null @@ -1,245 +0,0 @@ -const tree = require('directory-tree'); -const path = require('path'); -const fs = require('fs-extra'); -const _ = require('underscore'); -const op = require('object-path'); -const prettier = require('prettier'); -const chalk = require('chalk'); -const diff = require('fast-diff'); -const hb = require('handlebars'); -const rootPath = path.resolve(__dirname, '../..'); - -// flatten a tree of files from directory-tree module -const flattenRegistry = (registry = { children: [] }, manifest = []) => { - op.get(registry, 'children', []).forEach(item => { - const type = op.get(item, 'type'); - if (type === 'directory') { - const children = op.get(item, 'children', []); - if (children.length > 0) { - return flattenRegistry(item, manifest); - } - - return manifest; - } - - if ('path' in item) { - manifest.push(item); - } - }); - - return manifest; -}; - -/** - * For a given sourcepath relative to the project directory, returns a flat list of matching files. - */ -const sources = (sourcePath, searchParams) => { - const t = tree(sourcePath, searchParams); - return flattenRegistry(t); -}; - -const isRegExp = regEx => - typeof regEx === 'object' && regEx.constructor == RegExp; - -const find = (searches = [], sourceMappings = [], searchParams = {}) => { - let mappings = {}; - searches.forEach(({ name, type }) => { - mappings[name] = { - type, - imports: [], - originals: {}, - }; - }); - - sourceMappings.forEach(sourceMapping => { - const nodeModules = Boolean(op.get(sourceMapping, 'node_modules')); - const params = { - ...searchParams, - exclude: [...(op.get(searchParams, 'exclude', []) || [])], - }; - - const exclude = op - .get(params, 'exclude', []) - .concat(op.get(sourceMapping, 'exclude', [])); - - op.set(params, 'exclude', exclude); - - const files = []; - if (nodeModules) { - // exclude deep packages - exclude.push(/node_modules$/); - - const packagePath = module.paths - .map(p => path.resolve(path.dirname(p), 'package.json')) - .find(packagePath => fs.existsSync(packagePath)); - - let modules = Object.keys( - op.get(require(packagePath), 'dependencies', {}), - ); - - const reactiumModules = Object.keys( - op.get(require(packagePath), 'reactiumDependencies', {}), - ); - - // Special exception for reactium_modules dependencies, which will be considered - if (reactiumModules.length) { - const reactiumModuleDir = path.resolve( - path.dirname(packagePath), - 'reactium_modules', - ); - reactiumModules.forEach(reactiumModule => { - const subPackage = path.resolve( - reactiumModuleDir, - reactiumModule, - '_npm/package.json', - ); - if (fs.existsSync(subPackage)) { - modules = _.uniq( - modules.concat( - Object.keys( - op.get( - require(subPackage), - 'dependencies', - {}, - ), - ), - ), - ); - } - }); - } - - modules.forEach(mod => { - let from; - try { - from = path.dirname(require.resolve(mod)); - } catch (err) {} - - if (from) { - sources(from, params).forEach(file => { - file.mod = mod; - files.push(file); - }); - } - }); - } else if (op.has(sourceMapping, 'from')) { - sources(sourceMapping.from, params).forEach(file => - files.push(file), - ); - } - - files.forEach(fileObj => { - const file = fileObj.path; - - // ignore entire set of source paths if ignore specified - if ( - op.has(sourceMapping, 'ignore') && - isRegExp(sourceMapping.ignore) && - sourceMapping.ignore.test(file) - ) - return; - - searches.forEach(search => { - const { name, pattern, ignore } = search; - if (ignore && isRegExp(ignore) && ignore.test(file)) return; - - if (pattern.test(file)) { - let normalized = file; - if (nodeModules) { - normalized = normalized.replace( - new RegExp(`.*${fileObj.mod}`), - fileObj.mod, - ); - } - - normalized = normalized.replace(/\\/g, '/'); - if (op.has(sourceMapping, 'from')) { - normalized = normalized.replace( - sourceMapping.from, - op.get(sourceMapping, 'to', sourceMapping.from), - ); - } - - if (op.get(search, 'stripExtension', true)) { - normalized = normalized.replace(fileObj.extension, ''); - } - - mappings[name].originals[normalized] = file; - mappings[name].imports.push(normalized); - } - }); - }); - }); - - return mappings; -}; - -const regenManifest = function({ - manifestFilePath, - manifestConfig, - manifestTemplateFilePath, - manifestProcessor, -}) { - const patterns = op.get(manifestConfig, 'patterns', []); - const sourceMappings = op.get(manifestConfig, 'sourceMappings', []); - const searchParams = op.get(manifestConfig, 'searchParams', { - extensions: /\.jsx?$/, - exclude: [/.ds_store/i, /.core\/.cli\//i, /.cli\//i], - }); - - const manifest = find(patterns, sourceMappings, searchParams); - - const template = hb.compile( - fs.readFileSync(manifestTemplateFilePath, 'utf-8'), - ); - - let fileContents = template( - manifestProcessor({ - manifest, - manifestConfig, - }), - ); - - if (/.jsx?$/.test(manifestFilePath)) { - fileContents = prettier.format(fileContents, { - parser: 'babel', - trailingComma: 'all', - singleQuote: true, - tabWidth: 4, - useTabs: false, - }); - } - - const manifestHasChanged = () => { - const prevFileContents = fs.readFileSync(manifestFilePath, 'utf-8'); - const changes = diff(prevFileContents, fileContents).filter( - ([code, change]) => code !== 0, - ); - return changes.length > 0; - }; - - // Write Manifest only if it does not exist or has changed - if (!fs.existsSync(manifestFilePath) || manifestHasChanged()) { - console.log(`'${chalk.cyan(manifestFilePath)}'...`); - const dir = path.dirname(manifestFilePath); - fs.ensureDirSync(dir); - fs.writeFileSync(manifestFilePath, fileContents); - } -}; - -const domainRegExp = new RegExp('/([A-Za-z_0-9-]+?)[\\/][A-Za-z_0-9-]+$'); -const fileToDomain = file => { - let [, domain] = file.match(domainRegExp) || []; - const relativeOriginalPath = path.resolve(rootPath, file); - - return domain; -}; - -module.exports = { - regenManifest, - flattenRegistry, - sources, - isRegExp, - find, - fileToDomain, -}; diff --git a/.core/manifest/processors/domains.js b/.core/manifest/processors/domains.js deleted file mode 100644 index 4d25698f..00000000 --- a/.core/manifest/processors/domains.js +++ /dev/null @@ -1,27 +0,0 @@ -const path = require('path'); -const op = require('object-path'); -const { fileToDomain } = require('../manifest-tools'); -const rootPath = path.resolve(__dirname, '../../..'); - -module.exports = data => { - const domains = {}; - const relative = {}; - - for (const [file, original] of Object.entries( - op.get(data, 'manifest.allDomains.originals'), - )) { - const relativeOriginalPath = path.resolve(rootPath, original); - - const domainObj = require(relativeOriginalPath); - const impliedDomain = fileToDomain(file); - const domain = op.get(domainObj, 'name', impliedDomain); - - op.set(domains, [domain], domainObj); - op.set(domains, [domain, 'name'], domain); - op.set(domains, [domain, 'implied'], impliedDomain); - op.set(domains, [domain, 'original'], original); - op.set(relative, [path.dirname(original)], domain); - } - - return JSON.stringify({ domains, relative }); -}; diff --git a/.core/manifest/processors/externals.js b/.core/manifest/processors/externals.js deleted file mode 100644 index b7cfbd38..00000000 --- a/.core/manifest/processors/externals.js +++ /dev/null @@ -1,30 +0,0 @@ -const op = require('object-path'); -const fs = require('fs'); -const path = require('path'); -const rootPath = path.resolve(__dirname, '../../..'); -const chalk = require('chalk'); -module.exports = data => { - const externals = Object.values( - op.get(data, 'manifestConfig.pluginExternals', {}), - ).map(external => { - const { externalName, requirePath } = external; - - if (/^\/.*\/i?$/.test(externalName)) - return { - ...external, - externalName: requirePath, - requirePath, - }; - - return external; - }); - - const externalAliases = externals.filter( - ({ defaultAlias }) => defaultAlias, - ); - - return { - externals, - externalAliases, - }; -}; diff --git a/.core/manifest/processors/manifest.js b/.core/manifest/processors/manifest.js deleted file mode 100644 index ee0bf7da..00000000 --- a/.core/manifest/processors/manifest.js +++ /dev/null @@ -1,63 +0,0 @@ -const op = require('object-path'); -const fs = require('fs'); -const path = require('path'); -const rootPath = path.resolve(__dirname, '../../..'); -const chalk = require('chalk'); -module.exports = data => { - const explicitDomains = require(path.resolve(rootPath, 'src/domains.js')); - - const types = Object.entries(data.manifest).map(([name, typeDomains]) => { - const { fileToDomain } = require('../manifest-tools'); - const { imports, type } = typeDomains; - - const mapDomain = file => { - let domain = fileToDomain(file); - const relative = domain; - domain = op.get( - explicitDomains, - ['relative', path.dirname(typeDomains.originals[file])], - domain, - ); - - if (!domain) - console.log( - `Warning: Unable to add "${file}" of type "${type}. No domain.js found."`, - ); - return domain; - }; - - const domains = []; - imports - .map(file => file.replace(/\\/g, '/')) - .filter(mapDomain) - .forEach(file => { - const domain = mapDomain(file); - let existing; - if ( - (existing = domains.find(({ domain: d }) => d === domain)) - ) { - console.warn( - chalk.magenta( - `Warning: Unable to add "${file}" of type "${type}" to "${domain}" manifest. "${existing.file}" will be used.`, - ), - ); - return domains; - } - - domains.push({ - domain, - file, - }); - }); - - return { - name, - domains, - }; - }); - - return { - types, - manifest: JSON.stringify(data.manifest, null, 2), - }; -}; diff --git a/.core/manifest/processors/umd.js b/.core/manifest/processors/umd.js deleted file mode 100644 index ff5b53c2..00000000 --- a/.core/manifest/processors/umd.js +++ /dev/null @@ -1,76 +0,0 @@ -const path = require('path'); -const fs = require('fs-extra'); -const _ = require('underscore'); -const op = require('object-path'); -const config = require('../../gulp.config'); - -module.exports = data => { - const umdConfigs = op - .get(data, 'manifest.allUmdConfig.imports', []) - .reduce((configs, configPath) => { - const dir = path.dirname(path.normalize(configPath)); - let config = {}; - try { - config = JSON.parse( - fs.readFileSync(path.normalize(configPath), 'utf8'), - ); - } catch (err) {} - - configs[dir] = config; - - return configs; - }, {}); - - const defaultLibraryExternals = Object.values( - op.get(data, 'manifestConfig.defaultLibraryExternals', {}), - ).reduce((externals, { externalName }) => { - externals[externalName] = externalName; - return externals; - }, {}); - - return JSON.stringify( - op.get(data, 'manifest.allUmdEntries.imports', []).map(entryPath => { - const dir = path.dirname(entryPath); - const umdConfig = op.get(umdConfigs, dir, {}); - const libraryName = op.get( - umdConfig, - 'libraryName', - path.basename(dir), - ); - const outputBase = op.get(config, 'umd.outputPath'); - const outputPath = path.resolve( - outputBase, - op.get(umdConfig, 'outputPath', libraryName), - ); - const outputFile = op.get( - umdConfig, - 'outputFile', - `${libraryName}.js`, - ); - const externals = op.get( - umdConfig, - 'externals', - defaultLibraryExternals, - ); - const globalObject = op.get(umdConfig, 'globalObject', 'window'); - const babelPresetEnv = op.get(umdConfig, 'babelPresetEnv', true); - const babelReact = op.get(umdConfig, 'babelReact', true); - const babelLoader = op.get(umdConfig, 'babelLoader', true); - - return { - ...umdConfig, - entry: path.normalize(entryPath + '.js'), - libraryName, - outputPath, - outputFile, - externals, - globalObject, - babelPresetEnv, - babelReact, - babelLoader, - }; - }), - null, - 2, - ); -}; diff --git a/.core/manifest/templates/domains.hbs b/.core/manifest/templates/domains.hbs deleted file mode 100644 index b5f92630..00000000 --- a/.core/manifest/templates/domains.hbs +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Generated by Reactium - * DO NOT directly edit this file !!!!!! - */ - - module.exports = {{{this}}}; \ No newline at end of file diff --git a/.core/manifest/templates/externals.hbs b/.core/manifest/templates/externals.hbs deleted file mode 100644 index 196e5278..00000000 --- a/.core/manifest/templates/externals.hbs +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Generated by Reactium - * DO NOT directly edit this file !!!!!! - */ -import { isBrowserWindow } from '@atomic-reactor/reactium-sdk-core'; - -if (isBrowserWindow()) { - {{#each externals}} - window['{{externalName}}'] = require('{{requirePath}}'); - {{/each}} - {{#each externalAliases}} - window['{{defaultAlias}}'] = window['{{externalName}}']; - {{/each}} -} diff --git a/.core/manifest/templates/manifest.hbs b/.core/manifest/templates/manifest.hbs deleted file mode 100644 index 2b059c48..00000000 --- a/.core/manifest/templates/manifest.hbs +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Generated by Reactium - * DO NOT directly edit this file !!!!!! - */ -import op from 'object-path'; -import _ from 'underscore'; -import { isBrowserWindow } from '@atomic-reactor/reactium-sdk-core'; - -const deps = {}; -const reqs = { -{{#each types}} - '{{name}}': { - {{#each domains}} - '{{domain}}': { - req: () => { - return import('{{file}}'); - }, - file: '{{file}}', - }, - {{/each}} - }, -{{/each}} -}; - -const manifest = { - get: () => { - const domainLoaders = {}; - for (const [name, domains] of Object.entries(reqs)) { - const loaders = []; - for (const [domain, item] of Object.entries(domains)) { - loaders.push({ - name, - domain, - loader: () => new Promise((resolve, reject) => { - try { - item.req().then(module => { - resolve({ - name, - domain, - module, - }); - }); - } catch (error) { - const where = isBrowserWindow() ? ' in browser ' : ' on server '; - console.error(`Error loading manifest resource "${item.file}" of type ${name} from domain ${domain}${where}`, error); - resolve(false); - } - }), - }); - } - - op.set(domainLoaders, [name], loaders); - } - - return domainLoaders; - }, - list: () => { - return {{{manifest}}}; - }, -} - -export default manifest; diff --git a/.core/manifest/templates/umd.hbs b/.core/manifest/templates/umd.hbs deleted file mode 100644 index f1c9f5a0..00000000 --- a/.core/manifest/templates/umd.hbs +++ /dev/null @@ -1 +0,0 @@ -{{{this}}} diff --git a/.core/reactium-config.js b/.core/reactium-config.js deleted file mode 100644 index d5c17557..00000000 --- a/.core/reactium-config.js +++ /dev/null @@ -1,379 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const globby = require('./globby-patch'); -const rootPath = path.resolve(__dirname, '..'); -const gulpConfig = require('./gulp.config'); - -const version = '5.0.0-alpha-2'; - -const defaultLibraryExternals = { - axios: { - externalName: 'axios', - requirePath: 'axios', - }, - classnames: { - externalName: 'classnames', - requirePath: 'classnames', - }, - 'copy-to-clipboard': { - externalName: 'copy-to-clipboard', - requirePath: 'copy-to-clipboard', - }, - - moment: { - externalName: 'moment', - requirePath: 'dayjs', - }, - - dayjs: { - externalName: 'dayjs', - requirePath: 'dayjs', - }, - - 'object-path': { - externalName: 'object-path', - requirePath: 'object-path', - }, - 'prop-types': { - externalName: 'prop-types', - requirePath: 'prop-types', - }, - react: { - externalName: 'react', - requirePath: 'react', - // to provide both es6 named exports and React default alias - defaultAlias: 'React', - }, - 'react-router-dom': { - externalName: 'react-router-dom', - requirePath: 'react-router-dom', - }, - ReactDOM: { - externalName: 'react-dom', - requirePath: 'react-dom', - // to provide both es6 named exports and React default alias - defaultAlias: 'ReactDOM', - }, - Reactium: { - externalName: '/reactium-core/sdk$/', - // relative to src/manifest.js - requirePath: 'reactium-core/sdk', - // to provide both es6 named exports and Reactium default alias - defaultAlias: 'Reactium', - }, - semver: { - externalName: 'semver', - requirePath: 'semver', - }, - 'shallow-equals': { - externalName: 'shallow-equals', - requirePath: 'shallow-equals', - }, - underscore: { - externalName: 'underscore', - requirePath: 'underscore', - }, - uuid: { - externalName: 'uuid', - requirePath: 'uuid', - }, - xss: { - externalName: 'xss', - requirePath: 'xss', - }, -}; - -const defaultManifestConfig = { - patterns: [ - { - name: 'allRoutes', - type: 'route', - pattern: /route.jsx?$/, - }, - { - name: 'allServices', - type: 'services', - pattern: /services.jsx?$/, - }, - { - name: 'allPlugins', - type: 'plugin', - pattern: /(plugin|zone).jsx?$/, - }, - { - name: 'allHooks', - type: 'hooks', - pattern: /reactium-hooks.js$/, - }, - ], - sourceMappings: [ - { - from: 'src/app/', - to: '../src/app/', - }, - { - from: '.core/', - to: 'reactium-core/', - }, - { - from: 'reactium_modules/', - to: '../reactium_modules/', - }, - { - node_modules: true, - ignore: /^((?!reactium-plugin).)*$/, - }, - ], - pluginExternals: defaultLibraryExternals, - umd: { - defaultLibraryExternals, - patterns: [ - { - name: 'allUmdEntries', - type: 'umd', - pattern: /umd.js$/, - ignore: /assets/, - }, - { - name: 'allUmdConfig', - type: 'config', - pattern: /umd-config.json$/, - ignore: /assets/, - stripExtension: false, - }, - ], - sourceMappings: [ - { - from: 'src/', - to: path.resolve(rootPath, 'src') + '/', - }, - { - from: 'reactium_modules/', - to: path.resolve(rootPath, 'reactium_modules') + '/', - }, - ], - searchParams: { - extensions: /\.(js|json)$/, - exclude: [/\.ds_store/i, /\.core/i, /\.cli\//i, /src\/assets/], - }, - }, - domains: { - patterns: [ - { - name: 'allDomains', - type: 'domain', - pattern: /domain.js$/, - }, - ], - sourceMappings: [ - { - from: 'src/app/', - to: '../src/app/', - }, - { - from: '.core/', - to: '../.core/', - }, - { - from: 'reactium_modules/', - to: '../reactium_modules/', - }, - { - node_modules: true, - ignore: /^((?!reactium-plugin).)*$/, - }, - ], - }, -}; - -const overrides = config => { - globby - .sync([ - './manifest.config.override.js', - './node_modules/**/reactium-plugin/manifest.config.override.js', - './src/**/manifest.config.override.js', - './reactium_modules/**/manifest.config.override.js', - ]) - .forEach(file => require(path.resolve(file))(config)); - return config; -}; - -const manifestConfig = overrides(defaultManifestConfig); - -/** - * Use liberally for additional core configuration. - * @type {Object} - */ -module.exports = { - version, - semver: '^5.0.0', - build: gulpConfig, - update: { - package: { - dependencies: { - remove: [ - '@babel/plugin-syntax-dynamic-import', - '@babel/polyfill', - 'ajv', - 'beautify', - 'express-http-proxy', - 'htmltojsx', - 'js-beautify', - ], - }, - devDependencies: { - remove: [ - '@atomic-reactor/cli', - 'atomic-reactor-cli', - 'babel-cli', - 'babel-core', - 'babel-preset-env', - 'babel-preset-react', - 'babel-preset-stage-2', - 'gulp-install', - 'gulp-csso', - 'nodemon', - 'run-sequence', - 'vinyl-source-stream', - 'webpack-visualizer-plugin', - ], - }, - scripts: { - add: { - start: 'node .core/index.mjs', - build: 'npm-run-all build:*', - local: 'gulp local', - }, - remove: [ - 'build', - 'build:gulp', - 'build:babel-core', - 'build:babel-reactium_modules', - 'build:babel-src', - 'local-fe-start', - 'local-fe:gulp', - 'local-fe:babel-node', - 'local-ssr', - 'local-ssr-start', - 'local-ssr:gulp', - 'local-ssr:babel-node', - 'react-redux', - 'start', - 'static:build', - 'static', - ], - }, - husky: { - remove: ['hooks'], - }, - }, - files: { - add: [ - { - overwrite: true, - version: '>=3.1.0', - destination: '/apidoc.json', - source: '/tmp/update/apidoc.json', - }, - { - overwrite: true, - version: '>=3.0.0', - destination: '/Dockerfile', - source: '/tmp/update/Dockerfile', - }, - { - overwrite: true, - version: '>=2.3.16', - destination: '/src/app/plugable/index.js', - source: '/tmp/update/src/app/plugable/index.js', - }, - { - overwrite: false, - version: '>=2.3.16', - destination: '.stylelintrc', - source: '/tmp/update/.stylelintrc', - }, - { - overwrite: true, - version: '>=3.0.2', - destination: '/.eslintrc', - source: '/tmp/update/.eslintrc', - }, - { - overwrite: false, - version: '>=3.0.19', - destination: '/jest.config.js', - source: '/tmp/update/jest.config.js', - }, - { - overwrite: false, - version: '>=3.1.0', - destination: '/.gettext.json', - source: '/tmp/update/.gettext.json', - }, - { - overwrite: false, - version: '>=3.1.0', - destination: '/src/reactium-translations', - source: '/tmp/update/src/reactium-translations', - }, - { - overwrite: false, - version: '>=3.2.1', - destination: '/.flowconfig', - source: '/tmp/update/.flowconfig', - }, - { - overwrite: false, - version: '>=3.2.2', - destination: '/.huskyrc', - source: '/tmp/update/.huskyrc', - }, - { - overwrite: false, - version: '>=3.4.2', - destination: '/src/app/api/reactium-hooks.js', - source: '/tmp/update/src/app/api/reactium-hooks.js', - }, - { - overwrite: false, - version: '>=3.4.2', - destination: '/src/app/api/index.js', - source: '/tmp/update/src/app/api/index.js', - }, - { - overwrite: false, - version: '>=3.4.2', - destination: '/src/app/api/domain.js', - source: '/tmp/update/src/app/api/domain.js', - }, - { - overwrite: false, - version: '>=3.4.2', - destination: '/.npmrc', - source: '/tmp/update/.npmrc', - }, - { - overwrite: true, - version: '>=3.5.1', - destination: '/src/sw', - source: '/tmp/update/src/sw', - }, - { - overwrite: true, - version: '>=3.5.1', - destination: '/src/app/main.js', - source: '/tmp/update/src/app/main.js', - }, - { - overwrite: true, - version: '>=3.6.0', - destination: '/.dockerignore', - source: '/tmp/update/.dockerignore', - }, - ], - remove: [], - }, - }, - manifest: manifestConfig, -}; diff --git a/.core/reactium.log.cjs b/.core/reactium.log.cjs deleted file mode 100644 index a74664c3..00000000 --- a/.core/reactium.log.cjs +++ /dev/null @@ -1,76 +0,0 @@ -const op = require('object-path'); -const dayjs = require('dayjs'); -const chalk = require('chalk'); - -if (!global.REACTIUM_LOG_WRAPPED) { - global.REACTIUM_LOG_WRAPPED = true; - global.LOG_LEVELS = { - DEBUG: 1000, - INFO: 500, - BOOT: 0, - WARN: -500, - ERROR: -1000, - }; - - global.LEVEL_FUNCTIONS = { - DEBUG: 'log', - INFO: 'log', - BOOT: 'log', - WARN: 'warn', - ERROR: 'error', - }; - - global.LOG_LEVEL_STRING = op.get(process.env, 'LOG_LEVEL', 'BOOT'); - global.LOG_LEVEL = op.get(LOG_LEVELS, LOG_LEVEL_STRING, LOG_LEVELS.BOOT); - - const APP_NAME = op.get(process.env, 'APP_NAME', 'Reactium'); - const LOG_THRESHOLD = op.get( - LOG_LEVELS, - [LOG_LEVEL_STRING], - LOG_LEVELS.BOOT, - ); - - const reactiumConsole = global.console; - for (const [LEVEL, THRESHOLD] of Object.entries(LOG_LEVELS)) { - global[LEVEL] = (...args) => { - if ( - process.env.NO_LOGGING === 'true' || - THRESHOLD > LOG_THRESHOLD - ) { - return; - } - - const _W = THRESHOLD <= LOG_LEVELS.WARN; - const _E = THRESHOLD <= LOG_LEVELS.ERROR; - let color = _W ? chalk.yellow.bold : chalk.cyan; - color = _E ? chalk.red.bold : color; - - const time = `[${chalk.magenta(dayjs().format('HH:mm:ss'))}]`; - let name = `${color(String(APP_NAME))}`; - name = _E ? `%${name}%` : _W ? `!${name}!` : `[${name}]`; - - const [first, ...remaining] = args; - const logMethod = - op.get( - reactiumConsole, - [op.get(LEVEL_FUNCTIONS, [LEVEL], 'log')], - reactiumConsole.log, - ) || reactiumConsole.log; - - if (typeof first === 'string') { - logMethod(`${time} ${name} ${first}`, ...remaining); - } else { - logMethod(time, name, ...args); - } - }; - } - - global.console = { - log: global.BOOT, - warn: global.WARN, - error: global.ERROR, - info: global.BOOT, - }; - - global.LOG = global.BOOT; -} diff --git a/.core/sdk/i18n/index.js b/.core/sdk/i18n/index.js deleted file mode 100644 index 20eb644d..00000000 --- a/.core/sdk/i18n/index.js +++ /dev/null @@ -1,61 +0,0 @@ -import SDK, { isBrowserWindow } from '@atomic-reactor/reactium-sdk-core'; -import Jed from 'jed'; - -const { Hook } = SDK; - -class i18n { - locale = 'en_US'; - - constructor() { - this.setDefaultLocale(); - } - - setDefaultLocale = async () => { - if (!isBrowserWindow()) this.locale = 'en_US'; - else { - const langRaw = - window.navigator.userLanguage || window.navigator.language; - const [lang, location] = langRaw.replace('-', '_').split('_'); - this.locale = `${lang}_${location}`; - } - - return Hook.run('set-default-locale', this); - }; - - getStrings() { - const defaultStrings = { strings: JSON.stringify({}) }; - - try { - if (isBrowserWindow()) { - const context = require.context( - 'babel-loader!@atomic-reactor/webpack-po-loader!reactium-translations', - true, - /.pot?$/, - ); - - if ( - context - .keys() - .find( - translation => - translation === `./${this.locale}.po`, - ) - ) { - return context(`./${this.locale}.po`); - } - - return context('./template.pot'); - } else { - return defaultStrings; - } - } catch (error) { - return defaultStrings; - } - } - - getJed() { - return new Jed(JSON.parse(this.getStrings().strings)); - } -} - -export default new i18n(); diff --git a/.core/sdk/index.js b/.core/sdk/index.js deleted file mode 100644 index e3bd6bd5..00000000 --- a/.core/sdk/index.js +++ /dev/null @@ -1,68 +0,0 @@ -import { - Hook, - Enums, - Component, - Server, - ZoneRegistry as Zone, - Plugin, - Utils, - Handle, - Pulse, - Prefs, - Cache, -} from '@atomic-reactor/reactium-sdk-core'; - -import { AppContext } from './named-exports'; -import { - useDispatcherFactory, - useStateEffectFactory, -} from './named-exports/useDispatcher'; -export * from '@atomic-reactor/reactium-sdk-core'; -export * from './named-exports'; - -const SDK = { - Hook, - Enums, - Component, - Server, - Zone, - Plugin, - Utils, - Handle, - Pulse, - Prefs, - Cache, - AppContext, -}; - -const apiHandler = { - get(SDK, prop) { - if (prop in SDK) return SDK[prop]; - if (SDK.API) { - if (prop in SDK.API) return SDK.API[prop]; - if (SDK.API.Actinium && prop in SDK.API.Actinium) - return SDK.API.Actinium[prop]; - } - }, - - set(SDK, prop, value) { - // optionally protect SDK props by hook - const { ok = true } = SDK.Hook.runSync( - 'reactium-sdk-set-prop', - prop, - value, - ); - if (ok) { - SDK[prop] = value; - } - - return true; - }, -}; - -const Reactium = new Proxy(SDK, apiHandler); - -export const useDispatcher = useDispatcherFactory(Reactium); -export const useStateEffect = useStateEffectFactory(Reactium); - -export default Reactium; diff --git a/.core/sdk/named-exports/app-context.js b/.core/sdk/named-exports/app-context.js deleted file mode 100644 index 869688e9..00000000 --- a/.core/sdk/named-exports/app-context.js +++ /dev/null @@ -1,76 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { Registry, registryFactory } from '@atomic-reactor/reactium-sdk-core'; - -/** - * @api {Object} Reactium.AppContext Reactium.AppContext - * @apiGroup Reactium - * @apiName Reactium.AppContext - * @apiDescription A Registry used for top-level React wrapping context provider, such as Redux or Theme. See [Registry](#api-Reactium-Registry) for full details on Registry methods / properties. - * Use this to register a React context provider, as well as any properties that are passed to the context. - * - * @apiParam {Getter} list get list of most recent (or highest order) registered objects, filtering out unregistered or banned objects. - * @apiParam {Method} register `reg.register(id,data)` pass an identifier and a data object to register the object. The identifier will be added if it is not already registered (but protected) and not banned. - * @apiParam (register) {String} id the id of the data object to be registered - * @apiParam (register) {Provider} data the object to be registered - * @apiParam (Provider) {ContextProvider} provider the context provider. This provider must be a React component that will render children. - * @apiParam {Method} unregister `reg.unregister(id)` pass an identifier to unregister an object. When in HISTORY mode (default), previous registration will be retained, but the object will not be listed. In CLEAN mode, the previous registrations will be removed, unless protected. - * @apiExample reactium-hooks.js -// Example of Registering Material UI Theme -import Reactium from 'reactium-core/sdk'; -import { createTheme, ThemeProvider } from '@mui/material/styles'; -import { purple } from '@mui/material/colors'; - -(async () => { - await Reactium.Plugin.register('MUI-Theme'); - - await Reactium.Hook.register('app-context-provider', async () => { - const theme = createTheme({ - palette: { - primary: { - // Purple and green play nicely together. - main: purple[500], - }, - secondary: { - // This is green.A700 as hex. - main: '#11cb5f', - }, - }, - }); - - Reactium.AppContext.register('ThemeProvider', { - // provider required - provider: ThemeProvider, - - // remainder are optional props passed to your provider, in this case the theme - theme, - }); - }) -})(); - */ -export const AppContext = registryFactory( - 'AppContext', - 'name', - Registry.MODES.CLEAN, -); - -const Provider = ({ children }) => { - return children; -}; - -export const AppContexts = ({ children }) => { - const [, update] = useState(new Date()); - useEffect(() => { - return AppContext.subscribe(() => update(new Date())); - }, []); - - return AppContext.list.reduce( - (content, { name, order, provider: ContextProvider, ...props }) => { - return ( - - {content} - - ); - }, - {children}, - ); -}; diff --git a/.core/sdk/named-exports/capability.js b/.core/sdk/named-exports/capability.js deleted file mode 100644 index 76edf5ac..00000000 --- a/.core/sdk/named-exports/capability.js +++ /dev/null @@ -1,61 +0,0 @@ -import { useAsyncEffect } from '@atomic-reactor/reactium-sdk-core'; -import { useRef, useState, useEffect } from 'react'; -import _ from 'underscore'; - -/** - * @api {ReactHook} useCapabilityCheck(capabilities,strict) useCapabilityCheck() - * @apiDescription React hook to check a list of capabilities. Uses Reactium.Capability.check(). - * @apiParam {String} capabilities array of 1 or more capabilities - * @apiParam {Boolean} [strict=true] when true all capabilities must be allowed for current user - * @apiName useCapabilityCheck - * @apiGroup ReactHook - */ -export const useCapabilityCheck = (capabilities, strict = true) => { - const allowedRef = useRef(false); - const [, update] = useState(new Date()); - const caps = _.uniq(_.compact(_.flatten([capabilities]))); - const { default: SDK } = require('reactium-core/sdk'); - - useAsyncEffect( - async isMounted => { - allowedRef.current = false; - if (caps.length < 1) { - allowedRef.current = true; - } else { - allowedRef.current = await SDK.Capability.check(caps); - } - - if (isMounted()) update(new Date()); - }, - [caps.sort().join(''), strict], - ); - - return allowedRef.current; -}; - -/** - * @api {ReactHook} useCapability(capability) useCapability() - * @apiDescription React hook to get capability object. - * @apiParam {String} capability the name/tag of the capability - * @apiName useCapability - * @apiGroup ReactHook - */ -export const useCapability = capability => { - const ref = useRef({}); - const [, update] = useState(new Date()); - const updateCapRef = cap => { - ref.current = cap; - update(new Date()); - }; - const { default: SDK } = require('reactium-core/sdk'); - - useAsyncEffect( - async isMounted => { - const cap = await SDK.Capability.get(capability); - if (isMounted()) updateCapRef(cap); - }, - [capability], - ); - - return ref.current; -}; diff --git a/.core/sdk/named-exports/hookable-component.js b/.core/sdk/named-exports/hookable-component.js deleted file mode 100644 index 6ba43115..00000000 --- a/.core/sdk/named-exports/hookable-component.js +++ /dev/null @@ -1,6 +0,0 @@ -import { useHookComponent } from '@atomic-reactor/reactium-sdk-core'; - -export const hookableComponent = name => props => { - const Component = useHookComponent(name); - return ; -}; diff --git a/.core/sdk/named-exports/i18n.js b/.core/sdk/named-exports/i18n.js deleted file mode 100644 index 8eb7b33a..00000000 --- a/.core/sdk/named-exports/i18n.js +++ /dev/null @@ -1,47 +0,0 @@ -import i18n from '../i18n'; - -/** - * @api {Function} __(text) __() - * @apiDescription Wrap this around string literals to make them translateable with gettext Poedit utility. - Run `arcli i18n` to extract strings to `src/reactium-translations/template.pot` by default. - * @apiName __ - * @apiParam {StringLiteral} text the text to be translated. Important: this should not be a variable. It must be a string literal, or - `arcli i18n` command will not be able to locate the string. This string may not be an ES6 template literal. - * @apiGroup Translation - * @apiExample Usage -import React from 'react'; -import { __ } = 'reactium-core/sdk'; - -export default () => { - return ( -
{__('My Translatable string.')}
- ); -}; - */ -export const __ = (...params) => i18n.getJed().gettext(...params); - -/** - * @api {Function} _n(singular,plural,count) _n() - * @apiDescription Wrap this around string literals to make them translateable with gettext Poedit utility. - Run `arcli i18n` to extract strings to `src/reactium-translations/template.pot` by default. - * @apiName _n - * @apiParam {StringLiteral} singular the singular form text to be translated. Important: this should not be a variable. It must be a string literal, or - `arcli i18n` command will not be able to locate the string. This string may not be an ES6 template literal. - * @apiParam {StringLiteral} plural the plural form text to be translated. Important: this should not be a variable. It must be a string literal, or - `arcli i18n` command will not be able to locate the string. This string may not be an ES6 template literal. - * @apiParam {Number} count the number related to singular or plural string - * @apiGroup Translation - * @apiExample Usage -import React from 'react'; -import { _n } = 'reactium-core/sdk'; - -export default props => { - const count = props.count; - // singular / plural translation - const label = _n('%s thing', '%s things', count).replace('%s', count); - return ( -
{label}
- ); -}; - */ -export const _n = (...params) => i18n.getJed().ngettext(...params); diff --git a/.core/sdk/named-exports/index.js b/.core/sdk/named-exports/index.js deleted file mode 100644 index 37d87ef4..00000000 --- a/.core/sdk/named-exports/index.js +++ /dev/null @@ -1,8 +0,0 @@ -export * from './roles'; -export * from './capability'; -export * from './setting'; -export * from './window'; -export * from './i18n'; -export * from './routing'; -export * from './hookable-component'; -export * from './app-context'; diff --git a/.core/sdk/named-exports/roles.js b/.core/sdk/named-exports/roles.js deleted file mode 100644 index 4995259a..00000000 --- a/.core/sdk/named-exports/roles.js +++ /dev/null @@ -1,30 +0,0 @@ -import { useRef, useState } from 'react'; -import { useAsyncEffect } from '@atomic-reactor/reactium-sdk-core'; -import uuid from 'uuid/v4'; - -/** - * @api {ReactHook} useRoles(search) useRoles() - * @apiDescription React hook to get roles object. If search is provided, will retrieve a specific role. - * @apiParam {String} [search] Name, level or object id of the roles to retrieve. If not provide, an object will all roles will be returned. - * @apiName useRoles - * @apiGroup ReactHook - */ -export const useRoles = search => { - const ref = useRef({}); - const [, update] = useState(uuid()); - const setRoles = roles => { - ref.current = roles; - update(uuid()); - }; - const { default: SDK } = require('reactium-core/sdk'); - - useAsyncEffect( - async isMounted => { - const roles = await SDK.Roles.get(search); - if (isMounted()) setRoles(roles); - }, - [search], - ); - - return ref.current; -}; diff --git a/.core/sdk/named-exports/routing.js b/.core/sdk/named-exports/routing.js deleted file mode 100644 index 27eeced8..00000000 --- a/.core/sdk/named-exports/routing.js +++ /dev/null @@ -1,57 +0,0 @@ -import uuid from 'uuid/v4'; -import { useEffect } from 'react'; -import Routing from '../routing'; -import { useSyncState } from '@atomic-reactor/reactium-sdk-core'; - -export const useRouting = () => { - const routing = useSyncState({ - current: Routing.currentRoute, - previous: Routing.previousRoute, - active: Routing.currentRoute, - transitionState: Routing.transitionState || 'READY', - transitionStates: Routing.transitionStates || [], - changes: Routing.changes || {}, - }); - - const handler = (updates, forceRefresh = true) => { - routing.set(updates, undefined, forceRefresh); - }; - - const refreshFromRouting = () => { - const { - active: activeLabel = 'current', - currentRoute, - previousRoute, - transitionState = 'READY', - transitionStates = [], - changes, - } = Routing; - - const active = - activeLabel === 'previous' ? previousRoute : currentRoute; - - handler( - { - current: currentRoute, - previous: previousRoute, - active, - transitionState, - transitionStates, - changes, - }, - false, - ); - }; - - useEffect(() => { - const id = uuid(); - Routing.routeListeners.register(id, { handler }); - refreshFromRouting(); - - return () => { - Routing.routeListeners.unregister(id); - }; - }, []); - - return routing; -}; diff --git a/.core/sdk/named-exports/setting.js b/.core/sdk/named-exports/setting.js deleted file mode 100644 index 526af1fc..00000000 --- a/.core/sdk/named-exports/setting.js +++ /dev/null @@ -1,104 +0,0 @@ -import { useRef, useState } from 'react'; -import { useCapabilityCheck } from './capability'; -import { useAsyncEffect } from '@atomic-reactor/reactium-sdk-core'; - -/** - * @api {ReactHook} useSettingGroup(group) useSettingGroup() - * @apiVersion 3.2.1 - * @apiDescription Get and set a group of Actinium settings. - * @apiParam {String} group the setting group id - * @apiName useSettingGroup - * @apiGroup ReactHook - * @apiExample Usage -import React from 'react'; -import { useSettingGroup } from 'reactium-core/sdk'; -import op from 'object-path'; - -export default () => { - const { canGet, canSet, settingGroup, setSettingGroup } = useSettingGroup('MySettings'); - - // Set MySetting.foo = 'bar' on click - return ( -
- {canGet && Foo Setting: {op.get(settingGroup, 'foo')}} - - -
- ) -} - - * @apiExample Returns -{ - canGet, // Boolean, if current user is allowed to get this setting group - canSet, // Boolean, if current user is allowed to set this setting group - settingGroup, // setting group object - setSettingGroup, // wrapper around Reactium.Setting.set(), will trigger optimistic update and rerender on response -} - */ -export const useSettingGroup = group => { - const canSet = useCapabilityCheck( - ['Setting.create', 'Setting.update', `setting.${group}-set`], - false, - ); - const canGet = useCapabilityCheck( - ['Setting.retrieve', `setting.${group}-get`], - false, - ); - - const settingRef = useRef({}); - - const [loading, setLoading] = useState(true); - const [getter, updateGetter] = useState(1); - const refresh = () => { - updateGetter(getter + 1); - }; - - const { default: SDK } = require('reactium-core/sdk'); - - const updateSettingRef = settingGroup => { - settingRef.current = settingGroup; - refresh(); - }; - - const setSettingGroup = async (settingGroup, setPublic = false) => { - if (canSet) { - updateSettingRef(settingGroup); - setLoading(true); - const settings = await SDK.Setting.set( - group, - settingGroup, - setPublic, - ); - setLoading(false); - return settings; - } else { - throw new Error( - 'Unable to update setting %s. Not permitted.', - ).replace('%s', group); - } - }; - - useAsyncEffect( - async isMounted => { - if (group && canGet) { - const settingGroup = await SDK.Setting.get(group); - if (isMounted()) { - updateSettingRef(settingGroup); - setLoading(false); - } - } - }, - [canGet, canSet, group], - ); - - return { - canGet, - canSet, - settingGroup: settingRef.current, - setSettingGroup, - loading, - }; -}; diff --git a/.core/sdk/named-exports/useDispatcher.js b/.core/sdk/named-exports/useDispatcher.js deleted file mode 100644 index 29354594..00000000 --- a/.core/sdk/named-exports/useDispatcher.js +++ /dev/null @@ -1,46 +0,0 @@ -import _ from 'underscore'; -import op from 'object-path'; -import { ComponentEvent } from '@atomic-reactor/reactium-sdk-core'; -import cc from 'camelcase'; -import { useEffect } from 'react'; - -export const useDispatcherFactory = Reactium => ({ props, state }) => ( - type, - obj, -) => { - if (!state) state = Reactium.State; - - obj = _.isObject(obj) ? obj : {}; - - const evt = new ComponentEvent(type, obj); - const cb = op.get(props, cc(`on-${type}`)); - - if (_.isFunction(cb)) state.addEventListener(type, cb); - - state.dispatchEvent(evt); - - if (_.isFunction(cb)) state.removeEventListener(type, cb); -}; - -export const useStateEffectFactory = Reactium => (handlers = {}, deps) => { - const unsubs = []; - const target = Reactium.State; - - // sanitize handlers - Object.entries(handlers).forEach(([type, cb]) => { - if ( - typeof cb === 'function' && - !Object.values(op.get(target, ['listeners', type], {})).find( - f => f === cb, - ) - ) { - unsubs.push(target.addEventListener(type, cb)); - } - }); - - useEffect(() => { - return () => { - unsubs.forEach(unsub => unsub()); - }; - }, deps); -}; diff --git a/.core/sdk/named-exports/window.js b/.core/sdk/named-exports/window.js deleted file mode 100644 index 8ed7a2bb..00000000 --- a/.core/sdk/named-exports/window.js +++ /dev/null @@ -1,222 +0,0 @@ -import { Context } from 'reactium-core/components/WindowProvider'; -import { useContext, useEffect, useState, useRef } from 'react'; -import SDK, { - breakpoint, - breakpoints, - isWindow, -} from '@atomic-reactor/reactium-sdk-core'; -import _ from 'underscore'; -import op from 'object-path'; - -const { Utils } = SDK; - -/** - * @api {ReactHook} useWindow() useWindow() - * @apiDescription React hook which resolves to the browser or electron window - when run in normal context or in the Reactium toolkit. Otherwise will return `undefined`. - This is important particularly when you need to inspect the window inside the `react-frame-component` (`FrameContextConsumer`) - which sandboxes your component withing the toolkit. - Your component will automatically be rendered inside the WindowProvider, which will provide the correct `window` and `document` - objects. See `useWindowSize()` for the most important use case. - @apiExample BrowserComponent.js -import Reactium, { useWindow } from 'reactium-core/sdk'; -import React, { useEffect } from 'react'; -import op from 'object-path'; - -export default () => { - const window = useWindow(); - const [width, setWidth] = op.get(window, 'innerWidth', 1); - - useEffect(() => { - const isBrowser = Reactium.Utils.isWindow(window); - const updateWidth = () => setWidth(window.innerWidth); - - // safe for server-side rendering, which has no window - // when used in toolkit Frame, will use correct window object - if (isBrowser) { - window.addEventListener('resize', updateWidth) - return () => window.removeEventListener('resize', updateWidth); - } - }, []); -}; - - // import WindowProvider from 'reactium-core/components/WindowProvider'; - - * @apiName useWindow - * @apiGroup ReactHook - * - */ -export const useWindow = () => { - const { iWindow } = useContext(Context); - return iWindow; -}; - -/** - * @api {ReactHook} useDocument() useDocument() - * @apiDescription Serves same use-case as `useWindow()`, but provides context aware `document` object or `undefined`, that can be - used normally as well as in the `react-frame-component` within the toolkit. - * @apiName useDocument - * @apiGroup ReactHook - */ -export const useDocument = () => { - const { iDocument } = useContext(Context); - return iDocument; -}; - -/** - * @api {ReactHook} useBreakpoints() useBreakpoints() - * @apiDescription Provides an object describing the maximum width for each breakpoint used in the Reactium grid styles. - When using the out of the box scss styles in Reactium, a grid system is in place, and is defined by an - overridable sass map `$breakpoints-max`, defined by default as: - - ``` - $breakpoints-max: ('xs': 640, 'sm': 990, 'md': 1280, 'lg': 1440,'xl': 1600) !default; - ``` - - These breakpoint maximums are automatically encoded and added to the stylesheet as `:after` psuedo-element `content` property, which can - be loaded in the browser and used for in browser responsive behavior. Potentially, this can mean only having to manage your - responsive breakpoints in one place (the stylesheet). - * @apiName useBreakpoints - * @apiGroup ReactHook - * - */ -export const useBreakpoints = () => { - const iWindow = useWindow(); - const iDocument = useDocument(); - return breakpoints(iWindow, iDocument); -}; - -/** - * @api {ReactHook} useBreakpoint(width) useBreakpoint() - * @apiDescription Returns string representing the breakpoint size for a given width. - - When using the out of the box scss styles in Reactium, a grid system is in place, and is defined by an - overridable sass map `$breakpoints-max`, defined by default as: - - ``` - $breakpoints-max: ('xs': 640, 'sm': 990, 'md': 1280, 'lg': 1440,'xl': 1600) !default; - ``` - * @apiParam {Number} width the width to check the breakpoint for. Example for the default `$breakpoints-max` - providing a width of 640 or less will return `xs`, 990 or less will return `sm` and so on. - * @apiName useBreakpoint - * @apiGroup ReactHook - */ -export const useBreakpoint = width => { - const iWindow = useWindow(); - const iDocument = useDocument(); - - return breakpoint(width, iWindow, iDocument); -}; - -/** - * @api {ReactHook} useWindowSize(params) useWindowSize() - * @apiDescription Returns window `innerWidth` number, `innerHeight` number, and current `breakpoint`, and updates on window resizes. - When using the out of the box scss styles in Reactium, a grid system is in place, and is defined by an - overridable sass map `$breakpoints-max`, defined by default as: - - ``` - $breakpoints-max: ('xs': 640, 'sm': 990, 'md': 1280, 'lg': 1440,'xl': 1600) !default; - ``` - * @apiParam {Object} [params] `defaultWidth`, `defaultHeight`, and debounce `delay` properties. - * @apiParam {Number} [params.defaultWidth=1] Default width returned by the hook when window object is `undefined`. - * @apiParam {Number} [params.defaultHeight=1] Default height returned by the hook when window object is `undefined`. - * @apiParam {Number} [params.delay=0] Debounce delay to throttle many window resize events, to prevent unnecessary rerenders of - your component using this hook. - * @apiName useWindowSize - * @apiGroup ReactHook - * @apiExample ResponsiveComponent.js - import React from 'react'; - import { useWindowSize } from 'reactium-core/sdk'; - - const Mobile = () => { - return ( -
I'm a mobile component
- ); - } - - const Tablet = () => { - return ( -
I'm a tablet component
- ); - } - - const Desktop = () => { - return ( -
I'm a desktop component
- ); - } - - export () => { - const { breakpoint } = useWindowSize(); - - switch(breakpoint) { - case 'xl': - case 'lg': - return ; - - case 'md': - return ; - - case 'xs': - case 'sm': - default: - return ; - } - }; - * - */ -export const useWindowSize = (params = {}) => { - const iWin = useWindow(); - const iDoc = useWindow(); - const hasWindow = isWindow(iWin); - - let { defaultWidth = 1, defaultHeight = 1, delay = 0 } = params; - - const getSize = () => { - return hasWindow - ? { - width: iWin.innerWidth, - height: iWin.innerHeight, - breakpoint: breakpoint(iWin.innerWidth, iWin, iDoc), - } - : { - width: defaultWidth, - height: defaultHeight, - breakpoint: breakpoint(defaultWidth), - }; - }; - - const sizeRef = useRef(getSize()); - const [, update] = useState(sizeRef.current); - - const setWindowSize = _.debounce(() => { - sizeRef.current = { ...sizeRef.current, ...getSize() }; - update(sizeRef.current); - }, delay); - - const setScrollPosition = _.debounce(() => { - sizeRef.current = { - ...sizeRef.current, - scrollX: iWin.scrollX, - scrollY: iWin.scrollY, - }; - - update(sizeRef.current); - }, delay); - - useEffect(() => { - if (!hasWindow) { - return; - } - - iWin.addEventListener('resize', setWindowSize); - iWin.addEventListener('scroll', setScrollPosition); - - return () => { - iWin.removeEventListener('resize', setWindowSize); - iWin.removeEventListener('scroll', setScrollPosition); - }; - }, [delay, defaultWidth, defaultHeight]); - - return sizeRef.current; -}; diff --git a/.core/sdk/reactium-hooks.js b/.core/sdk/reactium-hooks.js deleted file mode 100644 index 36c95332..00000000 --- a/.core/sdk/reactium-hooks.js +++ /dev/null @@ -1,23 +0,0 @@ -import Reactium, { Hook, Enums } from 'reactium-core/sdk'; - -Enums.priority.core = Enums.priority.highest - 1000; - -Reactium.Hook.register( - 'sdk-init', - async () => { - const { default: Routing } = await import('./routing'); - Reactium.Routing = Routing; - }, - Enums.priority.core, - 'REACTIUM_CORE_Routing', -); - -Reactium.Hook.register( - 'sdk-init', - async () => { - const { default: i18n } = await import('./i18n'); - Reactium.i18n = i18n; - }, - Enums.priority.core, - 'REACTIUM_CORE_i18n', -); diff --git a/.core/sdk/routing/index.js b/.core/sdk/routing/index.js deleted file mode 100644 index 6f15bcd1..00000000 --- a/.core/sdk/routing/index.js +++ /dev/null @@ -1,477 +0,0 @@ -import SDK, { - Handle, - ReactiumSyncState, - useHookComponent, - isServerWindow, - isBrowserWindow, - isElectronWindow, -} from '@atomic-reactor/reactium-sdk-core'; -import uuid from 'uuid/v4'; -import _ from 'underscore'; -import op from 'object-path'; -import { createBrowserHistory, createMemoryHistory } from 'history'; -import queryString from 'querystring-browser'; -import { matchPath } from 'react-router'; -import React from 'react'; - -const { Hook } = SDK; - -const createHistory = isElectronWindow() - ? createMemoryHistory - : createBrowserHistory; - -const NotFoundWrapper = props => { - const NotFound = useHookComponent('NotFound'); - return ; -}; - -const defaultTransitionStates = [ - { - state: 'EXITING', - active: 'previous', - }, - { - state: 'LOADING', - active: 'current', - }, - { - state: 'ENTERING', - active: 'current', - }, - { - state: 'READY', - active: 'current', - }, -]; - -class Routing { - loaded = false; - updated = null; - routesRegistry = new SDK.Utils.Registry( - 'Routing', - 'id', - SDK.Utils.Registry.MODES.CLEAN, - ); - routeListeners = new SDK.Utils.Registry( - 'RoutingListeners', - 'id', - SDK.Utils.Registry.MODES.CLEAN, - ); - - active = 'current'; - currentRoute = null; - previousRoute = null; - subscriptions = {}; - - constructor() { - if (isBrowserWindow()) { - this.historyObj = createHistory(); - this.historyObj.listen(this.setCurrentRoute); - } - } - - set history(histObj) { - this.historyObj = histObj; - } - - get history() { - if (!isBrowserWindow()) return {}; - return this.historyObj; - } - - get routes() { - return _.sortBy( - _.sortBy(this.routesRegistry.list, 'path').reverse(), - 'order', - ); - } - - handleFrontEndDataLoading = async updates => { - if ( - Boolean( - [ - 'changes.pathChanged', - 'changes.routeChanged', - 'changes.searchChanged', - ].filter(path => Boolean(op.get(updates, path, false))).length, - ) - ) { - // remove any handles from previous routes - Object.entries(Handle.handles) - .filter(([, handle]) => { - return ( - op.get(handle, 'routeId') === - op.get(updates, 'previous.match.route.id', false) - ); - }) - .filter( - ([id]) => - Handle.get(id) && - op.get(Handle.get(id), 'persistHandle', false) !== true, - ) - .forEach(([id]) => { - Handle.unregister(id); - }); - - const loadState = op.get( - updates, - 'active.match.route.component.loadState', - op.get(updates, 'active.match.route.loadState'), - ); - - const handleId = op.get( - updates, - 'active.match.route.component.handleId', - op.get(updates, 'active.match.route.handleId', uuid()), - ); - - if (typeof loadState === 'function') { - try { - const persistHandle = op.get( - updates, - 'active.match.route.persistHandle', - false, - ); - if (!persistHandle || !Handle.get(handleId)) { - Handle.register(handleId, { - routeId: op.get(updates, 'active.match.route.id'), - persistHandle, - current: new ReactiumSyncState({}), - }); - } - - const route = op.get(updates, 'active.match.route', {}); - - // for consistency - op.set(route, 'handleId', handleId); - if (route.component) - op.set(route, 'component.handleId', handleId); - - const params = op.get(updates, 'active.params', {}); - const search = op.get(updates, 'active.search', {}); - const content = await loadState({ route, params, search }); - const handle = op.get(Handle.handles, [ - handleId, - 'current', - ]); - if (handle) handle.set(content); - } catch (error) { - const handle = op.get(Handle.handles, [ - handleId, - 'current', - ]); - if (handle) handle.set({ error }); - console.error('Error loading content for component', error); - } - } - } - }; - - setCurrentRoute = async location => { - const previous = this.currentRoute; - const current = { - location, - }; - - const matches = this.routes - .map(route => ({ - route, - match: matchPath(location.pathname, route), - })) - .filter(({ match }) => match); - - let [match] = matches; - - const notFound = !match; - - if (!match) - match = { - route: this.routes.find(({ id }) => id === 'NotFound'), - match: undefined, - }; - - op.set(current, 'match', match); - op.set(current, 'params', op.get(match, 'match.params', {})); - op.set( - current, - 'search', - queryString.parse( - op.get(current, 'location.search', '').replace(/^\?/, ''), - ), - ); - const changes = { - routeChanged: - op.get(previous, 'match.route.id') !== - op.get(match, 'route.id'), - pathChanged: - op.get(previous, 'location.pathname') !== - op.get(current, 'location.pathname'), - searchChanged: - op.get(previous, 'location.search', '') !== - op.get(current, 'location.search', ''), - notFound, - transitionStateChanged: false, - setCurrentRoute: 'setCurrentRoute', - }; - - this.currentRoute = current; - this.previousRoute = previous; - this.setupTransitions(); - - const active = - this.active === 'current' ? this.currentRoute : this.previousRoute; - - const updates = { - previous: this.previousRoute, - current: this.currentRoute, - active, - changes, - transitionState: this.transitionState, - transitionStates: this.transitionStates, - setCurrentRoute: 'setCurrentRoute', - }; - - // Automatic Content Loading - this.routeListeners.register('loadState', { - handler: () => this.handleFrontEndDataLoading(updates), - }); - - this.updateListeners(updates); - }; - - updateListeners = updates => { - this.routeListeners.list.forEach(sub => { - const cb = op.get(sub, 'handler', () => {}); - cb(updates); - }); - }; - - setupTransitions = () => { - const previousTransitions = - op.get(this.previousRoute, 'match.route.transitions', false) === - true && !isServerWindow(); - const currentTransitions = - op.get(this.currentRoute, 'match.route.transitions', false) === - true && !isServerWindow(); - const currentTransitionStates = - op.get( - this.currentRoute, - 'match.route.transitionStates', - defaultTransitionStates, - ) || []; - - // set transitionStates on allowed components - this.transitionStates = (!currentTransitions - ? [] - : currentTransitionStates - ).filter(({ active = 'current' }) => { - return ( - active === 'current' || - (active === 'previous' && previousTransitions) - ); - }); - - const [transition, ...transitionStates] = this.transitionStates; - this.transitionStates = transitionStates; - this.setTransitionState(transition); - }; - - jumpCurrent = () => { - this.transitionStates = []; - this.setTransitionState(null); - }; - - nextState = () => { - if (this.transitionStates.length > 0) { - const [transition, ...transitionStates] = this.transitionStates; - this.transitionStates = transitionStates; - this.setTransitionState(transition); - } - }; - - setTransitionState = (transition, update = true) => { - this.active = op.get(transition, 'active', 'current') || 'current'; - this.transitionState = op.get(transition, 'state', 'READY') || 'READY'; - const changes = { - routeChanged: false, - pathChanged: false, - searchChanged: false, - notFound: false, - transitionStateChanged: true, - }; - - const active = - this.active === 'current' ? this.currentRoute : this.previousRoute; - const updates = { - previous: this.previousRoute, - current: this.currentRoute, - active, - changes, - transitionState: this.transitionState, - transitionStates: this.transitionStates, - setTransitionState: 'setTransitionState', - }; - if (update) { - this.updateListeners(updates); - } - }; - - load = async () => { - if (this.loaded) return; - - /** - * @api {Hook} routes-init routes-init - * @apiName routes-init - * @apiDescription Called after plugin-init, to add React Router routes to Reactium.Routing register before - the Router component is initialized and finally the application is bound to the DOM. - async only - used in front-end - * @apiGroup Hooks - */ - await Hook.run('routes-init', this.routesRegistry); - - this.routesRegistry.register({ - id: 'NotFound', - exact: false, - component: NotFoundWrapper, - order: SDK.Enums.priority.lowest, - }); - - this.loaded = true; - - if (isBrowserWindow()) { - this.setCurrentRoute(this.historyObj.location); - } - - this._update(); - - console.log('Initializing routes.'); - }; - - subscribe(cb) { - if (typeof cb === 'function') { - const id = uuid(); - this.subscriptions[id] = cb; - - // initial callback - cb(); - return () => { - delete this.subscriptions[id]; - }; - } - } - - /** - * @api {Function} Routing.register(route) Routing.register() - * @apiDescription Dynamically register a new React router route. - * @apiParam {Object} route object to be used as properties of React Router `` component, including: - 1. path - the routing pattern - 2. exact - true/false if the pattern should be matched exactly - 3. component - the React component to render on this route - 4. order - (special) the priority of this route in the list of routes (which route will resolve first) - 5. load - (special) high-order Redux action function (thunk) to run when this route is resolved (should return a promise) - 6. ... any other property `` component accepts - - ## Important Note - - The browser will still - render the route correctly (will not break the page), however the server will deliver a 404 status code on - cold loads of the page (i.e. hard-refresh of the browser). - * @apiName Routing.register - * @apiGroup Reactium.Routing - * @apiSuccess {String} uuid unique id of the route - * @apiExample Example Usage: -import React from 'react'; -import op from 'object-path'; -import Reactium, { useSelect } from 'reactium-core/sdk'; - -// A new component subscribing to Redux state.myPlugin.name -const HelloYou = () => { - const name = useSelect(state => op.get(state, 'myPlugin.name', 'unknown')); - return { -
Hello {name}
- }; -}; - -// A Redux-Thunk high-order action function (useful for async actions) -const loadAction = (params, search) => (dispatch, getState) => { - dispatch({ - type: 'MY_NAME', - name: op.get(params, 'name', 'unknown'), - }); - - return Promise.resolve(); -}; - -// Register new routing pattern '/hello-world/:name' -const routeId = Reactium.Routing.register({ - path: '/hello-world/:name', - exact: true, - component: HelloYou, - load: loadAction, -}); - -// Register reducer to handle 'MY_NAME' action -const myReducer = (state = {name: 'unknown'}, action) => { - if (action.type === 'MY_NAME') return { - ...state, - name: action.name, - }; - return state; -}; -Reactium.Plugin.register('myPlugin').then(() => { - Reactium.Reducer.register('myPlugin', myReducer); -}) - */ - async register(route = {}, update = true) { - if (!route.id) route.id = uuid(); - if (!route.order) route.order = 0; - - /** - * @api {Hook} register-route register-route - * @apiName register-route - * @apiDescription Called on boot after routes-init, and during runtime operation of the front-end application, whenever - a new route is registered. Can be used to augment a router object before it is registered to the router. - async only - used in front-end - * @apiParam {Object} route the new or updated route, indentified by unique id (route.id) - * @apiGroup Hooks - */ - await Hook.run('register-route', route); - this.routesRegistry.register(route.id, route); - if (update) this._update(); - return route.id; - } - - /** - * @api {Function} Routing.unregister(id) Routing.unregister() - * @apiName Routing.unregister - * @apiDescription Unregister an existing route, by id. - Note: You can not unregister the 'NotFound' component. You can only replace it - using the registering a NotFound component with Reactium.Component.register(). - * @apiParam {String} id the route id - * @apiParam {Boolean} [update=true] update subscribers - * @apiGroup Reactium.Routing - */ - unregister(id, update = true) { - this.routesRegistry.unregister(id); - if (update) this._update(); - } - - _update() { - this.updated = new Date(); - Object.values(this.subscriptions).forEach(cb => cb()); - } - - /** - * @api {Function} Routing.get() Routing.get() - * @apiName Routing.get - * @apiDescription Get sorted array of all route objects. - * @apiGroup Reactium.Routing - */ - get() { - return this.routes; - } -} - -const routing = new Routing(); - -export default routing; diff --git a/.core/server-globals.mjs b/.core/server-globals.mjs deleted file mode 100644 index f0954303..00000000 --- a/.core/server-globals.mjs +++ /dev/null @@ -1,44 +0,0 @@ -import op from 'object-path'; -import _ from 'underscore'; -import reactiumBootHooks from './boot-hooks.mjs'; -import path from 'node:path'; -import { dirname } from '@atomic-reactor/dirname'; -import ReactiumBoot from '@atomic-reactor/reactium-sdk-core'; - -global.ReactiumBoot = ReactiumBoot; - -const __dirname = dirname(import.meta.url); - -global.rootPath = path.resolve(__dirname, '..'); - -export default async () => { - global.defines = {}; - - const defaultPort = 3030; - global.PORT = defaultPort; - - if (process.env.NODE_ENV === 'development') { - let gulpConfig; - try { - gulpConfig = require('./gulp.config'); - } catch (err) { - gulpConfig = { port: { proxy: PORT } }; - } - PORT = gulpConfig.port.proxy; - } - - const PORT_VAR = op.get(process.env, 'PORT_VAR', 'APP_PORT'); - if (PORT_VAR && op.has(process.env, [PORT_VAR])) { - PORT = op.get(process.env, [PORT_VAR], PORT); - } else { - PORT = op.get(process.env, ['PORT'], PORT); - } - - PORT = parseInt(PORT) || defaultPort; - - global.TLS_PORT = op.get(process.env, 'TLS_PORT', 3443); - - await import('./reactium.log.cjs'); - - await reactiumBootHooks(); -}; diff --git a/.core/server/placeholder/reactium-boot.js b/.core/server/placeholder/reactium-boot.js deleted file mode 100644 index ebb86ad7..00000000 --- a/.core/server/placeholder/reactium-boot.js +++ /dev/null @@ -1,110 +0,0 @@ -const express = require('express'); -const router = express.Router(); -const xss = require('xss'); - -const Enums = ReactiumBoot.Enums; - -const placeholder = (req, res) => { - const { width = 640, height = 480, filename = '' } = req.params; - - const { - title = '', - pattern = '#f7f7f7', - color = '#fff', - background = '#444', - notes = '', - region = '0,0,100,100', - content = 'none', - } = req.query; - - const [ - xPercent = 0, - yPercent = 0, - widthPercent = 100, - heightPercent = 100, - ] = (region || []).split(','); - - const useTitle = title === '' ? filename : title; - - res.set('Content-Type', 'image/svg+xml'); - res.send(` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${xss( - width, - )}×${xss( - height, - )} - - - - - ${xss(useTitle)} - - - - - ${xss(notes)} - - -`); -}; - -router.get('/placeholder/:width/:height/:filename', placeholder); -router.get('/placeholder/:width/:height', placeholder); - -ReactiumBoot.Server.Middleware.register('placeholder', { - name: 'placeholder', - use: router, - order: Enums.priority.highest, -}); diff --git a/.core/server/renderer/feo.js b/.core/server/renderer/feo.js deleted file mode 100644 index d68c8b1f..00000000 --- a/.core/server/renderer/feo.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = async (req, res, context) => req.template(req, res, context); diff --git a/.core/server/renderer/index.mjs b/.core/server/renderer/index.mjs deleted file mode 100644 index 3639ed8b..00000000 --- a/.core/server/renderer/index.mjs +++ /dev/null @@ -1,638 +0,0 @@ -import globby from 'globby'; -import path from 'path'; -import fs from 'fs'; -import semver from 'semver'; -import op from 'object-path'; -import _ from 'underscore'; -import serialize from 'serialize-javascript'; -import reactiumConfig from '../../reactium-config.js'; - -const normalizeAssets = assets => _.flatten([assets]); - -(async () => { - ReactiumBoot.Hook.registerSync( - 'Server.AppStyleSheets', - (req, AppStyleSheets) => { - const theme = op.get( - req, - 'query.theme', - process.env.DEFAULT_THEME || 'style', - ); - - const defaultStylesheet = `${theme}.css`; - - let styles = []; - let publicDir = - process.env.PUBLIC_DIRECTORY || - path.resolve(process.cwd(), 'public'); - let styleDir = path.normalize( - path.join(publicDir, '/assets/style'), - ); - - const corePath = path - .normalize(path.join(styleDir, 'core.css')) - .split(publicDir) - .join(''); - - const when = (req, itemPath) => { - const [url] = req.originalUrl.split('?'); - - const includes = [defaultStylesheet]; - ReactiumBoot.Hook.runSync( - 'Server.AppStyleSheets.includes', - includes, - ); - - const excludes = ['core.css', 'toolkit.css']; - ReactiumBoot.Hook.runSync( - 'Server.AppStyleSheets.excludes', - excludes, - ); - - const included = Boolean( - includes.find(search => itemPath.indexOf(search) >= 0), - ); - const excluded = Boolean( - excludes.find(search => itemPath.indexOf(search) >= 0), - ); - - return included && !excluded; - }; - - fs.readdirSync(styleDir).forEach(item => { - const itemPath = path.normalize(path.join(styleDir, item)); - const cssPath = itemPath.split(publicDir).join(''); - - AppStyleSheets.register(path.basename(itemPath), { - path: itemPath.split(publicDir).join(''), - when, - }); - }); - }, - ReactiumBoot.Enums.priority.highest, - 'SERVER-APP-STYLESHEETS-CORE', - ); - - ReactiumBoot.Hook.registerSync( - 'Server.AppScripts', - (req, AppScripts, res) => { - // Webpack assets - if (process.env.NODE_ENV === 'development') { - const { stats: context } = res.locals.webpack.devMiddleware; - const stats = context.toJson(); - _.pluck(stats.namedChunkGroups.main.assets, 'name').forEach( - path => { - AppScripts.register(path, { - path: `/${path}`, - order: ReactiumBoot.Enums.priority.highest, - footer: true, - }); - }, - ); - - return; - } - - try { - const webpackAssets = JSON.parse( - fs.readFileSync( - path.resolve( - rootPath, - 'src/app/server/webpack-manifest.json', - ), - ), - ); - - ReactiumBoot.Hook.runSync( - 'webpack-server-assets', - webpackAssets, - ); - webpackAssets.forEach(asset => - AppScripts.register(asset, { - path: `${global.resourceBaseUrl}${asset}`, - order: ReactiumBoot.Enums.priority.highest, - footer: true, - }), - ); - } catch (error) { - console.error( - 'build/src/app/server/webpack-manifest.json not found or invalid JSON', - error, - ); - process.exit(1); - } - }, - ReactiumBoot.Enums.priority.highest, - 'SERVER-APP-SCRIPTS-CORE', - ); - - ReactiumBoot.Hook.registerSync( - 'Server.AppHeaders', - (req, AppHeaders, res) => { - AppHeaders.register('shortcut', { - header: - '', - order: ReactiumBoot.Enums.priority.highest, - }); - AppHeaders.register('favicon', { - header: - '', - order: ReactiumBoot.Enums.priority.highest, - }); - AppHeaders.register('viewport', { - header: - '', - order: ReactiumBoot.Enums.priority.highest, - }); - AppHeaders.register('charset', { - header: '', - order: ReactiumBoot.Enums.priority.highest, - }); - }, - ReactiumBoot.Enums.priority.highest, - 'SERVER-APP-HEADERS-CORE', - ); - - ReactiumBoot.Hook.registerSync( - 'Server.AppBindings', - (req, AppBindings) => { - AppBindings.register('router', { - template: () => { - const binding = `
`; - return binding; - }, - requestParams: ['content'], - }); - }, - ReactiumBoot.Enums.priority.highest, - 'SERVER-APP-BINDINGS-CORE', - ); - - const sanitizeTemplateVersion = version => { - if (semver.valid(version)) { - return version; - } - return semver.coerce(version); - }; - - ReactiumBoot.Hook.register( - 'Server.beforeApp', - async req => { - if (fs.existsSync(`${rootPath}/src/app/server/template/feo.js`)) { - let { default: localTemplate } = await import( - `${rootPath}/src/app/server/template/feo.js` - ); - - let templateVersion = sanitizeTemplateVersion( - localTemplate.version, - ); - - // Check to see if local template should be compatible with core - if (semver.satisfies(templateVersion, reactiumConfig.semver)) { - req.template = localTemplate.template; - } else { - console.warn( - `${rootPath}/src/app/server/template/feo.js is out of date, and will not be used. Use 'arcli server template' command to update.`, - ); - } - } - }, - ReactiumBoot.Enums.priority.highest, - 'SERVER-BEFORE-APP-CORE-TEMPLATES', - ); - - ReactiumBoot.Hook.registerSync('Server.AppGlobals', (req, AppGlobals) => { - AppGlobals.register('resourceBaseUrl', { - name: 'resourceBaseUrl', - value: - process.env.NODE_ENV === 'development' - ? '/' - : process.env.WEBPACK_RESOURCE_BASE || '/assets/js/', - }); - }); -})(); - -export const renderAppBindings = req => { - let bindingsMarkup = ''; - _.sortBy(Object.values(req.Server.AppBindings.list), 'order').forEach( - ({ component, markup, template, requestParams = [] }) => { - // Reactium App will lookup these components and bind them - if (component && typeof component === 'string') { - bindingsMarkup += ``; - } else if (markup && typeof markup === 'string') { - bindingsMarkup += markup; - } else if (template && typeof template === 'function') { - const context = {}; - requestParams.forEach(name => { - context[name] = req[name] || ''; - }); - bindingsMarkup += template(context); - } - }, - ); - - return bindingsMarkup; -}; - -const requestRegistries = () => { - const Server = {}; - Server.AppHeaders = ReactiumBoot.Utils.registryFactory( - 'AppHeaders', - 'name', - ReactiumBoot.Utils.Registry.MODES.CLEAN, - ); - Server.AppScripts = ReactiumBoot.Utils.registryFactory( - 'AppScripts', - 'name', - ReactiumBoot.Utils.Registry.MODES.CLEAN, - ); - Server.AppSnippets = ReactiumBoot.Utils.registryFactory( - 'AppSnippets', - 'name', - ReactiumBoot.Utils.Registry.MODES.CLEAN, - ); - Server.AppStyleSheets = ReactiumBoot.Utils.registryFactory( - 'AppStyleSheets', - 'name', - ReactiumBoot.Utils.Registry.MODES.CLEAN, - ); - Server.AppBindings = ReactiumBoot.Utils.registryFactory( - 'AppBindings', - 'name', - ReactiumBoot.Utils.Registry.MODES.CLEAN, - ); - Server.AppGlobals = ReactiumBoot.Utils.registryFactory( - 'AppGlobals', - 'name', - ReactiumBoot.Utils.Registry.MODES.CLEAN, - ); - - return Server; -}; - -export default async (req, res, context) => { - const Server = (req.Server = requestRegistries()); - - req.Server = Server; - req.scripts = ''; - req.headerScripts = ''; - req.styles = ''; - req.appGlobals = ''; - req.appAfterScripts = ''; - req.headTags = ''; - req.appBindings = ''; - - const { default: coreTemplate } = await import(`../template/feo.js`); - req.template = coreTemplate.template; - - /** - * @api {Hook} Server.beforeApp Server.beforeApp - * @apiName Server.beforeApp - * @apiDescription Before index.html template render for SPA template (both Front-end and Server-Side Render). Called before other Server hooks. - * @apiParam {Object} req express request object - * @apiParam {Object} Server ReactiumBoot Server object. - * @apiGroup Hooks - */ - ReactiumBoot.Hook.runSync('Server.beforeApp', req, Server); - await ReactiumBoot.Hook.run('Server.beforeApp', req, Server); - - /** - * @api {Hook} Server.AppGlobals Server.AppGlobals - * @apiName Server.AppGlobals - * @apiDescription Before index.html template render for SPA template (both Front-end and Server-Side Render). Defines window globals to be defined in template. Will also define - global for nodejs (useful for Server-Side-Rendering). - * @apiParam {Object} req express request object - * @apiParam {Object} AppGlobals Server app globals registry object. - * @apiParam (global) {String} name The property name that will be added to window (for browser) or global (for nodejs). - * @apiParam (global) {Mixed} value any javascript value that can be serialized for use in a script tag - * @apiParam (global) {Mixed} [serverValue] optional different value for the server global, useful when value should be used differently on the server code - * @apiExample reactium-boot.js - // will result in window.environment = 'local' in browser and global.environment = 'local' on nodejs - ReactiumBoot.Hook.registerSync( - 'Server.AppGlobals', - (req, AppGlobals) => { - // Find the registered component "DevTools" and bind it - AppGlobals.register('environment', { - name: 'environment', - value: 'local', - }); - }); - * @apiGroup Hooks - */ - ReactiumBoot.Hook.runSync('Server.AppGlobals', req, Server.AppGlobals); - await ReactiumBoot.Hook.run('Server.AppGlobals', req, Server.AppGlobals); - - // Add application globals - _.sortBy(Object.values(Server.AppGlobals.list), 'order').forEach( - ({ name, value, serverValue }) => { - global[name] = - typeof serverValue !== 'undefined' ? serverValue : value; - req.appGlobals += `window["${name}"] = ${serialize(value)};\n`; - }, - ); - - /** - * @api {Hook} Server.AppHeaders Server.AppHeaders - * @apiName Server.AppHeaders - * @apiDescription Before index.html template render for SPA template (both Front-end and Server-Side Render). Defines html head tags (exluding stylesheet). - Use this hook to register/unregister tags as strings. Note: if using Server Side Render and react-helmet, this is often unnecessary to do. - * @apiParam {Object} req express request object - * @apiParam {Object} AppHeaders Server app header registry object. - * @apiExample reactium-boot.js - ReactiumBoot.Hook.register('Server.AppHeaders', async (req, AppHeaders) => { - // given some data was added to req by express middleware - const seo = req.seo; - if (seo) { - if (seo.canonicalURL) { - AppHeaders.register('canonical-url', { - header: `` - }); - } - if (seo.description) { - AppHeaders.register('meta-description', { - header: `` - }); - } - } - }); - * @apiGroup Hooks - */ - ReactiumBoot.Hook.runSync('Server.AppHeaders', req, Server.AppHeaders, res); - await ReactiumBoot.Hook.run( - 'Server.AppHeaders', - req, - Server.AppHeaders, - res, - ); - - // Add header tags - _.sortBy(Object.values(Server.AppHeaders.list), 'order').forEach( - ({ header = '' }) => { - req.headTags += header; - }, - ); - - /** - * @api {Hook} Server.AppScripts Server.AppScripts - * @apiName Server.AppScripts - * @apiDescription Before index.html template render for SPA template (both Front-end and Server-Side Render). Defines javascript files to be loaded. - * @apiParam {Object} req express request object - * @apiParam {Object} AppScripts Server app scripts registry object. - * @apiParam (script) {Boolean} [footer=true] Place the script tag in the footer if true - * @apiParam (script) {Boolean} [header=false] Place the script tag above the body if true - * @apiParam (script) {String} [path] the src of the javascript - * @apiParam (script) {String} [charset=UTF-8] charset attribute - * @apiParam (script) {String} [type] type attribute - * @apiParam (script) {Boolean} [defer=false] Add defer attribute - * @apiParam (script) {Boolean} [async=false] Add async attribute - * @apiParam (script) {Boolean} [content] script content - * @apiParam (script) {Number} [order=0] loading order of script - * @apiExample reactium-boot.js - ReactiumBoot.Hook.register('Server.AppScripts', async (req, AppScripts) => { - AppScripts.register('my-onsite-script', { - path: '/assets/js/some-additional.js' - footer: true, // load in footer (optional) - header: false, // don't load in header (optional) - order: 1, // scripts will be ordered by this - }); - - AppScripts.register('my-csn-script', { - path: 'https://cdn.example.com/cdn.loaded.js' - header: true, // maybe for an external - order: 1, // scripts will be ordered by this - }); - }); - * @apiGroup Hooks - */ - ReactiumBoot.Hook.runSync('Server.AppScripts', req, Server.AppScripts, res); - await ReactiumBoot.Hook.run( - 'Server.AppScripts', - req, - Server.AppScripts, - res, - ); - - // Add scripts and headerScripts - _.sortBy(Object.values(Server.AppScripts.list), 'order').forEach( - ({ - path, - footer = true, - header = false, - charset = 'UTF-8', - type, - defer = false, - async = false, - content, - }) => { - const attributes = { - charset: typeof charset === 'string' && `charset="${charset}"`, - defer: defer === true && 'defer', - type: typeof type === 'string' && `type="${type}"`, - src: typeof path === 'string' && `src="${path}"`, - async: async === true && 'async', - }; - - content = - typeof content === 'string' - ? `//\n` - : ''; - - const script = `\n`; - if (footer) { - req.scripts += script; - return; - } - - if (header || !footer) { - req.headerScripts += script; - } - }, - ); - - /** - * @api {Hook} Server.AppStyleSheets Server.AppStyleSheets - * @apiName Server.AppStyleSheets - * @apiDescription Before index.html template render for SPA template (both Front-end and Server-Side Render). Defines css files to be loaded. - * @apiParam {Object} req express request object - * @apiParam {Object} AppStyleSheets Server app styles registry object. - * @apiParam (stylesheet) {String} [href] the src of the stylesheet or resource - * @apiParam (stylesheet) {Number} [order=0] loading order of stylesheet or resource - * @apiParam (stylesheet) {String} [rel=stylesheet] the rel attribute - * @apiParam (stylesheet) {String} [crossorigin] the crossorigin attribute - * @apiParam (stylesheet) {String} [referrerpolicy] the referrerpolicy attribute - * @apiParam (stylesheet) {String} [hrefLang] the hreflang attribute - * @apiParam (stylesheet) {String} [sizes] the sizes attribute if rel=icon - * @apiParam (stylesheet) {String} [type] the type attribute - * @apiParam (stylesheet) {Function} [when] callback passed the request object, and returns true or false if the css should be included - * @apiExample reactium-boot.js - ReactiumBoot.Hook.register('Server.AppStyleSheets', async (req, AppStyleSheets) => { - AppStyleSheets.register('my-stylesheet', { - href: '/assets/css/some-additional.css' - }); - - AppStyleSheets.register('my-csn-script', { - href: 'https://cdn.example.com/cdn.loaded.css' - order: 1, // scripts will be ordered by this - }); - }); - * @apiGroup Hooks - */ - ReactiumBoot.Hook.runSync( - 'Server.AppStyleSheets', - req, - Server.AppStyleSheets, - ); - await ReactiumBoot.Hook.run( - 'Server.AppStyleSheets', - req, - Server.AppStyleSheets, - ); - - // Add stylesheets - _.sortBy(Object.values(Server.AppStyleSheets.list), 'order').forEach( - ({ - path, - href, - rel = 'stylesheet', - crossorigin, - referrerpolicy, - hrefLang, - media, - sizes, - type, - when = () => true, - }) => { - const hrefPath = path || href; - const attributes = { - rel: - typeof rel === 'string' && - [ - 'alternate', - 'author', - 'dns-prefetch', - 'help', - 'icon', - 'license', - 'next', - 'pingback', - 'preconnect', - 'prefetch', - 'preload', - 'prerender', - 'prev', - 'search', - 'stylesheet', - ].includes(rel) && - `rel="${rel}"`, - crossorigin: - typeof crossorigin === 'string' && - ['anonymous', 'use-credentials'].includes(crossorigin) && - `crossorigin="${crossorigin}"`, - referrerpolicy: - typeof referrerpolicy === 'string' && - [ - 'no-referrer', - 'no-referrer-when-downgrade', - 'origin', - 'origin-when-cross-origin', - 'unsafe-url', - ].includes(referrerpolicy) && - `referrerpolicy="${referrerpolicy}"`, - href: typeof hrefPath === 'string' && `href="${hrefPath}"`, - hrefLang: - typeof hrefLang === 'string' && `hreflang="${hrefLang}"`, - media: typeof media === 'string' && `media="${media}"`, - sizes: - typeof sizes === 'string' && - rel === 'icon' && - `sizes="${media}"`, - type: typeof type === 'string' && `type="${type}"`, - }; - - const stylesSheet = `\n`; - if (when(req, hrefPath)) req.styles += stylesSheet; - }, - ); - - /** - * @api {Hook} Server.AppBindings Server.AppBindings - * @apiName Server.AppBindings - * @apiDescription Before index.html template render for SPA template (both Front-end and Server-Side Render). Defines React bind pointes in markup. - * @apiParam {Object} req express request object - * @apiParam {Object} AppBindings Server app binding registry object. - * @apiParam (binding) {String} [component] string name of component to bind directly if possible (must be in a webpack search context in reactium-config) - * @apiParam (binding) {String} [markup] ordinary markup that React will use to bind the app. - * @apiExample reactium-boot.js - ReactiumBoot.Hook.registerSync( - 'Server.AppBindings', - (req, AppBindings) => { - // Find the registered component "DevTools" and bind it - AppBindings.register('DevTools', { - component: 'DevTools', - }); - - // Add ordinary markup for React to bind to - AppBindings.register('router', { - markup: '
', - }); - }, - ReactiumBoot.Enums.priority.highest, - 'SERVER-APP-BINDINGS-CORE', - ); - * @apiGroup Hooks - */ - ReactiumBoot.Hook.runSync('Server.AppBindings', req, Server.AppBindings); - await ReactiumBoot.Hook.run('Server.AppBindings', req, Server.AppBindings); - req.appBindings = renderAppBindings(req); - - /** - * @api {Hook} Server.AppSnippets Server.AppSnippets - * @apiName Server.AppSnippets - * @apiDescription Before index.html template render for SPA template (both Front-end and Server-Side Render). Defines snippets of code to be added to document in their entirety. - * @apiParam {Object} req express request object - * @apiParam {Object} AppSnippets Server app snippets registry object. - * @apiExample reactium-boot.js - ReactiumBoot.Hook.register('Server.AppSnippets', async (req, AppSnippets) => { - AppSnippets.register('ga-tracking', { - snippet: ``, - order: 1, - }) - }); - * @apiGroup Hooks - */ - ReactiumBoot.Hook.runSync('Server.AppSnippets', req, Server.AppSnippets); - await ReactiumBoot.Hook.run('Server.AppSnippets', req, Server.AppSnippets); - - // Add entire text script snippets - _.sortBy(Object.values(Server.AppSnippets.list), 'order').forEach( - ({ snippet = '' }) => { - req.appAfterScripts += `${snippet}\n`; - }, - ); - - /** - * @api {Hook} Server.afterApp Server.afterApp - * @apiName Server.afterApp - * @apiDescription Before index.html template render for SPA template (both Front-end and Server-Side Render). Called after other Server hooks. - * @apiParam {Object} req express request object - * @apiParam {Object} Server ReactiumBoot Server object. - * @apiGroup Hooks - */ - ReactiumBoot.Hook.runSync('Server.afterApp', req, Server); - await ReactiumBoot.Hook.run('Server.afterApp', req, Server); - const { default: feo } = await import('./feo.js'); - - return feo(req, res, context); -}; diff --git a/.core/server/router.mjs b/.core/server/router.mjs deleted file mode 100644 index 570ce1a2..00000000 --- a/.core/server/router.mjs +++ /dev/null @@ -1,94 +0,0 @@ -import express from 'express'; -import renderer from './renderer/index.mjs'; -import fs from 'fs'; -import path from 'path'; -import httpAuth from 'http-auth'; -import op from 'object-path'; -import _ from 'underscore'; - -const router = express.Router(); - -// Conditional basic auth -const basicAuthFile = path.resolve(process.env.BASIC_AUTH_FILE || '.htpasswd'); -if (fs.existsSync(basicAuthFile)) { - router.use((req, res, next) => { - if (req.url !== '/elb-healthcheck') { - let basic = httpAuth.basic({ - realm: 'Reactium.', - file: basicAuthFile, - }); - - httpAuth.connect(basic)(req, res, next); - } else { - next(); - } - }); -} - -router.get('/elb-healthcheck', (req, res) => res.send('Up')); - -process.on('unhandledRejection', (reason, p) => { - ERROR('Unhandled Rejection at: Promise', p, 'reason:', reason); - // application specific logging, throwing an error, or other logic here -}); - -router.use(async (req, res, next) => { - const [url] = req.originalUrl.split('?'); - const parsed = path.parse(path.basename(url)); - - // Slim down index.html handling to paths that aren't handling a file extension - if (['', 'htm', 'html'].includes(parsed.ext)) { - const context = {}; - - try { - const content = await renderer(req, res, context); - if (context.url) { - INFO('Redirecting to ', context.url); - return res.redirect(302, context.url); - } - - const responseHeaders = {}; - - /** - * @api {Hook} Server.ResponseHeaders Server.ResponseHeaders - * @apiName Server.ResponseHeaders - * @apiDescription On html template responses on server, this hook is called - when HTTP headers are added to the response. Both sync and async hook is called. - * @apiParam {Object} responseHeaders object with key pairs (header name => header value) - * @apiParam {Object} req Node/Express request object - * @apiParam {Object} res Node/Express response object - * @apiGroup Hooks - */ - ReactiumBoot.Hook.runSync( - 'Server.ResponseHeaders', - responseHeaders, - req, - res, - ); - await ReactiumBoot.Hook.run( - 'Server.ResponseHeaders', - responseHeaders, - req, - res, - ); - Object.entries(responseHeaders).forEach(([key, value]) => - res.set(key, value), - ); - - let status = 200; - if (/^\/404/.test(req.path) || context.notFound) { - status = 404; - } - - res.status(status).send(content); - } catch (err) { - ERROR('React Server Error', err); - res.status(500).send('[Reactium] Internal Server Error'); - } - } else { - // let assets naturally 404, or be handled by subsequent middleware - next(); - } -}); - -export default router; diff --git a/.core/server/template/feo.js b/.core/server/template/feo.js deleted file mode 100644 index a77adda9..00000000 --- a/.core/server/template/feo.js +++ /dev/null @@ -1,25 +0,0 @@ -const serialize = require('serialize-javascript'); - -module.exports = { - version: '%TEMPLATE_VERSION%', - template: req => { - return ` - - - ${req.headTags} - ${req.styles} - - - ${req.headerScripts} - ${req.appBindings} - - - ${req.scripts} - ${req.appAfterScripts} - - `; - }, -}; diff --git a/.core/umd.webpack.config.js b/.core/umd.webpack.config.js deleted file mode 100644 index 1a302104..00000000 --- a/.core/umd.webpack.config.js +++ /dev/null @@ -1,95 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const globby = require('./globby-patch'); -const op = require('object-path'); -const rootPath = path.resolve(__dirname, '..'); -const env = process.env.NODE_ENV || 'development'; -const CompressionPlugin = require('compression-webpack-plugin'); -const webpack = require('webpack'); -const WebpackSDK = require('./webpack.sdk'); - -const overrides = (umd, config) => { - globby - .sync([ - './umd.webpack.override.js', - './node_modules/**/reactium-plugin/umd.webpack.override.js', - './src/**/umd.webpack.override.js', - './reactium_modules/**/umd.webpack.override.js', - ]) - .forEach(file => { - try { - config = require(path.resolve(file))(umd, config); - } catch (error) { - console.error(chalk.red(`Error loading ${file}:`)); - console.error(error); - } - }); - return config; -}; - -module.exports = umd => { - const sdk = new WebpackSDK(umd.libraryName, 'reactium-webpack.js', umd); - - const plugins = []; - const presets = []; - const rules = []; - const defines = op.get(umd, 'staticDefines', {}); - - if (op.get(umd, 'babelPresetEnv', true)) presets.push('@babel/preset-env'); - if (op.get(umd, 'babelReact', true)) presets.push('@babel/react'); - if (op.get(umd, 'babelLoader', true)) - sdk.addRule('babel-loader', { - test: /(\.jsx|\.js)$/, - loader: 'babel-loader', - options: { - presets, - plugins: [ - [ - '@babel/plugin-proposal-class-properties', - { - loose: true, - }, - ], - ['module-resolver'], - ], - }, - }); - - if (op.get(umd, 'workerRestAPI', true)) { - op.set( - defines, - 'workerRestAPIConfig', - JSON.stringify({ - actiniumAppId: process.env.ACTINIUM_APP_ID || 'Actinium', - restAPI: process.env.WORKER_REST_API_URL || '/api', - }), - ); - } - - const externals = []; - Object.entries(umd.externals).forEach(([key, value]) => { - sdk.addExternal(key, { key, value }); - }); - - if (op.get(umd, 'addDefines', true)) { - sdk.addPlugin('defines', new webpack.DefinePlugin(defines)); - } - - sdk.mode = env; - sdk.entry = umd.entry; - sdk.output = { - path: umd.outputPath, - filename: umd.outputFile, - library: umd.libraryName, - libraryTarget: 'umd', - globalObject: umd.globalObject, - }; - - if (env === 'production') { - sdk.addPlugin('compression', new CompressionPlugin()); - } else if (op.get(umd, 'sourcemaps', true)) { - sdk.devtool = 'cheap-source-map'; - } - - return overrides(umd, sdk.config()); -}; diff --git a/.core/webpack.config.js b/.core/webpack.config.js deleted file mode 100644 index aefcab0a..00000000 --- a/.core/webpack.config.js +++ /dev/null @@ -1,152 +0,0 @@ -'use strict'; - -const fs = require('fs'); -const _ = require('underscore'); -const path = require('path'); -const globby = require('./globby-patch'); -const webpack = require('webpack'); -const CompressionPlugin = require('compression-webpack-plugin'); -const NodePolyfillPlugin = require('node-polyfill-webpack-plugin'); -const env = process.env.NODE_ENV || 'development'; -const rootPath = path.resolve(__dirname, '..'); -const chalk = require('chalk'); -const WebpackSDK = require('./webpack.sdk'); - -let defines = {}; -if (fs.existsSync(`${rootPath}/src/app/server/defines.js`)) { - defines = require(`${rootPath}/src/app/server/defines.js`); -} - -const overrides = config => { - globby - .sync([ - './webpack.override.js', - './node_modules/**/reactium-plugin/webpack.override.js', - './src/**/webpack.override.js', - './reactium_modules/**/webpack.override.js', - ]) - .forEach(file => { - try { - config = require(path.resolve(file))(config); - } catch (error) { - console.error(chalk.red(`Error loading ${file}:`)); - console.error(error); - } - }); - return config; -}; - -module.exports = config => { - const sdk = new WebpackSDK('reactium', 'reactium-webpack.js', config); - - let filename = '[name].js'; - let dest = config.dest.js; - - sdk.mode = env; - sdk.entry = config.entries; - sdk.target = 'web'; - sdk.output = { - publicPath: '/assets/js/', - path: path.resolve(__dirname, dest), - filename, - asyncChunks: true, - }; - if (env === 'development') { - sdk.devtool = 'source-map'; - } - - sdk.setCodeSplittingOptimize(env); - if (process.env.DISABLE_CODE_SPLITTING === 'true') { - sdk.setNoCodeSplitting(); - } - - Object.keys(defines).forEach(key => { - if (key !== 'process.env') { - config.defines[key] = JSON.stringify(defines[key]); - } - }); - - config.defines['process.env'] = { - NODE_ENV: JSON.stringify(env), - }; - - if ('process.env' in defines) { - Object.keys(defines['process.env']).forEach(key => { - config.defines['process.env'][key] = JSON.stringify( - defines['process.env'][key], - ); - }); - } - - sdk.addPlugin('defines', new webpack.DefinePlugin(config.defines)); - sdk.addPlugin( - 'node-polyfills', - new NodePolyfillPlugin({ - excludeAliases: ['console'], - }), - ); - sdk.addContext('reactium-modules-context', { - from: /reactium-translations$/, - to: path.resolve('./src/reactium-translations'), - }); - - if (env === 'production') { - sdk.addPlugin('asset-compression', new CompressionPlugin()); - } - - sdk.addRule('po-loader', { - test: [/\.pot?$/], - use: [ - { - loader: '@atomic-reactor/webpack-po-loader', - }, - ], - }); - - sdk.addRule('babel-loader', { - test: [/\.jsx|js($|\?)/], - exclude: [/node_modules/, /umd.js$/], - resolve: { - extensions: ['.js', '.jsx', '.json'], - }, - use: [ - { - loader: 'babel-loader', - }, - ], - }); - - sdk.addIgnore('umd', /umd.js$/); - sdk.addIgnore('hbs', /\.hbs$/); - sdk.addIgnore('css', /\.css$/); - sdk.addIgnore('sass', /\.sass$/); - sdk.addIgnore('scss', /\.scss$/); - sdk.addIgnore('less', /\.less$/); - sdk.addIgnore('backup', /\.BACKUP$/); - sdk.addIgnore('png', /\.png$/); - sdk.addIgnore('jpg', /\.jpg$/); - sdk.addIgnore('gif', /\.gif$/); - sdk.addIgnore('server-src', /\.core\/server/); - sdk.addIgnore('manifest-tools', /\.core\/manifest/); - sdk.addIgnore('core-index', /\.core\/index.js/); - sdk.addIgnore('gulp', /\.core\/gulp/); - sdk.addIgnore('reactium-config', /\.core\/reactium-config.js$/); - sdk.addIgnore('webpack-sdk', /webpack.sdk/); - sdk.addIgnore('core-configs', /\.core\/.*?\.config/); - sdk.addIgnore('core-cli', /\.core\/.cli\//); - sdk.addIgnore('project-cli', /\.cli/); - sdk.addIgnore('server-app', /src\/app\/server/); - sdk.addIgnore('arcli-install', /arcli-install.js$/); - sdk.addIgnore('arcli-publish', /arcli-publish.js$/); - sdk.addIgnore('reactium-boot', /reactium-boot.js$/); - sdk.addIgnore('reactium-gulp', /reactium-gulp.js$/); - sdk.addIgnore('reactium-webpack', /reactium-webpack.js$/); - sdk.addIgnore('parse-node', /parse\/node/); - sdk.addIgnore('xmlhttprequest', /xmlhttprequest/); - - if (env === 'production') { - sdk.addIgnore('redux-devtools', /redux-devtools/); - } - - return overrides(sdk.config()); -}; diff --git a/.core/webpack.sdk.js b/.core/webpack.sdk.js deleted file mode 100644 index 554f041c..00000000 --- a/.core/webpack.sdk.js +++ /dev/null @@ -1,385 +0,0 @@ -const ReactiumWebpack = require('@atomic-reactor/reactium-sdk-core').default; -const op = require('object-path'); -const _ = require('underscore'); -const webpack = require('webpack'); -const globby = require('./globby-patch'); -const chalk = require('chalk'); -const path = require('path'); - -global.ReactiumWebpack = ReactiumWebpack; - -let artifacts = {}; -class WebpackReactiumWebpack { - constructor(name, ddd, context) { - this.name = name; - this.context = context; - - // setter/getter initial values - this.entryValue = { - main: './src/app/main.js', - }; - this.modeValue = 'development'; - this.targetValue = 'web'; - this.outputValue = {}; - this.devtoolValue = ''; - this.optimizationValue = { - minimize: false, - }; - - this.resolveAliases = ReactiumWebpack.Utils.registryFactory( - 'resolveAliases', - 'id', - ReactiumWebpack.Utils.Registry.MODES.CLEAN, - ); - this.resolveAliases.sdk = this; - - this.transpiledDependencies = ReactiumWebpack.Utils.registryFactory( - 'transpiledDependencies', - 'module', - ReactiumWebpack.Utils.Registry.MODES.CLEAN, - ); - this.transpiledDependencies.sdk = this; - - this.ignores = ReactiumWebpack.Utils.registryFactory( - 'ignores', - 'id', - ReactiumWebpack.Utils.Registry.MODES.CLEAN, - ); - this.ignores.sdk = this; - - this.externals = ReactiumWebpack.Utils.registryFactory( - 'externals', - 'id', - ReactiumWebpack.Utils.Registry.MODES.CLEAN, - ); - this.externals.sdk = this; - - this.rules = ReactiumWebpack.Utils.registryFactory( - 'rules', - 'id', - ReactiumWebpack.Utils.Registry.MODES.CLEAN, - ); - this.rules.sdk = this; - - this.plugins = ReactiumWebpack.Utils.registryFactory( - 'plugins', - 'id', - ReactiumWebpack.Utils.Registry.MODES.CLEAN, - ); - this.plugins.sdk = this; - - this.overridesValue = {}; - - // avoid costly globbing - if (op.get(artifacts, [ddd])) return; - - globby - .sync([ - `./${ddd}`, - `./node_modules/**/reactium-plugin/${ddd}`, - `./src/**/${ddd}`, - `./reactium_modules/**/${ddd}`, - ]) - .forEach(file => { - try { - require(path.resolve(file)); - } catch (error) { - console.error(chalk.red(`Error loading ${file}:`)); - console.error(error); - } - }); - - op.set(artifacts, [ddd], true); - } - - set mode(value) { - this.modeValue = value; - } - - get mode() { - return this.modeValue; - } - - set entry(value) { - this.entryValue = value; - } - - get entry() { - return this.entryValue; - } - - set target(value) { - this.targetValue = value; - } - - get target() { - return this.targetValue; - } - - set output(value) { - this.outputValue = value; - } - - get output() { - return this.outputValue; - } - - set devtool(value) { - this.devtoolValue = value; - } - - get devtool() { - return this.devtoolValue; - } - - set optimization(value) { - this.optimizationValue = value; - } - - get optimization() { - return this.optimizationValue; - } - - set overrides(value) { - this.overridesValue = value; - } - - get overrides() { - return this.overridesValue || {}; - } - - addResolveAlias(id, alias) { - this.resolveAliases.register(id, { alias }); - } - - addRule(id, rule) { - this.rules.register(id, { rule }); - } - - addIgnore(id, test) { - this.ignores.register(id, { test }); - } - - addPlugin(id, plugin) { - this.plugins.register(id, { plugin }); - } - - addTranspiledDependency(module) { - this.transpiledDependencies.register(module); - } - - addContext(id, context) { - const { from, to } = context; - this.plugins.register(id, { - plugin: new webpack.ContextReplacementPlugin(from, context => { - context.request = to; - }), - }); - } - - addExternal(id, config) { - const { key, value } = config; - if (typeof key === 'string' || key instanceof String) { - // regex string - if (/^\/.*\/i?$/.test(key)) { - const args = [key.replace(/^\//, '').replace(/\/i?$/, '')]; - if (/i$/.test(key)) args.push('i'); - this.externals.register(id, { external: new RegExp(...args) }); - // string keypair - } else { - this.externals.register(id, { external: { key, value } }); - } - } else if (typeof value === 'object' && value instanceof RegExp) { - this.externals.register(id, { external: value }); - } else if (Array.isArray(value)) { - this.externals.register(id, { external: { key, value } }); - } else if (typeof value === 'function') { - this.externals.register(id, { external: value }); - } - } - - getIgnores() { - ReactiumWebpack.Hook.runSync( - 'ignores', - this.ignores, - this.name, - this.context, - ); - - const ignores = this.ignores.list; - if (ignores.length > 0) { - return { - test: ignores.map(ignore => ignore.test), - use: [ - { - loader: 'ignore-loader', - }, - ], - }; - } - - return false; - } - - getExternals() { - ReactiumWebpack.Hook.runSync( - 'externals', - this.externals, - this.name, - this.context, - ); - return _.compact( - this.externals.list.map(({ external }) => { - if (typeof external === 'object' && 'key' in external) { - const { key, value } = external; - return { [key]: value }; - } - - return external; - }), - ); - } - - getRules() { - ReactiumWebpack.Hook.runSync( - 'rules', - this.rules, - this.name, - this.context, - ); - return this.rules.list.map(({ id, rule }) => rule); - } - - getPlugins() { - ReactiumWebpack.Hook.runSync( - 'plugins', - this.plugins, - this.name, - this.context, - ); - return this.plugins.list.map(({ id, plugin }) => plugin); - } - - matchChunk(test) { - return module => { - const moduleName = - module.nameForCondition && module.nameForCondition(); - return test.test(moduleName); - }; - } - - setNoCodeSplitting(env) { - this.optimizationValue = { - minimize: Boolean(env !== 'development'), - }; - - this.addPlugin( - 'limit-chunks', - new webpack.optimize.LimitChunkCountPlugin({ - maxChunks: 1, - }), - ); - } - - setWebpackDefaultOptimize(env) { - this.optimizationValue = { - minimize: Boolean(env !== 'development'), - splitChunks: { - chunks: 'async', - minSize: 20000, - minRemainingSize: 0, - minChunks: 1, - maxAsyncRequests: 30, - maxInitialRequests: 30, - enforceSizeThreshold: 50000, - cacheGroups: { - defaultVendors: { - test: /[\\/]node_modules[\\/]/, - priority: -10, - reuseExistingChunk: true, - }, - default: { - minChunks: 2, - priority: -20, - reuseExistingChunk: true, - }, - }, - }, - }; - } - - setCodeSplittingOptimize(env) { - this.optimizationValue = { - minimize: Boolean(env !== 'development'), - chunkIds: 'named', - splitChunks: { - chunks: 'all', - minSizeReduction: 500000, - cacheGroups: { - main: { - minChunks: 1, - priority: -20, - reuseExistingChunk: true, - }, - }, - }, - }; - } - - config() { - ReactiumWebpack.Hook.runSync('before-config', this); - - if (this.transpiledDependencies.list.length > 0) { - this.addRule('babel-loader', { - test: [/\.jsx|js($|\?)/], - exclude: [ - new RegExp( - `node_modules\/(?!(${this.transpiledDependencies.list - .map(({ module }) => module) - .join('|')})\/).*`, - ), - /umd.js$/, - ], - resolve: { - extensions: ['.js', '.jsx', '.json'], - }, - use: [ - { - loader: 'babel-loader', - }, - ], - }); - } - - const theConfig = { - mode: this.mode, - target: this.target, - output: this.output, - entry: this.entry, - optimization: this.optimization, - externals: this.getExternals(), - module: { - rules: _.compact( - [...this.getRules()].concat(this.getIgnores()), - ), - }, - plugins: this.getPlugins(), - ...this.overrides, - }; - - if (this.devtool) theConfig.devtool = this.devtool; - - if (this.resolveAliases.list.length > 0) { - const alias = {}; - this.resolveAliases.list.forEach(({ id: from, alias: to }) => { - alias[from] = to; - }); - theConfig.resolve = { alias }; - } - - ReactiumWebpack.Hook.runSync('after-config', theConfig, this); - return theConfig; - } -} - -module.exports = WebpackReactiumWebpack; diff --git a/Dockerfile b/Dockerfile index 541eca25..bd87c6cd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build Stage -FROM node:lts as build +FROM node:lts-hydrogen as build RUN mkdir /tmp/app @@ -22,7 +22,7 @@ RUN npx reactium install && npm run build RUN npm prune --production # Deployable Stage -FROM node:lts +FROM node:lts-hydrogen # Create app directory WORKDIR /usr/src/app @@ -34,9 +34,6 @@ COPY --from=build /tmp/app/public ./public COPY --from=build /tmp/app/package.json ./package.json COPY --from=build /tmp/app/node_modules ./node_modules -# Includes entire server-side app (including reactium_modules) -COPY --from=build /tmp/app/.core ./.core - RUN chown -R node ./ USER node diff --git a/babel.config.js b/babel.config.js index c6efd151..f2cc5d55 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,4 +1,4 @@ -const config = require('./.core/babel.config'); +const config = require('@atomic-reactor/reactium-core/babel.config'); // @example // diff --git a/gulpfile.js b/gulpfile.js index 7e21779a..7aacd8b5 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1 +1,5 @@ -require('./.core/gulpfile'); +// *********** DO NOT MANUALLY EDIT THIS FILE ************ +// THIS FILE IS GENERATED VIA THE ARCLI UPDATE COMMAND +// ******************************************************* + +require('@atomic-reactor/reactium-core/gulpfile'); diff --git a/package-lock.json b/package-lock.json index d9ee5f6e..60150f83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,117 +9,11 @@ "version": "5.0.0-alpha-3", "license": "MIT", "workspaces": [ - "reactium_modules/**/_npm" + "reactium_modules/*", + "reactium_modules/@*/*" ], "dependencies": { - "@atomic-reactor/dirname": "^1.0.2", - "@atomic-reactor/reactium-sdk-core": "^1.2.23", - "@babel/cli": "^7.21.0", - "@babel/node": "^7.20.7", - "@loadable/component": "^5.15.3", - "action-sequence": "^1.1.2", - "axios": "^0.26.0", - "axios-retry": "^3.2.4", - "body-parser": "^1.20.2", - "camelcase": "^7.0.1", - "chalk": "^4.1.2", - "classnames": "^2.3.2", - "cookie-parser": "^1.4.6", - "cookie-session": "^2.0.0", - "copy-to-clipboard": "^3.3.3", - "core-js": "^3.29.1", - "cors": "^2.8.5", - "cross-env": "^7.0.3", - "dayjs": "^1.11.7", - "directory-tree": "^2.2.7", - "express": "^4.17.3", - "express-static-gzip": "^2.1.7", - "fs-extra": "^10.0.0", - "globby": "^11.0.3", - "http-auth": "^3.2.4", - "http-proxy-middleware": "^0.20.0", - "jed": "^1.1.1", - "jsdom": "^16.5.2", - "memory-cache": "^0.2.0", - "moment": "^2.29.4", - "morgan": "^1.10.0", - "npm-run-all": "^4.1.5", - "object-path": "^0.11.8", - "prettier": "^1.19.1", - "prop-types": "^15.8.1", - "querystring-browser": "^1.0.4", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-helmet": "^6.1.0", - "react-router-dom": "~5.2.0", - "regenerator-runtime": "^0.13.11", - "run-script-os": "^1.1.6", - "semver": "^7.3.8", - "serialize-javascript": "^6.0.1", - "shallow-equals": "^1.0.0", - "spdy": "^4.0.2", - "underscore": "^1.13.6", - "uuid": "^3.4.0", - "xss": "^1.0.14" - }, - "devDependencies": { - "@atomic-reactor/gulp-run": "^1.8.0", - "@atomic-reactor/gulp-watch": "^5.0.2", - "@atomic-reactor/node-sass-reactium-importer": "^1.0.0", - "@atomic-reactor/webpack-po-loader": "5.0.1", - "@babel/core": "^7.21.3", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-export-default-from": "^7.18.10", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/preset-env": "^7.20.2", - "@babel/preset-react": "^7.18.6", - "ajv": "^8.12.0", - "apidoc": "^0.25.0", - "babel-core": "^7.0.0-bridge.0", - "babel-eslint": "^10.1.0", - "babel-jest": "^26.6.3", - "babel-loader": "^9.1.2", - "babel-plugin-module-resolver": "^4.1.0", - "browser-sync": "^2.28.3", - "cli-spinners": "^2.7.0", - "compression-webpack-plugin": "^10.0.0", - "decamelize": "^3.2.0", - "del": "^5.1.0", - "eslint": "^5.16.0", - "eslint-plugin-react": "^7.28.0", - "eslint-plugin-react-hooks": "^2.5.0", - "fast-diff": "^1.2.0", - "file-api": "^0.10.4", - "fs-readdir-recursive": "^1.1.0", - "gettext-extract": "^2.0.1", - "gulp": "^4.0.2", - "gulp-autoprefixer": "^8.0.0", - "gulp-clean-css": "^4.3.0", - "gulp-concat": "^2.6.1", - "gulp-gzip": "^1.4.2", - "gulp-if": "^3.0.0", - "gulp-rename": "^2.0.0", - "gulp-sass": "^5.1.0", - "gulp-sourcemaps": "^3.0.0", - "gulp4-run-sequence": "^1.0.1", - "handlebars": "^4.7.7", - "husky": "^3.1.0", - "ignore-loader": "^0.1.2", - "lint-staged": "^9.4.3", - "module-alias": "^2.2.2", - "node-polyfill-webpack-plugin": "^2.0.1", - "nodemon": "^2.0.21", - "open": "^8.4.2", - "ora": "^5.4.1", - "reactium": "^3.0.10", - "readdir-recursive": "0.0.4", - "sass": "^1.59.3", - "sass-embedded": "^1.62.0", - "slugify": "^1.6.5", - "stylelint": "^13.12.0", - "webpack": "^5.76.2", - "webpack-dev-middleware": "^5.3.3", - "webpack-hot-middleware": "^2.25.3" + "react": "^18.2.0" }, "engines": { "node": "18.x", @@ -189,9 +83,9 @@ } }, "node_modules/@atomic-reactor/dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@atomic-reactor/dirname/-/dirname-1.0.2.tgz", - "integrity": "sha512-VwhCkROeMaZIsZV/iiCOIxRjQ1Uikxo5n3YOSpZExQkECYmadzjtNV4phzk4lt6NKVTgnTCFPUdZAAk+RjK7kA==" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@atomic-reactor/dirname/-/dirname-1.0.7.tgz", + "integrity": "sha512-jbhcrpFN1HqE35NVntOc/Gu0eSD8snH5u/Qk1tZ5z9NQPGu7TiG0VvJWi8aaawMn5iZXkhvOUkgQB7rBhEYoTw==" }, "node_modules/@atomic-reactor/gulp-run": { "version": "1.8.0", @@ -342,21 +236,25 @@ } }, "node_modules/@atomic-reactor/reactium-api": { - "resolved": "reactium_modules/@atomic-reactor/reactium-api/_npm", + "resolved": "reactium_modules/@atomic-reactor/reactium-api", "link": true }, "node_modules/@atomic-reactor/reactium-capability": { - "resolved": "reactium_modules/@atomic-reactor/reactium-capability/_npm", + "resolved": "reactium_modules/@atomic-reactor/reactium-capability", + "link": true + }, + "node_modules/@atomic-reactor/reactium-core": { + "resolved": "reactium_modules/@atomic-reactor/reactium-core", "link": true }, "node_modules/@atomic-reactor/reactium-role": { - "resolved": "reactium_modules/@atomic-reactor/reactium-role/_npm", + "resolved": "reactium_modules/@atomic-reactor/reactium-role", "link": true }, "node_modules/@atomic-reactor/reactium-sdk-core": { - "version": "1.2.23", - "resolved": "https://registry.npmjs.org/@atomic-reactor/reactium-sdk-core/-/reactium-sdk-core-1.2.23.tgz", - "integrity": "sha512-ba0zpJ10sgivlwMKogJEekJ+kYr5RY0qI7zXR/msowL/8tw/KgZ/qFDfe27xHBZulHxSp3Mg0Rvai+Q6bwqU6A==", + "version": "1.2.24", + "resolved": "https://registry.npmjs.org/@atomic-reactor/reactium-sdk-core/-/reactium-sdk-core-1.2.24.tgz", + "integrity": "sha512-abrkdaTg4/ui8TEMr0xJY+oScdVTPzSWPxb3sbtLTcAsM3L6TQcyd42hq7ZAOnslckkjkcETRTDhQ6qnbEBjnQ==", "dependencies": { "action-sequence": "^1.1.2", "classnames": "^2.3.2", @@ -369,15 +267,15 @@ } }, "node_modules/@atomic-reactor/reactium-setting": { - "resolved": "reactium_modules/@atomic-reactor/reactium-setting/_npm", + "resolved": "reactium_modules/@atomic-reactor/reactium-setting", "link": true }, "node_modules/@atomic-reactor/reactium-svg": { - "resolved": "reactium_modules/@atomic-reactor/reactium-svg/_npm", + "resolved": "reactium_modules/@atomic-reactor/reactium-svg", "link": true }, "node_modules/@atomic-reactor/reactium-user": { - "resolved": "reactium_modules/@atomic-reactor/reactium-user/_npm", + "resolved": "reactium_modules/@atomic-reactor/reactium-user", "link": true }, "node_modules/@atomic-reactor/webpack-po-loader": { @@ -390,9 +288,9 @@ } }, "node_modules/@babel/cli": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.21.0.tgz", - "integrity": "sha512-xi7CxyS8XjSyiwUGCfwf+brtJxjW1/ZTcBUkP10xawIEXLX5HzLn+3aXkgxozcP2UhRhtKTmQurw9Uaes7jZrA==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.21.5.tgz", + "integrity": "sha512-TOKytQ9uQW9c4np8F+P7ZfPINy5Kv+pizDIUwSVH8X5zHgYHV4AA8HE5LA450xXeu4jEfmUckTYvv1I4S26M/g==", "dependencies": { "@jridgewell/trace-mapping": "^0.3.17", "commander": "^4.0.1", @@ -547,28 +445,28 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", - "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==", + "version": "7.21.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.7.tgz", + "integrity": "sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz", - "integrity": "sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz", + "integrity": "sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-compilation-targets": "^7.21.4", - "@babel/helper-module-transforms": "^7.21.2", - "@babel/helpers": "^7.21.0", - "@babel/parser": "^7.21.4", + "@babel/generator": "^7.21.5", + "@babel/helper-compilation-targets": "^7.21.5", + "@babel/helper-module-transforms": "^7.21.5", + "@babel/helpers": "^7.21.5", + "@babel/parser": "^7.21.8", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.4", - "@babel/types": "^7.21.4", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -592,11 +490,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", - "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.5.tgz", + "integrity": "sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==", "dependencies": { - "@babel/types": "^7.21.4", + "@babel/types": "^7.21.5", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -617,23 +515,22 @@ } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.21.5.tgz", + "integrity": "sha512-uNrjKztPLkUk7bpCNC0jEKDJzzkvel/W+HguzbN8krA+LPfC1CEobJEvAvGka2A/M+ViOqXdcRL0GqPUJSjx9g==", "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", - "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz", + "integrity": "sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==", "dependencies": { - "@babel/compat-data": "^7.21.4", + "@babel/compat-data": "^7.21.5", "@babel/helper-validator-option": "^7.21.0", "browserslist": "^4.21.3", "lru-cache": "^5.1.1", @@ -655,18 +552,19 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.4.tgz", - "integrity": "sha512-46QrX2CQlaFRF4TkwfTt6nJD7IHq8539cCL7SDpqWSDeJKY1xylKKY5F/33mJhLZ3mFvKv2gGrVS6NkyF6qs+Q==", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.8.tgz", + "integrity": "sha512-+THiN8MqiH2AczyuZrnrKL6cAxFRRQDKW9h1YkBvbgKmAm6mwiacig1qT73DHIWMGo40GRnsEfN3LA+E6NtmSw==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-environment-visitor": "^7.21.5", "@babel/helper-function-name": "^7.21.0", - "@babel/helper-member-expression-to-functions": "^7.21.0", + "@babel/helper-member-expression-to-functions": "^7.21.5", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.20.7", + "@babel/helper-replace-supers": "^7.21.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/helper-split-export-declaration": "^7.18.6" + "@babel/helper-split-export-declaration": "^7.18.6", + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" @@ -675,13 +573,22 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.4.tgz", - "integrity": "sha512-M00OuhU+0GyZ5iBBN9czjugzWrEq2vDpf/zCYHxxf93ul/Q5rv+a5h+/+0WnI1AebHNVtl5bFV0qsJoH23DbfA==", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.8.tgz", + "integrity": "sha512-zGuSdedkFtsFHGbexAvNuipg1hbtitDLo2XE8/uf6Y9sOQV1xsYX/2pNbtedp/X0eU1pIt+kGvaqHCowkRbS5g==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.3.1" + "regexpu-core": "^5.3.1", + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" @@ -690,6 +597,14 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-define-polyfill-provider": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", @@ -715,20 +630,9 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", - "dependencies": { - "@babel/types": "^7.18.6" - }, + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz", + "integrity": "sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==", "engines": { "node": ">=6.9.0" } @@ -757,11 +661,11 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz", - "integrity": "sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.5.tgz", + "integrity": "sha512-nIcGfgwpH2u4n9GG1HpStW5Ogx7x7ekiFHbjjFRKXbn5zUvqO9ZgotCO4x1aNbKn/x/xOUaXEhyNHCwtFCpxWg==", "dependencies": { - "@babel/types": "^7.21.0" + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -779,18 +683,18 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", - "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz", + "integrity": "sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==", "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-module-imports": "^7.21.4", + "@babel/helper-simple-access": "^7.21.5", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.2", - "@babel/types": "^7.21.2" + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -808,9 +712,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz", + "integrity": "sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==", "engines": { "node": ">=6.9.0" } @@ -833,27 +737,27 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz", - "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.21.5.tgz", + "integrity": "sha512-/y7vBgsr9Idu4M6MprbOVUfH3vs7tsIfnVWv/Ml2xgwvyH6LTngdfbf5AdsKwkJy4zgy1X/kuNrEKvhhK28Yrg==", "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.20.7", + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-member-expression-to-functions": "^7.21.5", "@babel/helper-optimise-call-expression": "^7.18.6", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz", + "integrity": "sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==", "dependencies": { - "@babel/types": "^7.20.2" + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -882,9 +786,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", + "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", "engines": { "node": ">=6.9.0" } @@ -920,13 +824,13 @@ } }, "node_modules/@babel/helpers": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", - "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.5.tgz", + "integrity": "sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==", "dependencies": { "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0" + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -1024,9 +928,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", - "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz", + "integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==", "bin": { "parser": "bin/babel-parser.js" }, @@ -1417,7 +1321,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1559,11 +1462,11 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz", - "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.21.5.tgz", + "integrity": "sha512-wb1mhwGOCaXHDTcsRYMKF9e5bbMgqwxtqa2Y1ifH96dXJPwbuLX9qHy3clhrxVqgMz7nyNXs8VkxdH8UBcjKqA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -1639,11 +1542,11 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz", - "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.21.5.tgz", + "integrity": "sha512-TR653Ki3pAwxBxUe8srfF3e4Pe3FTA46uaNHYyQwIoM4oWKSoOZiDNyHJ0oIoDIUPSRQbQG7jzgVBX3FPVne1Q==", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-plugin-utils": "^7.21.5", "@babel/template": "^7.20.7" }, "engines": { @@ -1712,11 +1615,11 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz", - "integrity": "sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.5.tgz", + "integrity": "sha512-nYWpjKW/7j/I/mZkGVgHJXh4bA1sfdFnJoOXwJuj4m3Q2EraO/8ZyrkCau9P5tbHQk01RMSt6KYLCsW7730SXQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -1785,13 +1688,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz", - "integrity": "sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.5.tgz", + "integrity": "sha512-OVryBEgKUbtqMoB7eG2rs6UFexJi6Zj6FDXx+esBLPTCxCNxAY9o+8Di7IsUGJ+AVhp5ncK0fxWUBd0/1gPhrQ==", "dependencies": { - "@babel/helper-module-transforms": "^7.21.2", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-simple-access": "^7.20.2" + "@babel/helper-module-transforms": "^7.21.5", + "@babel/helper-plugin-utils": "^7.21.5", + "@babel/helper-simple-access": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -1933,15 +1836,15 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.0.tgz", - "integrity": "sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.5.tgz", + "integrity": "sha512-ELdlq61FpoEkHO6gFRpfj0kUgSwQTGoaEU8eMRoS8Dv3v6e7BjEAj5WMtIBRdHUeAioMhKP5HyxNzNnP+heKbA==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-jsx": "^7.18.6", - "@babel/types": "^7.21.0" + "@babel/helper-module-imports": "^7.21.4", + "@babel/helper-plugin-utils": "^7.21.5", + "@babel/plugin-syntax-jsx": "^7.21.4", + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -1980,11 +1883,11 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", - "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.21.5.tgz", + "integrity": "sha512-ZoYBKDb6LyMi5yCsByQ5jmXsHAQDDYeexT1Szvlmui+lADvfSecr5Dxd/PkrTC3pAD182Fcju1VQkB4oCp9M+w==", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-plugin-utils": "^7.21.5", "regenerator-transform": "^0.15.1" }, "engines": { @@ -2097,11 +2000,11 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.21.5.tgz", + "integrity": "sha512-LYm/gTOwZqsYohlvFUe/8Tujz75LqqVC2w+2qPHLR+WyWHGCZPN1KBpJCJn+4Bk4gOkQy/IXKIge6az5MqwlOg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -2126,13 +2029,13 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.21.4.tgz", - "integrity": "sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.21.5.tgz", + "integrity": "sha512-wH00QnTTldTbf/IefEVyChtRdw5RJvODT/Vb4Vcxq1AZvtXj6T0YeX0cAcXhI6/BdGuiP3GcNIL4OQbI2DVNxg==", "dependencies": { - "@babel/compat-data": "^7.21.4", - "@babel/helper-compilation-targets": "^7.21.4", - "@babel/helper-plugin-utils": "^7.20.2", + "@babel/compat-data": "^7.21.5", + "@babel/helper-compilation-targets": "^7.21.5", + "@babel/helper-plugin-utils": "^7.21.5", "@babel/helper-validator-option": "^7.21.0", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.20.7", @@ -2157,6 +2060,7 @@ "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", "@babel/plugin-syntax-import-assertions": "^7.20.0", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", @@ -2166,22 +2070,22 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.20.7", + "@babel/plugin-transform-arrow-functions": "^7.21.5", "@babel/plugin-transform-async-to-generator": "^7.20.7", "@babel/plugin-transform-block-scoped-functions": "^7.18.6", "@babel/plugin-transform-block-scoping": "^7.21.0", "@babel/plugin-transform-classes": "^7.21.0", - "@babel/plugin-transform-computed-properties": "^7.20.7", + "@babel/plugin-transform-computed-properties": "^7.21.5", "@babel/plugin-transform-destructuring": "^7.21.3", "@babel/plugin-transform-dotall-regex": "^7.18.6", "@babel/plugin-transform-duplicate-keys": "^7.18.9", "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.21.0", + "@babel/plugin-transform-for-of": "^7.21.5", "@babel/plugin-transform-function-name": "^7.18.9", "@babel/plugin-transform-literals": "^7.18.9", "@babel/plugin-transform-member-expression-literals": "^7.18.6", "@babel/plugin-transform-modules-amd": "^7.20.11", - "@babel/plugin-transform-modules-commonjs": "^7.21.2", + "@babel/plugin-transform-modules-commonjs": "^7.21.5", "@babel/plugin-transform-modules-systemjs": "^7.20.11", "@babel/plugin-transform-modules-umd": "^7.18.6", "@babel/plugin-transform-named-capturing-groups-regex": "^7.20.5", @@ -2189,17 +2093,17 @@ "@babel/plugin-transform-object-super": "^7.18.6", "@babel/plugin-transform-parameters": "^7.21.3", "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.20.5", + "@babel/plugin-transform-regenerator": "^7.21.5", "@babel/plugin-transform-reserved-words": "^7.18.6", "@babel/plugin-transform-shorthand-properties": "^7.18.6", "@babel/plugin-transform-spread": "^7.20.7", "@babel/plugin-transform-sticky-regex": "^7.18.6", "@babel/plugin-transform-template-literals": "^7.18.9", "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", + "@babel/plugin-transform-unicode-escapes": "^7.21.5", "@babel/plugin-transform-unicode-regex": "^7.18.6", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.21.4", + "@babel/types": "^7.21.5", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", @@ -2256,14 +2160,14 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.21.4.tgz", - "integrity": "sha512-sMLNWY37TCdRH/bJ6ZeeOH1nPuanED7Ai9Y/vH31IPqalioJ6ZNFUWONsakhv4r4n+I6gm5lmoE0olkgib/j/A==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.21.5.tgz", + "integrity": "sha512-iqe3sETat5EOrORXiQ6rWfoOg2y68Cs75B9wNxdPW4kixJxh7aXQE1KPdWLDniC24T/6dSnguF33W9j/ZZQcmA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-plugin-utils": "^7.21.5", "@babel/helper-validator-option": "^7.21.0", "@babel/plugin-syntax-jsx": "^7.21.4", - "@babel/plugin-transform-modules-commonjs": "^7.21.2", + "@babel/plugin-transform-modules-commonjs": "^7.21.5", "@babel/plugin-transform-typescript": "^7.21.3" }, "engines": { @@ -2297,9 +2201,9 @@ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "node_modules/@babel/runtime": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", - "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", + "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", "dependencies": { "regenerator-runtime": "^0.13.11" }, @@ -2333,18 +2237,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz", - "integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.5.tgz", + "integrity": "sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==", "dependencies": { "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-environment-visitor": "^7.18.9", + "@babel/generator": "^7.21.5", + "@babel/helper-environment-visitor": "^7.21.5", "@babel/helper-function-name": "^7.21.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.4", - "@babel/types": "^7.21.4", + "@babel/parser": "^7.21.5", + "@babel/types": "^7.21.5", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2353,11 +2257,11 @@ } }, "node_modules/@babel/types": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", - "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz", + "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==", "dependencies": { - "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-string-parser": "^7.21.5", "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" }, @@ -2957,38 +2861,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@svgr/core/node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@svgr/core/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@svgr/hast-util-to-babel-ast": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz", @@ -3005,17 +2877,6 @@ "url": "https://github.com/sponsors/gregberge" } }, - "node_modules/@svgr/hast-util-to-babel-ast/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/@svgr/plugin-jsx": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz", @@ -3057,38 +2918,6 @@ "@svgr/core": "*" } }, - "node_modules/@svgr/plugin-svgo/node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@svgr/plugin-svgo/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@svgr/webpack": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-6.3.1.tgz", @@ -3160,9 +2989,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", - "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.5.tgz", + "integrity": "sha512-enCvTL8m/EHS/zIvJno9nE+ndYPh1/oNFzRYRmtUqJICG2VnCSBzMLW5VN2KCQU91f23tsNKR8v7VJJQMatl7Q==", "dev": true, "dependencies": { "@babel/types": "^7.3.0" @@ -3280,9 +3109,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.16.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.0.tgz", - "integrity": "sha512-BsAaKhB+7X+H4GnSjGhJG9Qi8Tw+inU9nJDwmD5CgOmBLEI6ArdhikpLX7DjbjDRDTbqZzU2LSQNZg8WGPiSZQ==", + "version": "18.16.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.3.tgz", + "integrity": "sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==", "dev": true }, "node_modules/@types/normalize-package-data": { @@ -5615,9 +5444,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001481", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001481.tgz", - "integrity": "sha512-KCqHwRnaa1InZBtqXzP98LPg0ajCVujMKjqKDhZEthIpAsJl/YEIa3YvXjGXPVqzZVguccuu7ga9KOE1J9rKPQ==", + "version": "1.0.30001482", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001482.tgz", + "integrity": "sha512-F1ZInsg53cegyjroxLNW9DmrEQ1SuGRTO1QlpA0o2/6OpQ0gFeDRoq1yFmnr8Sakn9qwwt9DmbxHB6w167OSuQ==", "funding": [ { "type": "opencollective", @@ -5966,9 +5795,9 @@ } }, "node_modules/cli-spinners": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.8.0.tgz", - "integrity": "sha512-/eG5sJcvEIwxcdYM86k5tPwn0MUzkX5YY3eImTGpJOZgVe4SdTMY14vQpcxgBzJ0wXwAYrS8E+c3uHeK4JNyzQ==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", + "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==", "dev": true, "engines": { "node": ">=6" @@ -6730,40 +6559,18 @@ } }, "node_modules/cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "dependencies": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cosmiconfig/node_modules/import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", - "dev": true, + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dependencies": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" }, "engines": { - "node": ">=4" - } - }, - "node_modules/cosmiconfig/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true, - "engines": { - "node": ">=4" + "node": ">=10" } }, "node_modules/crc": { @@ -6997,6 +6804,14 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/css-select/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/css-selector-parser": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz", @@ -7657,6 +7472,15 @@ } ] }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/domain-browser": { "version": "4.22.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.22.0.tgz", @@ -7775,9 +7599,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.372", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.372.tgz", - "integrity": "sha512-MrlFq/j+TYHOjeWsWGYfzevc25HNeJdsF6qaLFrqBTRWZQtWkb1myq/Q2veLWezVaa5OcSZ99CFwTT4aF4Mung==" + "version": "1.4.383", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.383.tgz", + "integrity": "sha512-BQyvFauIMzCJqILViJNs0kIBEAlx1bYLS5CRLyJtlun1KAnZlhNSgyfyWifPWagQ5s8KYPY6BpNHZsEMkxZAQQ==" }, "node_modules/elegant-spinner": { "version": "1.0.1", @@ -7848,9 +7672,9 @@ } }, "node_modules/engine.io": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.1.tgz", - "integrity": "sha512-JFYQurD/nbsA5BSPmbaOSLa3tSVj8L6o4srSwXXY3NqE+gGUNmmPTbhn8tjzcCtSqhFgIeqef81ngny8JM25hw==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz", + "integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -7943,9 +7767,15 @@ } }, "node_modules/entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==" + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } }, "node_modules/error-ex": { "version": "1.3.2", @@ -11991,6 +11821,21 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, + "node_modules/husky/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/husky/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -12000,6 +11845,32 @@ "node": ">=4" } }, + "node_modules/husky/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "dev": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/husky/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/husky/node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -12012,6 +11883,15 @@ "node": ">=8" } }, + "node_modules/husky/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/husky/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -12088,12 +11968,6 @@ "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", "dev": true }, - "node_modules/ignore-loader": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ignore-loader/-/ignore-loader-0.1.2.tgz", - "integrity": "sha512-yOJQEKrNwoYqrWLS4DcnzM7SEQhRKis5mB+LdKKh4cPmGYlLPR0ozRzHV5jmEk2IxptqJNQA5Cc0gw8Fj12bXA==", - "dev": true - }, "node_modules/ignored": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/ignored/-/ignored-2.0.4.tgz", @@ -13741,6 +13615,21 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/lint-staged/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/lint-staged/node_modules/execa": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", @@ -13785,6 +13674,19 @@ "node": ">=4" } }, + "node_modules/lint-staged/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "dev": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/lint-staged/node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -13842,6 +13744,28 @@ "node": ">=8" } }, + "node_modules/lint-staged/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lint-staged/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/lint-staged/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -14576,6 +14500,12 @@ "markdown-it": "bin/markdown-it.js" } }, + "node_modules/markdown-it/node_modules/entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true + }, "node_modules/matchdep": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", @@ -15150,9 +15080,9 @@ } }, "node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "dev": true, "engines": { "node": ">=8" @@ -15895,6 +15825,18 @@ "node": ">=4" } }, + "node_modules/npm-run-all/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/npm-run-all/node_modules/path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -16732,15 +16674,20 @@ } }, "node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dependencies": { + "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/parse-node-version": { @@ -17404,9 +17351,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", - "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.12.tgz", + "integrity": "sha512-NdxGCAZdRrwVI1sy59+Wzrh+pMMHxapGnpfenDVlMEXoOcvt4pGE0JLK9YY2F5dLxcFYA/YbVQKhcGU+FtSYQg==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -17923,9 +17870,9 @@ } }, "node_modules/reactium": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/reactium/-/reactium-3.0.11.tgz", - "integrity": "sha512-9UY3EXnI3AlbDZrRgz1yNcoGLQh46bW5Mah9JAdgl5HbL5siXpuEQeVfzPTlH68c2RMkcSE0PPbnv2xGk4O1eg==", + "version": "3.0.19", + "resolved": "https://registry.npmjs.org/reactium/-/reactium-3.0.19.tgz", + "integrity": "sha512-J7IWawBhDtUbp7wP9bMqNrghWZpZoLUzz+Cu4eNlfZCATlCHe5dG+xVOgkjkA5sRyCDG+8SuuS9ARcoViLv/jg==", "dev": true, "dependencies": { "@atomic-reactor/decompress": "^4.2.5", @@ -17998,9 +17945,9 @@ } }, "node_modules/reactium/node_modules/axios": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.6.tgz", - "integrity": "sha512-PEcdkk7JcdPiMDkvM4K6ZBRYq9keuVJsToxm2zQIM70Qqo2WHTdJZMXcG9X+RmRp2VPNUQC8W1RAGbgt6b1yMg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", "dev": true, "dependencies": { "follow-redirects": "^1.15.0", @@ -18310,24 +18257,6 @@ "node": ">=8" } }, - "node_modules/read-pkg/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/read-pkg/node_modules/type-fest": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", @@ -19404,9 +19333,9 @@ } }, "node_modules/sass": { - "version": "1.62.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.62.0.tgz", - "integrity": "sha512-Q4USplo4pLYgCi+XlipZCWUQz5pkg/ruSSgJ0WRDSb/+3z9tXUOkQ7QPYn4XrhZKYAK4HlpaQecRwKLJX6+DBg==", + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.62.1.tgz", + "integrity": "sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -19581,9 +19510,9 @@ "dev": true }, "node_modules/sass-embedded/node_modules/rxjs": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", - "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, "dependencies": { "tslib": "^2.1.0" @@ -20752,9 +20681,9 @@ } }, "node_modules/string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, "engines": { "node": ">=0.6.19" @@ -21079,22 +21008,6 @@ "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", "dev": true }, - "node_modules/stylelint/node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dev": true, - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/stylelint/node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -21198,24 +21111,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/stylelint/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/stylelint/node_modules/picocolors": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", @@ -21574,14 +21469,14 @@ } }, "node_modules/tar": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", - "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.14.tgz", + "integrity": "sha512-piERznXu0U7/pW7cdSn7hjqySIVTYT6F76icmFk7ptU7dDYlXTm5r9A6K04R2vU3olYgoKeo1Cg3eeu5nhftAw==", "dev": true, "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" @@ -23334,9 +23229,9 @@ } }, "node_modules/webpack": { - "version": "5.80.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.80.0.tgz", - "integrity": "sha512-OIMiq37XK1rWO8mH9ssfFKZsXg4n6klTEDL7S8/HqbAOBBaiy8ABvXvz0dDCXeEF9gqwxSvVk611zFPjS8hJxA==", + "version": "5.82.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.82.0.tgz", + "integrity": "sha512-iGNA2fHhnDcV1bONdUu554eZx+XeldsaeQ8T67H6KKHl2nUSwX8Zm7cmzOA46ox/X1ARxf7Bjv8wQ/HsB5fxBg==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", @@ -23844,9 +23739,9 @@ } }, "node_modules/yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "dependencies": { "cliui": "^8.0.1", @@ -23957,8 +23852,7 @@ "url": "https://github.com/sponsors/wooorm" } }, - "reactium_modules/@atomic-reactor/reactium-api/_npm": { - "name": "@atomic-reactor/reactium-api", + "reactium_modules/@atomic-reactor/reactium-api": { "version": "5.0.3", "license": "MIT", "dependencies": { @@ -23967,31 +23861,139 @@ "socket.io-client": "^4.6.1" } }, - "reactium_modules/@atomic-reactor/reactium-capability/_npm": { - "name": "@atomic-reactor/reactium-capability", + "reactium_modules/@atomic-reactor/reactium-capability": { "version": "5.0.1", "license": "MIT" }, - "reactium_modules/@atomic-reactor/reactium-role/_npm": { - "name": "@atomic-reactor/reactium-role", + "reactium_modules/@atomic-reactor/reactium-core": { + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "@atomic-reactor/dirname": "^1.0.2", + "@atomic-reactor/reactium-sdk-core": "^1.2.23", + "@babel/cli": "^7.21.0", + "@babel/node": "^7.20.7", + "@loadable/component": "^5.15.3", + "action-sequence": "^1.1.2", + "axios": "^0.26.0", + "axios-retry": "^3.2.4", + "body-parser": "^1.20.2", + "camelcase": "^7.0.1", + "chalk": "^4.1.2", + "classnames": "^2.3.2", + "cookie-parser": "^1.4.6", + "cookie-session": "^2.0.0", + "copy-to-clipboard": "^3.3.3", + "core-js": "^3.29.1", + "cors": "^2.8.5", + "cross-env": "^7.0.3", + "dayjs": "^1.11.7", + "directory-tree": "^2.2.7", + "express": "^4.17.3", + "express-static-gzip": "^2.1.7", + "fs-extra": "^10.0.0", + "globby": "^11.0.3", + "http-auth": "^3.2.4", + "http-proxy-middleware": "^0.20.0", + "jed": "^1.1.1", + "jsdom": "^16.5.2", + "memory-cache": "^0.2.0", + "moment": "^2.29.4", + "morgan": "^1.10.0", + "npm-run-all": "^4.1.5", + "object-path": "^0.11.8", + "prettier": "^1.19.1", + "prop-types": "^15.8.1", + "querystring-browser": "^1.0.4", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-helmet": "^6.1.0", + "react-router-dom": "~5.2.0", + "regenerator-runtime": "^0.13.11", + "run-script-os": "^1.1.6", + "semver": "^7.3.8", + "serialize-javascript": "^6.0.1", + "shallow-equals": "^1.0.0", + "spdy": "^4.0.2", + "underscore": "^1.13.6", + "uuid": "^3.4.0", + "xss": "^1.0.14" + }, + "devDependencies": { + "@atomic-reactor/gulp-run": "^1.8.0", + "@atomic-reactor/gulp-watch": "^5.0.2", + "@atomic-reactor/node-sass-reactium-importer": "^1.0.0", + "@atomic-reactor/webpack-po-loader": "5.0.1", + "@babel/core": "^7.21.3", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-export-default-from": "^7.18.10", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "ajv": "^8.12.0", + "apidoc": "^0.25.0", + "babel-core": "^7.0.0-bridge.0", + "babel-eslint": "^10.1.0", + "babel-jest": "^26.6.3", + "babel-loader": "^9.1.2", + "babel-plugin-module-resolver": "^4.1.0", + "browser-sync": "^2.28.3", + "cli-spinners": "^2.7.0", + "compression-webpack-plugin": "^10.0.0", + "decamelize": "^3.2.0", + "del": "^5.1.0", + "eslint": "^5.16.0", + "eslint-plugin-react": "^7.28.0", + "eslint-plugin-react-hooks": "^2.5.0", + "fast-diff": "^1.2.0", + "file-api": "^0.10.4", + "fs-readdir-recursive": "^1.1.0", + "gettext-extract": "^2.0.1", + "gulp": "^4.0.2", + "gulp-autoprefixer": "^8.0.0", + "gulp-clean-css": "^4.3.0", + "gulp-concat": "^2.6.1", + "gulp-gzip": "^1.4.2", + "gulp-if": "^3.0.0", + "gulp-rename": "^2.0.0", + "gulp-sass": "^5.1.0", + "gulp-sourcemaps": "^3.0.0", + "gulp4-run-sequence": "^1.0.1", + "handlebars": "^4.7.7", + "husky": "^3.1.0", + "lint-staged": "^9.4.3", + "module-alias": "^2.2.2", + "node-polyfill-webpack-plugin": "^2.0.1", + "nodemon": "^2.0.21", + "open": "^8.4.2", + "ora": "^5.4.1", + "reactium": "^3.0.10", + "readdir-recursive": "0.0.4", + "sass": "^1.59.3", + "sass-embedded": "^1.62.0", + "slugify": "^1.6.5", + "stylelint": "^13.12.0", + "webpack": "^5.76.2", + "webpack-dev-middleware": "^5.3.3", + "webpack-hot-middleware": "^2.25.3" + } + }, + "reactium_modules/@atomic-reactor/reactium-role": { "version": "5.0.1", "license": "MIT" }, - "reactium_modules/@atomic-reactor/reactium-setting/_npm": { - "name": "@atomic-reactor/reactium-setting", + "reactium_modules/@atomic-reactor/reactium-setting": { "version": "5.0.1", "license": "MIT" }, - "reactium_modules/@atomic-reactor/reactium-svg/_npm": { - "name": "@atomic-reactor/reactium-svg", + "reactium_modules/@atomic-reactor/reactium-svg": { "version": "0.0.3", "license": "MIT", "dependencies": { "@svgr/webpack": "6.3.1" } }, - "reactium_modules/@atomic-reactor/reactium-user/_npm": { - "name": "@atomic-reactor/reactium-user", + "reactium_modules/@atomic-reactor/reactium-user": { "version": "5.0.1", "license": "MIT" } diff --git a/package.json b/package.json index de9879ce..8b7475f0 100644 --- a/package.json +++ b/package.json @@ -4,15 +4,12 @@ "description": "A framework for creating React + Redux apps using the domain driven design (DDD) paradigm.", "main": "index.js", "scripts": { - "start": "node .core/index.mjs", + "start": "node src/index.mjs", "build": "cross-env NODE_ENV=production gulp", "heroku-prebuild": "npx reactium install", "static": "npm-run-all build:* && gulp static", "local": "gulp local", "clean": "gulp clean", - "docker": "npm-run-all -s clean docker:*", - "docker:build": "cross-env docker image build -t $npm_package_name:$npm_package_version -t $npm_package_name:latest .", - "docker:push": "cross-env docker push $npm_package_name:$npm_package_version && cross-env docker push $npm_package_name:$npm_package_version:latest", "precommit": "lint-staged" }, "keywords": [ @@ -36,114 +33,7 @@ "parse/node": false }, "dependencies": { - "@atomic-reactor/dirname": "^1.0.2", - "@atomic-reactor/reactium-sdk-core": "^1.2.23", - "@babel/cli": "^7.21.0", - "@babel/node": "^7.20.7", - "@loadable/component": "^5.15.3", - "action-sequence": "^1.1.2", - "axios": "^0.26.0", - "axios-retry": "^3.2.4", - "body-parser": "^1.20.2", - "camelcase": "^7.0.1", - "chalk": "^4.1.2", - "classnames": "^2.3.2", - "cookie-parser": "^1.4.6", - "cookie-session": "^2.0.0", - "copy-to-clipboard": "^3.3.3", - "core-js": "^3.29.1", - "cors": "^2.8.5", - "cross-env": "^7.0.3", - "dayjs": "^1.11.7", - "directory-tree": "^2.2.7", - "express": "^4.17.3", - "express-static-gzip": "^2.1.7", - "fs-extra": "^10.0.0", - "globby": "^11.0.3", - "http-auth": "^3.2.4", - "http-proxy-middleware": "^0.20.0", - "jed": "^1.1.1", - "jsdom": "^16.5.2", - "memory-cache": "^0.2.0", - "moment": "^2.29.4", - "morgan": "^1.10.0", - "npm-run-all": "^4.1.5", - "object-path": "^0.11.8", - "prettier": "^1.19.1", - "prop-types": "^15.8.1", - "querystring-browser": "^1.0.4", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-helmet": "^6.1.0", - "react-router-dom": "~5.2.0", - "regenerator-runtime": "^0.13.11", - "run-script-os": "^1.1.6", - "semver": "^7.3.8", - "serialize-javascript": "^6.0.1", - "shallow-equals": "^1.0.0", - "spdy": "^4.0.2", - "underscore": "^1.13.6", - "uuid": "^3.4.0", - "xss": "^1.0.14" - }, - "devDependencies": { - "@atomic-reactor/gulp-run": "^1.8.0", - "@atomic-reactor/gulp-watch": "^5.0.2", - "@atomic-reactor/node-sass-reactium-importer": "^1.0.0", - "@atomic-reactor/webpack-po-loader": "5.0.1", - "@babel/core": "^7.21.3", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-export-default-from": "^7.18.10", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/preset-env": "^7.20.2", - "@babel/preset-react": "^7.18.6", - "ajv": "^8.12.0", - "apidoc": "^0.25.0", - "babel-core": "^7.0.0-bridge.0", - "babel-eslint": "^10.1.0", - "babel-jest": "^26.6.3", - "babel-loader": "^9.1.2", - "babel-plugin-module-resolver": "^4.1.0", - "browser-sync": "^2.28.3", - "cli-spinners": "^2.7.0", - "compression-webpack-plugin": "^10.0.0", - "decamelize": "^3.2.0", - "del": "^5.1.0", - "eslint": "^5.16.0", - "eslint-plugin-react": "^7.28.0", - "eslint-plugin-react-hooks": "^2.5.0", - "fast-diff": "^1.2.0", - "file-api": "^0.10.4", - "fs-readdir-recursive": "^1.1.0", - "gettext-extract": "^2.0.1", - "gulp": "^4.0.2", - "gulp-autoprefixer": "^8.0.0", - "gulp-clean-css": "^4.3.0", - "gulp-concat": "^2.6.1", - "gulp-gzip": "^1.4.2", - "gulp-if": "^3.0.0", - "gulp-rename": "^2.0.0", - "gulp-sass": "^5.1.0", - "gulp-sourcemaps": "^3.0.0", - "gulp4-run-sequence": "^1.0.1", - "handlebars": "^4.7.7", - "husky": "^3.1.0", - "ignore-loader": "^0.1.2", - "lint-staged": "^9.4.3", - "module-alias": "^2.2.2", - "node-polyfill-webpack-plugin": "^2.0.1", - "nodemon": "^2.0.21", - "open": "^8.4.2", - "ora": "^5.4.1", - "reactium": "^3.0.10", - "readdir-recursive": "0.0.4", - "sass": "^1.59.3", - "sass-embedded": "^1.62.0", - "slugify": "^1.6.5", - "stylelint": "^13.12.0", - "webpack": "^5.76.2", - "webpack-dev-middleware": "^5.3.3", - "webpack-hot-middleware": "^2.25.3" + "react": "^18.2.0" }, "nodemonConfig": { "quite": true, @@ -167,9 +57,11 @@ "@atomic-reactor/reactium-role": "5.0.1", "@atomic-reactor/reactium-user": "5.0.1", "@atomic-reactor/reactium-setting": "5.0.1", - "@atomic-reactor/reactium-svg": "0.0.3" + "@atomic-reactor/reactium-svg": "0.0.3", + "@atomic-reactor/reactium-core": "5.0.1" }, "workspaces": [ - "reactium_modules/**/_npm" + "reactium_modules/*", + "reactium_modules/@*/*" ] -} +} \ No newline at end of file diff --git a/src/app/main.js b/src/app/main.js index 56ce957f..fa0e5e60 100644 --- a/src/app/main.js +++ b/src/app/main.js @@ -1,20 +1,29 @@ // Uncomment this if you need corejs polyfills or runtime // import 'core-js/stable'; // import 'regenerator-runtime/runtime'; - -import { Shell } from 'reactium-core/app/shell'; - -__webpack_public_path__ = window.resourceBaseUrl || '/assets/js/'; +import { Shell } from '@atomic-reactor/reactium-core/app/shell'; (async () => { try { await Shell(); } catch (error) { - const { AppError } = await import('reactium-core/app'); + const { AppError } = await import('@atomic-reactor/reactium-core/app'); await AppError(error); } + /** + * @description Initialize the app. + */ if (module.hot) { - module.hot.accept(['../../.core/app/shell.js'], window.location.reload); + module.hot.accept( + [ + '../../reactium_modules/@atomic-reactor/reactium-core/dependencies/index.js', + '../../reactium_modules/@atomic-reactor/reactium-core/app.js', + '../../reactium_modules/@atomic-reactor/reactium-core/sdk/index.js', + ], + () => { + window.location.reload(); + }, + ); } })();