{"id":19300041,"url":"https://github.com/kirschbaum-development/paragon","last_synced_at":"2026-03-16T20:33:17.288Z","repository":{"id":257792271,"uuid":"860750575","full_name":"kirschbaum-development/paragon","owner":"kirschbaum-development","description":null,"archived":false,"fork":false,"pushed_at":"2024-10-29T21:05:48.000Z","size":92,"stargazers_count":5,"open_issues_count":3,"forks_count":0,"subscribers_count":13,"default_branch":"main","last_synced_at":"2024-10-29T21:36:14.704Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","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/kirschbaum-development.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-21T04:38:45.000Z","updated_at":"2024-10-29T21:05:51.000Z","dependencies_parsed_at":null,"dependency_job_id":"c2f5524a-4c0b-4037-bf9e-f3e9e01cf92b","html_url":"https://github.com/kirschbaum-development/paragon","commit_stats":null,"previous_names":["kirschbaum-development/paragon"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kirschbaum-development%2Fparagon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kirschbaum-development%2Fparagon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kirschbaum-development%2Fparagon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kirschbaum-development%2Fparagon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kirschbaum-development","download_url":"https://codeload.github.com/kirschbaum-development/paragon/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223893052,"owners_count":17220834,"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-11-09T23:13:30.428Z","updated_at":"2026-03-16T20:33:17.274Z","avatar_url":"https://github.com/kirschbaum-development.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Paragon\n\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/kirschbaum-development/paragon.svg)](https://packagist.org/packages/kirschbaum-development/paragon)\n[![Total Downloads](https://img.shields.io/packagist/dt/kirschbaum-development/paragon.svg)](https://packagist.org/packages/kirschbaum-development/paragon)\n[![Actions Status](https://github.com/kirschbaum-development/paragon/actions/workflows/tests.yml/badge.svg)](https://github.com/kirschbaum-development/paragon/actions)\n\nA tool for automatically generating typescript/javascript objects and utilities based on their PHP counterparts.\n\n## Table of Contents\n\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Enums](#enums)\n  - [Custom Enum Methods](#custom-enum-methods)\n  - [Ignoring Enums or Methods](#ignoring-enums-or-public-methods)\n  - [Configuration](#configuration)\n  - [Recommendations](#recommendations)\n  - [Automatically Regenerate](#automatically-re-generating-when-modifying-php-enums)\n  - [Technical Details](#technical-details-)\n- [Events](#broadcast-events)\n  - [Usage](#usage)\n\n\n## Requirements\n\n| Laravel Version | Paragon Version |\n|:----------------|:----------------|\n| 12.0            | ^1.0           |\n| 11.0            | ^1.0           |\n| 10.0            | ^1.0            |\n\n## Installation\n\n```bash\ncomposer require kirschbaum-development/paragon\n```\n\n## Enums\n\n**TL;DR:** Run the following command to generate Typescript (or Javascript) enums from your PHP enums:\n\n```bash\nphp artisan paragon:enum:generate\n```\n\nThat's it. Now, wherever you may have had enums in your project, \"paragons\" or near perfect duplicates of those have been recreated inside of `resources/js/enums`. Here are some examples of the API:\n\n```php PHP API\nuse App\\Enums\\Status;\n\nStatus::Active;\nStatus::Active-\u003evalue;\nStatus::cases();\nStatus::from('active'); \nStatus::tryFrom('active'); \n```\n\n```ts TypeScript API\nimport Status from '@/js/enums/Status.ts';\n\nStatus.Active;\nStatus.Active.value;\nStatus.cases();\nStatus.from('active');\nStatus.tryFrom('active'); \n```\n\nAs you can see the API is nearly the same, the only difference being how the two languages expect you to access objects!\n\n**Generating javascript enums**\n\nThis package also supports generating Javascript enums. To do so, simply pass the `--javascript` flag to the command:\n\n```bash\nphp artisan paragon:enum:generate --javascript\n```\n\n#### Public Methods\n\nA good majority of the time it is useful to use public methods to return a proper human-readable label or some other functionality on an enum. Paragon got this covered too. Assuming the following method exists on the above `Status` enum:\n\n```php\npublic function label(): string\n{\n    return match ($this) {\n        self::Active =\u003e 'Active',\n        self::Inactive =\u003e 'Inactive',\n    }; \n}\n\npublic function color(): string\n{\n    return match ($this) {\n        self::Active =\u003e 'bg-green-100',\n        self::Inactive =\u003e 'bg-red-100',\n    }; \n}\n```\n\nThe following method would become accessible using TypeScript:\n\n```ts\nStatus.Active.label() // 'Active'\nStatus.Inactive.label() // 'Inactive'\nStatus.Active.color() // 'bg-green-100'\nStatus.Inactive.color() // 'bg-red-100'\n```\n\n### Custom Enum Methods\n\nWhile this package ignores static methods on the PHP Enums, we allow you to create additional methods that Paragon will make available for every generated Enum.\n\n```bash\nphp artisan paragon:enum:add-method\n```\n\nYou will be prompted to search for the enum this method should belong to. It will be placed inside a directory that matches the namespace of the enum. For example, an enum at `App\\Enums\\Status` would place an enum method file at `resources/js/vendors/paragon/enums/App/Enums/Status`. You are free to do whatever you need inside this file. You have direct access to `this.items` which allows you to interact with the enum cases in whatever way you need. Just keep in mind that because the items are \"frozen\", you can't mutate them directly. An example would be to have a method that automatically generates a select list from your Enum.\n\nIf you need to create a method that is available to every enum, just create an enum method with the `--global` or `-g` flag.\n\n```bash\nphp artisan paragon:enum-method --global\n```\n\nThis will create a new file at `resources/js/vendors/paragon/enums` containing a method.\n\n### Ignoring Enums Or Public Methods\n\nThere may be enums or enum methods that you don't want inside your automatically generated code. If this is the case simply use the `IgnoreParagon` attribute.\n\n```php\nuse Kirschbaum\\Paragon\\Concerns\\IgnoreParagon;\n\n#[IgnoreParagon]\nenum IgnoreMe\n{\n    case Ignored;\n}\n```\n\n```php\nuse Kirschbaum\\Paragon\\Concerns\\IgnoreParagon;\n\nenum Status\n{\n    // ...\n    \n    #[IgnoreParagon]\n    public method ignoreMe()\n    {\n        // ...\n    }\n}\n```\n\n### Configuration\n\nYou can publish the configuration file by running `php artisan vendor:publish` and locating the Paragon config which will be published at `config/paragon.php`.\n\n### Recommendations\n\nIt is recommended that the generated path for the enums is added to the `.gitignore` file. Make sure to run this command during deployment if you do this.\n\n### Automatically Re-generating When Modifying PHP Enums\n\nInstall the [`vite-plugin-watch`](https://www.npmjs.com/package/vite-plugin-watch) plugin in your project via `npm`:\n\n```shell\nnpm i -D vite-plugin-watch\n```\n\nIn your `vite.config.js` file, import the plugin, and add the plugin paramaters to your plugins array:\n\n```js\nimport { watch } from \"vite-plugin-watch\";\n\nexport default defineConfig({\n    plugins: [\n        // ...\n        \n        watch({\n            pattern: \"app/Enums/**/*.php\",\n            command: \"php artisan paragon:generate-enums\",\n        }),\n    ],\n});\n```\n\n### Technical Details 🤓\n\nEnums are a fantastic addition to the PHP-verse but are really lame in the TypeScript-verse. However, it can be annoying trying to get those enum values on the\nfront-end of your project. Are you supposed to pass them as a method when returning a view or perhaps via an API? This\ngenerator solves that problem by scraping your app directory for any and all enums and recreates them as TypeScript\nclasses so you can import them directly into your Vue, React, or Svelte front-end!\n\nLet's take a closer look at a simple PHP enum and its generated Typescript code.\n\n```php\nnamespace App\\Enums;\n\nenum Status: string\n{\n    case Active = 'active';\n    case Inactive = 'inactive';\n}\n```\n\n```ts\nimport Enum from '../Enum.ts';\n\ntype StatusDefinition = {\n    name: string;\n    value: string;\n};\n\nclass Status extends Enum {\n    protected static items = Object.freeze({\n        Active: Object.freeze({\n            name: 'Active',\n            value: 'active',\n        }),\n        Inactive: Object.freeze({\n            name: 'Inactive',\n            value: 'inactive',\n        }),\n    });\n\n    public static get Active(): AlarmStatusDefinition {\n        return this.items['Active'];\n    }\n\n    public static get Inactive(): AlarmStatusDefinition {\n        return this.items['Inactive'];\n    }\n}\n\nexport default Status;\n```\n\nAt first glance it appears as though a lot more stuff is happening, but the above generated code allows us to interact\nwith the enum in a nearly identical way as in PHP. And you may notice the generated TypeScript class extends the `Enum`\nclass. This gives us some underlying functionality that is available to every enum.\n\n## Broadcast Events\n\n**TL;DR:** Run the following command to generate a Typescript (or Javascript) broadcast event object based on your broadcastable events:\n\n```bash\nphp artisan paragon:event:generate\n```\n\nAny events within the `App\\Events` namespace will be automatically added to the `Events` object. Just make sure your event implements the `ShouldBroadcast` contract!\n\nIf javascript is needed, just make sure to add the `--javascript` or `-j` flag.\n\n### Usage\n\nThe primary usage of this tool is for Laravel Echo. Listening to for an event class based on a hard-coded string is not exactly preferable. The can easily get out of sync or just get mistyped.\n\nHere is a quick example event:\n\n```php\nnamespace App\\Events;\n\nclass ParagonGenerated implements ShouldBroadcast\n{ \n    // ...\n}\n```\n\nThen listen for it with Echo:\n\n```js\nimport Events from '@/events/Events.ts';\n\nEcho.channel(...)\n    .listen(Events.ParagonGenerated, /* ... */);\n```\n\nIf you have defined a `broadcastOn` method that returns a custom name, this will be handled correctly for you as well.\n\nOne thing to note is that if an event namespace starts with `App\\Events` or `App`, these will be removed from the dot path within the object. If an event is nested, the dot path will reflect this: For example:\n\n```php\nnamespace App\\Support;\n\nclass NestedEvent implements ShouldBroadcast\n{ \n    // ...\n}\n```\n\n```js\nimport Events from '@/events/Events.ts';\n\nEcho.channel(...)\n    .listen(Events.Support.NestedEvent, /* ... */);\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkirschbaum-development%2Fparagon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkirschbaum-development%2Fparagon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkirschbaum-development%2Fparagon/lists"}