@lukoweb/apitogo 0.2.42 → 0.2.44

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