{"id":15097211,"url":"https://github.com/creadigme/aurelia-docgen","last_synced_at":"2025-04-15T00:45:51.326Z","repository":{"id":38336744,"uuid":"486921577","full_name":"creadigme/aurelia-docgen","owner":"creadigme","description":"Aurelia + Storybook (can be) ❤","archived":false,"fork":false,"pushed_at":"2023-07-31T08:13:20.000Z","size":917,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-15T00:45:35.272Z","etag":null,"topics":["aurelia","documentation","storybook","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/creadigme.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-04-29T09:55:42.000Z","updated_at":"2022-07-26T13:13:42.000Z","dependencies_parsed_at":"2022-08-24T22:41:23.526Z","dependency_job_id":null,"html_url":"https://github.com/creadigme/aurelia-docgen","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creadigme%2Faurelia-docgen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creadigme%2Faurelia-docgen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creadigme%2Faurelia-docgen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creadigme%2Faurelia-docgen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/creadigme","download_url":"https://codeload.github.com/creadigme/aurelia-docgen/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248986274,"owners_count":21194024,"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":["aurelia","documentation","storybook","typescript"],"created_at":"2024-09-25T16:05:25.461Z","updated_at":"2025-04-15T00:45:51.308Z","avatar_url":"https://github.com/creadigme.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![npm version](https://img.shields.io/npm/v/@creadigme/aurelia-docgen.svg)](https://www.npmjs.com/package/@creadigme/aurelia-docgen)\n[![Build Status](https://github.com/creadigme/aurelia-docgen/actions/workflows/ci.yml/badge.svg)](https://github.com/creadigme/aurelia-docgen/actions)\n[![CodeQL](https://github.com/creadigme/aurelia-docgen/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/creadigme/aurelia-docgen/actions/workflows/codeql-analysis.yml)\n[![codecov](https://codecov.io/gh/creadigme/aurelia-docgen/branch/main/graph/badge.svg?token=BV2ZP1FH6K)](https://codecov.io/gh/creadigme/aurelia-docgen)\n[![License Badge](https://img.shields.io/badge/License-AGPL%203%2B-blue.svg)](LICENSE)\n\u003cbr /\u003e\n\n# Aurelia Docgen | @creadigme/aurelia-docgen\n\n\u003e Aurelia + Storybook (*can be*) ❤\n\n`Aurelia Docgen` brings the ability to **generate** component\u003csup\u003e1\u003c/sup\u003e documentations, **stories**, from *any*\u003csup\u003e2\u003c/sup\u003e `Aurelia`\u003csup\u003e3\u003c/sup\u003e `TypeScript` project.\nComponent's stories are written in class comments `@story` or in [YAML](https://yaml.org/) files.\n\nThis tool is intended to be used with projects based on [Aurelia framework](https://aurelia.io/)\u003csup\u003e3\u003c/sup\u003e + [Storybook](https://storybook.js.org). It could also work with projects using only `Aurelia` **without** `Storybook`.\n\n[![aurelia logo](https://aurelia.io/styles/images/logo.svg \"Aurelia\")](https://aurelia.io/)\n\n[![storybook logo](https://storybook.js.org/showcase/images/logos/storybookLogo.svg \"Storybook\")](https://storybook.js.org)\n\n\n\u003csup\u003e1. `customElement`, `valueConverter`, `customAttribute`, `bindingBehavior` and services.\u003c/sup\u003e\u003cbr\u003e\n\u003csup\u003e2. Without any warranty.\u003c/sup\u003e\u003cbr\u003e\n\u003csup\u003e3. ⚠️ Aurelia 1 support is not implemented yet.\u003c/sup\u003e\n\n## 📝 License\n\nCopyright © 2022-2023 [Creadigme](https://www.creadigme.net).\n\n**Disclaimer**\n\nThis project has a dual license:\n- The **AGPLv3** License - see the [LICENSE file](LICENSE) for details.\n- A private license agreement for private or/and commercial use.\n\nSee [the FAQ on licensing](https://github.com/creadigme/aurelia-docgen/wiki/License-FAQ#faq).\n\nDo not hesitate to [contact us](https://creadigme.net/contact/).\n\n\u003c!--\n\u003e [AD]\n\u003e \n\u003e An issue with your Aurelia project? *(Architecture, component, compatibility, performance...)*\n\u003e A request concerning an Aurelia project?\n\u003e \n\u003e Do not hesitate to contact us via this form, we can certainly help you.\n\u003e \n\u003e [/AD]\n--\u003e\n\n## 💾 Installation\n\n### Aurelia Docgen\n\n```bash\nnpm i @creadigme/aurelia-docgen@^2 -D\n# or\nyarn add @creadigme/aurelia-docgen@^2 -D\n# or for global use\nyarn add @creadigme/aurelia-docgen@^2 -g\n```\n\n### Storybook (*version 6*)\n\n#### Storybook for HTML (if needed)\n[Storybook for HTML](https://storybook.js.org/docs/html/get-started/install)\n\n```bash\n# Aurelia 2 project with webpack\nnpx sb init --type html --builder webpack5\n```\n\n#### Webpack configuration\n\n\u003e `./webpack.config.js`\n\nStorybook and Aurelia use **HMR** (Hot Module Replacement), we have to disable Aurelia HMR if Storybook is used.\n\nIn your project, edit this file: `./webpack.config.js`.\n\n**Example**: [webpack.config.js](./examples/au2-basic/webpack.config.js)\n\n```diff\n/** Your content */\n\n- module.exports = function(env, { analyze }) {\n+ module.exports = function(env, { analyze, hmr }) {\n\n/** Your content */\n\n{ test: /\\.ts$/i, use: ['ts-loader', \n- '@aurelia/webpack-loader'\n+ {\n+   loader: '@aurelia/webpack-loader',\n+   options: {\n+     hmr: hmr === false ? false : undefined,\n+   },\n+ }\n], exclude: /node_modules/ },\n{\n  test: /[/\\\\]src[/\\\\].+\\.html$/i,\n- use: '@aurelia/webpack-loader',\n+ use: {\n+   loader: '@aurelia/webpack-loader',\n+   options: {\n+     hmr: hmr === false ? false : undefined,\n+   },\n+ },\n\n/** Your content */\n```\n\n\u003e `./.storybook/main.js`\n\nStorybook must use Aurelia configuration. In your project, edit this file: `./.storybook/main.js`.\n\n**Example**: [main.js](./examples/au2-basic/.storybook/main.js)\n\n```diff\n+ const customWP = require('../webpack.config.js');\n\nmodule.exports = {\n+ webpackFinal: async (config) =\u003e {\n+   const customConfigs = customWP(config.mode, {\n+     hmr: false\n+   });\n+   return {\n+     ...config,\n+     module: {\n+       ...config.module,\n+       rules: (Array.isArray(customConfigs) ? customConfigs[0] : customConfigs).module.rules\n+     }\n+   };\n+ },\n+ core: {\n+   builder: 'webpack5',\n+ },\n  \"stories\": [\n-   \"../src/**/*.stories.mdx\",\n    \"../src/**/*.stories.@(js|jsx|ts|tsx)\"\n  ],\n  \"addons\": [\n    \"@storybook/addon-links\",\n    \"@storybook/addon-essentials\"\n  ],\n  \"framework\": \"@storybook/html\",\n  \"core\": {\n    \"builder\": \"@storybook/builder-webpack5\"\n  }\n}\n```\n\n\u003e ⚠️ Currently we do not support .mdx stories.\n\n## 📝 Write stories\n\n\u003e **TLDR;** comment your class with `@story` **or**/**and** via YAML files.\n\n### Comment your class `@story`\n\nJust like that:\n\n#### `customElement`\n\n```typescript\n/**\n * My component\n *\n * @story My story\n * ```html\n * \u003cau-component value.bind=\"1\"\u003e\u003c/\u003cau-component\u003e\n * ```\n *\n * @story My another story\n * ```html\n * \u003cau-component value.bind=\"200\"\u003e\u003c/\u003cau-component\u003e\n * ```\n */\n@customElement('au-component')\nexport class AuComponent implements ICustomElementViewModel {\n  /** ... */\n  @bindable()\n  public value = 1;\n}\n```\n\n#### `valueConverter`\n\n```typescript\n/**\n * My converter\n *\n * @example\n * ```html\n * \u003c!-- it's the default usage for valueConverter ! --\u003e\n * \u003cspan\u003e${ '1' | doSomething}\u003c/span\u003e\n * ```\n *\n * @story My story\n * ```html\n * \u003clet my-value.bind=\"{ a: 1 }\"\u003e\n * \u003cspan\u003e${ myValue | doSomething}\u003c/span\u003e\n * ```\n *\n * @story My another story\n * ```html\n * \u003clet my-value.bind=\"{ a: 1, b: 2 }\"\u003e\n * \u003cspan\u003e${ myValue | doSomething}\u003c/span\u003e\n * ```\n */\n@valueConverter('doSomething')\nexport class DoSomethingValueConverter {\n  public toView(value: string | Record\u003cstring, number\u003e): string {\n    return /* ?? */ 'ok';\n  }\n}\n```\n\n#### `customAttribute`\n\n```typescript\nimport { customAttribute, INode } from 'aurelia';\n\n/**\n * Red Square\n * From https://docs.aurelia.io/getting-to-know-aurelia/custom-attributes#attribute-aliases\n *\n * @group attributes/red-square\n */\n@customAttribute({ name: 'red-square', aliases: ['redify', 'redbox'] }) \nexport class RedSquareCustomAttribute {\n  constructor(@INode private element: HTMLElement){\n      this.element.style.width = this.element.style.height = '100px';\n      this.element.style.backgroundColor = 'red';\n  }\n}\n```\n\n#### `bindingBehavior`\n\n```typescript\nimport { ILogger, bindingBehavior } from 'aurelia';\n\n/**\n * Log behavior\n *\n * @group binding-behavior/log\n */\n@bindingBehavior('log')\nexport class Log {\n  constructor(\n    @ILogger readonly logger: ILogger,\n  ) {}\n  bind(...args) {\n    this.logger.debug('bind', ...args);\n  }\n  unbind(...args) {\n    this.logger.debug('unbind', ...args);\n  }\n}\n```\n\n#### `service`\n\nThe tag comment `@service` is the key.\n\n```typescript\n/**\n * My Service\n *\n * @service\n */\nexport class MyService implements IMyService {\n  /**\n   * @inheritDoc\n   */\n  public running: boolean = false;\n\n  /**\n   * @inheritDoc\n   */\n  public start(): void {\n    this.running = true;\n  }\n\n  /**\n   * @inheritDoc\n   */\n   public stop(): void {\n    this.running = false;\n  }\n}\n```\n\n### YAML Way\n\nStories are written in [YAML](https://yaml.org/) next to components like these:\n\n```diff\n components\n ├── something\n │   ├── au2-button.html\n │   ├── au2-button.ts\n+│   ├── au2-button.stories.yml\n │   ├── au2-switch.html\n │   ├── au2-switch.ts\n+│   ├── au2-switch.stories.yml\n └── else\n │   ├── supra-ultra-component.html\n │   ├── supra-ultra-component.ts\n+│   ├── supra-ultra-component.stories.yml\n```\n\nWith this format:\n\n```yml\n# au2-button stories\n- title: Toggle\n  help: |\n    A button toggle\n  tags:\n    - button\n    - simple\n  code: |\n    \u003clet state.bind=\"false\"\u003e\u003c/let\u003e\n    \u003cau2-button action.bind=\"() =\u003e state = !state\" content=\"${state ? 'Turn me off' : 'Turn me on'}\"\u003e\u003c/au2-button\u003e\n    \u003cdiv\u003e${state ? '✅' : '☐' }\u003c/div\u003e\n- title: Another story\n  help: |\n    Another story. Look at this sample...\n  tags:\n    - button\n    - simple\n    - supra\n  code: |\n    \u003clet state.bind=\"false\"\u003e\u003c/let\u003e\n    \u003cau2-button action.bind=\"() =\u003e state = !state\" content=\"${state ? '✅' : '☐'}\"\u003e\u003c/au2-button\u003e\n    \u003cdiv\u003e${state ? '✅' : '☐' }\u003c/div\u003e\n```\n\n## 🔨 How to use\n\n### **(optional)** Add script in your package.json\n\n```diff\n{\n  \"name\": \"something\",\n  \"scripts\": {\n+   \"build:stories\": \"aurelia-docgen --out ./src/stories\"\n!   \"build:stories\": \"aurelia-docgen\"\n!   \"build:stories\": \"aurelia-docgen --out ./src/stories --auConfigure ./src/configure\"\n  }\n}\n```\n\n### Default way - All component stories in one directory\n\n```bash\n# Go to your project\ncd ./my-supra-project\n\n# add a new script in package.json, like `build:stories` with command\n# aurelia-docgen --out ./src/stories\nnpm run build:stories\n\n# all detect components and stories will be written in ./src/stories directory.\n```\n\n### DRY way - Component stories next to components\n\n```bash\n# add a new script in package.json, like `build:stories` with command\n# aurelia-docgen\nnpm run build:stories\n\n# all detected components and the stories will be written next to the detected components.\n```\n\n### Real world installation\n\n- Install `@creadigme/aurelia-docgen` in [`devDependencies`](#aurelia-docgen).\n- Script on `package.json` as below.\n- All component stories in one directory.\n- Storybook stories can use any register elements.\n- `./.storybook/main.js` is edited with [webpack configuration](#webpack-configuration).\n\n**./package.json**\n```diff\n{\n  \"name\": \"something\",\n  \"scripts\": {\n+   \"build:stories\": \"aurelia-docgen --out ./src/stories --auConfigure ./src/configure\"\n+   \"watch:stories\": \"npm run build:stories -- --watch\"\n  },\n  \"devDependencies\": {\n+   \"@creadigme/aurelia-docgen\": \"^1\"\n  }\n}\n```\n\n**./src/configure.ts**\n```typescript\nimport { Aurelia, Registration, type IEnhancementConfig, type IHydratedParentController } from \"aurelia\";\n\n/** It's just an example */\nlet au: Aurelia;\n\n/**\n * If specified, this function is called to retrieve the instance of Aurelia\n * @return Aurelia\n */\nexport async function getOrCreateAurelia(): Promise\u003cAurelia\u003e {\n  if (!au) {\n    au = new Aurelia().register(/** Your configuration */);\n    // Do your specific stuff here\n  }\n  return au;\n}\n\nlet lastController: ICustomElementController\u003cunknown\u003e;\n\n/** Cleanup previous story and enhance current */\nexport async function enhance(aureliaInst: Aurelia, config: IEnhancementConfig\u003cunknown\u003e, parentController?: IHydratedParentController | null): Promise\u003cICustomElementController\u003cunknown\u003e\u003e {\n  if (lastController) {\n    // detaching, unbinding\n    await lastController.deactivate(lastController, null);\n    // dispose\n    await lastController.dispose();\n  }\n\n  lastController = await aureliaInst.enhance(config, parentController);\n  return lastController;\n}\n```\n\n```bash\nnpm run build:stories\n# all detect components and stories will be written in ./src/stories directory.\n```\n\n```bash\n# launch storybook\nnpm run storybook\n```\n\n### CLI parameters\n\n| Parameter | Description | Sample |\n|---|---|---|\n| --projectDir | Project directory. *Current working directory is used by default.* | `./` |\n| --out | Output directory for generated stories. *If not specified, stories are written next to the components.* | `./src/stories/` |\n| --mergeOut | If `out` is specified, merges the component stories into a single file | `./src/stories/components.stories.ts` |\n| --auConfigure | Specify the TS file for Aurelia configuration (**without extension**).\u003cbr\u003e\u003cbr\u003eExample `./src/configure` file:\u003cbr\u003e`export async function getOrCreateAurelia(): Promise\u003cAurelia\u003e { return Aurelia.register(/** */); }`.\u003cbr\u003e *If null or empty, only the current component will be register.* | |\n| --etaTemplate | Path of Eta template (https://eta.js.org/). *If null, the default template is used* | |\n| --verbose | More logs | |\n| --watch | Monitor changes | |\n\n### API Parameters\n\n[CLI Parameters](#cli-parameters) + below:\n\n| Parameter | Description | Sample |\n|---|---|---|\n| logger | `(msg: string, level: LevelLog) =\u003e void` | `console.log(``${level} - ${msg}``)` |\n\n```typescript\nimport { AureliaDocgen } from '@creadigme/aurelia-docgen';\n\nconst au2Docgen = new AureliaDocgen({\n  projectDir: './path-of-your-supra-ultra-project',\n  out: './src/stories',\n});\n\nfor (const ceStories of au2Docgen.getStories()) {\n  console.dir(ceStories);\n}\n```\n\n\n## Coverage\n[![codecov](https://codecov.io/gh/creadigme/aurelia-docgen/branch/main/graph/badge.svg?token=BV2ZP1FH6K)](https://codecov.io/gh/creadigme/aurelia-docgen)\n\n![Coverage sunburst](https://codecov.io/gh/creadigme/aurelia-docgen/branch/main/graphs/sunburst.svg?token=BV2ZP1FH6K)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcreadigme%2Faurelia-docgen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcreadigme%2Faurelia-docgen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcreadigme%2Faurelia-docgen/lists"}