diff --git a/demo/nodefony/.eslintignore b/demo/nodefony/.eslintignore new file mode 100644 index 0000000..c8d9abb --- /dev/null +++ b/demo/nodefony/.eslintignore @@ -0,0 +1,15 @@ +assets +**/assets/** +app/Resources/public/assets/ +app/Resources/views/base.html.twig +config/generatedConfig.yml +app/Resources/databases/* +web/* + +node_modules +**/node_modules/** + +**/workbox-* +**/hot/* +**/service-worker.js + diff --git a/demo/nodefony/.eslintrc.js b/demo/nodefony/.eslintrc.js new file mode 100644 index 0000000..1048e39 --- /dev/null +++ b/demo/nodefony/.eslintrc.js @@ -0,0 +1,97 @@ +module.exports = { + root: true, + env: { + browser: true, + node: true, + commonjs: true, + es2021: true + }, + // Extends: ["standard"], + extends: [ + "plugin:vue/vue3-essential", + // 'eslint:recommended', + "eslint:all" + // 'standard' + ], + plugins: ["prettier"], + overrides: [], + parserOptions: { + ecmaVersion: "latest", + sourceType: "module" + }, + globals: { + nodefony: true, + kernel: true, + process: true, + require: true, + console: true, + module: true, + exports: true, + yaml: true, + util: true, + fs: true, + path: true, + cluster: true, + xmlParser: true, + async: true, + crypto: true, + Sequelize: true, + url: true, + http: true, + https: true, + pm2: true, + WebSocketServer: true, + nodedomain: true, + dns: true, + Promise: true, + zone: true, + it: true, + describe: true, + before: true, + beforeEach: true, + BlueBird: true, + twig: true, + shell: true, + clc: true, + notDefinded: true, + varNotExit: true, + window: true, + document: true, + navigator: true, + stage: true, + $: true, + jQuery: true, + Rx: true, + inquirer: true, + workbox: true + }, + rules: { + "no-console": process.env.NODE_ENV === "production" + ? "warn" + : "off", + "no-debugger": process.env.NODE_ENV === "production" + ? "warn" + : "off", + "quotes": ["error", "double"], + "max-len": ["error", {"code": 150}], + "padded-blocks": ["error", "never"], + "id-length": ["error", {min: 1}], + "indent": ["error", 2], + "function-call-argument-newline": ["error", "consistent"], + "array-bracket-newline": ["error", "consistent"], + "quote-props": [0], + "no-return-await": [0], + "sort-keys": [0], + "array-element-newline": [0], + "dot-location": [0], + "multiline-comment-style": [0], + "capitalized-comments": [0], + "max-lines-per-function": ["warn", 100], + "no-await-in-loop": [0], + "max-statements": ["warn", 20], + "no-magic-numbers": [0], + "sort-vars": ["off"], + "no-ternary": ["off"], + "multiline-ternary": ["error", "always-multiline"] + } +}; diff --git a/demo/nodefony/.gitignore b/demo/nodefony/.gitignore index ecccecf..69f2bde 100644 --- a/demo/nodefony/.gitignore +++ b/demo/nodefony/.gitignore @@ -11,6 +11,7 @@ app/Resources/databases/* node_modules/** **/node_modules/** npm-debug.log +pnpm-lock.yaml *.[oa] config/certificates/**/* diff --git a/demo/nodefony/.jshintignore b/demo/nodefony/.jshintignore deleted file mode 100644 index 3c3629e..0000000 --- a/demo/nodefony/.jshintignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/demo/nodefony/.jshintrc b/demo/nodefony/.jshintrc deleted file mode 100644 index 75d86aa..0000000 --- a/demo/nodefony/.jshintrc +++ /dev/null @@ -1,60 +0,0 @@ -{ - "esversion": 8, - "node": true, - "undef": true, - "unused": true, - "boss": true, - "eqeqeq": true, - "curly": true, - "loopfunc": true, - "multistr": true, - "browser": true, - "node": true, - "shelljs": true, - "globals": { - "nodefony": true, - "kernel": true, - "process": true, - "require": true, - "console": true, - "module": true, - "exports": true, - "kernel": true, - "yaml": true, - "util": true, - "fs": true, - "path": true, - "cluster": true, - "xmlParser": true, - "async": true, - "crypto": true, - "Sequelize": true, - "url": true, - "http": true, - "https": true, - "pm2": true, - "WebSocketServer": true, - "nodedomain": true, - "dns": true, - "Promise": true, - "zone": true, - "it": true, - "describe": true, - "before": true, - "beforeEach": true, - "BlueBird": true, - "twig": true, - "shell": true, - "clc": true, - "notDefinded": true, - "varNotExit": true, - "window": true, - "document": true, - "navigator": true, - "stage": true, - "$": true, - "jQuery": true, - "Rx": true, - "inquirer": true - } -} diff --git a/demo/nodefony/README.md b/demo/nodefony/README.md index 1871ae1..69ddb6a 100644 --- a/demo/nodefony/README.md +++ b/demo/nodefony/README.md @@ -1,19 +1,16 @@


-

NODEFONY V6

+

NODEFONY V7

[![npm package](https://nodei.co/npm/nodefony.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/nodefony) [![Issues Status](https://img.shields.io/github/issues/nodefony/nodefony.svg)](https://github.com/nodefony/nodefony/issues) [![Build Status](https://github.com/nodefony/nodefony/workflows/nodefony/badge.svg)](https://github.com/nodefony/nodefony/actions) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/495/badge)](https://bestpractices.coreinfrastructure.org/projects/495) -Nodefony is Node.js full-stack web framework. +Nodefony is Node.js full-stack web framework. Nodefony can be used to develop a complete solution to create a Fullstack Web Application, Secure Api, or Microservices. -The Nodefony project is inspired by the PHP Symfony framework, a developer can find most of the concepts, configurations and patterns of Symfony framework. - -Nodefony is not an exhaustive port of symfony ! ## Table of content @@ -67,7 +64,7 @@ Nodefony is not an exhaustive port of symfony ! - [Passport](http://passportjs.org/) Simple, unobtrusive authentication for Node.js . - ~~[Angular](https://github.com/angular/angular-cli) Experimental Bundle Generator ( Angular cli no longer allows the ejection of a webpack config)~~ -**Nodefony 6 adds the following features** : +**Nodefony 7 adds the following features** : - [React](https://github.com/facebookincubator/create-react-app) Experimental Bundle Generator ( Now an React Project can be merge into a Nodefony Bundle ) - [Vue.js](https://vuejs.org) Experimental Bundle Generator ( Now an Vue.js Project can be merge into a Nodefony Bundle ) @@ -77,10 +74,12 @@ Nodefony is not an exhaustive port of symfony ! Evolution priorities for the next version will focus on robustness, unit testing, documentation and security. +You can follow Nodefony build with github actions at **** -#### Nodefony is ported with ECMAScript 6 ( Class, Inheritance ). +## Nodefony implement modules with CommonJS and ECMAScript 6 ( Class, Inheritance ). +The development framework will not be ported to typescript, but will wait for the version with type syntax in Emacsript -You can follow Nodefony build with github actions at **** +**[proposal-type-annotations](https://github.com/tc39/proposal-type-annotations)** ## **Resources for Newcomers** @@ -100,7 +99,7 @@ You can follow Nodefony build with github actions at **= 8 ) -- **[npm](https://www.npmjs.com/)** or **[yarn](https://yarnpkg.com/lang/en/)** Packages Manager for javascript application +- **[npm](https://www.npmjs.com/)** or **[yarn](https://yarnpkg.com/lang/en/)** or **[pnpm](https://pnpm.io/cli/install)** Packages Manager for javascript application - **[nvm](https://github.com/nvm-sh/nvm/)** Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions @@ -128,21 +127,21 @@ You can follow Nodefony build with github actions at ** Linux or OSX Installation (Recommanded) +## Linux or OSX Installation **[NVM](https://github.com/nvm-sh/nvm#installation-and-update) Installation (Node Version Manager )** : - [NVM](https://github.com/creationix/nvm) Node Version Manager - Simple bash script to manage multiple active node.js versions To install or update nvm, you can use the install script: ```sh -curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash # or -wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash +wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash $ source ~/.bashrc # or source ~/.bash_profile -$ nvm ls-remote # show all remote versions +$ nvm ls-remote # show all remote versions $ nvm ls # show local versions ``` @@ -198,7 +197,7 @@ C:\Users\myuser\AppData\Roaming\npm\bin **Cli command when use Global installation** ```bash $ nodefony -v -6.0.0 +7.0.0 ``` **Cli command when By using yarn or npm in trunk** @@ -212,7 +211,8 @@ npm run nodefony **By using npx** ***note: npx is included with npm > v5.2 or can be installed separately.*** ```bash -npx nodefony +npx nodefony -v +7.0.0-beta.10 ``` **The long way with the full path** @@ -245,17 +245,17 @@ YOU CAN USE CLI NO INTERACTIVE (nodefony with args) : ```bash # CLI generate project name : myproject -$ nodefony create myproject +$ npx nodefony create myproject $ cd myproject ``` **Cli Help** : ```bash -$ nodefony -h +$ npx nodefony -h -nodefony - create [-i] name [path] Create New Nodefony Project +nodefony + create [-i] name [path] Create New Nodefony Project ``` ## Build Project with Github Starter : @@ -264,9 +264,9 @@ nodefony Clone nodefony starter ```bash - $ git clone https://github.com/nodefony/nodefony.git + $ git clone https://github.com/nodefony/nodefony-starter.git $ cd nodefony - $ nodefony build + $ npx nodefony build ... ... $ npm start @@ -275,7 +275,7 @@ nodefony YOU CAN USE CLI INTERACTIVE MODE TO BUILD PROJECT (nodefony without args) ```bash - $ git clone https://github.com/nodefony/nodefony.git + $ git clone https://github.com/nodefony/nodefony-starter.git $ cd nodefony $ ls -l -rw-r--r-- 1 cci staff 21306 27 mar 19:22 README.md @@ -290,7 +290,7 @@ nodefony drwxr-xr-x 12 cci staff 384 29 mar 11:01 web -rw-r--r-- 1 cci staff 542660 27 mar 19:24 yarn.lock - $ nodefony + $ npx nodefony ? Nodefony CLI : (Use arrow keys) ❯ Build Project @@ -307,7 +307,7 @@ nodefony **Starting Development Servers** : ```bash -$ nodefony dev +$ npx nodefony dev # TO STOP $ @@ -315,7 +315,7 @@ $ **Starting Development Servers in Debug Mode (-d)** : ```bash -$ nodefony -d dev +$ npx nodefony -d dev # TO STOP $ @@ -326,14 +326,14 @@ OR YOU CAN USE CLI INTERACTIVE MODE (nodefony without args) _ _ ___ ____ _____ _____ ___ _ _ __ __ | \ | | / _ \ | _ \ | ____| | ___| / _ \ | \ | | \ \ / / | \| | | | | | | | | | | _| | |_ | | | | | \| | \ V / -| |\ | | |_| | | |_| | | |___ | _| | |_| | | |\ | | | -|_| \_| \___/ |____/ |_____| |_| \___/ |_| \_| |_| +| |\ | | |_| | | |_| | | |___ | _| | |_| | | |\ | | | +|_| \_| \___/ |____/ |_____| |_| \___/ |_| \_| |_| Version : 4.0.0 Platform : linux Process : nodefony PID : 31635 Fri Jul 27 2018 17:01:11 INFO nodefony : WELCOME PROJECT : myproject 1.0.0 -? Nodefony CLI : +? Nodefony CLI : ❯ Start Servers Development Start Servers Pre-Production Start Servers Production @@ -355,6 +355,8 @@ Fri Jul 27 2018 17:01:11 INFO nodefony : WELCOME PROJECT : myproject 1.0.0 $ npm -g install npx $ npx --node-arg=--inspect nodefony dev +// new version npx > 7 +$ npx --node-options=--inspect nodefony dev # check chrome://inspect in your browser ``` @@ -363,23 +365,23 @@ $ npx --node-arg=--inspect nodefony dev **Starting a Nodefony project with [PM2](http://pm2.keymetrics.io/)** : ```bash -$ nodefony prod +$ npx nodefony prod or -$ nodefony start +$ npx nodefony start ``` Tools PM2 You can see PM2 config : config/pm2.config.js ```bash # To See log -$ nodefony logs +$ npx nodefony logs # To List Status of Production projects -$ nodefony list +$ npx nodefony list # TO KILL PM2 DEAMON -$ nodefony kill +$ npx nodefony kill # TO STOP APPLICATION WITHOUT KILL PM2 DEAMON -$ nodefony stop +$ npx nodefony stop # YOU can use all pm2 command by using $ yarn pm2 monit @@ -391,7 +393,7 @@ $ npm run pm2 logs --lines 200 **Checking a Nodefony Project Pre-Production (Usefull to check Clusters Node)** : ```bash -$ nodefony preprod +$ npx nodefony preprod ``` ## Serving a Nodefony project with HTTPS or WSS @@ -417,7 +419,7 @@ You can find certificate authority (ca) here: #### Access to Secure App with URL : #### Access to App with URL : -[![nodefony](https://raw.githubusercontent.com/nodefony/nodefony/master/src/nodefony/bundles/documentation-bundle/Resources/public/images/nodefony.png)](https://nodefony.net) +[![nodefony](https://raw.githubusercontent.com/nodefony/nodefony/master/src/nodefony/bundles/monitoring-bundle/Resources/public/images/nodefony.png)](https://nodefony.net) ## Framework Configurations @@ -592,7 +594,7 @@ class defaultController extends nodefony.Controller { indexAction() { return this.render("hello-bundle::index.html.twig", { name: this.bundle.name, - description: this.bundle.package.description + description: this.bundle.package.description }); } } @@ -714,7 +716,7 @@ module.exports = webpackMerge(config, { Access to monitoring route with URL : -[![MONITORING](https://raw.githubusercontent.com/nodefony/nodefony/master/src/nodefony/doc/cluster.png)](https://nodefony.net/nodefony) +[![MONITORING](https://raw.githubusercontent.com/nodefony/nodefony/master/src/nodefony/bundles/monitoring-bundle/Resources/public/images/monitor.png)](https://nodefony.net/nodefony) Monitoring in progress !!! diff --git a/demo/nodefony/app/Resources/scss/app.scss b/demo/nodefony/app/Resources/scss/app.scss new file mode 100644 index 0000000..9c7e844 --- /dev/null +++ b/demo/nodefony/app/Resources/scss/app.scss @@ -0,0 +1,60 @@ +@import url(https://fonts.googleapis.com/css?family=Comfortaa); +@import url(https://fonts.googleapis.com/css?family=Gochi+Hand); + +.hello { + text-align: center; +} + +.hello h1 { + font-family: 'Gochi Hand', cursive; + color: #0167b8; + letter-spacing: 0; + font-size: 4em; + text-transform: none; +} + +.nodefony{ + font-family: 'Comfortaa', cursive; +} + +.nodefony h1 { + text-align: center; + font-family: 'Gochi Hand', cursive; + color: #0167b8; + letter-spacing: 0; + font-size: 4em; + text-transform: none; +} + +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.42857143; + color: #333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; +} + +.nodefony-signin { + width: 100%; + max-width: 330px; + padding: 15px; + margin: 0 auto; +} + +.mt-6{ + margin-top: ($spacer * 4) !important;; +} + +.mt-7{ + margin-top: ($spacer * 4.5) !important;; +} + +.mt-8{ + margin-top: ($spacer * 5) !important;; +} diff --git a/demo/nodefony/app/Resources/scss/awesome/font-awesome.config.js b/demo/nodefony/app/Resources/scss/awesome/font-awesome.config.js new file mode 100644 index 0000000..8d7fe8e --- /dev/null +++ b/demo/nodefony/app/Resources/scss/awesome/font-awesome.config.js @@ -0,0 +1,11 @@ + module.exports = { + styles: { + "mixins": true, + + "core": true, + "icons": true, + + "larger": true, + "path": true, + } + }; \ No newline at end of file diff --git a/demo/nodefony/app/Resources/scss/custom.scss b/demo/nodefony/app/Resources/scss/custom.scss new file mode 100644 index 0000000..3c58a9f --- /dev/null +++ b/demo/nodefony/app/Resources/scss/custom.scss @@ -0,0 +1,21 @@ +@import "~bootstrap/scss/bootstrap"; + +$fa-font-path: "~font-awesome/fonts"; +@import '~font-awesome/scss/font-awesome.scss'; +//@import './awesome/font-awesome.config.js'; + +@import "./app.scss"; + +// Custom.scss +// Option B: Include parts of Bootstrap +// Required +/*@import "node_modules/bootstrap/scss/functions"; +@import "node_modules/bootstrap/scss/variables"; +@import "node_modules/bootstrap/scss/mixins"; + +// Optional +@import "node_modules/bootstrap/scss/reboot"; +@import "node_modules/bootstrap/scss/type"; +@import "node_modules/bootstrap/scss/images"; +@import "node_modules/bootstrap/scss/code"; +@import "node_modules/bootstrap/scss/grid";*/ diff --git a/demo/nodefony/app/Resources/views/framework-bundle/views/index.html.twig b/demo/nodefony/app/Resources/views/framework-bundle/views/index.html.twig index 37a86fe..b629a9e 100644 --- a/demo/nodefony/app/Resources/views/framework-bundle/views/index.html.twig +++ b/demo/nodefony/app/Resources/views/framework-bundle/views/index.html.twig @@ -1,6 +1,6 @@ {% extends "./base.html.twig" %} {% block body %} -
+
{% block content %}{% endblock %}
{% endblock %} diff --git a/demo/nodefony/app/Resources/views/framework-bundle/views/layout.html.twig b/demo/nodefony/app/Resources/views/framework-bundle/views/layout.html.twig index 4572339..bcd9c68 100644 --- a/demo/nodefony/app/Resources/views/framework-bundle/views/layout.html.twig +++ b/demo/nodefony/app/Resources/views/framework-bundle/views/layout.html.twig @@ -6,118 +6,120 @@ {% block content %} {{ parent() }} -
-
-
-
- -

{{ error.code }} - {{ error.message }}

-
-
-
-
-
-
-
- -
+

{{ error.code }} - {{ error.message }}

-
-
-
    -
  • - URL - -
  • -
  • - code - -
  • -
  • - Error Type -
    {{ error.type }}
    -
  • - {% if error.type == "SystemError" %} +
+
+
+
+
+
+ +
+
+
+
+
  • - Ernno -
    {{ error.ernno }}
    + URL +
  • - Syscall -
    {{ error.syscall }}
    + code + +
  • +
  • + Error Type +
    {{ error.type }}
  • - {% if error.address %} + {% if error.type == "SystemError" %}
  • - Address -
    {{ error.address }}
    + Ernno +
    {{ error.ernno }}
  • - {% endif %} - {% if error.port %}
  • - Port -
    {{ error.port }}
    + Syscall +
    {{ error.syscall }}
  • - {% endif %} - {% else %} - {% if error.type == "securityError" %} + {% if error.address %} +
  • + Address +
    {{ error.address }}
    +
  • + {% endif %} + {% if error.port %} +
  • + Port +
    {{ error.port }}
    +
  • + {% endif %} + {% else %} + {% if error.type == "securityError" %} +
  • + Secured Area +
    {{ error.securedArea }}
    +
  • + {% endif %} + {% if error.bundle %} +
  • + Bundle +
    {{ error.bundle }}
    +
  • + {% endif %} + {% if error.controller %}
  • - Secured Area -
    {{ error.securedArea }}
    + Controller +
    {{ error.controller }}
  • - {% endif %} - {% if error.bundle %} + {% endif %} + {% if error.action %}
  • - Bundle -
    {{ error.bundle }}
    + Action +
    {{ error.action }}
  • + {% endif %} {% endif %} - {% if error.controller %} -
  • - Controller -
    {{ error.controller }}
    -
  • - {% endif %} - {% if error.action %} + {% if error.pdu %}
  • - Action -
    {{ error.action }}
    + PDU (Protocol Data Unit syslog json) +
    {{ error.pdu }}
  • {% endif %} - {% endif %} - {% if error.pdu %} -
  • - PDU (Protocol Data Unit syslog json) -
    {{ error.pdu }}
    -
  • - {% endif %} -
+ +
-
-
-
-
- -
-
-
-
-
{{ error.stack }}
+
+
+
+ +
+
+
+
+
{{ error.stack }}
+
-
+
{% endblock %} diff --git a/demo/nodefony/app/appKernel.js b/demo/nodefony/app/appKernel.js index 7d4fa5b..4d5aaa5 100644 --- a/demo/nodefony/app/appKernel.js +++ b/demo/nodefony/app/appKernel.js @@ -1,15 +1,126 @@ -/* +/** * ENTRY POINT FRAMEWORK APP KERNEL */ "use strict;"; +const blue = clc.blueBright.bold; +const green = clc.green; +const yellow = clc.yellow.bold; +const magenta = clc.magenta.bold; +const reset = clc.reset; // '\x1b[0m'; + module.exports = class appKernel extends nodefony.kernel { constructor(environment, cli, settings) { // kernel constructor - try { - super(environment, cli, settings); + super(environment, cli, settings); + this.appEnvironment = this.getAppEnvironment() + if (this.appEnvironment.environment === 'development') { + this.once("onPreRegister", () => { + /*if (this.type === "SERVER") { + return this.showBanner() + }*/ + }) + } + } + + showBanner() { + let banner = `App Environment` + for (let ele in this.appEnvironment) { + let module = this.appEnvironment[ele] + switch (ele) { + case "environment": + banner = ` ${magenta(" Environement")} : ${green(module)}`; + console.log(banner) + this.cli.blankLine(); + break; + case "vault": + banner = `Module : ${green(ele)} Vault : ${blue(module.active)}`; + this.log(banner); + break + default: + banner = `Module : ${green(ele)} `; + if (module.vault) { + banner += `Vault : ${blue(module.vault.active)}` + } + this.log(banner); + } + } + this.cli.blankLine(); + } + + getAppEnvironment() { + const environment = this.getVariableEnvironment() + return { + environment: environment, + database: this.getDatabaseEnvironment(environment), + vault: this.getVaultEnvironment(environment) + } + } + + getVariableEnvironment() { + if (process.env.NODEFONY_ENV_APP) { + return process.env.NODEFONY_ENV_APP + } + const production = process.env.NODE_ENV === "production" + const development = process.env.NODE_ENV === "development" + if (production) { + return 'production' + } + if (development) { + return 'development' + } + return 'development' + } + + /* VAULT BUNDLE */ + getVaultEnvironment(environment) { + switch (environment) { + case 'production': + return { + active: true, + prepareAuth: false, + getVaultCredentialsApprole: this.getVaultCredentialsApprole(environment) + } + case 'development': + default: + return { + active: true, + prepareAuth: true, + getVaultCredentialsApprole: this.getVaultCredentialsApprole(environment) + } + } + } + getDatabaseEnvironment(environment) { + switch (environment) { + case 'production': + return { + vault: { + active: true, + path: "nodefony/data/postgresql/connector/nodefony" + }, + } + case 'development': + default: + return { + vault: { + active: false, + path: "nodefony/data/sqlite/connector/nodefony" + }, + } + } + } - } catch (e) { - throw e; + getVaultCredentialsApprole(environment) { + switch (environment) { + case 'production': + return async () => { + return { + role_id: "", + secret_id: "" + } + } + case 'development': + default: + return null } } }; diff --git a/demo/nodefony/app/config/config.js b/demo/nodefony/app/config/config.js index fdb9102..615b914 100644 --- a/demo/nodefony/app/config/config.js +++ b/demo/nodefony/app/config/config.js @@ -10,7 +10,7 @@ module.exports = { locale: "en_en", type : "sandbox", App: { - projectYear: 2020, + projectYear: 2023, locale: "en_en", authorName: "admin", authorMail: "admin@nodefony.com", @@ -37,12 +37,12 @@ module.exports = { * } * */ - watch: true, + watch: false, /** * DEV SERVER */ devServer: { - hot: true + hot: false }, /* diff --git a/demo/nodefony/app/config/nodefony/framework-bundle.js b/demo/nodefony/app/config/nodefony/framework-bundle.js index 86a23b3..b84e7da 100644 --- a/demo/nodefony/app/config/nodefony/framework-bundle.js +++ b/demo/nodefony/app/config/nodefony/framework-bundle.js @@ -10,8 +10,13 @@ module.exports = { outputFileSystem: "file-system", // memory-fs not implemented yet stats: { colors: true, - verbose: true, - maxModules: 16 // Infinity + preset: 'normal' // normal || minimal || verbose || detailed || summary + }, + watchOptions: { + ignored: /node_modules|assets/, + aggregateTimeout: 1000, + poll: false, + followSymlinks: true } } -}; \ No newline at end of file +}; diff --git a/demo/nodefony/app/config/nodefony/http-bundle.js b/demo/nodefony/app/config/nodefony/http-bundle.js index 9b7e7f8..6559ac6 100644 --- a/demo/nodefony/app/config/nodefony/http-bundle.js +++ b/demo/nodefony/app/config/nodefony/http-bundle.js @@ -16,13 +16,15 @@ * sockjs dev server ( webpack dev server like WDS) * */ +const tmpDir = kernel.tmpDir.path || "/tmp" module.exports = { // For more options request parser formidable @see : https://github.com/felixge/node-formidable request: { - uploadDir: "/tmp", // temporing file upload system - maxFileSize: 2097152, // In Bytes - maxFieldsSize: 2097152, // 2MB + uploadDir: tmpDir, // temporing file upload system + maxFileSize: 524288000, // In Bytes 500 MB + maxFieldsSize: 2097152, // 2 MB maxFields: 1000, // 0 for unlimited + encoding: 'utf-8' }, //For more options queryString parser QS @see : https://github.com/ljharb/qs queryString: { @@ -72,6 +74,7 @@ module.exports = { port: kernel.settings.system.httpsPort }, session: { + applyTransaction: true, // sequelize transaction session entity (no effective for sqlite) start: false, // false || true || Session Context Name (waf) name: "nodefony", handler: "orm", // files | orm | memcached diff --git a/demo/nodefony/app/config/nodefony/mongoose-bundle.js b/demo/nodefony/app/config/nodefony/mongoose-bundle.js index e4ebdb9..555eb81 100644 --- a/demo/nodefony/app/config/nodefony/mongoose-bundle.js +++ b/demo/nodefony/app/config/nodefony/mongoose-bundle.js @@ -3,26 +3,50 @@ * * @see MONGO BUNDLE config for more options * @more options https://mongoosejs.com/docs/connections.html + * https://mongoosejs.com/docs/api.html#mongoose_Mongoose-createConnection * * By default nodefony create connector name nodefony * for manage Sessions / Users */ -module.exports = { - debug: false, - connectors: { - nodefony: { + +let connectors = {} +const vault = async () => { + const serviceVault = kernel.get("vault"); + return await serviceVault.getSecret({ + path: "nodefony/data/database/mongo/connector/nodefony" + }) + .then((secret) => { + return secret.data.data + }) + .catch(e => { + throw e + }) +} + +switch (kernel.appEnvironment.environment) { + case "production": + case "development": + default: + connectors.nodefony = { host: "localhost", port: 27017, dbname: "nodefony", + //credentials: vault, settings: { - user: "", - pass: "", - authSource: "admin", - reconnectTries: 100, - reconnectInterval: 5000, - autoReconnect: true, - poolSize: 5 + user: "nodefony", + pass: "nodefony", + maxPoolSize: 50, + useNewUrlParser: true, + serverSelectionTimeoutMS: 5000, + socketTimeoutMS: 5000, + connectTimeoutMS: 5000 } } +} + +module.exports = { + mongoose: { + debug: true, + connectors: connectors } -}; \ No newline at end of file +}; diff --git a/demo/nodefony/app/config/nodefony/monitoring-bundle.js b/demo/nodefony/app/config/nodefony/monitoring-bundle.js index 50d3303..9ae42c0 100644 --- a/demo/nodefony/app/config/nodefony/monitoring-bundle.js +++ b/demo/nodefony/app/config/nodefony/monitoring-bundle.js @@ -4,12 +4,31 @@ * see MONITORING BUNDLE config for more options * */ - module.exports = { debugBar: true, forceDebugBarProd: false, profiler: { active: false, storage: "orm" - } + }, + // entry point swagger Multi URL + swagger:{ + projectName: "NODEFONY", + logo: "/app/images/app-logo.png", + urls: [{ + url: "/api/users/documentation", + name: "users" + }, { + url: "/api/jwt/documentation", + name: "login" + }], + primaryName: "users" + }, + + // entry point graphigl monitoring only 1 URL (use merge in graphgl controller ) + graphigl:{ + projectName: "Nodefony Graphql Api", + logo: "/app/images/app-logo.png", + url:"/api/graphql" + }, }; diff --git a/demo/nodefony/app/config/nodefony/realtime-bundle.js b/demo/nodefony/app/config/nodefony/realtime-bundle.js index 91d01e3..5a66eb1 100644 --- a/demo/nodefony/app/config/nodefony/realtime-bundle.js +++ b/demo/nodefony/app/config/nodefony/realtime-bundle.js @@ -10,23 +10,6 @@ module.exports = { type: "tcp", port: 1318, domain: "0.0.0.0" - }, - sip: { - //domain: "pbx.example.com", - domain: "127.0.0.1", - type: "udp", - port: 5062, - options:{} - }, - /*sip:{ - type: "tcp", - //domain: "pbx.example.com", - domain: "127.0.0.1", - port: 5060, - options:{ - allowHalfOpen: true, - highWaterMark: 1024 * 64 - } - }*/ + } } -}; +}; \ No newline at end of file diff --git a/demo/nodefony/app/config/nodefony/redis-bundle.js b/demo/nodefony/app/config/nodefony/redis-bundle.js index 1f443bd..69c9b59 100644 --- a/demo/nodefony/app/config/nodefony/redis-bundle.js +++ b/demo/nodefony/app/config/nodefony/redis-bundle.js @@ -1,7 +1,8 @@ /** * OVERRIDE REDIS BUNDLE SETTINGS * - * All Options : https://github.com/NodeRedis/node_redis + * All Options : https://github.com/redis/node-redis + * https://github.com/redis/node-redis/blob/master/docs/client-configuration.md * * Add clients connections * connections :{ @@ -20,20 +21,24 @@ module.exports = { redis: { debug: true, globalOptions: { - host: "localhost", - port: 6379, - family: "IPv4", - disable_resubscribing: false, - tls: null, - no_ready_check: false, - socket_keepalive: false, - return_buffers: false, - retry_unfulfilled_commands: true + socket:{ + host: "localhost", + port: 6379, + family: "IPv4" + }, + //username:"nodefony", + //password:"nodefony", }, connections: { main: { name: "main" } + /*publish: { + name: "publish" + }, + subscribe: { + name: "subscribe" + },*/ } } -}; \ No newline at end of file +}; diff --git a/demo/nodefony/app/config/nodefony/sequelize-bundle.js b/demo/nodefony/app/config/nodefony/sequelize-bundle.js index 1ce3896..bded33f 100644 --- a/demo/nodefony/app/config/nodefony/sequelize-bundle.js +++ b/demo/nodefony/app/config/nodefony/sequelize-bundle.js @@ -10,23 +10,22 @@ * By default nodefony create connector name nodefony ( driver sqlite ) * for manage Sessions / Users * - * For mysql/mariadb create database nodefony before : + * Strategy sync or migrate Create Structure Database * - * $ nodefony sequelize:create:database [force] => Create database + * Strategy sync + * $ nodefony sequelize:sync => Create Structure tables from Entity * - * Synchronize entities : - * $ nodefony sequelize:sync [force] => Create tables index ... + * Strategy migrate + * $ nodefony sequelize:migrate => Create Structure tables from migrate files * - * Here create new databases connectors - * and use for sync connectors : - * nodefony sequelize:sync * - * connectors: { - * nodefony: { + * connectors: { + * nodefony: { * driver: "mysql", * dbname: 'nodefony', * username: 'nodefony', * password: 'nodefony', + * credentials: vault, * options: { * dialect: "mysql", * host: "localhost", @@ -38,10 +37,120 @@ * acquire:60000 * } * } - * } - * + * }, + * myconnector:{ + * dbname: 'nodefony', + * username: 'postgres', + * password: 'nodefony', + * options: { + * dialect: "postgres", + * host: "localhost", + * port: "5432", + * pool: { + * max: 30, + * min: 0, + * idle: 10000, + * acquire: 60000 + * }, + * retry: { + * match: [ + * Sequelize.ConnectionError, + * Sequelize.ConnectionTimedOutError, + * Sequelize.ConnectionRefusedError, + * Sequelize.TimeoutError, + * /Deadlock/i + * ], + * max: Infinit + * } + * } + * } */ +let Transaction, Sequelize +if (nodefony.Sequelize) { + Transaction = nodefony.Sequelize.Transaction + Sequelize = nodefony.Sequelize.Sequelize +} + +const vault = async () => { + const serviceVault = kernel.get("vault"); + return await serviceVault.getSecret({ + path: "nodefony/data/database/postgresql/connector/nodefony" + }) + .then((secret) => { + return secret.data.data + }) + .catch(e => { + throw e + }) +} + +const connectors = {} +switch (kernel.appEnvironment.environment) { + case "production": + case "development": + default: + connectors.nodefony = { + driver: 'sqlite', + dbname: path.resolve("app", "Resources", "databases", "nodefony.db"), + options: { + dialect: "sqlite", + //isolationLevel: Transaction.ISOLATION_LEVELS.SERIALIZABLE, + retry: { + match: [ + //Sequelize.ConnectionError, + //Sequelize.ConnectionTimedOutError, + //Sequelize.TimeoutError, + /Deadlock/i, + 'SQLITE_BUSY' + ], + max: Infinity + }, + pool: { + max: 5, + min: 0, + idle: 10000 + } + } + } + /*connectors.nodefony = { + driver: "postgres", + dbname: 'nodefony', + username: 'postgres', + password: 'nodefony', + //credentials: vault, + options: { + dialect: "postgres", + host: "localhost", + port: "5432", + //isolationLevel: Transaction.ISOLATION_LEVELS.SERIALIZABLE, + retry: { + match: [ + //Sequelize.ConnectionError, + //Sequelize.ConnectionTimedOutError, + //Sequelize.TimeoutError, + /Deadlock/i + ], + max: 5 + }, + pool: { + max: 20, + min: 0, + idle: 10000, + acquire: 60000 + } + } + }*/ +} + module.exports = { debug: false, - connectors: {} -}; \ No newline at end of file + strategy: "migrate", // sync || migrate || none when nodefony build or nodefony install + connectors: connectors, + migrations: { + storage: "sequelize", // sequelize || memory || json + path: path.resolve(kernel.path, "migrations", "sequelize"), + seedeersPath: path.resolve(kernel.path, "migrations", "seedeers"), + storageSeedeers:"json", + options: {} + } +} diff --git a/demo/nodefony/app/config/routing.js b/demo/nodefony/app/config/routing.js index 381bc12..a11500e 100644 --- a/demo/nodefony/app/config/routing.js +++ b/demo/nodefony/app/config/routing.js @@ -3,13 +3,13 @@ * =============================================================================== * ROUTING BUNDLE app * - * Copyright © 2020/ admin | admin@nodefony.com + * Copyright © 2023/ admin | admin@nodefony.com * * =============================================================================== * * GENERATE BY BUILDER * - * demo ROUTING app + * nodefony-starter ROUTING app **/ diff --git a/demo/nodefony/app/config/services.js b/demo/nodefony/app/config/services.js index 9f019ff..20bfa92 100644 --- a/demo/nodefony/app/config/services.js +++ b/demo/nodefony/app/config/services.js @@ -1,6 +1,6 @@ module.exports = { webrtc: { - class: nodefony.services.webrtc, + class: nodefony.services.webrtc, arguments: ["@container"] } }; diff --git a/demo/nodefony/app/config/webpack.config.js b/demo/nodefony/app/config/webpack.config.js index 5dd50a4..2ab9b25 100644 --- a/demo/nodefony/app/config/webpack.config.js +++ b/demo/nodefony/app/config/webpack.config.js @@ -10,7 +10,7 @@ const bundleName = path.basename(path.resolve(__dirname, "..")); const publicPath = bundleName + "/assets/"; let config = null; -const debug = kernel.debug ? "*" : false ; +const debug = kernel.debug ? "*" : false; let dev = true; if (kernel.environment === "dev") { config = require("./webpack/webpack.dev.config.js"); @@ -35,7 +35,7 @@ module.exports = merge(config, { filename: "./js/[name].js", library: "[name]", libraryExport: "default", - assetModuleFilename:'[hash][ext][query]' + assetModuleFilename: '[hash][ext][query]' }, externals: {}, resolve: { @@ -74,7 +74,7 @@ module.exports = merge(config, { exposes: [{ globalName: '$', override: true - },{ + }, { globalName: 'jQuery', override: true }] @@ -104,7 +104,7 @@ module.exports = merge(config, { test: /\.(gif|png|jpe?g|svg)$/i, type: 'asset/resource', generator: { - filename: "images/[name][ext][query]", + filename: "images/[name][ext][query]", } /*use: [{ loader: 'image-webpack-loader', @@ -148,6 +148,6 @@ module.exports = merge(config, { ], devServer: { hot: false, // false || true || "only", - progress:false + progress: false } }); diff --git a/demo/nodefony/app/config/webpack/webpack.prod.config.js b/demo/nodefony/app/config/webpack/webpack.prod.config.js index 7af77ef..58d66fc 100644 --- a/demo/nodefony/app/config/webpack/webpack.prod.config.js +++ b/demo/nodefony/app/config/webpack/webpack.prod.config.js @@ -1,5 +1,4 @@ // WEBPACK PROD CONFIGURATION -const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); module.exports = { @@ -17,14 +16,5 @@ module.exports = { }) ] }, - plugins: [ - new OptimizeCssAssetsPlugin({ - cssProcessorOptions: { - discardComments: { - removeAll: true - } - }, - canPrint: true - }) - ] + plugins: [] }; diff --git a/demo/nodefony/app/package.json b/demo/nodefony/app/package.json index e5e236e..a2a57ae 100644 --- a/demo/nodefony/app/package.json +++ b/demo/nodefony/app/package.json @@ -1,7 +1,7 @@ { "name": "app", "version": "1.0.0", - "description": "demo description", + "description": "nodefony-starter description", "author": "admin <>", "main": "appKernel.js", "scripts": {}, @@ -9,39 +9,38 @@ "keywords": [ "nodefony", "javascript", - "demo" + "nodefony-starter" ], "repository": {}, - "dependencies": { - "@babel/core": "7.17.5", - "@babel/preset-env": "7.16.11", - "@popperjs/core": "2.11.2", - "babel-loader": "^8.2.2", - "bootstrap": "^5.1.3", - "clean-webpack-plugin": "^4.0.0", - "css-hot-loader": "^1.4.4", - "css-loader": "6.6.0", - "expose-loader": "^3.0.0", - "font-awesome": "^4.7.0", - "html-webpack-plugin": "^5.3.2", - "imports-loader": "^3.0.0", - "jquery": "^3.6.0", - "mini-css-extract-plugin": "2.5.3", - "node-sass": "^7.0.1", - "optimize-css-assets-webpack-plugin": "^6.0.1", - "sass-loader": "12.6.0", - "style-loader": "^3.3.0", - "terser-webpack-plugin": "5.3.1", - "webpack": "5.69.1", - "webpack-merge": "^5.8.0", - "workbox-webpack-plugin": "6.5.0" - }, + "dependencies": {}, "devDependencies": { - "@mapbox/node-pre-gyp": "^1.0.5", - "node-gyp": "9.0.0", - "webpack-dev-server": "4.7.4" + "@popperjs/core": "2.11.8", + "bootstrap": "5.3.2", + "jquery": "3.7.1", + "font-awesome": "^4.7.0", + "@babel/core": "7.23.2", + "@babel/preset-env": "7.23.2", + "babel-loader": "9.1.3", + "clean-webpack-plugin": "4.0.0", + "css-hot-loader": "1.4.4", + "css-loader": "6.8.1", + "expose-loader": "4.1.0", + "favicons": "7.1.4", + "favicons-webpack-plugin": "6.0.1", + "html-webpack-plugin": "5.5.3", + "imports-loader": "4.0.1", + "mini-css-extract-plugin": "2.7.6", + "sass": "1.69.5", + "sass-loader": "13.3.2", + "sitemap-webpack-plugin": "1.1.1", + "style-loader": "3.3.3", + "terser-webpack-plugin": "5.3.9", + "webpack": "5.89.0", + "webpack-dev-server": "4.15.1", + "webpack-merge": "5.10.0", + "@mapbox/node-pre-gyp": "1.0.11", + "node-gyp": "10.0.0" }, "license": "", - "readmeFilename": "README.md", - "contributors": [] + "readmeFilename": "README.md" } diff --git a/demo/nodefony/bin/dev-deploy.sh b/demo/nodefony/bin/dev-deploy.sh new file mode 100755 index 0000000..f1cc502 --- /dev/null +++ b/demo/nodefony/bin/dev-deploy.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +npx nodefony sequelize:revert +rm -rf ./app/Resources/databases/nodefony.db +npx nodefony build diff --git a/demo/nodefony/bin/prod-deploy.sh b/demo/nodefony/bin/prod-deploy.sh new file mode 100755 index 0000000..c33feee --- /dev/null +++ b/demo/nodefony/bin/prod-deploy.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +npx nodefony build diff --git a/demo/nodefony/config/pm2.config.js b/demo/nodefony/config/pm2.config.js index e2fb003..ef1ae67 100644 --- a/demo/nodefony/config/pm2.config.js +++ b/demo/nodefony/config/pm2.config.js @@ -3,13 +3,37 @@ const path = require("path"); const package = require(path.resolve("package.json")); const name = package.name; -const logFile = path.resolve("tmp", `${name}.log`); const script = process.argv[1] || "nodefony"; -/** - * Application configuration section - * http://pm2.keymetrics.io/docs/usage/application-declaration/ - */ +// options - An object with the following options (additional descriptions of these options are here): + +// name - An arbitrary name that can be used to interact with (e.g. restart) the process later in other commands. Defaults to the script name without its extension (eg "testScript" for "testScript.js"). +// script - The path of the script to run. +// args - A string or array of strings composed of arguments to pass to the script. +// interpreterArgs - A string or array of strings composed of arguments to call the interpreter process with. Eg “–harmony” or [”–harmony”,”–debug”]. Only applies if interpreter is something other than “none” (its “node” by default). +// cwd - The working directory to start the process with. +// output - (Default: "~/.pm2/logs/app_name-out.log") The path to a file to append stdout output to. Can be the same file as error. +// error - (Default: "~/.pm2/logs/app_name-error.err") The path to a file to append stderr output to. Can be the same file as output. +// logDateFormat - The display format for log timestamps (eg “YYYY-MM-DD HH:mm Z”). The format is a moment display format. +// pid - (Default: "~/.pm2/pids/app_name-id.pid") The path to a file to write the pid of the started process. The file will be overwritten. Note that the file is not used in any way by pm2 and so the user is free to manipulate or remove that file at any time. The file will be deleted when the process is stopped or the daemon killed. +// minUptime - The minimum uptime of the script before it’s considered successfully started. +// maxRestarts - The maximum number of times in a row a script will be restarted if it exits in less than minUptime. +// maxMemoryRestart - If sets and script’s memory usage goes about the configured number, pm2 restarts the script. Uses human-friendly suffixes: ‘K’ for kilobytes, ‘M’ for megabytes, ‘G’ for gigabytes’, etc. Eg “150M”. +// killTimeout - (Default: 1600) The number of milliseconds to wait after a stop or restart command issues a SIGINT signal to kill the script forcibly with a SIGKILL signal. +// restartDelay - (Default: 0) Number of milliseconds to wait before restarting a script that has exited. +// interpreter - (Default: 'node') The interpreter for your script (eg “python”, “ruby”, “bash”, etc). The value “none” will execute the ‘script’ as a binary executable. +// execMode - (Default: 'fork') If sets to ‘cluster’, will enable clustering (running multiple instances of the script). See here for more details. +// instances - (Default: 1) How many instances of script to create. Only relevant in exec_mode ‘cluster’. +// mergeLogs - (Default: false) If true, merges the log files for all instances of script into one stderr log and one stdout log. Only applies in ‘cluster’ mode. For example, if you have 4 instances of ‘test.js’ started via pm2, normally you would have 4 stdout log files and 4 stderr log files, but with this option set to true you would only have one stdout file and one stderr file. +// watch - If set to true, the application will be restarted on change of the script file. +// force (Default: false) By default, pm2 will only start a script if that script isn’t already running (a script is a path to an application, not the name of an application already running). If force is set to true, pm2 will start a new instance of that script. +// autorestart (Default true). If false, pm2 will not attempt to restart it following successful completion or process failure. +// cron +// executeCommand +// write +// sourceMapSupport +// disableSourceMapSupport + module.exports = { apps: [{ name: name, @@ -17,22 +41,22 @@ module.exports = { args: "pm2", //node_args : "--expose-gc", watch: false, - exec_mode: "cluster", - instances: cpu, - max_memory_restart: "1024M", + execMode: "cluster", + instances: cpu, //5, + maxMemoryRestart: "1024M", autorestart: true, - max_restarts: 10, - // Log in one file - //log_file : logFile, - // Log in separate files - out_file: path.resolve("tmp", `${name}.log`), - error_file: path.resolve("tmp", `${name}.error`), - // Merge clusters - merge_logs: true, + restartDelay:2000, + maxRestarts: 5, + minUptime:60*1000, + //log_file : "./tmp/nodefony.log", + output: path.resolve("tmp", `${name}.log`), + error: path.resolve("tmp", `${name}.log`), + mergeLogs: true, env: { "NODE_ENV": "production", "MODE_START": "PM2", - "NODEFONY_DEBUG": false + "NODEFONY_DEBUG": false, + "NODEFONY_ENV_APP": "production" } }] }; diff --git a/demo/nodefony/migrations/seedeers/nodefony-seedeers-nodefony.json b/demo/nodefony/migrations/seedeers/nodefony-seedeers-nodefony.json new file mode 100644 index 0000000..3f8d101 --- /dev/null +++ b/demo/nodefony/migrations/seedeers/nodefony-seedeers-nodefony.json @@ -0,0 +1,3 @@ +[ + "2023.01.03T16.50.53.seeders-users.js" +] \ No newline at end of file diff --git a/demo/nodefony/migrations/seedeers/nodefony/2023.01.03T16.50.53.seeders-users.js b/demo/nodefony/migrations/seedeers/nodefony/2023.01.03T16.50.53.seeders-users.js new file mode 100644 index 0000000..31e433f --- /dev/null +++ b/demo/nodefony/migrations/seedeers/nodefony/2023.01.03T16.50.53.seeders-users.js @@ -0,0 +1,186 @@ +const { + // Sequelize, + // DataTypes, + // Model, + Op +} = nodefony.Sequelize; + +const path = require("node:path"); + +const users = [{ + username: "anonymous", + name: "anonymous", + surname: "anonymous", + password: "anonymous", + email: "anonymous@nodefony.com", + "2fa": false, + "2fa-token": "", + enabled: true, + userNonExpired: true, + credentialsNonExpired: true, + accountNonLocked: true, + url: null, + image: "", + lang: "en_en", + gender: "none", + roles: ["ROLE_ANONYMOUS"] +}, { + username: "admin", + name: "administrator", + surname: "nodefony", + password: "admin", + email: "administrator@nodefony.com", + "2fa": false, + "2fa-token": "", + enabled: true, + userNonExpired: true, + credentialsNonExpired: true, + accountNonLocked: true, + url: null, + image: "", + lang: "en_en", + gender: "none", + roles: ["ROLE_ADMIN", "ROLE_DEV"] +}, { + username: "1000", + name: "Michael", + surname: "Corleone", + password: "1234", + email: "michael@nodefony.com", + "2fa": false, + "2fa-token": "", + enabled: true, + userNonExpired: true, + credentialsNonExpired: true, + accountNonLocked: true, + url: null, + image: "", + lang: "fr_fr", + gender: "male", + roles: ["ROLE_ADMIN"] +}, { + username: "2000", + name: "Vito", + surname: "Corleone", + password: "1234", + email: "vito@nodefony.com", + "2fa": false, + "2fa-token": "", + enabled: true, + userNonExpired: true, + credentialsNonExpired: true, + accountNonLocked: true, + url: null, + image: "", + lang: "fr_fr", + gender: "male", + roles: ["ROLE_USER"] +}, { + username: "3000", + name: "Connie", + surname: "Corleone", + password: "1234", + email: "connie@nodefony.com", + "2fa": false, + "2fa-token": "", + enabled: true, + userNonExpired: true, + credentialsNonExpired: true, + accountNonLocked: true, + url: null, + image: "", + gender: "female", + lang: "fr_fr", + roles: ["ROLE_USER"] +}]; + +class Seedeers extends nodefony.Service { + constructor (kernel) { + super(path.basename(__filename), kernel.container); + this.orm = this.kernel.getORM(); + this.entity = this.orm.getNodefonyEntity("user"); + } + + async up ({ + name, + context: queryInterface, + context: sequelize + }) { + let transaction = null; + return await queryInterface.describeTable("user") + .then(async (tableDefinition) => { + const date = new Date(); + for (const user of users) { + user.createdAt = date; + user.updatedAt = date; + user.roles = JSON.stringify(user.roles); + this.entity.validPassword(user.password); + const hash = await this.entity.encode(user.password) + .catch((err) => { + this.logger(err, "ERROR"); + throw err; + }); + user.password = hash; + } + + /* const datas = users.map(async (user) => { + user.createdAt = date + user.updatedAt = date + user.roles = JSON.stringify(user.roles) + this.entity.validPassword(user.password); + const hash = await this.entity.encode(user.password) + .catch(err => { + this.logger(err, "ERROR"); + throw err; + }); + user.password = hash + return user + })*/ + transaction = await queryInterface.sequelize.transaction(); + return await queryInterface.bulkInsert("user", users, { + transaction + }) + .then(async (nb) => { + await transaction.commit(); + this.log(`Add ${nb} seeds`); + return users; + }) + .catch(async (e) => { + if (transaction && !transaction.finished) { + await transaction.rollback(); + } + throw e; + }); + }) + .catch(async (e) => { + if (transaction && !transaction.finished) { + await transaction.rollback(); + } + throw e; + }); + } + + async down ({ + context: queryInterface + }) { + return await queryInterface.describeTable("user") + .then(async (tableDefinition) => { + const datas = users.map((user) => user.username); + this.log(datas, "INFO", "DELETE SEEDS"); + return await queryInterface.bulkDelete("user", { + username: { + [Op.in]: datas + } + }) + .then((res) => res) + .catch((e) => { + throw e; + }); + }) + .catch((e) => { + throw e; + }); + } +} + +module.exports = new Seedeers(kernel); diff --git a/demo/nodefony/migrations/sequelize/2023.10.31T10.55.56-migrate-entity.js.example b/demo/nodefony/migrations/sequelize/2023.10.31T10.55.56-migrate-entity.js.example new file mode 100644 index 0000000..71e9210 --- /dev/null +++ b/demo/nodefony/migrations/sequelize/2023.10.31T10.55.56-migrate-entity.js.example @@ -0,0 +1,101 @@ +const { + Sequelize +} = require('sequelize'); + +class Migrate extends nodefony.Service { + constructor(kernel) { + super("Migrate", kernel.container); + this.serviceUmzug = this.get("umzug"); + this.orm = this.kernel.getOrm(); + } + + async up({ + context: queryInterface + }) { + this.log("Migrate up for user table"); + let sequelize = queryInterface.sequelize; + let userModel = sequelize.model("user"); + + return await queryInterface.describeTable("user") + .then(async (tableDefinition) => { + if (tableDefinition.token) { + return Promise.resolve(userModel) + } + this.transaction = await queryInterface.sequelize.transaction(); + return queryInterface.addColumn( + "user", + "token", { + type: Sequelize.STRING, + allowNull: true, + defaultValue: "1234" + }, { + transaction: this.transaction + } + ).then(() => { + return Promise.resolve(userModel); + }) + }) + .then(async (model) => { + this.log("Migrate upgrade data for user table"); + let users = await model.findAll(); + users.map(async (user) => { + // change data + this.log(`Update token for user : ${user.username}`); + /*await user.update({ + }).then((updatedRecord) => { + this.log(`Update token for user : ${updatedRecord.username}`); + })*/ + }) + if( this.transaction){ + await this.transaction.commit(); + } + return this; + }) + .catch(async (e) => { + if (this.transaction) { + await this.transaction.rollback(); + } + return Promise.reject(e); + }) + } + + async down({ + context: queryInterface + }) { + this.log("Migrate Reverting for user table"); + let sequelize = queryInterface.sequelize; + let userModel = sequelize.model("user"); + return await queryInterface.describeTable("user") + .then(async (tableDefinition) => { + if (tableDefinition.token) { + this.transaction = await queryInterface.sequelize.transaction(); + return await queryInterface.removeColumn("user", "token", { + transaction: this.transaction + }); + } + return Promise.resolve(userModel); + }) + .then(() => { + this.log(`Table user removeColumn token`); + return userModel + }) + .then(async (model) => { + let users = await model.findAll(); + users.map(async (user) => { + this.log(`Update user when migrate down : ${user.username}`); + }); + if( this.transaction){ + await this.transaction.commit(); + } + return this; + }) + .catch(async (e) => { + if (this.transaction) { + await this.transaction.rollback(); + } + this.log(e, "ERROR"); + }) + } +} + +module.exports = new Migrate(kernel); diff --git a/demo/nodefony/migrations/sequelize/nodefony/2022.12.25T17.37.37.entity-user.js b/demo/nodefony/migrations/sequelize/nodefony/2022.12.25T17.37.37.entity-user.js new file mode 100644 index 0000000..cdf886d --- /dev/null +++ b/demo/nodefony/migrations/sequelize/nodefony/2022.12.25T17.37.37.entity-user.js @@ -0,0 +1,137 @@ +'use strict'; +const { + Sequelize, + DataTypes, + Model +} = require('sequelize'); + +class Migrate extends nodefony.Service { + constructor(kernel) { + super("Migrate", kernel.container); + this.entityName = "user" + } + + async up({ + name, + context: queryInterface + }) { + let descriptions = null + try { + descriptions = await queryInterface.describeTable(this.entityName) + } catch (e) { + this.log(`Migrate file : ${name}`) + } + const exist = await queryInterface.tableExists(this.entityName) + if (exist) { + this.log(`Entity ${this.entityName} already exist`); + return descriptions + } + let transaction = null + try { + transaction = await queryInterface.sequelize.transaction(); + let res = await queryInterface.createTable(this.entityName, { + username: { + type: DataTypes.STRING(126), + primaryKey: true, + unique: true, + allowNull: false + }, + password: { + type: DataTypes.STRING(256), + allowNull: false + }, + "2fa": { + type: DataTypes.BOOLEAN, + defaultValue: false + }, + "2fa-token": DataTypes.STRING(256), + enabled: { + type: DataTypes.BOOLEAN, + defaultValue: true + }, + userNonExpired: { + type: DataTypes.BOOLEAN, + defaultValue: true + }, + credentialsNonExpired: { + type: DataTypes.BOOLEAN, + defaultValue: true + }, + accountNonLocked: { + type: DataTypes.BOOLEAN, + defaultValue: true + }, + email: { + type: DataTypes.STRING, + //primaryKey: true, + unique: true, + allowNull: false, + }, + name: { + type: DataTypes.STRING, + allowNull: true + }, + surname: { + type: DataTypes.STRING, + allowNull: true + }, + lang: { + type: DataTypes.STRING, + defaultValue: "en_en" + }, + roles: { + type: DataTypes.JSON, + defaultValue: ["ROLE_USER"] + }, + gender: { + type: DataTypes.STRING, + defaultValue: "none" + }, + url: { + type: DataTypes.STRING, + allowNull: true + }, + image: DataTypes.STRING, + createdAt: { + allowNull: false, + type: DataTypes.DATE + }, + updatedAt: { + allowNull: false, + type: DataTypes.DATE + } + }, { + transaction + }); + await transaction.commit(); + return await queryInterface.addIndex(this.entityName, { + unique: true, + fields: ['email'] + }) + } catch (e) { + if (transaction && !transaction.finished) { + this.log(e, "ERROR") + this.log(`Rollback transaction on table ${this.entityName}`); + await transaction.rollback(); + } + this.log("Rollback Transaction already finished", "WARNING") + throw e + } + } + + async down({ + name, + context: queryInterface, + context: sequelize + }) { + try { + const descriptions = await queryInterface.describeTable(this.entityName) + return await queryInterface.dropTable(this.entityName); + } catch (e) { + this.log(`Entity ${this.entityName} not exist`, "WARNING") + throw e + } + } +} + +module.exports = new Migrate(kernel); diff --git a/demo/nodefony/migrations/sequelize/nodefony/2022.12.25T17.37.38.entity-session.js b/demo/nodefony/migrations/sequelize/nodefony/2022.12.25T17.37.38.entity-session.js new file mode 100644 index 0000000..df7b2cb --- /dev/null +++ b/demo/nodefony/migrations/sequelize/nodefony/2022.12.25T17.37.38.entity-session.js @@ -0,0 +1,97 @@ +'use strict'; +const { + Sequelize, + DataTypes, + Model +} = require('sequelize'); + +class Migrate extends nodefony.Service { + constructor(kernel) { + super("Migrate", kernel.container); + this.entityName = "sessions" + } + + async up({ + name, + context: queryInterface + }) { + let descriptions = null + try { + descriptions = await queryInterface.describeTable(this.entityName) + } catch (e) { + this.log(`Migrate file : ${name}`) + } + const exist = await queryInterface.tableExists(this.entityName) + if (exist) { + this.log(`Entity ${this.entityName} already exist`); + return descriptions + } + let transaction = null + try { + transaction = await queryInterface.sequelize.transaction(); + let res = await queryInterface.createTable(this.entityName, { + session_id: { + type: DataTypes.STRING(126), + primaryKey: true + }, + context: { + type: DataTypes.STRING(126), + defaultValue: "default" + }, + Attributes: { + type: DataTypes.JSON + }, + flashBag: { + type: DataTypes.JSON + }, + metaBag: { + type: DataTypes.JSON, + }, + createdAt: { + allowNull: false, + type: DataTypes.DATE + }, + updatedAt: { + allowNull: false, + type: DataTypes.DATE + }, + username: { + type: DataTypes.STRING(126), + references: { + model: 'user', + key: 'username' + }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + }, + }, { + transaction + }); + return await transaction.commit(); + } catch (e) { + if (transaction && !transaction.finished) { + this.log(e, "ERROR") + this.log(`Rollback transaction on table ${this.entityName}`); + await transaction.rollback(); + } + this.log("Rollback Transaction already finished", "WARNING") + throw e + } + } + + async down({ + name, + context: queryInterface, + context: sequelize + }) { + try { + const descriptions = await queryInterface.describeTable(this.entityName) + return await queryInterface.dropTable(this.entityName); + } catch (e) { + this.log(`Entity ${this.entityName} not exist`, "WARNING") + throw e + } + } +} + +module.exports = new Migrate(kernel); diff --git a/demo/nodefony/migrations/sequelize/nodefony/2022.12.25T17.37.39.entity-requests.js b/demo/nodefony/migrations/sequelize/nodefony/2022.12.25T17.37.39.entity-requests.js new file mode 100644 index 0000000..5a7dff2 --- /dev/null +++ b/demo/nodefony/migrations/sequelize/nodefony/2022.12.25T17.37.39.entity-requests.js @@ -0,0 +1,115 @@ +'use strict'; +const { + Sequelize, + DataTypes, + Model +} = require('sequelize'); + +class Migrate extends nodefony.Service { + constructor(kernel) { + super("Migrate", kernel.container); + this.entityName = "requests" + } + + async up({ + name, + context: queryInterface + }) { + let descriptions = null + try { + descriptions = await queryInterface.describeTable(this.entityName) + } catch (e) { + this.log(`Migrate file : ${name}`) + } + const exist = await queryInterface.tableExists(this.entityName) + if (exist) { + this.log(`Entity ${this.entityName} already exist`); + return descriptions + } + let transaction = null + try { + transaction = await queryInterface.sequelize.transaction(); + let res = await queryInterface.createTable(this.entityName, { + id: { + type: DataTypes.INTEGER, + primaryKey: true, + autoIncrement: true + }, + remoteAddress: { + type: DataTypes.STRING + }, + userAgent: { + type: DataTypes.STRING + }, + url: { + type: DataTypes.TEXT + }, + route: { + type: DataTypes.STRING + }, + method: { + type: DataTypes.STRING + }, + state: { + type: DataTypes.STRING + }, + protocol: { + type: DataTypes.STRING + }, + scheme: { + type: DataTypes.STRING + }, + time: { + type: DataTypes.FLOAT + }, + data: { + type: DataTypes.TEXT + }, + createdAt: { + allowNull: false, + type: DataTypes.DATE + }, + updatedAt: { + allowNull: false, + type: DataTypes.DATE + }, + username: { + type: DataTypes.STRING(126), + references: { + model: 'user', + key: 'username' + }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + } + }, { + transaction + }); + return await transaction.commit(); + } catch (e) { + if (transaction && !transaction.finished) { + this.log(e, "ERROR") + this.log(`Rollback transaction on table ${this.entityName}`); + await transaction.rollback(); + } + this.log("Rollback Transaction already finished", "WARNING") + throw e + } + } + + async down({ + name, + context: queryInterface, + context: sequelize + }) { + try { + const descriptions = await queryInterface.describeTable(this.entityName) + return await queryInterface.dropTable(this.entityName); + } catch (e) { + this.log(`Entity ${this.entityName} not exist`, "WARNING") + throw e + } + } +} + +module.exports = new Migrate(kernel); diff --git a/demo/nodefony/migrations/sequelize/nodefony/2022.12.25T17.37.40.entity-jwts.js b/demo/nodefony/migrations/sequelize/nodefony/2022.12.25T17.37.40.entity-jwts.js new file mode 100644 index 0000000..dcd1bac --- /dev/null +++ b/demo/nodefony/migrations/sequelize/nodefony/2022.12.25T17.37.40.entity-jwts.js @@ -0,0 +1,97 @@ +'use strict'; +const { + Sequelize, + DataTypes, + Model +} = require('sequelize'); + +class Migrate extends nodefony.Service { + constructor(kernel) { + super("Migrate", kernel.container); + this.entityName = "jwts" + } + + async up({ + name, + context: queryInterface + }) { + let descriptions = null + try { + descriptions = await queryInterface.describeTable(this.entityName) + } catch (e) { + this.log(`Migrate file : ${name}`) + } + const exist = await queryInterface.tableExists(this.entityName) + if (exist) { + this.log(`Entity ${this.entityName} already exist`); + return descriptions + } + let transaction = null + try { + transaction = await queryInterface.sequelize.transaction(); + let res = await queryInterface.createTable(this.entityName, { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true + }, + refreshToken: { + type: DataTypes.TEXT, + allowNull: false + }, + token: { + type: DataTypes.TEXT, + }, + active: { + type: DataTypes.BOOLEAN, + defaultValue: true + }, + createdAt: { + allowNull: false, + type: DataTypes.DATE + }, + updatedAt: { + allowNull: false, + type: DataTypes.DATE + }, + username: { + type: DataTypes.STRING(126), + references: { + model: 'user', + key: 'username' + }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + }, + }, { + transaction + }); + return await transaction.commit(); + } catch (e) { + if (transaction && !transaction.finished) { + this.log(e, "ERROR") + this.log(`Rollback transaction on table ${this.entityName}`); + await transaction.rollback(); + } + this.log("Rollback Transaction already finished", "WARNING") + throw e + } + //`username` VARCHAR(126) REFERENCES `user` (`username`) ON DELETE CASCADE ON UPDATE CASCADE); + } + + async down({ + name, + context: queryInterface, + context: sequelize + }) { + try { + const descriptions = await queryInterface.describeTable(this.entityName) + return await queryInterface.dropTable(this.entityName); + } catch (e) { + this.log(`Entity ${this.entityName} not exist`, "WARNING") + throw e + } + } +} + +module.exports = new Migrate(kernel); diff --git a/demo/nodefony/package.json b/demo/nodefony/package.json index 96b1545..61b87b3 100644 --- a/demo/nodefony/package.json +++ b/demo/nodefony/package.json @@ -1,12 +1,12 @@ { "name": "nodefony-client-demo", "version": "1.0.0", - "description": "nodefony-client demo", + "description": "nodefony-client-demo", "main": "nodefony", "scripts": { "nodefony": "nodefony", "pm2": "pm2", - "start": "nodefony", + "start": "nodefony start", "dev": "nodefony dev", "build": "nodefony build", "rebuild": "nodefony rebuild", @@ -14,7 +14,12 @@ "prod": "nodefony prod", "kill": "nodefony kill", "test": "nodefony test", - "help": "nodefony -h" + "compile": "nodefony webpack:dump", + "help": "nodefony -h", + "changelog": "conventional-changelog -p conventionalcommits -i CHANGELOG.md -s -r 0", + "dev-deploy": "bash bin/dev-deploy.sh", + "prod-deploy": "bash bin/prod-deploy.sh", + "lint": "eslint ." }, "private": true, "keywords": [ @@ -31,24 +36,38 @@ "win32" ], "engines": { - "node": ">=10" + "node": ">=12" }, "dependencies": { - "mongoose": "6.2.4", - "nodefony": "6.11.0", - "pm2": "5.2.0", - "pm2-logrotate": "^2.7.0", - "sequelize": "6.17.0", - "webpack": "5.69.1", - "webpack-dev-server": "4.7.4" + "graphql": "16.8.1", + "mongoose": "7.6.3", + "nodefony": "7.0.0-beta.21", + "pm2": "5.3.0", + "pm2-logrotate": "2.7.0", + "sequelize": "6.33.0", + "webpack": "5.89.0", + "webpack-dev-server": "4.15.1" }, "devDependencies": { - "node-gyp": "9.0.0", - "node-pre-gyp": "^0.17.0" + "@babel/core": "7.23.2", + "@babel/eslint-parser": "7.22.15", + "@mapbox/node-pre-gyp": "1.0.11", + "conventional-changelog-cli": "4.1.0", + "eslint": "8.52.0", + "eslint-config-standard": "17.1.0", + "eslint-plugin-html": "7.1.0", + "eslint-plugin-import": "2.29.0", + "eslint-plugin-markdown": "3.0.1", + "eslint-plugin-node": "11.1.0", + "eslint-plugin-promise": "^6.0.0", + "eslint-plugin-vue": "9.18.1", + "markdown-eslint-parser": "1.2.1", + "node-gyp": "10.0.0", + "vue-eslint-parser": "9.3.2" }, "author": "admin ", "readmeFilename": "README.md", "contributors": [ {} ] -} +} \ No newline at end of file diff --git a/demo/nodefony/src/bundles/users-bundle/Command/fixtureTask.js b/demo/nodefony/src/bundles/users-bundle/Command/fixtureTask.js index b17c2d8..ea786ca 100644 --- a/demo/nodefony/src/bundles/users-bundle/Command/fixtureTask.js +++ b/demo/nodefony/src/bundles/users-bundle/Command/fixtureTask.js @@ -1,15 +1,16 @@ class fixtureTask extends nodefony.Task { - - constructor(name, command) { + constructor (name, command) { super(name, command); this.bundle = command.bundle; } - showHelp() { - this.setHelp("users:fixtures:default", + showHelp () { + this.setHelp( + "users:fixtures:default", "Generate admin, anonymous and 3 common users `nodefony users:fixtures:default` " ); - this.setHelp("users:fixtures:random nb", + this.setHelp( + "users:fixtures:random nb", "Generate ramdom users with faker `nodefony users:fixtures:random 10` " ); } @@ -19,30 +20,28 @@ class fixtureTask extends nodefony.Task { const fixtures = this.bundle.getFixture("users"); if (fixtures) { this.log(`LOAD FIXTURES users : ${args}`, "INFO"); - let inst = new fixtures(this.container); + const inst = new fixtures(this.container); return await inst.run(args); } - throw new Error(`users fixtures not found `); - + throw new Error("users fixtures not found "); } catch (e) { throw e; } } - async random(args = null) { + async random (args = null) { try { const fixtures = this.bundle.getFixture("users"); if (fixtures) { this.log(`RANDOM FIXTURES users : ${args}`, "INFO"); - let inst = new fixtures(this.container); + const inst = new fixtures(this.container); return await inst.run(args); } - throw new Error(`users fixtures not found `); + throw new Error("users fixtures not found "); } catch (e) { throw e; } } - } module.exports = fixtureTask; diff --git a/demo/nodefony/src/bundles/users-bundle/Command/usersCommand.js b/demo/nodefony/src/bundles/users-bundle/Command/usersCommand.js index a4f192f..aa1523e 100644 --- a/demo/nodefony/src/bundles/users-bundle/Command/usersCommand.js +++ b/demo/nodefony/src/bundles/users-bundle/Command/usersCommand.js @@ -1,26 +1,29 @@ const fixtureTask = require(path.resolve(__dirname, "fixtureTask.js")); class usersCommand extends nodefony.Command { - constructor(cli, bundle) { + constructor (cli, bundle) { super("users", cli, bundle); this.usersService = this.get("users"); this.setTask("fixtures", fixtureTask); } - showHelp() { - this.setHelp("users:show [user]", + showHelp () { + this.setHelp( + "users:show [user]", "nodefony users:show admin" ); - this.setHelp("users:find [--json] username", + this.setHelp( + "users:find [--json] username", "nodefony --json users:find admin" ); - this.setHelp("users:findAll [--json]", + this.setHelp( + "users:findAll [--json]", "nodefony --json users:findAll" ); super.showHelp(); } - async show(username) { + async show (username) { let obj = null; if (username) { obj = await this.find(username); @@ -29,43 +32,40 @@ class usersCommand extends nodefony.Command { } } - find(username) { + find (username) { return this.usersService.findOne(username) .then((res) => { if (this.cli.commander.opts().json) { return process.stdout.write(`${JSON.stringify(res)}\n`); - } else { - return this.display(res); } - }).catch(e => { + return this.display(res); + }) + .catch((e) => { if (this.cli.commander.opts().json) { return process.stdout.write(`${JSON.stringify({})}\n`); - } else { - throw e; } + throw e; }); } - findAll() { + findAll () { return this.usersService.find() .then((res) => { if (this.cli.commander.opts().json) { return process.stdout.write(`${JSON.stringify(res.rows)}\n`); - } else { - return this.display(res.rows); } + return this.display(res.rows); }) - .catch(e => { + .catch((e) => { if (this.cli.commander.opts().json) { return process.stdout.write(`${JSON.stringify({})}\n`); - } else { - throw e; } + throw e; }); } - display(obj) { - this.cli.logger("START TABLE : " + this.cli.getEmoji("clapper")); + display (obj) { + this.cli.logger(`START TABLE : ${this.cli.getEmoji("clapper")}`); const type = nodefony.typeOf(obj); if (type === "object" || type === null) { if (!obj) { @@ -74,7 +74,7 @@ class usersCommand extends nodefony.Command { obj = [obj]; } } - let options = { + const options = { head: [ "username", "First Name", @@ -85,7 +85,7 @@ class usersCommand extends nodefony.Command { "Enabled" ] }; - let table = this.cli.displayTable(null, options); + const table = this.cli.displayTable([], options); for (let i = 0; i < obj.length; i++) { const user = obj[i]; table.push([ @@ -99,8 +99,7 @@ class usersCommand extends nodefony.Command { ]); } console.log(table.toString()); - this.cli.logger("END TABLE : " + this.cli.getEmoji("checkered_flag")); + this.cli.logger(`END TABLE : ${this.cli.getEmoji("checkered_flag")}`); } - } module.exports = usersCommand; diff --git a/demo/nodefony/src/bundles/users-bundle/Entity/mongoose/userEntity.js b/demo/nodefony/src/bundles/users-bundle/Entity/mongoose/userEntity.js index 54df618..1383e56 100644 --- a/demo/nodefony/src/bundles/users-bundle/Entity/mongoose/userEntity.js +++ b/demo/nodefony/src/bundles/users-bundle/Entity/mongoose/userEntity.js @@ -5,14 +5,13 @@ * * */ -//const Mongoose = require('mongoose'); -const Schema = require('mongoose').Schema; -const mongoosePaginate = require('mongoose-paginate-v2'); -const validator = require('validator'); +// const Mongoose = require('mongoose'); +const {Schema} = require("mongoose"); +const mongoosePaginate = require("mongoose-paginate-v2"); +const validator = require("validator"); class userEntity extends nodefony.Entity { - - constructor(bundle) { + constructor (bundle) { /* * @param bundle instance * @param Entity name @@ -20,14 +19,10 @@ class userEntity extends nodefony.Entity { * @param connection name */ super(bundle, "user", "mongoose", "nodefony"); - this.once("onConnect", (name, db) => { - this.model = this.registerModel(db); - this.orm.setEntity(this); - }); } - getSchema() { - //const encodePassword = this.encode.bind(this); + getSchema () { + // const encodePassword = this.encode.bind(this); return { username: { type: String, @@ -65,7 +60,7 @@ class userEntity extends nodefony.Entity { type: String, unique: true, required: true, - validate: [validator.isEmail, 'invalid email {VALUE}'], + validate: [validator.isEmail, "invalid email {VALUE}"], createIndexes: { unique: true } @@ -117,8 +112,8 @@ class userEntity extends nodefony.Entity { }; } - validPassword(value) { - let valid = validator.isLength(value, { + validPassword (value) { + const valid = validator.isLength(value, { min: 4, max: undefined }); @@ -128,46 +123,46 @@ class userEntity extends nodefony.Entity { return value; } - registerModel(db) { - let mySchema = new Schema(this.getSchema(), { + registerModel (db) { + const mySchema = new Schema(this.getSchema(), { timestamps: { - createdAt: 'createdAt', - updatedAt: 'updatedAt' + createdAt: "createdAt", + updatedAt: "updatedAt" } }); mySchema.plugin(mongoosePaginate); - let entity = this; - mySchema.pre('save', function (next) { - if (!this.isModified('password')) { + const entity = this; + mySchema.pre("save", function (next) { + if (!this.isModified("password")) { return next(); } entity.logger("hash password ", "DEBUG"); entity.validPassword(this.password); return entity.encode(this.password) - .then(hash => { + .then((hash) => { entity.logger(hash, "DEBUG"); this.password = hash; return hash; }) - .catch(err => { + .catch((err) => { entity.logger(err, "ERROR"); throw err; }); }); - mySchema.pre('updateOne', function (next) { - //const data = this.getUpdate(); - let password = this.get("password"); + mySchema.pre("updateOne", function (next) { + // const data = this.getUpdate(); + const password = this.get("password"); if (!password) { return next(); } entity.logger("update password hash", "DEBUG"); entity.validPassword(password); return entity.encode(password) - .then(hash => { + .then((hash) => { entity.logger(hash, "DEBUG"); this._update.password = hash; }) - .catch(err => { + .catch((err) => { entity.logger(err, "ERROR"); throw err; }); @@ -176,4 +171,4 @@ class userEntity extends nodefony.Entity { } } -module.exports = userEntity; \ No newline at end of file +module.exports = userEntity; diff --git a/demo/nodefony/src/bundles/users-bundle/Entity/sequelize/userEntity.js b/demo/nodefony/src/bundles/users-bundle/Entity/sequelize/userEntity.js index d3693c3..437b50d 100644 --- a/demo/nodefony/src/bundles/users-bundle/Entity/sequelize/userEntity.js +++ b/demo/nodefony/src/bundles/users-bundle/Entity/sequelize/userEntity.js @@ -1,5 +1,10 @@ -const { Sequelize, DataTypes, Model } = require("sequelize"); -const validator = require('validator'); +const { + Sequelize, + DataTypes, + Model +} = nodefony.Sequelize; // require("sequelize"); +const validator = require("validator"); + /* * * @@ -8,8 +13,8 @@ const validator = require('validator'); * */ class userEntity extends nodefony.Entity { + constructor (bundle) { - constructor(bundle) { /* * @param bundle instance * @param Entity name @@ -17,7 +22,8 @@ class userEntity extends nodefony.Entity { * @param connection name */ super(bundle, "user", "sequelize", "nodefony"); - /*this.orm.on("onOrmReady", ( orm ) => { + + /* this.orm.on("onOrmReady", ( orm ) => { let session = this.orm.getEntity("session"); if (session) { this.model.hasMany(session, { @@ -31,7 +37,8 @@ class userEntity extends nodefony.Entity { });*/ } - getSchema() { + // eslint-disable-next-line max-lines-per-function + getSchema () { return { username: { type: DataTypes.STRING(126), @@ -40,10 +47,11 @@ class userEntity extends nodefony.Entity { allowNull: false, validate: { is: { - args: /[^\w]|_|-|./g, - msg: `username allow alphanumeric and ( _ | - | . ) characters` + args: /^[\w-_.]+$/, + msg: "username allow alphanumeric and ( _ | - | . ) characters" } - /*notIn: { + + /* notIn: { args: [['admin', 'root']], msg: `username don't allow (admin , root) login name` }*/ @@ -51,13 +59,14 @@ class userEntity extends nodefony.Entity { }, password: { type: DataTypes.STRING(256), - allowNull: false, - validate: { + allowNull: false + + /* validate: { min: { args: [[4]], - msg: `password allow 4 characters min ` + msg: "password allow 4 characters min " } - } + }*/ }, "2fa": { type: DataTypes.BOOLEAN, @@ -82,7 +91,7 @@ class userEntity extends nodefony.Entity { }, email: { type: DataTypes.STRING, - //primaryKey: true, + // primaryKey: true, unique: true, allowNull: false, validate: { @@ -96,8 +105,8 @@ class userEntity extends nodefony.Entity { allowNull: true, validate: { is: { - args: /[^\w]|_|-|.|'/g, - msg: `name allow alphanumeric characters` + args: /^[\w-_.]*$/, + msg: "name allow alphanumeric characters" } } }, @@ -106,8 +115,8 @@ class userEntity extends nodefony.Entity { allowNull: true, validate: { is: { - args: /[^\w]|_|-|.|''/g, - msg: `surname allow alphanumeric characters` + args: /^[\w-_.]*$/, + msg: "surname allow alphanumeric characters" } } }, @@ -118,9 +127,9 @@ class userEntity extends nodefony.Entity { roles: { type: DataTypes.JSON, defaultValue: ["ROLE_USER"], - get(key) { + get (key) { let val = this.getDataValue(key); - if (typeof (val) === "string") { + if (typeof val === "string") { val = JSON.parse(val); } return val; @@ -141,8 +150,8 @@ class userEntity extends nodefony.Entity { }; } - validPassword(value) { - let valid = validator.isLength(value, { + validPassword (value) { + const valid = validator.isLength(value, { min: 4, max: undefined }); @@ -152,19 +161,37 @@ class userEntity extends nodefony.Entity { return value; } - registerModel(db) { - class MyModel extends Model {} + registerModel (db) { + class MyModel extends Model { + static associate (models) { + // define association here + } + + hasRole (name) { + for (const role in this.roles) { + if (this.roles[role] === name) { + return true; + } + } + return false; + } + + isGranted (role) { + return this.hasRole(role); + } + } MyModel.init(this.getSchema(), { sequelize: db, modelName: this.name, hooks: { beforeCreate: (user) => { + console.log("beforeCreate", user); this.validPassword(user.password); return this.encode(user.password) - .then(hash => { + .then((hash) => { user.password = hash; }) - .catch(err => { + .catch((err) => { this.logger(err, "ERROR"); throw err; }); @@ -173,10 +200,10 @@ class userEntity extends nodefony.Entity { if ("password" in userUpate.attributes) { this.validPassword(userUpate.attributes.password); return this.encode(userUpate.attributes.password) - .then(hash => { + .then((hash) => { userUpate.attributes.password = hash; }) - .catch(err => { + .catch((err) => { this.logger(err, "ERROR"); throw err; }); @@ -184,19 +211,19 @@ class userEntity extends nodefony.Entity { } }, freezeTableName: true, - //add indexes + // add indexes indexes: [{ unique: true, - fields: ['email'] + fields: ["email"] }] // add custom validations - //validate: {} + // validate: {} }); return MyModel; } - logger(pci /*, sequelize*/ ) { - const msgid = "Entity " + this.name; + logger (pci /* , sequelize*/) { + const msgid = `Entity ${this.name}`; return super.logger(pci, "DEBUG", msgid); } } diff --git a/demo/nodefony/src/bundles/users-bundle/Fixtures/users.js b/demo/nodefony/src/bundles/users-bundle/Fixtures/users.js index 852219d..3a5ebc3 100644 --- a/demo/nodefony/src/bundles/users-bundle/Fixtures/users.js +++ b/demo/nodefony/src/bundles/users-bundle/Fixtures/users.js @@ -1,17 +1,17 @@ const localFramework = kernel.app.settings.locale; -let Faker = null ; +let Faker = null; try { - Faker = require(`faker`); + Faker = require("@withshepherd/faker"); } catch (e) {} -//const local = localFramework.slice(0, 2); -//const Faker = require(`faker/locale/${local}`); -//Faker.locale = local; +// const local = localFramework.slice(0, 2); +// const Faker = require(`faker/locale/${local}`); +// Faker.locale = local; -//let uuid = Faker.random.uuid(); -//let ele = `/${uuid.split('-').slice(1, 4).join('\/')}/${uuid}.jpg `; +// let uuid = Faker.random.uuid(); +// let ele = `/${uuid.split('-').slice(1, 4).join('\/')}/${uuid}.jpg `; -const rolesArray = ['ROLE_USER', 'ROLE_ADMIN', 'ROLE_TEST', 'ROLE_AUDIO', 'ROLE_VIDEO']; +const rolesArray = ["ROLE_USER", "ROLE_ADMIN", "ROLE_TEST", "ROLE_AUDIO", "ROLE_VIDEO"]; const defaultFixtures = [{ username: "anonymous", @@ -63,7 +63,7 @@ const defaultFixtures = [{ }]; class randomFixture { - constructor() { + constructor () { this.matrice = { username: "", name: "", @@ -77,8 +77,8 @@ class randomFixture { }; } - randomUser(nb = 100) { - let tab = []; + randomUser (nb = 100) { + const tab = []; for (let i = 0; i < nb; i++) { let gender = "male"; let lang = "fr-FR"; @@ -86,33 +86,31 @@ class randomFixture { gender = "female"; lang = "en_EN"; } - tab.push( - nodefony.extend({}, this.matrice, { - username: Faker.internet.userName(), - name: Faker.name.lastName(), - surname: Faker.name.firstName(), - email: Faker.internet.email(), - gender: gender, - lang: Faker.random.locale(), - image: Faker.image.avatar(), - url: Faker.internet.url(), - roles: [Faker.random.arrayElement(rolesArray)] - })); + tab.push(nodefony.extend({}, this.matrice, { + username: Faker.internet.userName(), + name: Faker.name.lastName(), + surname: Faker.name.firstName(), + email: Faker.internet.email(), + gender, + lang: Faker.random.locale(), + image: Faker.image.avatar(), + url: Faker.internet.url(), + roles: [Faker.random.arrayElement(rolesArray)] + })); } return tab; } - faker(option) { + faker (option) { return Faker.fake(option); } - randomFloat(modulo = 0, min = 0, max = 100) { + randomFloat (modulo = 0, min = 0, max = 100) { if (modulo % 2) { return -(Math.random() * (max - min) + min).toFixed(2); } return (Math.random() * (max - min) + min).toFixed(2); } - } module.exports.default = defaultFixtures; diff --git a/demo/nodefony/src/bundles/users-bundle/Fixtures/usersFixtures.js b/demo/nodefony/src/bundles/users-bundle/Fixtures/usersFixtures.js index 557a5e5..4dcd42f 100644 --- a/demo/nodefony/src/bundles/users-bundle/Fixtures/usersFixtures.js +++ b/demo/nodefony/src/bundles/users-bundle/Fixtures/usersFixtures.js @@ -1,16 +1,15 @@ const users = require("./users.js"); class usersFixture extends nodefony.Fixture { - - constructor(container) { + constructor (container) { super("users", container); this.usersService = this.get("users"); this.entity = this.orm.getEntity("user"); } - async initialize(random = 0) { + async initialize (random = 0) { switch (this.ormName) { - case 'sequelize': + case "sequelize": if (random) { return await this.randomSequelize(random); } @@ -23,12 +22,12 @@ class usersFixture extends nodefony.Fixture { } } - async randomSequelize(nb) { + async randomSequelize (nb) { try { - let tab = []; + const tab = []; const random = new users.random(); - let fixs = random.randomUser(nb); - for await (let user of fixs) { + const fixs = random.randomUser(nb); + for await (const user of fixs) { tab.push(await this.loadSequelizeFixtures(user)); } return tab; @@ -37,10 +36,10 @@ class usersFixture extends nodefony.Fixture { } } - async runSequelize() { + async runSequelize () { try { - let tab = []; - for await (let user of users.default) { + const tab = []; + for await (const user of users.default) { tab.push(await this.loadSequelizeFixtures(user)); } return tab; @@ -49,29 +48,29 @@ class usersFixture extends nodefony.Fixture { } } - loadSequelizeFixtures(obj) { + loadSequelizeFixtures (obj) { return this.entity.findOrCreate({ - where: { - username: obj.username - }, - defaults: obj - }) + where: { + username: obj.username + }, + defaults: obj + }) .then((res) => { if (res[1]) { - this.log("ADD USER : " + res[0].username, "INFO"); + this.log(`ADD USER : ${res[0].username}`, "INFO"); } else { - this.log("ALREADY EXIST USER : " + res[0].username, "INFO"); + this.log(`ALREADY EXIST USER : ${res[0].username}`, "INFO"); } return res[1]; }); } - async randomMongoose(nb) { + async randomMongoose (nb) { try { - let tab = []; + const tab = []; const random = new users.random(); - let fixs = random.randomUser(nb); - for await (let user of fixs) { + const fixs = random.randomUser(nb); + for await (const user of fixs) { tab.push(await this.loadMongooseFixtures(user)); } return tab; @@ -80,10 +79,10 @@ class usersFixture extends nodefony.Fixture { } } - async runMongoose() { + async runMongoose () { try { - let tab = []; - for await (let user of users.default) { + const tab = []; + for await (const user of users.default) { tab.push(await this.loadMongooseFixtures(user)); } return tab; @@ -92,17 +91,17 @@ class usersFixture extends nodefony.Fixture { } } - loadMongooseFixtures(obj) { + loadMongooseFixtures (obj) { return new Promise(async (resolve, reject) => { try { let document = await this.entity.findOne({ username: obj.username }); if (document) { - this.log("ALREADY EXIST USER : " + obj.username, "INFO"); + this.log(`ALREADY EXIST USER : ${obj.username}`, "INFO"); } else { document = await new this.entity(obj).save(); - this.log("ADD DOCUMENT USER : " + obj.username, "INFO"); + this.log(`ADD DOCUMENT USER : ${obj.username}`, "INFO"); } return resolve(document); } catch (e) { diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/config/config.js b/demo/nodefony/src/bundles/users-bundle/Resources/config/config.js index 78cf9da..408928d 100644 --- a/demo/nodefony/src/bundles/users-bundle/Resources/config/config.js +++ b/demo/nodefony/src/bundles/users-bundle/Resources/config/config.js @@ -12,8 +12,8 @@ * GENERATE BY nodefony-starter BUILDER */ -//const crypto = require('crypto'); -const path = require('path'); +// const crypto = require('crypto'); +const path = require("path"); const readFile = function (Path) { try { return fs.readFileSync(Path, { @@ -25,13 +25,14 @@ const readFile = function (Path) { } }; const randomSecret = function () { - let sercretPath = path.resolve("config", "certificates", "ca", "private", "ca.key.pem"); + const sercretPath = path.resolve("config", "certificates", "ca", "private", "ca.key.pem"); return readFile(sercretPath); }; module.exports = { type: "sandbox", locale: "en_en", + /** * WATCHERS * @@ -74,14 +75,10 @@ module.exports = { }, jwt: { token: { - expiresIn: 900 + expiresIn: 900 // seconds }, refreshToken: { - expiresIn: 3600 + expiresIn: 3600 // seconds } - }, - swagger: require(path.resolve(__dirname, "..", "swagger", "config.js")), - - graphiql: require(path.resolve(__dirname, "..", "graphiql", "config.js")) - + } }; diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/config/routing.js b/demo/nodefony/src/bundles/users-bundle/Resources/config/routing.js index bd9bf01..e92a421 100644 --- a/demo/nodefony/src/bundles/users-bundle/Resources/config/routing.js +++ b/demo/nodefony/src/bundles/users-bundle/Resources/config/routing.js @@ -3,7 +3,7 @@ * =============================================================================== * ROUTING BUNDLE users-bundle * - * Copyright © /2019 | + * Copyright © /2019 | * * =============================================================================== * @@ -13,5 +13,5 @@ **/ - module.exports = {}; +module.exports = {}; diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/config/security.js b/demo/nodefony/src/bundles/users-bundle/Resources/config/security.js index 83d1937..c3bb22f 100644 --- a/demo/nodefony/src/bundles/users-bundle/Resources/config/security.js +++ b/demo/nodefony/src/bundles/users-bundle/Resources/config/security.js @@ -13,6 +13,7 @@ const cors = { module.exports = { security: { + /** * FIREWALL PROVIDER */ @@ -39,19 +40,12 @@ module.exports = { /** * FIREWALL Authorization */ - access_control: [{ - path: /^\/nodefony/, - roles: ["ROLE_MONITORING"], - requires_channel: "https", - /*allow_if: { - roles: ["ROLE_ADMIN", "ROLE_USER"] - }*/ - }], + access_control: [], firewalls: { // SECURITY AREA nodefony_area: { - pattern: /^\/secure/, + pattern: /^\/secure/u, provider: "nodefony", form_login: { login_path: "/login/secure", @@ -59,8 +53,8 @@ module.exports = { default_target_path: "/users" }, "passport-local": { - usernameField: 'username', - passwordField: 'passwd' + usernameField: "username", + passwordField: "passwd" }, logout: "/logout", context: null, @@ -68,24 +62,24 @@ module.exports = { }, // SECURITY AREA LOGIN API login_api_area: { - pattern: /^\/api\/jwt\/login/, + pattern: /^\/api\/jwt\/login/u, provider: "nodefony", "passport-local": { - usernameField: 'username', - passwordField: 'passwd' + usernameField: "username", + passwordField: "passwd" }, - stateless: true, + stateless: false, redirectHttps: true, crossDomain: cors }, // SECURITY AREA API api_area: { - pattern: /^\/api/, + pattern: /^\/api/u, redirectHttps: true, stateless: true, "passport-jwt": { algorithms: "RS256", - //secretOrKey:"Les sanglots longs Des violons De l’automne Blessent mon cœur D’une langueur Monotone." + // secretOrKey:"Les sanglots longs Des violons De l’automne Blessent mon cœur D’une langueur Monotone." certificats: { private: path.resolve("config", "certificates", "ca", "private", "ca.key.pem"), public: path.resolve("config", "certificates", "ca", "public", "public.key.pem") diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/config/webpack.config.js b/demo/nodefony/src/bundles/users-bundle/Resources/config/webpack.config.js index fe68eda..8fda331 100644 --- a/demo/nodefony/src/bundles/users-bundle/Resources/config/webpack.config.js +++ b/demo/nodefony/src/bundles/users-bundle/Resources/config/webpack.config.js @@ -1,12 +1,12 @@ const path = require("path"); -const webpack = require('webpack'); +const webpack = require("webpack"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const { merge -} = require('webpack-merge'); +} = require("webpack-merge"); // Default context -//const context = path.resolve(__dirname, "..", "public"); +// const context = path.resolve(__dirname, "..", "public"); const public = path.resolve(__dirname, "..", "public", "assets"); const package = require(path.resolve("package.json")); @@ -26,107 +26,115 @@ if (kernel.environment === "dev") { module.exports = merge(config, { - //context: context, + // context: context, target: "web", entry: { - users: ["./Resources/js/users.js"], - swagger: ["./Resources/swagger/swagger.js"], - graphiql: ["./Resources/graphiql/graphiql.jsx"] + users: ["./Resources/js/users.js"] }, output: { path: public, - publicPath: publicPath, + publicPath, filename: "./js/[name].js", + hashFunction: "xxhash64", library: "[name]", libraryExport: "default" }, externals: {}, resolve: { - extensions: ['.js', '.json', '.jsx', '.css', '.mjs'], + extensions: [".js", ".json", ".jsx", ".css", ".mjs"], + alias: { + "@modules": path.join(__dirname, "..", "..", "node_modules") + }, fallback: { "path": false, - "assert": false + "assert": false, + buffer: require.resolve("buffer/") } }, module: { rules: [{ - // BABEL TRANSCODE - test: /\.(jsx|mjs|js|es6)$/, - exclude: new RegExp("node_modules"), - use: [{ - loader: 'babel-loader', + // BABEL TRANSCODE + test: /\.(jsx|mjs|js|es6)$/, + exclude: new RegExp("node_modules"), + use: [{ + loader: "babel-loader", + options: { + // presets: ['@babel/preset-env', '@babel/preset-react'] + presets: [ + ["@babel/preset-env", { + modules: false + }], + "@babel/preset-react" + ] + } + }] + }, { + type: "javascript/auto", + test: /\.mjs$/, + use: [], + include: /node_modules/ + }, { + test: require.resolve("jquery"), + rules: [{ + loader: "expose-loader", + options: { + // expose: ['$', 'jQuery'], + exposes: [{ + globalName: "$", + override: true + }, { + globalName: "jQuery", + override: true + }] + } + }] + }, { + test: /\.(sa|sc|c)ss$/, + use: [ + // 'css-hot-loader', + MiniCssExtractPlugin.loader, + { + loader: "css-loader", options: { - //presets: ['@babel/preset-env', '@babel/preset-react'] - presets: [ - ['@babel/preset-env', { - modules: false - }], - '@babel/preset-react', - ], + sourceMap: true } - }] - }, { - type: 'javascript/auto', - test: /\.mjs$/, - use: [], - include: /node_modules/, - }, { - test: require.resolve('jquery'), - rules: [{ - loader: 'expose-loader', + }, { + loader: "sass-loader", options: { - //expose: ['$', 'jQuery'], - exposes: [{ - globalName: '$', - override: true, - }, { - globalName: 'jQuery', - override: true, - }] + sourceMap: true } - }] - }, { - test: /\.(sa|sc|c)ss$/, - use: [ - //'css-hot-loader', - MiniCssExtractPlugin.loader, - { - loader: "css-loader", - options: { - sourceMap: true - } - }, { - loader: "sass-loader", - options: { - sourceMap: true - } - } - ] - }, { - test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/, - type: 'asset/inline' - }, { - test: /\.svg$/, - use: [{ - loader: 'svg-inline-loader' - }], - }, { - // IMAGES - test: /\.(gif|png|jpe?g|svg)$/i, - type: 'asset/resource', - generator: { - filename: "images/[name][ext][query]", } + ] + }, { + test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/, + type: "asset/inline" + }, { + test: /\.svg$/, + use: [{ + loader: "svg-inline-loader" + }] + }, { + // IMAGES + test: /\.(gif|png|jpe?g|svg)$/i, + type: "asset/resource", + generator: { + filename: "images/[name][ext][query]" } - ] + }] }, plugins: [ + new webpack.ProvidePlugin({ + Buffer: ["buffer", "Buffer"] + }), new MiniCssExtractPlugin({ filename: "./css/[name].css" }), new webpack.DefinePlugin({ - 'process.env': { - 'NODE_ENV': JSON.stringify(process.env.NODE_ENV), + "process": { + platform: `'${process.platform}'` + }, + "process.env": { + "NODE_ENV": JSON.stringify(process.env.NODE_ENV), "NODE_DEBUG": JSON.stringify(debug), "GRAPHIQL": JSON.stringify(bundleConfig.graphiql), "SWAGGER": JSON.stringify(bundleConfig.swagger) diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/config/webpack/webpack.dev.config.js b/demo/nodefony/src/bundles/users-bundle/Resources/config/webpack/webpack.dev.config.js index 1a8aa90..efc5e6d 100644 --- a/demo/nodefony/src/bundles/users-bundle/Resources/config/webpack/webpack.dev.config.js +++ b/demo/nodefony/src/bundles/users-bundle/Resources/config/webpack/webpack.dev.config.js @@ -1,4 +1,4 @@ -const { CleanWebpackPlugin } = require('clean-webpack-plugin'); +const {CleanWebpackPlugin} = require("clean-webpack-plugin"); module.exports = { mode: "development", @@ -7,7 +7,7 @@ module.exports = { new CleanWebpackPlugin({ verbose: kernel.debug }) - //new webpack.NamedModulesPlugin(), - //new webpack.HotModuleReplacementPlugin() + // new webpack.NamedModulesPlugin(), + // new webpack.HotModuleReplacementPlugin() ] }; diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/config/webpack/webpack.prod.config.js b/demo/nodefony/src/bundles/users-bundle/Resources/config/webpack/webpack.prod.config.js index 7af77ef..609785c 100644 --- a/demo/nodefony/src/bundles/users-bundle/Resources/config/webpack/webpack.prod.config.js +++ b/demo/nodefony/src/bundles/users-bundle/Resources/config/webpack/webpack.prod.config.js @@ -1,6 +1,6 @@ // WEBPACK PROD CONFIGURATION -const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); -const TerserPlugin = require('terser-webpack-plugin'); +// const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); +const TerserPlugin = require("terser-webpack-plugin"); module.exports = { mode: "production", @@ -18,13 +18,14 @@ module.exports = { ] }, plugins: [ - new OptimizeCssAssetsPlugin({ + + /* new OptimizeCssAssetsPlugin({ cssProcessorOptions: { discardComments: { removeAll: true } }, canPrint: true - }) + })*/ ] }; diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/graphiql/config.js b/demo/nodefony/src/bundles/users-bundle/Resources/graphiql/config.js deleted file mode 100644 index 5507ce4..0000000 --- a/demo/nodefony/src/bundles/users-bundle/Resources/graphiql/config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - projectName: "Nodefony User", - logo: "/app/images/app-logo.png", - url:"/api/graphql/users" -}; diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/graphiql/graphiql.jsx b/demo/nodefony/src/bundles/users-bundle/Resources/graphiql/graphiql.jsx deleted file mode 100644 index 4a58ce8..0000000 --- a/demo/nodefony/src/bundles/users-bundle/Resources/graphiql/graphiql.jsx +++ /dev/null @@ -1,60 +0,0 @@ -import * as React from "react"; -import { render } from "react-dom"; -import GraphiQL from "graphiql"; -import "graphiql/graphiql.min.css"; -import "./index.css"; -const NODE_ENV = process.env.NODE_ENV ; -const DEBUG = process.env.DEBUG ; -const config = process.env.GRAPHIQL ; - -const URL = config.url; - -function graphQLFetcher(graphQLParams) { - return fetch(URL, { - method: 'post', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify(graphQLParams), - credentials: 'same-origin', - }).then(response => response.json().then((ele)=>{ - console.log(ele) - return ele.data; - })); -} - -const defaultQuery = ` -{ - user(username: "admin") { - username - surname - name - } - users { - username - name - surname - updatedAt - roles - } -} -`; - -const container = document.getElementById("graphiql"); -const Logo = () => { - return - - - {config.projectName} - - ; -} - -// See GraphiQL Readme - Advanced Usage section for more examples like this -GraphiQL.Logo = Logo; - -render( - , - container -); diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/graphiql/index.css b/demo/nodefony/src/bundles/users-bundle/Resources/graphiql/index.css deleted file mode 100644 index dc7ae58..0000000 --- a/demo/nodefony/src/bundles/users-bundle/Resources/graphiql/index.css +++ /dev/null @@ -1,7 +0,0 @@ -body { - margin: 0; -} - -#graphiql { - height: 100vh; -} \ No newline at end of file diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/scss/awesome/font-awesome.config.js b/demo/nodefony/src/bundles/users-bundle/Resources/scss/awesome/font-awesome.config.js index 8d7fe8e..453b89a 100644 --- a/demo/nodefony/src/bundles/users-bundle/Resources/scss/awesome/font-awesome.config.js +++ b/demo/nodefony/src/bundles/users-bundle/Resources/scss/awesome/font-awesome.config.js @@ -1,11 +1,11 @@ - module.exports = { - styles: { - "mixins": true, +module.exports = { + styles: { + "mixins": true, - "core": true, - "icons": true, + "core": true, + "icons": true, - "larger": true, - "path": true, - } - }; \ No newline at end of file + "larger": true, + "path": true + } +}; diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/scss/users.scss b/demo/nodefony/src/bundles/users-bundle/Resources/scss/users.scss index 9c7e844..260b505 100644 --- a/demo/nodefony/src/bundles/users-bundle/Resources/scss/users.scss +++ b/demo/nodefony/src/bundles/users-bundle/Resources/scss/users.scss @@ -1,16 +1,7 @@ @import url(https://fonts.googleapis.com/css?family=Comfortaa); @import url(https://fonts.googleapis.com/css?family=Gochi+Hand); -.hello { - text-align: center; -} - -.hello h1 { - font-family: 'Gochi Hand', cursive; - color: #0167b8; - letter-spacing: 0; - font-size: 4em; - text-transform: none; +body{ } .nodefony{ @@ -25,6 +16,14 @@ font-size: 4em; text-transform: none; } +.nodefony h3 { + text-align: center; + font-family: 'Gochi Hand', cursive; + color: #0167b8; + letter-spacing: 0; + font-size: 1.2em; + text-transform: none; +} pre { display: block; diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/swagger/config.js b/demo/nodefony/src/bundles/users-bundle/Resources/swagger/config.js deleted file mode 100644 index 85599c6..0000000 --- a/demo/nodefony/src/bundles/users-bundle/Resources/swagger/config.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = { - projectName: "Nodefony User", - logo: "/app/images/app-logo.png", - urls: [{ - url: "/api/users/documentation", - name: "users" - }, { - url: "/api/jwt/documentation", - name: "login" - }], - primaryName: "login" -}; \ No newline at end of file diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/swagger/openapi/login.js b/demo/nodefony/src/bundles/users-bundle/Resources/swagger/openapi/login.js index 2f319f1..78b5352 100644 --- a/demo/nodefony/src/bundles/users-bundle/Resources/swagger/openapi/login.js +++ b/demo/nodefony/src/bundles/users-bundle/Resources/swagger/openapi/login.js @@ -67,14 +67,14 @@ const openapi = { summary: "Get OpenAPI (OAS 3.0) configuration", tags: ["JSON WEB TOKEN"], responses: { - '200': { + "200": { description: "A paged array of users" }, default: { $ref: "#/components/responses/default" } } - }, + } }, "/api/jwt/login": { post: { @@ -92,7 +92,7 @@ const openapi = { required: true }], responses: { - '200': { + "200": { description: "get Authentication tokens", content: { "application/json": { @@ -104,7 +104,7 @@ const openapi = { properties: { result: { $ref: "#/components/schemas/jwt" - }, + } } }] }, @@ -172,12 +172,12 @@ const openapi = { parameters: [{ name: "refreshToken", description: "Authentication refreshToken", - in: "header", - //required: true + in: "header" + // required: true }], requestBody: { - description: ``, - //required: true, + description: "", + // required: true, content: { "application/x-www-form-urlencoded": { schema: { @@ -190,10 +190,10 @@ const openapi = { required: ["refreshToken"] } } - }, + } }, responses: { - '200': { + "200": { description: "Regenerated Token" }, default: { @@ -213,7 +213,7 @@ const openapi = { required: true }], responses: { - '200': { + "200": { description: "logout user" }, default: { @@ -222,9 +222,9 @@ const openapi = { }, security: [{ jwtAuth: "" - }], + }] } - }, + } }, tags: [{ name: "JSON WEB TOKEN", diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/swagger/openapi/users.js b/demo/nodefony/src/bundles/users-bundle/Resources/swagger/openapi/users.js index ff139eb..1be8c19 100644 --- a/demo/nodefony/src/bundles/users-bundle/Resources/swagger/openapi/users.js +++ b/demo/nodefony/src/bundles/users-bundle/Resources/swagger/openapi/users.js @@ -84,21 +84,21 @@ const openApi = { required: true }], responses: { - '200': { + "200": { description: "User Description", content: { "application/json": { schema: { allOf: [{ $ref: "#/components/schemas/users-api" - }, { + }, { type: "object", properties: { result: { $ref: "#/components/schemas/user" - }, + } } - }] + }] } } } @@ -114,7 +114,7 @@ const openApi = { summary: "Get OpenAPI (OAS 3.0) configuration", tags: ["users"], responses: { - '200': { + "200": { description: "OpenAPI (OAS 3.0) configuration", content: { "application/json": {} @@ -140,7 +140,7 @@ const openApi = { required: false }], responses: { - '200': { + "200": { description: "List or filter Users", content: { "application/json": { @@ -164,7 +164,7 @@ const openApi = { } } } - }, + } } }] } @@ -179,24 +179,24 @@ const openApi = { post: { summary: "Create user", requestBody: { - description: `Parameters **users** schema`, + description: "Parameters **users** schema", required: true, content: { "application/json": { schema: { - $ref: '#/components/schemas/user' + $ref: "#/components/schemas/user" } }, "application/x-www-form-urlencoded": { schema: { - $ref: '#/components/schemas/user' + $ref: "#/components/schemas/user" } } - }, + } }, tags: ["users"], responses: { - '200': { + "200": { description: "get headers request" }, default: { @@ -211,7 +211,7 @@ const openApi = { jwtAuth: "" }], responses: { - '200': { + "200": { description: "get headers request" }, default: { @@ -219,7 +219,7 @@ const openApi = { } } } - }, + } }, tags: [{ diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/swagger/swagger.css b/demo/nodefony/src/bundles/users-bundle/Resources/swagger/swagger.css deleted file mode 100644 index 45e474e..0000000 --- a/demo/nodefony/src/bundles/users-bundle/Resources/swagger/swagger.css +++ /dev/null @@ -1,18 +0,0 @@ -.swagger-ui .topbar { - background: #43853d; - /* Old browsers */ - background: #43853d; - /* Old browsers */ - background: -moz-linear-gradient(left, #0337ab 0%, #167b87 41%); - /* FF3.6+ */ - background: -webkit-linear-gradient(left, #0337ab 0%, #167b87 41%); - /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(left, #0337ab 0%, #167b87 41%); - /* Opera 11.10+ */ - background: -ms-linear-gradient(left, #0337ab 0%, #167b87 41%); - /* IE10+ */ - background: linear-gradient(to right, #0337ab 0%, #167b87 41%); - /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0167b8', endColorstr='#0337ab',GradientType=0 ); - /* IE6-9 */ -} diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/swagger/swagger.js b/demo/nodefony/src/bundles/users-bundle/Resources/swagger/swagger.js deleted file mode 100644 index d5b18df..0000000 --- a/demo/nodefony/src/bundles/users-bundle/Resources/swagger/swagger.js +++ /dev/null @@ -1,58 +0,0 @@ -import SwaggerUI from 'swagger-ui'; -import { - SwaggerUIBundle, - SwaggerUIStandalonePreset -} from "swagger-ui-dist"; - -import "swagger-ui/dist/swagger-ui.css"; -import "./swagger.css"; - -const configSwagger = process.env.SWAGGER; - -class Swagger { - constructor() { - this.config = configSwagger; - this.initialize(); - this.changeLogo(); - } - - changeLogo() { - window.addEventListener("load", () => { - setTimeout(() => { - // Section 01 - Set url link - const logo = document.getElementsByClassName('link'); - logo[0].href = "/"; - logo[0].target = "_blank"; - // Section 02 - Set logo - logo[0].children[0].alt = this.config.projectName; - logo[0].children[0].src = this.config.logo; - }); - }); - } - - initialize() { - this.swagger = SwaggerUI({ - //url: "/api/users/documentation", - urls: this.config.urls, - "urls.primaryName": this.config.primaryName, - dom_id: '#swagger', - //defaultModelsExpandDepth: -1, - deepLinking: true, - presets: [ - SwaggerUI.presets.apis, - SwaggerUIStandalonePreset - ], - plugins: [ - SwaggerUIBundle.plugins.DownloadUrl - ], - layout: "StandaloneLayout", - requestInterceptor: function (request) { - //console.log('[Swagger] intercept try-it-out request'); - //request.headers.jwt = localstorage; - return request; - } - }); - } -} - -export default new Swagger(); diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/translations/login.en_en.yml b/demo/nodefony/src/bundles/users-bundle/Resources/translations/login.en_en.yml index 3879b81..0c0e354 100644 --- a/demo/nodefony/src/bundles/users-bundle/Resources/translations/login.en_en.yml +++ b/demo/nodefony/src/bundles/users-bundle/Resources/translations/login.en_en.yml @@ -2,11 +2,13 @@ security : Security login : Sign In +signin : Sign In logout : Sign Out submit : Submit surname : Surname name : Name user_name : User -register : Register +register : Sign Up +signup : Sign Up update : Update diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/translations/login.fr_fr.yml b/demo/nodefony/src/bundles/users-bundle/Resources/translations/login.fr_fr.yml index eb20892..0062f29 100644 --- a/demo/nodefony/src/bundles/users-bundle/Resources/translations/login.fr_fr.yml +++ b/demo/nodefony/src/bundles/users-bundle/Resources/translations/login.fr_fr.yml @@ -2,6 +2,7 @@ security : Securité login : Se Connecter +signin : Se Connecter logout : Se Déconnecter submit : Valider surname : Nom @@ -9,4 +10,5 @@ name : Prénom username : Utilisateur register : "S'enregistrer" +signup : "S'enregistrer" update : Modifer diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/views/documentation/base.html.twig b/demo/nodefony/src/bundles/users-bundle/Resources/views/documentation/base.html.twig deleted file mode 100644 index 4cfe1a7..0000000 --- a/demo/nodefony/src/bundles/users-bundle/Resources/views/documentation/base.html.twig +++ /dev/null @@ -1,38 +0,0 @@ - - - - {% block head %}{% endblock %} - {% block meta %} - - - - - - - - {% endblock %} - {% block description %} - - {% endblock %} - - {% block title %}{{nodefony.name|escape}}{% endblock %} - - {% block stylesheets %} - - - {% endblock %} - - - {% block header %} - {{ render( controller("documentation:documentation:header" )) }} - {% endblock %} - {% block body %}{% endblock %} - {% block footer %} - {{ render( controller("documentation:documentation:footer" )) }} - {% endblock %} - {% block javascripts %} - - - {% endblock %} - - diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/views/documentation/index.html.twig b/demo/nodefony/src/bundles/users-bundle/Resources/views/documentation/index.html.twig deleted file mode 100644 index 806425d..0000000 --- a/demo/nodefony/src/bundles/users-bundle/Resources/views/documentation/index.html.twig +++ /dev/null @@ -1,25 +0,0 @@ -{% extends './base.html.twig' %} -{{trans_default_domain("documentation")}} - -{% block stylesheets %} - -{% endblock %} - -{% block body %} - -
-
- {% include './navbar.html.twig' with { - 'route' : nodefony.route - } %} -
- {{readme}} -
-
-
- - {% block javascripts %} - - {% endblock %} - -{% endblock %} diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/views/documentation/navbar.html.twig b/demo/nodefony/src/bundles/users-bundle/Resources/views/documentation/navbar.html.twig deleted file mode 100644 index 66c9c2c..0000000 --- a/demo/nodefony/src/bundles/users-bundle/Resources/views/documentation/navbar.html.twig +++ /dev/null @@ -1,12 +0,0 @@ -
- - - -
diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/views/documentation/slides.html.twig b/demo/nodefony/src/bundles/users-bundle/Resources/views/documentation/slides.html.twig deleted file mode 100644 index 467e9f5..0000000 --- a/demo/nodefony/src/bundles/users-bundle/Resources/views/documentation/slides.html.twig +++ /dev/null @@ -1,37 +0,0 @@ -{% extends '../base.html.twig' %} -{{trans_default_domain("documentation")}} - -{% block stylesheets %} - - -{% endblock %} - -{% block body %} - -
-
-
-
- -

Welcome Users Bundle

-
-
-
-
-
-
- - {% block javascripts %} - - - - - {% endblock %} - -{% endblock %} diff --git a/demo/nodefony/src/bundles/users-bundle/Resources/views/footer.html.twig b/demo/nodefony/src/bundles/users-bundle/Resources/views/footer.html.twig index 2e7700b..86b9247 100644 --- a/demo/nodefony/src/bundles/users-bundle/Resources/views/footer.html.twig +++ b/demo/nodefony/src/bundles/users-bundle/Resources/views/footer.html.twig @@ -1,9 +1,7 @@ -