{"id":11016745,"url":"https://github.com/LaiJunBin/typespec-template","last_synced_at":"2025-09-19T16:31:10.022Z","repository":{"id":243814411,"uuid":"805577257","full_name":"LaiJunBin/typespec-template","owner":"LaiJunBin","description":"This is a template for my typespec project, it implements a simple code-generation tool and hot-reloading server for typespec projects.","archived":false,"fork":false,"pushed_at":"2024-05-25T04:31:08.000Z","size":38,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-09-20T13:30:55.953Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/LaiJunBin.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-24T22:25:03.000Z","updated_at":"2024-06-10T23:59:38.000Z","dependencies_parsed_at":"2024-06-11T10:37:35.850Z","dependency_job_id":null,"html_url":"https://github.com/LaiJunBin/typespec-template","commit_stats":null,"previous_names":["laijunbin/typespec-template"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LaiJunBin%2Ftypespec-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LaiJunBin%2Ftypespec-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LaiJunBin%2Ftypespec-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LaiJunBin%2Ftypespec-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LaiJunBin","download_url":"https://codeload.github.com/LaiJunBin/typespec-template/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233578500,"owners_count":18697203,"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-06-11T10:18:18.921Z","updated_at":"2025-09-19T16:31:04.708Z","avatar_url":"https://github.com/LaiJunBin.png","language":"JavaScript","funding_links":[],"categories":["others","JavaScript"],"sub_categories":[],"readme":"# Typespec Template\r\n\r\nThis is a template for my [typespec](https://typespec.io/) project, it implements a simple code-generation tool and hot-reloading server for typespec projects.\r\n\r\n## Main Project Structure\r\n\r\n```\r\n.\r\n├── src\r\n│   ├── shared\r\n│   │   ├── authorization.tsp\r\n│   │   ├── response.tsp\r\n│   │   └── ...\r\n│   ├── specs\r\n│   │   ├── auth\r\n│   │   │   ├── index.tsp\r\n│   │   │   ├── model.tsp\r\n│   │   │   └── ...\r\n│   │   └── ...\r\n├── main.tsp\r\n├── .env\r\n\r\n```\r\n\r\n---\r\n\r\n## Getting Started\r\n\r\nYou can use other package manager to install the dependencies and run the project, I'll be using npm in this example.\r\n\r\n### Install\r\n```bash\r\nnpm install\r\n```\r\n\r\n### Development\r\n```bash\r\nnpm run dev\r\n```\r\n\r\n### Build\r\n```bash\r\nnpm run build\r\n```\r\n\r\nThis will generate a `main.tsp` file in the root of the project and generate the tsp-output(such as `openapi.yaml`)\r\n\r\n---\r\n\r\n## How it works\r\n\r\nThe project is divided into two main parts, the `src/shared` and `src/specs` folders.\r\n\r\n### Shared\r\n\r\nnamespace: `Shared`\r\n\r\nThis folder contains all the shared typespec files, and it will automatically imports all files into the `main.tsp` file.\r\n\r\n### Specs\r\n\r\nThis folder contains all the specs for the project, each folder represents a different spec, and it will automatically imports all files into the `main.tsp` file and bundle all namespaces and interfaces.\r\n\r\nThe interface is divided into two parts, the `Interface` and `AuthedInterface`, the `AuthedInterface` is a special interface that requires the user to be authenticated to access it.\r\n\r\nThe Authorizations samples can be found in the `src/shared/authorization.tsp` file, it contains a `authorization` alias, it will be used to `@useAuth` decorator, which will automatically generate to all `Operation` in the `AuthedInterface`.\r\n\r\nEvery spec file should have `namespace` defined, and you can define `@tag` and `@route` to `namespace` before, it will effect all `Operation`, otherwise, you can define `@tag` and `@route` to `Operation` directly.\r\n\r\nThe tool also supports nested `namespace`, it will automatically generate the nested `namespace` and `interface` in the output file, allowing you to organize your code within a folder structure.\r\n\r\nFinally, the `model.tsp` isn't required, you can split your source code into multiple files, because the `main.tsp` will automatically import all files in the `src/specs` folder.\r\n\r\n### Environment Variables\r\n* `SERVICE_TITLE` - The title of the service\r\n* `SERVER_NAME` - The name of the server\r\n* `SERVER_URL` - The server URL\r\n* `BUILD_PATH` - The path to the generated file\r\n\r\n---\r\n\r\n## Example\r\n\r\nThis project contains `./src/specs/auth` folder, and `index.tsp` has the following definition at the top level:\r\n\r\n```typespec\r\n@tag(\"Auth\")\r\n@route(\"/auth\")\r\nnamespace AuthSpec;\r\n```\r\n\r\nand two interface definitions, `Interface` and `AuthedInterface`, so it will generate the below code in the output file:\r\n\r\n```typespec\r\nnamespace AuthSpecImpl {\r\n  @tag(\"Auth\")\r\n  @route(\"/auth\")\r\n  interface AuthSpecInterface extends AuthSpec.Interface {}\r\n\r\n  @tag(\"Auth\")\r\n  @route(\"/auth\")\r\n  @useAuth(Authorization)\r\n  interface AuthSpecAuthedInterface extends AuthSpec.AuthedInterface {}\r\n}\r\n```\r\n\r\nIn addition, the output file will auto-import, like this:\r\n\r\n```typespec\r\nimport \"./src/specs/auth/index.tsp\";\r\nimport \"./src/specs/auth/model.tsp\";\r\n```\r\n\r\nFinally, generate openapi.yaml file:\r\n\r\n```yaml\r\nopenapi: 3.0.0\r\ninfo:\r\n  title: Main Service\r\n  version: 0.0.0\r\ntags:\r\n  - name: Auth\r\npaths:\r\n  /auth/login:\r\n    post:\r\n      tags:\r\n        - Auth\r\n      operationId: AuthSpecInterface_login\r\n      parameters: []\r\n      responses:\r\n        '200':\r\n          description: The request has succeeded.\r\n          content:\r\n            application/json:\r\n              schema:\r\n                type: object\r\n                required:\r\n                  - data\r\n                  - success\r\n                properties:\r\n                  data:\r\n                    type: string\r\n                  success:\r\n                    type: boolean\r\n        '400':\r\n          description: The server could not understand the request due to invalid syntax.\r\n          content:\r\n            application/json:\r\n              schema:\r\n                $ref: '#/components/schemas/Shared.APIBadRequestResponse'\r\n      requestBody:\r\n        required: true\r\n        content:\r\n          application/json:\r\n            schema:\r\n              $ref: '#/components/schemas/AuthSpec.LoginRequest'\r\n  /auth/logout:\r\n    post:\r\n      tags:\r\n        - Auth\r\n      operationId: AuthSpecAuthedInterface_logout\r\n      parameters: []\r\n      responses:\r\n        '200':\r\n          description: The request has succeeded.\r\n          content:\r\n            application/json:\r\n              schema:\r\n                type: object\r\n                required:\r\n                  - success\r\n                properties:\r\n                  success:\r\n                    type: boolean\r\n        '400':\r\n          description: The server could not understand the request due to invalid syntax.\r\n          content:\r\n            application/json:\r\n              schema:\r\n                $ref: '#/components/schemas/Shared.APIBadRequestResponse'\r\n        '401':\r\n          description: Access is unauthorized.\r\n          content:\r\n            application/json:\r\n              schema:\r\n                $ref: '#/components/schemas/Shared.APIUnauthorizedResponse'\r\n      security:\r\n        - BearerAuth: []\r\n  /auth/profile:\r\n    get:\r\n      tags:\r\n        - Auth\r\n      operationId: AuthSpecAuthedInterface_getProfile\r\n      parameters: []\r\n      responses:\r\n        '200':\r\n          description: The request has succeeded.\r\n          content:\r\n            application/json:\r\n              schema:\r\n                type: object\r\n                required:\r\n                  - data\r\n                  - success\r\n                properties:\r\n                  data:\r\n                    $ref: '#/components/schemas/AuthSpec.Profile'\r\n                  success:\r\n                    type: boolean\r\n        '400':\r\n          description: The server could not understand the request due to invalid syntax.\r\n          content:\r\n            application/json:\r\n              schema:\r\n                $ref: '#/components/schemas/Shared.APIBadRequestResponse'\r\n        '401':\r\n          description: Access is unauthorized.\r\n          content:\r\n            application/json:\r\n              schema:\r\n                $ref: '#/components/schemas/Shared.APIUnauthorizedResponse'\r\n      security:\r\n        - BearerAuth: []\r\ncomponents:\r\n  schemas:\r\n    AuthSpec.LoginRequest:\r\n      type: object\r\n      required:\r\n        - username\r\n        - password\r\n      properties:\r\n        username:\r\n          type: string\r\n        password:\r\n          type: string\r\n    AuthSpec.Profile:\r\n      type: object\r\n      required:\r\n        - name\r\n        - username\r\n      properties:\r\n        name:\r\n          type: string\r\n        username:\r\n          type: string\r\n    Shared.APIBadRequestResponse:\r\n      type: object\r\n      required:\r\n        - message\r\n        - success\r\n      properties:\r\n        message:\r\n          type: string\r\n          enum:\r\n            - Bad Request\r\n        success:\r\n          type: boolean\r\n    Shared.APIUnauthorizedResponse:\r\n      type: object\r\n      required:\r\n        - message\r\n        - success\r\n      properties:\r\n        message:\r\n          type: string\r\n          enum:\r\n            - Unauthorized\r\n        success:\r\n          type: boolean\r\n  securitySchemes:\r\n    BearerAuth:\r\n      type: http\r\n      scheme: bearer\r\nservers:\r\n  - url: http://localhost:3000\r\n    description: MainServer\r\n    variables: {}\r\n```\r\n\r\n---\r\n\r\n## Next Steps?\r\n\r\nYou can use openapi.yaml to generate source code through various tools to improve your development efficiency.\r\n\r\n---\r\n\r\nHappy coding!\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLaiJunBin%2Ftypespec-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FLaiJunBin%2Ftypespec-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLaiJunBin%2Ftypespec-template/lists"}