{"id":18972073,"url":"https://github.com/ngx-rocket/core","last_synced_at":"2025-04-19T16:11:53.351Z","repository":{"id":20484633,"uuid":"90010144","full_name":"ngx-rocket/core","owner":"ngx-rocket","description":":factory: Core generator for ngX-Rocket add-ons","archived":false,"fork":false,"pushed_at":"2022-11-28T14:58:40.000Z","size":1955,"stargazers_count":8,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-04-14T21:50:49.373Z","etag":null,"topics":["addon","core","generator","ngx","ngx-rocket","rocket","template","yeoman"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ngx-rocket.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-02T08:36:04.000Z","updated_at":"2022-02-06T16:11:47.000Z","dependencies_parsed_at":"2022-08-18T05:15:21.731Z","dependency_job_id":null,"html_url":"https://github.com/ngx-rocket/core","commit_stats":null,"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngx-rocket%2Fcore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngx-rocket%2Fcore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngx-rocket%2Fcore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngx-rocket%2Fcore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ngx-rocket","download_url":"https://codeload.github.com/ngx-rocket/core/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249220842,"owners_count":21232421,"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":["addon","core","generator","ngx","ngx-rocket","rocket","template","yeoman"],"created_at":"2024-11-08T15:06:38.154Z","updated_at":"2025-04-16T08:33:48.738Z","avatar_url":"https://github.com/ngx-rocket.png","language":"JavaScript","readme":"# :rocket: ngx-rocket/core\n\n[![NPM version](https://img.shields.io/npm/v/@ngx-rocket/core.svg)](https://www.npmjs.com/package/@ngx-rocket/core)\n[![Build Status](https://github.com/ngx-rocket/core/workflows/build/badge.svg)](https://github.com/ngx-rocket/core/actions)\n![Node version](https://img.shields.io/node/v/@ngx-rocket/core.svg)\n[![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\n\u003e Core generator for creating ngX-Rocket add-ons\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n## Table of Contents\n\n- [Usage](#usage)\n- [Concepts](#concepts)\n  - [Prompts and properties](#prompts-and-properties)\n  - [Templates](#templates)\n  - [File prefix rules](#file-prefix-rules)\n    - [Conditional prefix](#conditional-prefix)\n    - [Action prefix](#action-prefix)\n  - [Advanced customization](#advanced-customization)\n  - [Generating only tools](#generating-only-tools)\n  - [Standalone note](#standalone-note)\n  - [Fullstack mode](#fullstack-mode)\n- [API](#api)\n  - [Static methods/properties](#static-methodsproperties)\n    - [`Generator.make(options)`](#generatormakeoptions)\n    - [`Generator.defaultPrefixRules`](#generatordefaultprefixrules)\n    - [`Generator.sharedProps`](#generatorsharedprops)\n    - [`Generator.shareProps(props)`](#generatorsharepropsprops)\n  - [Instance properties](#instance-properties)\n    - [`sharedProps` (read-only)](#sharedprops-read-only)\n    - [`shareProps(props)`](#sharepropsprops)\n    - [`isStandalone` (read-only)](#isstandalone-read-only)\n    - [`isFullstack` (read-only)](#isfullstack-read-only)\n    - [`packageManager` (read-only)](#packagemanager-read-only)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Usage\n\nThis package extends [Yeoman](https://yeoman.io) base generator with all the boilerplate needed to create\n[ngX-Rocket add-ons](https://github.com/ngx-rocket/addon-example), and even more.\n\nFirst install the dependency:\n```bash\nnpm install --save @ngx-rocket/core\n```\n\nThen create a new add-on generator like this:\n```javascript\n'use strict';\nconst Generator = require('@ngx-rocket/core');\nmodule.exports = Generator.make({ baseDir: __dirname });\n```\n\nAdd some template files in a `templates/` folder and you're done.\n\nCongratulations on making your first Yeoman generator! :tada:\n\n## Concepts\n\nThis package allows you to create advanced [Yeoman](https://yeoman.io) generators that can be used as\n[ngX-Rocket](https://github.com/ngx-rocket/generator-ngx-rocket) add-ons or standalone generators.\n\nSee this [example addon](https://github.com/ngx-rocket/addon-example), you can use it as a base for your own add-ons.\n\nFirst it may be helping to be familiar with [Yeoman generators](http://yeoman.io/authoring/), since they have to\nfollow specific naming and structure rules.\n\n### Prompts and properties\n\nYou may want to ask the user some question about what he wants to generate, to do so you have to provide a list of\nprompts like this:\n\n```javascript\nmodule.exports = Generator.make({\n  baseDir: __dirname,\n\n  // Your generator prompts\n  // See https://github.com/sboudrias/Inquirer.js#objects for details\n  prompts: [\n    {\n      type: 'confirm',\n      name: 'sayHello',\n      message: 'Shall we say hello?',\n      default: true\n    },\n    {\n      type: 'input',\n      name: 'helloName',\n      message: 'To whom shall we say hello?',\n      default: 'world',\n      // Only ask this one when \"yes\" is replied to the sayHello prompt\n      when: props =\u003e props.sayHello\n    }\n  ]\n});\n```\n\nYou can see in this example that prompts can even be shown conditionally using the property `when`.\n\nAfter the user has answered your prompts, the results will be exposed as properties of the `props` object.\nThe `props` object can then be used directly in your [templates](#templates).\n\nTo avoid repeating the same questions between core and add-ons generators, these `props` can be shared and retrieved\nusing [`Generator.shareProps`](#generatorshareprops) and [`Generator.sharedProps`](#generatorsharedprops).\nNote that in that goal, prompts name matching already defined properties with be automatically skipped once defined.\n\n### Templates\n\nYour generator templates should go under the `generators/app/templates/` folder.\n\nWith its most basic usage, any file put in this folder will be copied as-is in the generated project folder.\nBut you may often have to customize the file depending of the user [prompts](#prompts-and-properties).\n\nTo do so, just prepend an underscore (`_`) to the file name and it will become an [EJS template](http://ejs.co), will\nfull access to the `props` object:\n\n```ejs\n// generators/app/templates/_hello.md\n\n# \u003c%= props.appName // From shared properties %\u003e\n\n\u003c% if (props.sayHello) { -%\u003e\nHello \u003c%= props.helloName %\u003e!\n\u003c% } else { -%\u003e\n...was not in the mood to say hello :-(\n\u003c% }-%\u003e\n```\n\nYou can then inject strings from the prompts or apply conditions for example.\n\nSee the [EJS documentation](http://ejs.co/#docs) for the complete syntax options.\n\n### File prefix rules\n\nTo avoid using complex hardcoded logic in generator, prefix-based file naming rules are used.\n\n#### Conditional prefix\n\nThere is two ways to conditionally include a file depending of user choices:\n\n- Using a *conditional folder* at root level, with the syntax `__\u003cprefix\u003e/`:\n  all files under this folder will be copied if the prefix condition is matched.\n\n  **Example:** `__authentication/my-service.ts` will be copied to `\u003cproject-dir\u003e/my-service.ts` only if the user has\n  enabled authentication during prompts.\n\n- Using a *conditional prefix* on a specific file, with the syntax `__\u003cprefix\u003e.\u003cfilename\u003e`:\n  this file will be copied if the prefix condition is matched.\n\n  You can even complete this by adding `_` before the `\u003cfilename\u003e` part to also make it an EJS template, ie\n  `__\u003cprefix\u003e._\u003cfilename\u003e`.\n\n  **Example:** `__authentication.myservice.ts` will be copied to `\u003cproject-dir\u003e/my-service.ts` only if the user has\n  enabled authentication during prompts.\n\nMultiple conditions are also supported using the `+` character: `__\u003cprefix1\u003e+\u003cprefix2\u003e+\u003cprefixN\u003e.\u003cfilename\u003e`.\n\nYou can use the [default prefix rules](#generatordefaultprefixrules) and extend them if needed.\nThese rules match the questions asked by the main generator\n([generator-ngx-rocket](https://github.com/ngx-rocket/generator-ngx-rocket)):\n\n- `web`: the user has chosen to make a *web* app as one of its targets\n- `cordova`: the user has chosen to make a *mobile* app as one of its targets\n- `electron`: the user has chosen to make a *desktop* app as one of its targets\n- `pwa`: the user has chosen to add progressive web app support\n- `bootstrap`: the user has chosen *Bootstrap* for its UI\n- `ionic`: the user has chosen *Ionic* for its UI\n- `material`: the user has chosen *Angular Material* for its UI\n- `raw`: the user has chosen to not use any UI library\n- `universal`: the user has chosen to use *Angular Universal* (Server-Side Rendering)\n- `auth`: the user has enabled authentication\n- `ios`: the user has chosen to support iOS for its mobile app\n- `android`: the user has chosen to support Android for its mobile app\n- `windows`: the user has chosen to support Windows (Universal) for its mobile app\n\n#### Action prefix\n\nIn addition to conditional prefix, you can specify *how* the file should be copied to the destination folder.\n\nBy default files are copied entirely, overwriting previous version if needed (if multiple add-ons are trying to write\nthe same file, the one finally written will be from the last processed add-on).\n\nTo use actions you have to use this syntax `(\u003caction\u003e).\u003cfilename\u003e`. This syntax can also be combined with the\nconditional/template prefixes like this: `__\u003cconditional-prefix\u003e(\u003caction\u003e)._\u003cfilename\u003e`\n\n**Example**: `(merge).package.json` will merge the content with `\u003cproject-dir\u003e/package.json`.\n\nThis is the list of currently implemented file actions:\n\n- `merge` (only for JSON files): performs a deep merge of the JSON properties, concatenating arrays with unique values.\n- `raw`: disable template processing even if filename starts with an underscore (`_`).\n\n### Advanced customization\n\nIf your generator needs to perform additional specific actions, you can add code for custom tasks to be executed as\npart of the composition lifecycle.\n\nFor this you simply create a new class to extend the base `Generator`:\n```javascript\n// generators/app/templates/index.js\n\nconst Generator = require('@ngx-rocket/core');\nconst pkg = require('../../package.json');\n\nclass ExampleGenerator extends Generator {\n  // DO NOT add a constructor, it won't be called.\n  // Use initializing() method instead.\n\n  initializing() {\n    // Setting version allows Yeoman to automatically notify the user of updates\n    this.version = pkg.version;\n    this.log(`Example generator is running version ${this.version}`);\n  }\n\n  end() {\n    this.log(`This was nice, see ya!`);\n  }\n}\n\nmodule.exports = Generator.make({\n  baseDir: __dirname,\n\n  // Your custom generator\n  generator: ExampleGenerator\n});\n\n```\nA complete working example is available here:\n[addon-example](https://github.com/ngx-rocket/addon-example/blob/master/generators/app/index.js)\n\nThere is a set of specific task names for each part of the project generation lifecycle, for example the `initializing`\ntask of all generators will be executed before moving on to the next one.\n\nTo learn more about Yeoman's run loop and see the list of specific task with their priorities, see the\n[running context documentation](http://yeoman.io/authoring/running-context.html). The composability docs also have\n[example execution sequence](http://yeoman.io/authoring/composability.html#order) to understand how generators work\nwith each other.\n\nSee also the full Yeoman [Base generator documentation](http://yeoman.io/generator/Base.html) for the list of\navailable properties and methods you can use in your generator.\n\n\u003e Note: be careful when overriding one of the methods already defined in `@ngx-rocket/core` base Generator (`prompting`\n\u003e or `writing`)! To maintain the base behavior along with your additions, you have to manually call the original method\n\u003e using `super.\u003cmethod\u003e()` in your overridden method, like this:\n\n```javascript\nclass ExampleGenerator extends Generator {\n  writing() {\n    // Do your stuff here\n    console.log('Hey there!');\n\n    // Make sure you call the base method to maintain proper behavior!\n    return super.writing();\n  }\n}\n```\n\n### Generating only tools\n\nAs part of the update process or if your users are only interested with generating only the toolchain, you can define\nfilters to exclude template files that are not part of the toolchain.\n\nAll generators automatically support the `--tools` option that enable the filters.\n\nTo define these filters you have 2 possibilities:\n\n- Create a `.toolsignore` in your generator `baseDir` root to exclude files that are not part of the toolchain.\n  It uses the same syntax as a [`.gitignore`](https://git-scm.com/docs/gitignore) file.\n\n- Specify a `toolsFilter` option when [creating your generator instance](#generatormakeoptions). Note that\n  setting this option will remplace any rules that may be defined in a `.toolsignore` file.\n  This option takes either a string or an array of strings, using the same syntax as a\n  [`.gitignore`](https://git-scm.com/docs/gitignore) file.\n\n### Standalone note\n\nIf you want your generator to work as a standalone and not only as an ngX-Rocket add-on, you must define the `appName`\npropery, either using an argument option:\n```javascript\nclass MyStandaloneGenerator extends Generator {\n  initializing() {\n    this.argument('appName', {\n      desc: 'Name of the app to generate',\n      type: String,\n      required: true\n    });\n  }\n}\n```\nor a prompt:\n```javascript\nmodule.exports = Generator.make({\n  baseDir: __dirname,\n\n  prompts: [\n    {\n      type: 'input',\n      name: 'appName',\n      message: 'What\\'s the name of your app?'\n    }\n  ]\n});\n```\nor both :)\n\n### Fullstack mode\n\nBy default, an add-on is configured to generate *client* templates, but by setting the `type`\n[option](#object-options-configures-your-generator-instance) you can generate *server* templates or *both client and\nserver* templates.\n\nWhen any add-on generator is either configured as `server` or `fullstack`, the whole project generation switches to\n**fullstack** mode, meaning that the generated output will contain both client and server code.\n\nAt any time after the initialization of your generator you can check if fullstack mode is enabled by using the\n`isFullstack()` instance method.\n\nThe client and server output folders can be modified by the user or forced by your generator through the environment\nvariables `NGX_CLIENT_PATH` and `NGX_SERVER_PATH`. If not modified, `client` and `server` will be used as default\noutput folders.\n\n## API\n\n### Static methods/properties\n\n#### `Generator.make(options)`\n\nCreates a new Yeoman generator extending the core ngx-rocket generator.\n\n##### `{object}` *options* Configures your generator instance:\n\n- `baseDir`: base directory for your generator templates\n- `generator`: your generator base class (optional)\n- `options`: generator options, see related section at http://yeoman.io/authoring/user-interactions.html (optional).\n- `prompts`: generator prompts, using [Inquirer.js](https://github.com/SBoudrias/Inquirer.js#question) format (optional).\n- `templatesDir`: generator templates directory (optional, default: `'templates'`)\n- `prefixRules`: generator template prefix rules (optional, default: `Generator.defaultPrefixRules()`)\n- `toolsFilter`: file filter patterns to use when toolchain only option is enabled. If not provided, the generator\n  will try to load the `.toolsignore` file inside `baseDir`.\n- `type`: generator type, can be `client`, `server` or `fullstack` (optional, default: 'client'). In `fullstack`\n  mode, client and server templates must be separated into `client`, `server` and `root` subfolders.\n\n#### `Generator.defaultPrefixRules`\n\nGets the default prefix rules.\n\nThe default rules are these:\n```javascript\n{\n  web: props =\u003e props.target.includes('web'),\n  cordova: props =\u003e props.target.includes('cordova'),\n  electron: props =\u003e props.target.includes('electron'),\n  pwa: props =\u003e Boolean(props.pwa),\n  bootstrap: props =\u003e props.ui === 'bootstrap',\n  ionic: props =\u003e props.ui === 'ionic',\n  raw: props =\u003e props.ui === 'raw',\n  universal: props =\u003e Boolean(props.universal),\n  auth: props =\u003e Boolean(props.auth),\n  ios: props =\u003e props.mobile.includes('ios'),\n  android: props =\u003e props.mobile.includes('android'),\n  windows: props =\u003e props.mobile.includes('windows')\n};\n```\n\nYou can use this method to extend the default rules with your own, like this:\n```javascript\nconst extentedRules = Object.assign(Generator.defaultPrefixRules, {\n  hello: props =\u003e Boolean(props.hello)\n});\n```\n\n#### `Generator.sharedProps`\n\nGets a copy of properties shared between generators.\nTo share additional properties, use [`Generator.shareProps`](#generatorshareprops).\n\nAlso available on the generator instance.\n\n#### `Generator.shareProps(props)`\n\nSets additional properties shared between generators.\nTo avoid collisions issues, only properties that are currently undefined will be added.\n\nAlso available on the generator instance.\n\n### Instance properties\n\n#### `sharedProps` (read-only)\n\nSee [`Generator.sharedProps`](#generatorsharedprops).\n\n#### `shareProps(props)`\n\nSee [`Generator.shareProps`](#generatorshareprops).\n\n#### `isStandalone` (read-only)\n\nReturns `true` if the generator is running standalone or `false` if it is running as an add-on.\n\n#### `isFullstack` (read-only)\n`true` if this or a composed generator has declared to be in `server` or `fullstack` mode or `false` if it is running\nin client only mode.\n\n#### `packageManager` (read-only)\n\nReturns the package manager to use (either `npm` or `yarn`).\nThe default value is `npm`, and can be changed either by the `--packageManager` option or the environment variable\n`NGX_PACKAGE_MANAGER`.\n","funding_links":[],"categories":["Awesome Angular [![Awesome TipeIO](https://img.shields.io/badge/Awesome%20Angular-@TipeIO-6C6AE7.svg)](https://github.com/gdi2290/awesome-angular) [![Awesome devarchy.com](https://img.shields.io/badge/Awesome%20Angular-@devarchy.com-86BDC1.svg)](https://github.com/brillout/awesome-angular-components)"],"sub_categories":["Angular \u003ca id=\"angular\"\u003e\u003c/a\u003e"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngx-rocket%2Fcore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fngx-rocket%2Fcore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngx-rocket%2Fcore/lists"}