example tsp project

This commit is contained in:
2025-03-11 09:14:34 -04:00
commit 9f77150784
10 changed files with 6957 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
node_modules
tsp-output

6827
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

27
package.json Normal file
View File

@@ -0,0 +1,27 @@
{
"name": "@foo/cms",
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "multiview [npm run compile -- --watch] [npm run serve]",
"compile": "npm run clean && tsp compile src",
"serve": "counterfact ./openapi.json server --prefix api/",
"clean": "echo foo"
},
"exports": {
"./crud": "./src/crud.tsp"
},
"peerDependencies": {
"@typespec/compiler": "latest",
"@typespec/http": "latest",
"@typespec/openapi3": "latest"
},
"devDependencies": {
"@pojagi/http-server-drf": "../http-server-drf",
"@typespec/compiler": "latest",
"@typespec/http": "latest",
"@typespec/openapi3": "latest",
"counterfact": "^0.25.5",
"multiview": "^3.0.1"
}
}

12
src/api.tsp Normal file
View File

@@ -0,0 +1,12 @@
import "@typespec/http";
import "./api/v1.tsp";
using TypeSpec.Http;
@doc("A content management service.")
@service({
title: "Foo Content Management Service",
})
@route("/api")
namespace Api;

10
src/api/v1.tsp Normal file
View File

@@ -0,0 +1,10 @@
import "@typespec/http";
import "./v1/config.tsp";
import "./v1/journal.tsp";
using TypeSpec.Http;
@doc("The first version of the Api.")
@route("/v1")
namespace Api.V1;

17
src/api/v1/config.tsp Normal file
View File

@@ -0,0 +1,17 @@
import "@typespec/http";
import "@foo/cms/crud";
using TypeSpec.Http;
namespace Api.V1.Config;
model Setting {
name: string;
value: string;
}
@route("/settings")
@tag("config")
@summary("A collection of application settings.")
interface Settings extends Entity<Setting> {}

23
src/api/v1/journal.tsp Normal file
View File

@@ -0,0 +1,23 @@
import "@typespec/http";
import "@foo/cms/crud";
using TypeSpec.Http;
namespace Api.V1.Journal;
model EntryBody {
date: utcDateTime;
name: string;
value: string;
}
model Entry extends EntryBody {
@minValue(1)
id: uint32;
}
@route("/entries")
@tag("config")
@summary("A collection of journal entries.")
interface Entries extends Entity<Entry, Body = EntryBody, Id = uint32> {}

27
src/crud.tsp Normal file
View File

@@ -0,0 +1,27 @@
import "@typespec/http";
using TypeSpec.Http;
@error
model ProblemDetails {
type: string;
title: string;
status: int32;
detail: string;
}
model NotFound {
@statusCode _: 404;
}
interface Entity<T, Body = T, Id = string> {
@get list(): T[] | ProblemDetails;
@get read(@path id: Id): T | NotFound | ProblemDetails;
@post create(@body body: Body): {
@statusCode _: 201;
...T;
} | ProblemDetails;
@patch update(@path id: Id, ...Body): T | NotFound | ProblemDetails;
@delete delete(@path id: string): T | NotFound | ProblemDetails;
}

1
src/main.tsp Normal file
View File

@@ -0,0 +1 @@
import "./api.tsp";

11
tspconfig.yaml Normal file
View File

@@ -0,0 +1,11 @@
emit:
# - "@typespec/openapi3"
# - "@typespec/http-server-csharp"
# - "@typespec/http-server-js"
- "@pojagi/http-server-drf"
options:
# "@typespec/openapi3":
# # emitter-output-dir: "{project-root}"
# file-type: yaml
# "@typespec/http-server-js":
# express: true