@lukoweb/apitogo 0.2.42 → 0.2.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,187 @@
1
+ /**
2
+ * The backend of the full template: a small Node.js server with no dependencies, so the platform can build and run it
3
+ * as it is (`npm start`, port from `PORT`), and the OpenAPI file that describes it. The two must list the same
4
+ * endpoints: the gateway only forwards what the file names, and the API reference shows the file.
5
+ */
6
+
7
+ /** The folder of the backend code, relative to the project. */
8
+ export const FULL_SERVER_SOURCE = "server";
9
+ export const FULL_SERVER_RUNTIME = "nodejs";
10
+ export const FULL_SERVER_RUNTIME_VERSION = "NODE_22_LTS";
11
+ export const FULL_SERVER_HEALTH_PATH = "/health";
12
+
13
+ const packageName = (name: string) =>
14
+ `${
15
+ name
16
+ .toLowerCase()
17
+ .replace(/[^a-z0-9-]+/g, "-")
18
+ .replace(/^-+|-+$/g, "") || "api"
19
+ }-server`;
20
+
21
+ /** The files of the server, by path relative to its folder. */
22
+ export function fullServerFiles(name: string): Record<string, string> {
23
+ return {
24
+ "package.json": `${JSON.stringify(
25
+ {
26
+ name: packageName(name),
27
+ version: "1.0.0",
28
+ private: true,
29
+ type: "module",
30
+ main: "index.js",
31
+ scripts: { start: "node index.js" },
32
+ engines: { node: ">=22" },
33
+ },
34
+ null,
35
+ 2,
36
+ )}\n`,
37
+ "index.js": `// A small API for ${JSON.stringify(name)}. Every endpoint here is listed in apitogo/apis/openapi.yaml:
38
+ // add an endpoint in both places, then run \`apitogo deploy\`.
39
+ import { createServer } from "node:http";
40
+
41
+ const items = [
42
+ { id: "1", name: "First item" },
43
+ { id: "2", name: "Second item" },
44
+ { id: "3", name: "Third item" },
45
+ ];
46
+
47
+ // Lets the portal's API page call this server while you run it locally (\`apitogo dev\`). Once deployed, the gateway
48
+ // answers browsers itself and keeps its own list of allowed sites.
49
+ const cors = {
50
+ "access-control-allow-origin": "*",
51
+ "access-control-allow-methods": "GET, OPTIONS",
52
+ "access-control-allow-headers": "*",
53
+ };
54
+
55
+ function send(res, status, body) {
56
+ res.writeHead(status, { "content-type": "application/json", ...cors });
57
+ res.end(JSON.stringify(body));
58
+ }
59
+
60
+ const server = createServer((req, res) => {
61
+ const url = new URL(req.url ?? "/", "http://localhost");
62
+ const itemMatch = url.pathname.match(/^\\/items\\/([^/]+)$/);
63
+
64
+ if (req.method === "OPTIONS") {
65
+ res.writeHead(204, cors);
66
+ return res.end();
67
+ }
68
+ if (req.method !== "GET") return send(res, 405, { error: "Method not allowed" });
69
+ if (url.pathname === "/health") return send(res, 200, { status: "ok" });
70
+ if (url.pathname === "/hello") {
71
+ const who = url.searchParams.get("name") || "world";
72
+ return send(res, 200, { message: \`Hello, \${who}!\` });
73
+ }
74
+ if (url.pathname === "/items") return send(res, 200, items);
75
+ if (itemMatch) {
76
+ const item = items.find((candidate) => candidate.id === itemMatch[1]);
77
+ return item ? send(res, 200, item) : send(res, 404, { error: "Item not found" });
78
+ }
79
+ return send(res, 404, { error: "Not found" });
80
+ });
81
+
82
+ const port = Number(process.env.PORT) || 8080;
83
+ server.listen(port, () => console.log(\`API listening on port \${port}\`));
84
+ `,
85
+ "README.md": `# ${name} server
86
+
87
+ A small Node.js API with no dependencies, created by \`apitogo create --template full\`.
88
+
89
+ - Run it locally: \`npm start\` (port 8080, or \`PORT\`)
90
+ - Deploy it: \`apitogo deploy\` from the project folder
91
+
92
+ Every endpoint in \`index.js\` is also listed in \`apitogo/apis/openapi.yaml\`. Keep the two in step: the gateway only
93
+ forwards the endpoints the file names, and the API reference of the portal is built from it.
94
+ `,
95
+ };
96
+ }
97
+
98
+ /** The OpenAPI file of the full template, matching `fullServerFiles`. */
99
+ export const FULL_SPEC = (name: string) => `openapi: 3.1.0
100
+ info:
101
+ title: ${JSON.stringify(name)}
102
+ version: 1.0.0
103
+ description: A small sample API. Edit server/index.js and this file together.
104
+ paths:
105
+ /health:
106
+ get:
107
+ operationId: getHealth
108
+ summary: Health check
109
+ responses:
110
+ "200":
111
+ description: The service is up.
112
+ content:
113
+ application/json:
114
+ schema:
115
+ type: object
116
+ properties:
117
+ status:
118
+ type: string
119
+ example: ok
120
+ /hello:
121
+ get:
122
+ operationId: getHello
123
+ summary: Say hello
124
+ parameters:
125
+ - name: name
126
+ in: query
127
+ required: false
128
+ description: Who to greet.
129
+ schema:
130
+ type: string
131
+ example: developer
132
+ responses:
133
+ "200":
134
+ description: A greeting.
135
+ content:
136
+ application/json:
137
+ schema:
138
+ type: object
139
+ properties:
140
+ message:
141
+ type: string
142
+ example: Hello, developer!
143
+ /items:
144
+ get:
145
+ operationId: listItems
146
+ summary: List items
147
+ responses:
148
+ "200":
149
+ description: All items.
150
+ content:
151
+ application/json:
152
+ schema:
153
+ type: array
154
+ items:
155
+ $ref: "#/components/schemas/Item"
156
+ /items/{id}:
157
+ get:
158
+ operationId: getItem
159
+ summary: Get one item
160
+ parameters:
161
+ - name: id
162
+ in: path
163
+ required: true
164
+ schema:
165
+ type: string
166
+ example: "1"
167
+ responses:
168
+ "200":
169
+ description: The item.
170
+ content:
171
+ application/json:
172
+ schema:
173
+ $ref: "#/components/schemas/Item"
174
+ "404":
175
+ description: No item has this id.
176
+ components:
177
+ schemas:
178
+ Item:
179
+ type: object
180
+ properties:
181
+ id:
182
+ type: string
183
+ example: "1"
184
+ name:
185
+ type: string
186
+ example: First item
187
+ `;