{"id":22428469,"url":"https://github.com/momsfriendlydevco/doop","last_synced_at":"2025-04-13T15:56:02.512Z","repository":{"id":18854039,"uuid":"63403216","full_name":"MomsFriendlyDevCo/Doop","owner":"MomsFriendlyDevCo","description":"The MEVN micro-framework used by MomsFriendlyDevCo","archived":false,"fork":false,"pushed_at":"2023-03-28T05:03:47.000Z","size":27450,"stargazers_count":4,"open_issues_count":5,"forks_count":5,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-12T03:56:37.752Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MomsFriendlyDevCo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-07-15T07:59:07.000Z","updated_at":"2024-04-20T22:57:03.000Z","dependencies_parsed_at":"2023-01-11T20:29:59.010Z","dependency_job_id":null,"html_url":"https://github.com/MomsFriendlyDevCo/Doop","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MomsFriendlyDevCo%2FDoop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MomsFriendlyDevCo%2FDoop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MomsFriendlyDevCo%2FDoop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MomsFriendlyDevCo%2FDoop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MomsFriendlyDevCo","download_url":"https://codeload.github.com/MomsFriendlyDevCo/Doop/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248741144,"owners_count":21154251,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-05T20:14:54.322Z","updated_at":"2025-04-13T15:56:02.488Z","avatar_url":"https://github.com/MomsFriendlyDevCo.png","language":"Vue","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\t\u003cimg src=\"https://github.com/MomsFriendlyDevCo/Doop/raw/master/assets/doop.png\"\u003e\n\u003c/p\u003e\n\u003cbr\u003e\u003cbr\u003e\n\nDoop@3!\n=======\nThe MEVN micro-framework used by [MomsFriendlyDevCo](http://mfdc.biz).\n\n**If we hit that bullseye, the rest of the dominoes will fall like a house of cards. Checkmate - Zapp Brannigan**\n\n\nBasic principles:\n\n* Doop tries to have the lowest understanding cost possible\n* Doop units are designed to be as generic and transferable between projects as possible\n\n\nTerminology:\n\n* The Doop documentation endeavour to use requirement levels that abide by the definitions specified by [RFC 2119 (Requirement Levels)](http://www.ietf.org/rfc/rfc2119.txt)\n\n\nMajor releases:\n\n* **[V3 - Cubert](https://github.com/MomsFriendlyDevCo/Doop/tree/master)** - Current stable release (Vue@3 compatible frontend)\n* **[V2 - Bender](https://github.com/MomsFriendlyDevCo/Doop/tree/v2)** - Previous stable release (Vue@2 frontend)\n* **[V1 - Amy](https://github.com/MomsFriendlyDevCo/Doop/releases/tag/v1)** - Initial Doop implementation\n\n\nGeneral concept\n===============\nDoop is made up of two types of files. Files ending in `.vue` are frontend Vue framework(esk) and `.doop` are backend Express framework(esk).\n\nWithin these two file types there can be blocks of code which expose things like controllers, schemas, models, CSS, HTML templates and so on.\n\nGenerally all areas of an application are exposed at the root level (e.g. `widgets/`) with shared components living inside directories such as `filters`, `widgets` and so on.\n\n\nNPM modules\n-----------\nMFDC relies on various common NPM modules across all its projects.\n\nYou can read more about how MFDC structures its project in the [Momsronomicon](https://github.com/MomsFriendlyDevCo/Momsronomicon/blob/master/devstack-node.md).\n\n\nProject directories and files\n-----------------------------\nThe project tree breakdown is listed below. For each path an 'edit chance' is given (i.e. the possibility of the developer needing to change the contents of that directory) and a brief description.\n\n| Path or Glob                   | Description\n|--------------------------------|----------------------------------\n| `/`                            | The project root\n| `/app/`                        | Core initialization files\n| `/assets/`                     | Generic static assets such as logo images and favicons\n| `/build/`                      | Build scripts\n| `/cache/`                      | Generic cache handling\n| `/config/index.js`             | Base config file showing default variables subsequently overridden by each `NODE_ENV` config file\n| `/config/*.js`                 | Other config files, loaded selectively based on the `NODE_ENV` environment variable\n| `/config/private.js`           | Private config details. This file is listed in `.gitignore` and should *never* be checked in to GitHub as it can contain private details - e.g. database connection passwords or API keys\n| `/config/production.conf.js`   | Production server config details. This should include settings to enable all minimizers and other optimizations for production-ready code\n| `/config/`                     | Storage for all config scripts read at startup, see `config/index.js` for default config setup. Other files are read depending on the `NODE_ENV` setting\n| `/dashboard/`                  | Front end application entry point\n| `/data/`                       | Generic data for the project - could contain resource files used during automated builds\n| `/db/`                         | The main database driver and schema loader\n| `/debug/`                      | Various debugging utilities\n| `/directives/`                 | Shared frontend Vue directives\n| `/dist/`                       | Generated files directory. Do not edit the contents of this directory as it is auto-generated by Gulp\n| `/docs/`                       | Any miscellaneous files not relevant to the operation of the project but which need to be retained e.g. scope documents, ERD diagrams\n| `/errors/`                     | Error handling and reporting\n| `/filters/`                    | Shared frontend Vue filters\n| `/fonts.fa5/`                  | Font-Awesome 5\n| `/fonts/`                      | Other font files\n| `/.git/`                       | Git storage and meta information\n| `/gulpfile.js`                 | Main Gulp build-system config file\n| `/layouts/`                    | Global page layout templates\n| `/layouts/main.html`           | Default page layout template\n| `/middleware/db.*.doop`        | Database middleware\n| `/middleware/`                 | Express and Database middleware\n| `/middleware/express.*.doop`   | Express middleware\n| `/node_modules/`               | Install directory for all NPM controlled packages\n| `/scenario/`                   | Database scenario templates\n| `/server/`                     | Server bootstrapping scripts\n| `/services/`                   | Shared frontend Vue services (usually available as `vm.$SERVICE`)\n| `/tests/`                      | Optional testing files\n| `/theme/bootstrap-extensions/` | Various CSS files which extend Bootstrap@4\n| `/theme/`                      | Site theme\n| `/theme/theme-overrides/`      | Various CSS files which fix issues with the main theme\n| `/users`                       | User schemas and management\n| `/vendors`                     | Externally supported vendor scripts\n| `/widgets`                     | Shared frontend Vue services\n| `/**/*.mjs`                    | Isomorphic JS files available to frontend/backend as required via `import` / `require` respectively\n| `/**/*.doop`                   | Backend Doop modules\n| `/**/*.gulp.js`                | Global Gulp build-system task files\n| `/**/*.vue`                    | Frontend Vue modules\n\n\nModules\n=======\nThe following modules are provided separately and can be optionally included within a project.\n\n| Module                     | Default | Description                                                             |\n|----------------------------|---------|-------------------------------------------------------------------------|\n| `@doop/service-components` | Yes     | `$components` service allowing cross talk and enumeration of components |\n| `@doop/service-data`       | Yes     | Various data manipulation service components                            |\n| `@doop/service-toast`      | Yes     | `$toast` service to display simple UI messages                          |\n| `@doop/service-data`       | Yes     | Various data I/O services - `$assign`, `${has,get,set}Path`, `$push`    |\n| `@doop/service-morph`      | Yes     | Animation library to transform DOM components with animations           |\n| `@doop/directive-jump`     | Yes     | `v-jump` directive to easily scroll around pages using `\u003ca/\u003e` style anchors |\n\n\nContent Blocks\n==============\n\nBackend .doop files\n--------------------\nDoop backend files are made of `\u003cscript/\u003e` blocks which execute when a named event is emitted (via `app.emit(event)`).\n\nFor example simple ReST endpoints endpoint are registered like so:\n\n```vue\n\u003cscript lang=\"js\" backend endpoint\u003e\n/**\n* This function does something\n*/\napp.get('/api/foobar', (req, res) =\u003e {\n\t// Do something //\n});\n\u003c/script\u003e\n```\n\n\nDatabase schemas are registered similarly:\n\n```vue\n\u003cscript lang=\"js\" backend schema\u003e\napp.middleware.db.schema('widgets', {\n\ttitle: String,\n});\n\u003c/script\u003e\n```\n\n\nMore advanced functions can be registered in a specific place within the load order (see the [server file](`./skeleton/server/index.js`) for the exact load order)\n\n```vue\n\u003cscript lang=\"js\" backend on=\"postServer\"\u003e\n// Server has now loaded\n\u003c/script\u003e\n```\n\nSome `\u003cscript/\u003e` attributes are provided which makes typing a little less tedious:\n\n| Block        | Alias of                   | Definition                   |\n|--------------|----------------------------|------------------------------|\n| `endpoint`   | `\u003cscript on=\"endpoints\"\u003e`  | An API endpoint              |\n| `middleware` | `\u003cscript on=\"middleware\"\u003e` | Database / server middleware |\n| `schema`     | `\u003cscript on=\"schemas\"\u003e`    | A database schema            |\n\n\nFor the `server` block the `on` event must be specified and can contain a CSV of multiple events.\n\nFor a reference of which events fire and in what order see the [server](./server/index.js) and [gulpfile](./gulpfile.js).\n\n\nFrontend .vue files\n--------------------\nVue files follow the regular Vue [Single-Page-Component](https://vue-loader.vuejs.org/spec.html) format with the following block types:\n\n| Block       | Contents                   | Definition                                                                                                               |\n|-------------|----------------------------|--------------------------------------------------------------------------|\n| `script`    | Frontend javascript        | A Vue frontend definition (limit of one block per file)                  |\n| `style`     | CSS                        | Global level CSS                                                         |\n| `template`  | HTML                       | Template file (the file name is used to match it against the controller) |\n\n\nFor example the following file registers a Vue component with the name `widget`:\n\n```vue\n\u003cscript lang=\"js\" frontend\u003e\napp.component('widget', {\n\t// Vue component definition\n})\n\u003c/script\u003e\n```\n\n\n`.vue` files can also contain an optional properties which gets specical treatment during the component load phase:\n\n```vue\n\u003cscript lang=\"js\" frontend\u003e\napp.component('ordersEdit', {\n\troute: '/orders/:id',                 // Set up a route for this component automatically\n\trouteRequiresAuth: true,              // Require a session to access this component (the default), otherwise let guest users view\n\t// ... Vue component definition ... //\n})\n\u003c/script\u003e\n```\n\n\nSpecial component properties supported by Doop:\n\n| Property            | Type    | Default | Description                                                                  |\n|---------------------|---------|---------|------------------------------------------------------------------------------|\n| `route`             | String  |         | Auto-installed route to access the component                                 |\n| `routeRequiresAuth` | Boolean | `true`  | Whether the route should redirect to the login page if no session is present |\n\n\nStandard frontend component registration types are:\n\n| Type               | Syntax example                                                | Description                                              |\n|--------------------|---------------------------------------------------------------|----------------------------------------------------------|\n| Vue Component      | `app.component('name', { ... Vue Component dedinition ... })` | Register a Vue frontend component (`route` key optional) |\n| Doop / Vue filter  | `app.filter('name', (value, options) =\u003e {}`                   | Register a filter function                               |\n| Doop / Vue service | `app.service('$name', { ... definition ... })`                | Register a service                                       |\n\n\n**Notes:**\n* Names of exported items (such as components, filters, services and templates) are all automatically derive from the filename and transformed via CamelCase.  The name can be overridden by specifying the name attribute e.g. `\u003cservice name=\"myService\"/\u003e` to export as `vm.$myService`.\n* Services are accessible via either `vm.$SERVICE` or `app.service.$SERVICE`\n* All registered filters are likewise available via `vm.$filters.FILTER` or `app.filter.FILTER`\n\n\nSyntax\n------\n\nAll `.vue` files are compiled via Babel and executed with the following presets:\n\n* [babel-preset-env](https://babeljs.io/docs/en/babel-preset-env)\n* [babel-plugin-proposal-optional-chaining](https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining)\n\nIn essence this is really just an in-built version of the [lodash.get](https://lodash.com/docs#get) function wrapped in regular JavaScript syntax.\n\n```javascript\n// Assuming:\nvar obj = {\n\tfoo: {\n\t\tbar: {\n\t\t\tbaz: 42,\n\t\t},\n\t},\n};\n\nvar baz = obj?.foo?.bar?.baz; //= 42\nvar nonExistant = obj?.qux?.baz; //= undefined\n```\n\n\n* [babel-plugin-proposal-pipeline-operator](https://babeljs.io/docs/en/babel-plugin-proposal-pipeline-operator) using the [#F sharp standard](https://github.com/valtech-nyc/proposal-fsharp-pipelines)\n\nChain multiple functions in a pipeline using something like Promise / arrow function syntax:\n\n```javascript\nvar result = 'hello'\n\t|\u003e doubleSay\n\t|\u003e capitalize\n\t|\u003e x =\u003e exclaim('Howdy or', x);\n```\n\n\n\nAPI\n===\n\nBackend\n--------\nDoop is exposed as a global level `app` object which contains the following functions:\n\n\napp\n---\nThe App object is a global, available everywhere in the project. It is a mutated version of the [ExpressJS App object](http://expressjs.com/en/4x/api.html#app) and [eventer](https://github.com/MomsFriendlyDevCo/eventer) classes.\n\n\napp.cache\n---------\nGlobally available instance of [Generic-Cache](https://github.com/MomsFriendlyDevCo/generic-cache)\n\n\napp.config\n----------\nAn object used to hold the calculated contents of the `/config` files. This is typically a combination of the main `index.js` file, any `NODE_ENV` specific files and the `private.js` file. To see the config of the profile you are currently using run `gulp app.config`.\n\n\napp.db OR db\n------------\nIn a typical Doop deployment this object represents an object of all loaded models. This may not be the case in all projects, depending on the database driver used.\n\n`db` is also registered as a global for convenience.\n\n\napp.emit(event, args...)\n------------------------\nEmit an event using [eventer](https://github.com/MomsFriendlyDevCo/eventer).\n\n\napp.log(...msg)\n---------------\nVarious logging functionality. Try to use `app.log()` instead of `console.log()` as text output via it is properly prefixed to the running file name.\n\n\napp.log.as(name, ...msg)\n------------------------\nModule name prefixed version of `app.log()`.\n\n\napp.log.colors\n--------------\nGlobally available version of [Chalk](https://github.com/chalk/chalk).\n\n\napp.log.dump(...msg)\n--------------------\nGlobally available version of [dumper.js](https://github.com/ziishaned/dumper.js)\n\n\napp.log.debug(...msg)\n---------------------\nGlobally available version of [debug](https://github.com/visionmedia/debug)\n\n\napp.log.error(Error)\n--------------------\nGlobally available version of [Crash](https://github.com/MomsFriendlyDevCo/crash).\nUse `app.log.errorCrash(Error)` to perform a fatal error.\n\n\napp.log.warn(...msg)\n--------------------\nSame as `app.log()` but with a \"[WARNING]\" prefix.\n\n\napp.log.warn.as(module, ...msg)\n-------------------------------\nPrefixed version of `app.log.warn()`\n\n\napp.middleware\n--------------\nIn a typical Doop deployment this object represents an object of available middleware. Use `app.middleware.express` or `app.middleware.db` for the Express and database middlewares respectively.\n\n\napp.on(event, handler)\n----------------------\nRegister an event listener using [eventer](https://github.com/MomsFriendlyDevCo/eventer).\n\n\n\nTesting + Debugging\n===================\n\nUnit tests\n----------\nLarger projects can populate the `/tests/` directory with [Mocha](https://mochajs.org) + [Chai](http://chaijs.com/api/bdd) test cases. Tests can also be specified per-unit by adding any file matching the glob `*.test.js` within their unit directory.\n\nTo run a Unit test you will need to have Mocha installed (`sudo npm i -g mocha`). Either run mocha with no specified files to process *all* test files or specify the specific test file(s) you wish Mocha to examine as command line arguments.\n\nRun the *all* the tests with mocha in the project root directory with `mocha`.\n\n**TIP:** Unit tests can be skipped temporarily by either adding an 'x' before `describe` / `it` or adding `.skip` as a suffix. e.g. To temporarily skip a test rename the function `describe('something something')` to `xdescribe('something something')` or `describe.skip('something something')`.\n**TIP::** As with the above you can also force Mocha to *only* run one test - this is useful if your test is deeply nested within an existing file and you don't want to add `skip` to each other case. To use this add `.only` as a suffix for the `describe` / `it` declaration. e.g. `it('should do this', function() { ... })` becomes `it.only('should do this', function() { ... })`.\n\n\nCommand line debugging\n----------------------\nDoop, like most modules, responds to the `DEBUG` flag used by the [Debug](https://github.com/visionmedia/debug) module. This turns on verbose logging when running within a console.\nThe `DEBUG` variable can be set to the specific module you would like to log, a number of them via comma-separated-values or a glob expression. For example `DEBUG=doop gulp` runs Gulp and tells Doop to run in debug mode.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmomsfriendlydevco%2Fdoop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmomsfriendlydevco%2Fdoop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmomsfriendlydevco%2Fdoop/lists"}