{"id":17215126,"url":"https://github.com/codyjdalton/litstack","last_synced_at":"2025-04-13T23:16:37.462Z","repository":{"id":31940650,"uuid":"130591149","full_name":"codyjdalton/litstack","owner":"codyjdalton","description":"Typescript RESTful web service framework inspired by Angular and Spring Boot design patterns","archived":false,"fork":false,"pushed_at":"2023-02-01T17:17:54.000Z","size":520,"stargazers_count":1,"open_issues_count":7,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-09T21:40:25.282Z","etag":null,"topics":["angular","express","rest-api","restapi","restful","restful-api","restful-webservices","spring-boot","ts","typescript","typescript-framework"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/codyjdalton.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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":"2018-04-22T17:33:40.000Z","updated_at":"2022-10-17T15:18:43.000Z","dependencies_parsed_at":"2023-02-17T08:46:15.872Z","dependency_job_id":null,"html_url":"https://github.com/codyjdalton/litstack","commit_stats":null,"previous_names":["codyjdalton/service-starter"],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codyjdalton%2Flitstack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codyjdalton%2Flitstack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codyjdalton%2Flitstack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codyjdalton%2Flitstack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codyjdalton","download_url":"https://codeload.github.com/codyjdalton/litstack/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248794569,"owners_count":21162615,"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":["angular","express","rest-api","restapi","restful","restful-api","restful-webservices","spring-boot","ts","typescript","typescript-framework"],"created_at":"2024-10-15T03:23:19.057Z","updated_at":"2025-04-13T23:16:37.439Z","avatar_url":"https://github.com/codyjdalton.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![npm version](https://badge.fury.io/js/%40litstack%2Fcore.svg)](https://badge.fury.io/js/%40litstack%2Fcore) [![Build Status](https://travis-ci.org/codyjdalton/litstack.svg?branch=master)](https://travis-ci.org/codyjdalton/litstack) [![Coverage Status](https://coveralls.io/repos/github/codyjdalton/litstack/badge.svg?branch=master)](https://coveralls.io/github/codyjdalton/litstack?branch=master)\n\n# Litstack\n\nUsing Angular and Spring boot design patterns, Litstack is a Typescript REST framework that Angular/Spring Boot engineers already know how to use, keeping their code organized and concise, and pushing off the express wiring to the library.\n\n## Getting Started\n\n### Option 1: Clone the seed app\n\nFollow the directions in [the litstack seed](https://github.com/codyjdalton/litstack-seed) to get started right away.\n\n### Option 2: Start with a blank slate\n\nCreate a new project and install the Litstack core library.\n\n```\n\u003e npm install @litstack/core --save\n```\n\nMake sure experimental decorators are on in your tsconfig.json at the root level:\n\n```json\n{\n    \"compilerOptions\": {\n        \"experimentalDecorators\": true\n    }\n}\n```\n\nFor more on building, see the minimum configuration section below.\n\n## Bootstrapping\n\nBootstrap app.module at the index.ts level:\n\n```typescript\n// in index.ts\nimport { LitCompiler } from '@litstack/core/dist/compiler';\n\nimport { AppModule } from './modules/app.module';\n\nLitCompiler.bootstrap(AppModule);\n```\n\n## Modules\nModules can export component routes and package other modules.\n\n### Basic Module\n\nThis module will export app.component's routes.\n\n```typescript\n// in app.module.ts\nimport { LitModule } from '@litstack/core';\n\nimport { AppComponent } from './app.component';\n\n@LitModule({\n    exports: [\n        AppComponent\n    ]\n})\nexport class AppModule {\n}\n```\n\n### Module with Imports\n\nModules can also import other modules with components:\n\n```typescript\nimport { LitModule } from '@litstack/core';\n\nimport { ItemsModule } from  './modules/items/items.module';\nimport { OrdersModule } from  './modules/orders/orders.module';\nimport { PeopleModule } from  './modules/people/people.module';\nimport { VersionComponent } from  './components/version/version.component';\n\n@LitModule({\n    path: 'api', // will add all imported routes at '/api/..'\n    imports: [ \n        ItemsModule,\n        PeopleModule,\n        OrdersModule\n    ],\n    exports: [\n        VersionComponent\n    ]\n})\nexport class AppModule {\n}\n```\n\n## Components\nComponents register route listeners:\n\n### Basic Component\n\n```typescript\n// in app.component.ts\nimport { LitComponent } from '@litstack/core';\nimport { HttpResponse } from '@litstack/core/dist/http';\nimport { GetMapping } from '@litstack/core/dist/http/mappings';\n\n@LitComponent()\nexport class AppComponent {\n\n    private message = 'Hello World!';\n\n    @GetMapping() // defaults to '/'\n    onHello(res: HttpResponse): void {\n        res.success({\n            message: this.message\n        });\n    }\n}\n```\n\n### Using path params\n\nSpecify params in the path:\n\n```typescript\nimport { LitComponent } from '@litstack/core';\nimport { HttpRequest, HttpResponse } from '@litstack/core/dist/http';\nimport { GetMapping } from '@litstack/core/dist/http/mappings';\n\n@LitComponent()\nexport class ItemsComponent {\n\n    @GetMapping({\n        path: ':id'\n    })\n    getItem(req: HttpRequest, res: HttpResponse): void {\n        res.success({\n            id: req.params.id\n        });\n    }\n}\n```\n\n### Chaining methods with next\n\nWe can keep our route functionality isolated by using the \"next\" param:\n\n```typescript\nimport { LitComponent } from '@litstack/core';\nimport { HttpRequest, HttpResponse, HttpNext } from '@litstack/core/dist/http';\nimport { PutMapping } from '@litstack/core/dist/http/mappings';\n\n@LitComponent()\nexport class ItemsComponent {\n\n    // NOTE: The order matters here:\n    @PutMapping({\n        path: ':id'\n    })\n    updateItem(req: HttpRequest, res: HttpResponse, next: HttpNext) {\n\n        if(req.param.id === 'some-id') {\n\n            // do some update\n            res.success({ id: 'some-id' });\n            return;\n        }\n\n        next();\n    }\n\n    // same route as above, will run only if \"next\" is called\n    @PutMapping({\n        path: ':id'\n    })\n    updateItemErr(res: HttpResponse) {\n        \n        res.error(404);\n    }\n}\n```\n\n### Dependency Injection\n\nServices are a great place for business logic:\n\n```typescript\n// ./services/items.service\nimport { LitService } from '@litstack/core';\n\n@LitService()\nexport class ItemsService {\n\n    get description(): string {\n        return 'This is an item description';\n    }\n}\n```\nAnd then in our component:\n\n```typescript\nimport { LitComponent } from '@litstack/core';\nimport { HttpResponse } from '@litstack/core/dist/http';\nimport { GetMapping } from '@litstack/core/dist/http/mappings';\n\nimport { ItemsService } from './services/items.service';\n\n@LitComponent()\nexport class ItemsComponent {\n\n    constructor(private itemsService: ItemsService) {}\n\n    @GetMapping()\n    getItems(res: HttpResponse) {\n        res.success({\n            description: this.itemsService.description\n        });\n    }\n}\n```\n\n## Testing\n\nTest components [using supertest methods](https://github.com/visionmedia/supertest) and the Litstack TestBed:\n\n```typescript\nimport { TestBed, LitComponentTest } from '@litstack/core/dist/testing';\n\nimport { AppComponent } from './app.component';\n\ndescribe('AppComponent', () =\u003e {\n\n    let component: LitComponentTest;\n\n    beforeEach(() =\u003e {\n        \n        component = TestBed.start(AppComponent);\n    });\n\n    afterEach(() =\u003e {\n\n        TestBed.stop();\n    });\n\n    it('should return a welcome message', (done) =\u003e {\n\n        component\n            .get('/')\n            .expect(200)\n            .expect((res) =\u003e {\n                expect(res.body.message).to.equal('Hello World!');\n            })\n            .end((err, res) =\u003e {\n                if (err) return done(err);\n                done();\n            });\n    });\n});\n```\n\n## Minimum Configuration\n\nThe build process can be customized to the needs of the project, but a minimum configuration could look like this:\n\n```\n\u003e mkdir my-project\n\u003e cd my-project\n\u003e npm init -y\n\u003e npm install @litstack/core --save\n\u003e npm install typescript -D\n\u003e npm install ts-node -D\n```\n\nChange the following in package.json:\n\n```json\n{\n  \"main\": \"dist/index.js\",\n  \"scripts\": {\n    \"start\": \"tsc \u0026\u0026 node dist/index.js\"\n  }\n}\n```\n\nA tsconfig.json could look like this:\n\n```json\n{\n    \"compilerOptions\": {\n        \"module\": \"commonjs\",\n        \"target\": \"es5\",\n        \"outDir\": \"dist\",\n        \"lib\": [\n            \"es7\"\n        ],\n        \"experimentalDecorators\": true,\n        \"emitDecoratorMetadata\": true\n    },\n    \"include\": [\n        \"**/*.ts\"\n    ]\n}\n```\n\nNow, run the app:\n\n```\n\u003e npm start\n```\n\nHave fun!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodyjdalton%2Flitstack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodyjdalton%2Flitstack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodyjdalton%2Flitstack/lists"}