flet-box 1.0.4 → 1.0.5

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.
Files changed (147) hide show
  1. package/README.md +10 -0
  2. package/bin/cli.js +15 -0
  3. package/bin/commands/checkApi.js +761 -0
  4. package/bin/commands/create.js +77 -5
  5. package/bin/utils/dtsProps.js +191 -0
  6. package/bin/utils/moduleExports.js +165 -0
  7. package/bin/utils/neutralise.js +64 -0
  8. package/bin/utils/templates.js +366 -27
  9. package/docs/CONTRIBUTING.md +156 -0
  10. package/docs/README.md +68 -0
  11. package/docs/arquitectura.md +164 -0
  12. package/docs/cli/README.md +542 -0
  13. package/docs/guides/README.md +33 -0
  14. package/docs/guides/app-templates.md +197 -0
  15. package/docs/guides/compatibility.md +95 -0
  16. package/docs/guides/embedding.md +284 -0
  17. package/docs/guides/first-app.md +208 -0
  18. package/docs/guides/frontend-services.md +171 -0
  19. package/docs/guides/minification-and-protection.md +260 -0
  20. package/docs/guides/mobile-and-platforms.md +439 -0
  21. package/docs/guides/online-updates.md +196 -0
  22. package/docs/guides/router.md +282 -0
  23. package/docs/guides/state.md +283 -0
  24. package/docs/guides/syntax-philosophy.md +150 -0
  25. package/docs/guides/utilities.md +241 -0
  26. package/docs/guides/widget-structure.md +163 -0
  27. package/docs/server/README.md +68 -0
  28. package/docs/server/START_HERE.md +121 -0
  29. package/docs/server/api.md +225 -0
  30. package/docs/server/data-services.md +300 -0
  31. package/docs/server/deployment.md +113 -0
  32. package/docs/server/security.md +196 -0
  33. package/docs/services/README.md +79 -0
  34. package/docs/services/RamStore.md +84 -0
  35. package/docs/services/Session.md +84 -0
  36. package/docs/services/Storage.md +88 -0
  37. package/docs/services/http.md +86 -0
  38. package/docs/tools/README.md +138 -0
  39. package/docs/tools/animation.md +87 -0
  40. package/docs/tools/async-ids-log.md +80 -0
  41. package/docs/tools/device.md +132 -0
  42. package/docs/tools/introspection.md +67 -0
  43. package/docs/tools/lists.md +96 -0
  44. package/docs/tools/markdown.md +79 -0
  45. package/docs/tools/reactivity.md +288 -0
  46. package/docs/tools/state.md +103 -0
  47. package/docs/tools/styling.md +92 -0
  48. package/docs/tools/text-and-time.md +89 -0
  49. package/docs/tools/theme.md +102 -0
  50. package/docs/tools/validation.md +75 -0
  51. package/docs/tools/visual-effects.md +84 -0
  52. package/docs/widget/Accordion.md +144 -0
  53. package/docs/widget/AdMob.md +144 -0
  54. package/docs/widget/AdSense.md +133 -0
  55. package/docs/widget/AdaptiveScaffold.md +105 -0
  56. package/docs/widget/AlertDialog.md +103 -0
  57. package/docs/widget/AnimatedBox.md +130 -0
  58. package/docs/widget/AnimatedText.md +123 -0
  59. package/docs/widget/AppBar.md +118 -0
  60. package/docs/widget/Audio.md +135 -0
  61. package/docs/widget/Avatar.md +119 -0
  62. package/docs/widget/Badge.md +128 -0
  63. package/docs/widget/BottomNavigation.md +116 -0
  64. package/docs/widget/BottomSheet.md +125 -0
  65. package/docs/widget/Button.md +137 -0
  66. package/docs/widget/COMMON_PROPS.md +150 -0
  67. package/docs/widget/Card.md +125 -0
  68. package/docs/widget/Carousel.md +151 -0
  69. package/docs/widget/Chart.md +151 -0
  70. package/docs/widget/Checkbox.md +118 -0
  71. package/docs/widget/Chip.md +126 -0
  72. package/docs/widget/CircularBar.md +168 -0
  73. package/docs/widget/CircularChart.md +164 -0
  74. package/docs/widget/CodeViewer.md +130 -0
  75. package/docs/widget/CollapsibleSideBar.md +112 -0
  76. package/docs/widget/Column.md +129 -0
  77. package/docs/widget/Container.md +136 -0
  78. package/docs/widget/DataTable.md +150 -0
  79. package/docs/widget/Divider.md +109 -0
  80. package/docs/widget/DraggBox.md +129 -0
  81. package/docs/widget/Drawer.md +135 -0
  82. package/docs/widget/DrawerItem.md +98 -0
  83. package/docs/widget/Dropdown.md +139 -0
  84. package/docs/widget/DroppBox.md +152 -0
  85. package/docs/widget/FloatingActionButton.md +120 -0
  86. package/docs/widget/GridView.md +140 -0
  87. package/docs/widget/Icon.md +117 -0
  88. package/docs/widget/Image.md +125 -0
  89. package/docs/widget/Input.md +151 -0
  90. package/docs/widget/Inspector.md +92 -0
  91. package/docs/widget/InstallButton.md +128 -0
  92. package/docs/widget/ListTile.md +132 -0
  93. package/docs/widget/ListView.md +138 -0
  94. package/docs/widget/Markdown.md +175 -0
  95. package/docs/widget/MatrixRain.md +122 -0
  96. package/docs/widget/Modal.md +129 -0
  97. package/docs/widget/Pagination.md +135 -0
  98. package/docs/widget/ParallaxBox.md +128 -0
  99. package/docs/widget/ProgressBar.md +130 -0
  100. package/docs/widget/QRCode.md +117 -0
  101. package/docs/widget/README.md +188 -0
  102. package/docs/widget/Radio.md +123 -0
  103. package/docs/widget/Rating.md +131 -0
  104. package/docs/widget/Row.md +131 -0
  105. package/docs/widget/START_HERE.md +146 -0
  106. package/docs/widget/Scaffold.md +152 -0
  107. package/docs/widget/Skeleton.md +130 -0
  108. package/docs/widget/Slider.md +146 -0
  109. package/docs/widget/SnackBar.md +102 -0
  110. package/docs/widget/Stack.md +128 -0
  111. package/docs/widget/Stepper.md +145 -0
  112. package/docs/widget/Switch.md +118 -0
  113. package/docs/widget/Tabs.md +124 -0
  114. package/docs/widget/Text.md +133 -0
  115. package/docs/widget/Tooltip.md +145 -0
  116. package/docs/widget/TreeView.md +176 -0
  117. package/docs/widget/Video.md +127 -0
  118. package/docs/widget/_template.md +61 -0
  119. package/package.json +3 -2
  120. package/src/animations/animate.js +180 -70
  121. package/src/animations/index.js +1 -0
  122. package/src/create-index.sh +1 -1
  123. package/src/index.d.ts +45 -22
  124. package/src/index.js +1 -0
  125. package/src/navigations/AdaptiveScaffold.js +11 -2
  126. package/src/navigations/BottomNavigation.js +10 -3
  127. package/src/navigations/Tabs.js +6 -2
  128. package/src/tools/useState.js +54 -63
  129. package/src/widget-factory/assignProps.js +23 -1
  130. package/src/widget-factory/processProps.js +10 -3
  131. package/src/widget-factory/reactiveValue.js +43 -18
  132. package/src/widget-factory/translateProps.js +777 -901
  133. package/src/widgets/AlertDialog.js +7 -5
  134. package/src/widgets/Checkbox.js +9 -7
  135. package/src/widgets/CircularBar.js +12 -1
  136. package/src/widgets/FloatingActionButton.js +4 -7
  137. package/src/widgets/Image.js +5 -7
  138. package/src/widgets/Input.js +92 -0
  139. package/src/widgets/ListView.js +73 -29
  140. package/src/widgets/Pagination.js +6 -3
  141. package/src/widgets/ProgressBar.js +16 -13
  142. package/src/widgets/Radio.js +6 -7
  143. package/src/widgets/Slider.js +23 -4
  144. package/src/widgets/Stack.js +36 -3
  145. package/src/widgets/Stepper.js +4 -3
  146. package/src/widgets/Switch.js +3 -4
  147. package/src/widgets/TreeView.js +0 -1
@@ -0,0 +1,225 @@
1
+ # API and routes
2
+
3
+ ## `Api()`
4
+
5
+ `Api()` turns a readable route object into the internal route map used by the server.
6
+
7
+ ```javascript
8
+ import { Api } from "flet-box-server";
9
+
10
+ const routes = Api({
11
+ "/products": {
12
+ GET: {
13
+ handler: ({ query }) => ({
14
+ items: [],
15
+ search: query.search || null,
16
+ }),
17
+ tag: "products",
18
+ description: "List products",
19
+ },
20
+ },
21
+ });
22
+ ```
23
+
24
+ Supported methods are `GET`, `POST`, `PUT`, `DELETE`, and `PATCH`.
25
+
26
+ ## Handler styles
27
+
28
+ A short handler can be a function:
29
+
30
+ ```javascript
31
+ "/health": {
32
+ GET: () => ({ ok: true }),
33
+ }
34
+ ```
35
+
36
+ A detailed handler can include middleware, metadata, schemas, and examples:
37
+
38
+ ```javascript
39
+ "/tasks": {
40
+ POST: {
41
+ handler: ({ title, completed }) => ({
42
+ id: 1,
43
+ title,
44
+ completed,
45
+ }),
46
+ middleware: [],
47
+ tag: "tasks",
48
+ description: "Create a task",
49
+ example: {
50
+ title: "Read the docs",
51
+ completed: false,
52
+ },
53
+ responseExample: {
54
+ id: 1,
55
+ title: "Read the docs",
56
+ completed: false,
57
+ },
58
+ },
59
+ }
60
+ ```
61
+
62
+ ## URL parameters
63
+
64
+ Use `:name` in a route path:
65
+
66
+ ```javascript
67
+ "/users/:id": {
68
+ GET: ({ id }) => ({
69
+ userId: id,
70
+ }),
71
+ }
72
+ ```
73
+
74
+ The server matches `/users/42` and provides `id: "42"` to the handler.
75
+
76
+ ## Query parameters
77
+
78
+ Query values are available through `query` or `req.query`:
79
+
80
+ ```javascript
81
+ "/search": {
82
+ GET: ({ query }) => ({
83
+ term: query.term || "",
84
+ page: Number(query.page || 1),
85
+ }),
86
+ }
87
+ ```
88
+
89
+ Request example:
90
+
91
+ ```bash
92
+ curl "http://localhost:3000/search?term=widgets&page=2"
93
+ ```
94
+
95
+ ## Request body
96
+
97
+ For JSON requests, body fields are spread into the handler context:
98
+
99
+ ```javascript
100
+ "/profile": {
101
+ PUT: {
102
+ handler: ({ name, email }) => ({ name, email }),
103
+ example: {
104
+ name: "Ada",
105
+ email: "ada@example.com",
106
+ },
107
+ },
108
+ }
109
+ ```
110
+
111
+ You can also access the original body through `req.body`.
112
+
113
+ ## Automatic request schemas
114
+
115
+ When a method has an `example`, the server calls `inferSchema()` and stores the generated schema in the route documentation.
116
+
117
+ ```javascript
118
+ example: {
119
+ name: "Ada",
120
+ age: 30,
121
+ active: true,
122
+ tags: ["developer"],
123
+ }
124
+ ```
125
+
126
+ Use real JavaScript values in examples. For example, `age: 30`, not `age: thirty`.
127
+
128
+ The inferred schema detects strings, numbers, booleans, arrays, objects, email-like values, and URL-like values.
129
+
130
+ ## Manual schemas
131
+
132
+ Use `schemas` when the inferred schema is not enough:
133
+
134
+ ```javascript
135
+ "/users": {
136
+ POST: {
137
+ handler: ({ body }) => body,
138
+ schemas: {
139
+ CreateUser: {
140
+ type: "object",
141
+ properties: {
142
+ name: { type: "string", minLength: 2 },
143
+ email: { type: "email" },
144
+ },
145
+ required: ["name", "email"],
146
+ },
147
+ },
148
+ },
149
+ }
150
+ ```
151
+
152
+ For active validation, use `validate: true` in the server options or add validation middleware explicitly.
153
+
154
+ ## Response examples
155
+
156
+ `responseExample` creates response documentation and a success response entry:
157
+
158
+ ```javascript
159
+ responseExample: {
160
+ id: 1,
161
+ name: "Ada",
162
+ }
163
+ ```
164
+
165
+ ## Middleware
166
+
167
+ Middleware uses the Express-style `(req, res, next)` shape:
168
+
169
+ ```javascript
170
+ const logRequest = (req, res, next) => {
171
+ console.log(req.method, req.url);
172
+ next();
173
+ };
174
+
175
+ const routes = Api({
176
+ "/health": {
177
+ GET: {
178
+ handler: () => ({ ok: true }),
179
+ middleware: [logRequest],
180
+ },
181
+ },
182
+ });
183
+ ```
184
+
185
+ ## Generated documentation
186
+
187
+ Enable docs when starting the server:
188
+
189
+ ```javascript
190
+ runServer(routes, { docs: true });
191
+ ```
192
+
193
+ The server exposes:
194
+
195
+ ```text
196
+ GET /docs
197
+ ```
198
+
199
+ The response groups endpoints by tag and includes methods, descriptions, schemas, responses, and generated curl, Python, and JavaScript examples.
200
+
201
+ ## HTTP responses
202
+
203
+ Returning an object sends a JSON response with status `200`:
204
+
205
+ ```javascript
206
+ "/status": {
207
+ GET: () => ({ status: "ok" }),
208
+ }
209
+ ```
210
+
211
+ For errors inside middleware, use:
212
+
213
+ ```javascript
214
+ return res.error("Unauthorized", 401);
215
+ ```
216
+
217
+ ## Route checklist
218
+
219
+ - Use a clear path.
220
+ - Use the correct HTTP method.
221
+ - Add `description` and `tag`.
222
+ - Add `example` for body-based methods.
223
+ - Add `responseExample` for useful response documentation.
224
+ - Add authentication and validation where needed.
225
+ - Do not expose secrets in examples or responses.
@@ -0,0 +1,300 @@
1
+ # Database and services
2
+
3
+ ## Where should your data live?
4
+
5
+ A browser cannot run every database engine. The Node `better-sqlite3` library used by the server tools is a **native module** — it only runs on the server. Before choosing storage, decide where the data lives.
6
+
7
+ ### Option 1 — Browser only (no API)
8
+
9
+ Data stays on the visitor's device. No server and no network calls.
10
+
11
+ - **localStorage** — ships with the framework as `src/services/Storage.js` (`saveData`, `getData`, `updateData`, `deleteData`, ...). Synchronous, ~5 MB per origin, string values; the helpers serialize objects for you.
12
+ - **IndexedDB** — asynchronous and much larger (gigabytes). Good for big records or offline files. Not bundled; call it directly or wrap it in a small helper.
13
+ - **SQLite in the browser** — sql.js or sqlite-wasm run real SQL as WebAssembly. Not bundled.
14
+
15
+ Choose this for drafts, per-device settings, offline caches, or single-user prototypes.
16
+
17
+ ### Option 2 — SQLite API server
18
+
19
+ Data lives on your server and the UI talks to it over HTTP through the [API server section](#api-server-for-sqlite) below:
20
+
21
+ ```text
22
+ UI widget (httpGet / httpPost / httpPut / httpDelete)
23
+ ↓ HTTPS + JSON
24
+ Server routes (Api + runServer)
25
+ ↓
26
+ SQLite (better-sqlite3 wrapper)
27
+ ```
28
+
29
+ Choose this when data is shared between users or devices, must survive a browser reset, or is read by other systems.
30
+
31
+ ### Option 3 — Hybrid
32
+
33
+ Use browser storage for offline cache and preferences, and sync with the API when the app is online.
34
+
35
+ ## SQLite database
36
+
37
+ The current `Database` helper supports SQLite through the `SQLite` wrapper.
38
+
39
+ > **Import rule:** the package root exports the core only. Every tool is a deep import (`flet-box-server/tools/<name>.js`) so that loading one never pulls in puppeteer, twilio, xlsx or the optional Google Cloud packages.
40
+
41
+ ```javascript
42
+ import { Database } from "flet-box-server/tools/Database.js";
43
+
44
+ const db = Database({
45
+ type: "sqlite",
46
+ path: "data/app.db",
47
+ tables: {
48
+ users: {
49
+ id: "INTEGER PRIMARY KEY AUTOINCREMENT",
50
+ name: "TEXT",
51
+ email: "TEXT",
52
+ },
53
+ },
54
+ });
55
+ ```
56
+
57
+ Use the generated table API:
58
+
59
+ ```javascript
60
+ const result = db.users.insert({
61
+ name: "Ada",
62
+ email: "ada@example.com",
63
+ });
64
+
65
+ const users = db.users.readAll();
66
+ const ada = db.users.readWhere(["email", "ada@example.com"], true);
67
+ db.users.update({ name: "Ada Lovelace" }, ["email", "ada@example.com"]);
68
+ db.users.delete(["email", "ada@example.com"]);
69
+ ```
70
+
71
+ The lower-level SQLite class also provides table creation, updates, deletes, structure inspection, and reads.
72
+
73
+ ## API server for SQLite
74
+
75
+ Wire the SQLite wrapper into the route server so the UI can read and write data safely over HTTP. Every wrapper method returns `[status, messageOrData]` — `true` when the operation succeeded.
76
+
77
+ ```javascript
78
+ // server/index.js
79
+ import { Api, runServer } from "flet-box-server/core/index.js";
80
+ import { SQLite } from "flet-box-server/tools/betterSqlite.js";
81
+
82
+ const db = new SQLite("data/app.db");
83
+ db.createTable("users", {
84
+ id: "INTEGER PRIMARY KEY AUTOINCREMENT",
85
+ name: "TEXT",
86
+ email: "TEXT",
87
+ });
88
+
89
+ const routes = Api({
90
+ "/api/users": {
91
+ GET: () => {
92
+ const [ok, rows] = db.readAll("users");
93
+ return { ok, items: ok ? rows : [] };
94
+ },
95
+ POST: ({ body }) => {
96
+ const [ok, msg] = db.insert("users", {
97
+ name: body.name,
98
+ email: body.email,
99
+ });
100
+ return ok ? { ok } : { ok, error: msg };
101
+ },
102
+ },
103
+ "/api/users/:id": {
104
+ PUT: ({ id, body }) => {
105
+ const [ok, msg] = db.update("users", { email: body.email }, ["id", id]);
106
+ return ok ? { ok } : { ok, error: msg };
107
+ },
108
+ DELETE: ({ id }) => {
109
+ const [ok, msg] = db.delete("users", ["id", id]);
110
+ return ok ? { ok } : { ok, error: msg };
111
+ },
112
+ },
113
+ });
114
+
115
+ runServer(routes, { port: 3000, docs: true });
116
+ ```
117
+
118
+ Consume the API from the UI with the framework HTTP client:
119
+
120
+ ```javascript
121
+ // app.js (FletBox UI)
122
+ import { httpGet, httpPost, httpPut, httpDelete } from "flet-box";
123
+
124
+ const list = await httpGet("http://localhost:3000/api/users");
125
+ const created = await httpPost("http://localhost:3000/api/users", {
126
+ body: { name: "Ada", email: "ada@example.com" },
127
+ });
128
+ const updated = await httpPut("http://localhost:3000/api/users/1", {
129
+ body: { email: "ada@lovelace.dev" },
130
+ });
131
+ const removed = await httpDelete("http://localhost:3000/api/users/1");
132
+ ```
133
+
134
+ Start the server, then open the auto-generated docs at `http://localhost:3000/docs` to browse and test the endpoints.
135
+
136
+ ## Redis cache
137
+
138
+ Configure Redis with `REDIS_URL`:
139
+
140
+ ```bash
141
+ REDIS_URL=redis://localhost:6379
142
+ ```
143
+
144
+ Use the cache helpers:
145
+
146
+ ```javascript
147
+ import { connectRedis, cacheSet, cacheGet, cacheDel } from "flet-box-server/tools/cache.js";
148
+
149
+ connectRedis();
150
+ await cacheSet("user:1", { name: "Ada" }, 3600);
151
+ const user = await cacheGet("user:1");
152
+ await cacheDel("user:1");
153
+ ```
154
+
155
+ ## File storage
156
+
157
+ The local storage module uses `STORAGE_PATH` or `./storage`:
158
+
159
+ ```javascript
160
+ import { uploadFile, downloadFile, listFiles, deleteFile } from "flet-box-server/tools/storage.js";
161
+
162
+ const file = await uploadFile("avatars", "profile.jpg", imageBuffer);
163
+ const stream = await downloadFile(file.path);
164
+ const files = await listFiles("avatars");
165
+ await deleteFile(file.path);
166
+ ```
167
+
168
+ Validate file names, sizes, and content types before storing uploads.
169
+
170
+ ## Email
171
+
172
+ Configure SMTP credentials through environment variables in production. A simple send looks like:
173
+
174
+ ```javascript
175
+ import { sendEmail } from "flet-box-server/tools/email.js";
176
+
177
+ await sendEmail({
178
+ sendTo: "user@example.com",
179
+ title: "Welcome",
180
+ personalCode: 123456,
181
+ userName: "Ada",
182
+ });
183
+ ```
184
+
185
+ Never commit passwords or application tokens in source code.
186
+
187
+ ## SMS
188
+
189
+ Configure Twilio:
190
+
191
+ ```bash
192
+ TWILIO_ACCOUNT_SID=...
193
+ TWILIO_AUTH_TOKEN=...
194
+ TWILIO_PHONE_NUMBER=...
195
+ ```
196
+
197
+ ```javascript
198
+ import { sendSMS, sendVerificationCode, verifyPhone } from "flet-box-server/tools/sms.js";
199
+
200
+ await sendSMS("+123456789", "Your code is 123456");
201
+ const code = await sendVerificationCode("+123456789");
202
+ const valid = await verifyPhone("+123456789", code);
203
+ ```
204
+
205
+ The default verification store is in memory. Use a shared persistent store when scaling.
206
+
207
+ ## PDF
208
+
209
+ ```javascript
210
+ import { generatePDF, savePDF, generateInvoice } from "flet-box-server/tools/pdf.js";
211
+
212
+ const pdf = await generatePDF("<h1>Hello</h1>", { format: "A4" });
213
+ await savePDF(pdf, "output.pdf");
214
+
215
+ const invoice = await generateInvoice({
216
+ number: "INV-001",
217
+ date: "2026-01-01",
218
+ client: "Ada Lovelace",
219
+ items: [{ description: "Consulting", quantity: 2, price: 50 }],
220
+ total: 100,
221
+ });
222
+ ```
223
+
224
+ PDF generation uses Puppeteer and may require additional system configuration in deployment environments.
225
+
226
+ ## CSV and Excel
227
+
228
+ ```javascript
229
+ import { readCSV, writeCSV, readExcel, writeExcel } from "flet-box-server/tools/csv.js";
230
+
231
+ const users = await readCSV("users.csv");
232
+ await writeCSV("copy.csv", users);
233
+ const workbookRows = await readExcel("users.xlsx");
234
+ await writeExcel("copy.xlsx", workbookRows);
235
+ ```
236
+
237
+ ## Queues
238
+
239
+ Queues use Redis and Bull:
240
+
241
+ ```javascript
242
+ import { createQueue, addJob, processQueue } from "flet-box-server/tools/queue.js";
243
+
244
+ createQueue("emails", { attempts: 3, backoff: 5000 });
245
+
246
+ processQueue("emails", async (job) => {
247
+ await sendEmail(job.data);
248
+ });
249
+
250
+ await addJob("emails", {
251
+ sendTo: "user@example.com",
252
+ title: "Welcome",
253
+ });
254
+ ```
255
+
256
+ Use queues for slow work that should not block an HTTP request.
257
+
258
+ ## WebSockets
259
+
260
+ ```javascript
261
+ import { createWebSocketServer } from "flet-box-server/tools/webSocket.js";
262
+
263
+ const wss = createWebSocketServer(3001);
264
+
265
+ wss.onConnection((ws) => {
266
+ ws.send(JSON.stringify({ type: "connected" }));
267
+ });
268
+
269
+ wss.onMessage((ws, message) => {
270
+ wss.broadcast({ type: "message", data: message });
271
+ });
272
+ ```
273
+
274
+ The server supports connection, message, close, error, broadcast, and room operations.
275
+
276
+ ## Speech and translation
277
+
278
+ Optional Google Cloud modules provide speech-to-text and text-to-speech. They are `optionalDependencies`, so install the ones you use (`npm install @google-cloud/speech @google-cloud/text-to-speech`); they require cloud credentials and should be configured outside source control.
279
+
280
+ ```javascript
281
+ import { transcribeFile } from "flet-box-server/tools/speechToText.js";
282
+ import { speak } from "flet-box-server/tools/textToSpeech.js";
283
+ import { translate } from "flet-box-server/tools/translator.js";
284
+
285
+ const text = await transcribeFile("audio.mp3", { language: "en-US" });
286
+ const audio = await speak("Hello", "en");
287
+ const translated = await translate("hello", "es");
288
+ ```
289
+
290
+ ## Logging
291
+
292
+ ```javascript
293
+ import { logger } from "flet-box-server/tools/logger.js";
294
+
295
+ logger.save("logs/app.log");
296
+ logger.info("Server started");
297
+ logger.warn("Slow request", { duration: 800 });
298
+ logger.error("Database error", { code: "DB_ERROR" });
299
+ logger.close();
300
+ ```
@@ -0,0 +1,113 @@
1
+ # Deployment and operations
2
+
3
+ ## Development server
4
+
5
+ Create a small entry file and run it with Node:
6
+
7
+ ```bash
8
+ node server.js
9
+ ```
10
+
11
+ For automatic restarts, use the package script or nodemon:
12
+
13
+ ```bash
14
+ npm run dev
15
+ ```
16
+
17
+ ## Environment variables
18
+
19
+ Use environment variables for secrets and deployment settings:
20
+
21
+ ```bash
22
+ PORT=3000
23
+ JWT_SECRET=replace-with-a-long-random-secret
24
+ CORS_ORIGINS=https://app.example.com
25
+ REDIS_URL=redis://localhost:6379
26
+ STORAGE_PATH=./storage
27
+ TWILIO_ACCOUNT_SID=...
28
+ TWILIO_AUTH_TOKEN=...
29
+ TWILIO_PHONE_NUMBER=...
30
+ ```
31
+
32
+ Do not commit `.env` files containing secrets.
33
+
34
+ ## Production server
35
+
36
+ Prefer the secure wrapper:
37
+
38
+ ```javascript
39
+ import { Api, runSecureServer } from "flet-box-server";
40
+
41
+ const routes = Api({
42
+ "/health": {
43
+ GET: () => ({ status: "ok" }),
44
+ },
45
+ });
46
+
47
+ runSecureServer(routes, {
48
+ port: Number(process.env.PORT || 3000),
49
+ docs: false,
50
+ rateLimit: { max: 100, windowMs: 60_000 },
51
+ });
52
+ ```
53
+
54
+ Set `docs: true` only when the generated documentation is safe to expose.
55
+
56
+ ## Health check
57
+
58
+ Add a simple route for monitoring:
59
+
60
+ ```javascript
61
+ "/health": {
62
+ GET: () => ({
63
+ status: "ok",
64
+ timestamp: new Date().toISOString(),
65
+ }),
66
+ }
67
+ ```
68
+
69
+ ## Docker
70
+
71
+ A minimal Dockerfile:
72
+
73
+ ```dockerfile
74
+ FROM node:20-alpine
75
+ WORKDIR /app
76
+ COPY package*.json ./
77
+ RUN npm ci --omit=dev
78
+ COPY . .
79
+ EXPOSE 3000
80
+ CMD ["node", "server.js"]
81
+ ```
82
+
83
+ Build and run:
84
+
85
+ ```bash
86
+ docker build -t flet-box-server .
87
+ docker run --env-file .env -p 3000:3000 flet-box-server
88
+ ```
89
+
90
+ ## HTTPS and proxies
91
+
92
+ Put HTTPS at a trusted reverse proxy such as Nginx, Caddy, or a cloud load balancer. Forward only the headers your proxy controls and configure CORS explicitly.
93
+
94
+ ## Scaling
95
+
96
+ The default cache, rate limiter, verification store, and security incident list use memory. For multiple server processes, move shared state to Redis or another shared service.
97
+
98
+ Queues also require Redis to coordinate jobs between workers.
99
+
100
+ ## Production checklist
101
+
102
+ - Use Node.js 18 or newer.
103
+ - Run `npm ci --omit=dev` in deployment.
104
+ - Set a strong `JWT_SECRET`.
105
+ - Remove hardcoded admin credentials.
106
+ - Disable or protect `/docs` when it exposes internal routes.
107
+ - Set explicit CORS origins.
108
+ - Use HTTPS.
109
+ - Enable validation and rate limiting.
110
+ - Configure Redis for shared cache, sessions, queues, and verification codes.
111
+ - Configure persistent storage and database backups.
112
+ - Monitor `/health`, errors, latency, and resource usage.
113
+ - Do not log passwords, tokens, or private personal data.