flet-box 1.0.4 → 1.0.6

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 +23 -7
  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,241 @@
1
+ # FletBox utilities
2
+
3
+ FletBox includes small helpers for common UI and application tasks. Import only the helpers you need from `flet-box`.
4
+
5
+ ## Layout helpers
6
+
7
+ Use direct props for the simplest code:
8
+
9
+ ```javascript
10
+ Container({
11
+ padding: 16,
12
+ margin: "8px 0",
13
+ gap: 12,
14
+ });
15
+ ```
16
+
17
+ Use helpers when spacing or layout becomes more descriptive:
18
+
19
+ ```javascript
20
+ import { border, flex, grid, margin, padding, shadow } from "flet-box";
21
+
22
+ Container({
23
+ padding: padding({ horizontal: 20, vertical: 12 }),
24
+ margin: margin({ top: 8, bottom: 16 }),
25
+ border: border(1, "solid", "#e5e7eb"),
26
+ shadow: shadow(0, 4, 12, 0, "rgba(0,0,0,0.12)"),
27
+ });
28
+
29
+ const columns = grid({ columns: 3, gap: 16 });
30
+ const flexible = flex(1, 0, "auto");
31
+ ```
32
+
33
+ ## Colors and effects
34
+
35
+ ```javascript
36
+ import { color, gradient, rgba } from "flet-box";
37
+
38
+ const transparentBlue = rgba(37, 99, 235, 0.2);
39
+ const background = gradient("linear", ["#6366f1", "#8b5cf6"], 135);
40
+ const lighter = color("#6366f1").lighten(20);
41
+ ```
42
+
43
+ Color helpers can lighten, darken, adjust alpha, inspect contrast, and create related colors.
44
+
45
+ Effects such as transforms and transitions return values that can be used by supported direct props:
46
+
47
+ ```javascript
48
+ import { transform, transition } from "flet-box";
49
+
50
+ Container({
51
+ transform: transform({ translateY: -4, scale: 1.02 }),
52
+ transition: transition({ property: "all", duration: 0.3, timing: "ease" }),
53
+ });
54
+ ```
55
+
56
+ ## Lists and mapping
57
+
58
+ ```javascript
59
+ import { createList, mapList, range, repeat } from "flet-box";
60
+
61
+ const numbers = range(0, 10, 2);
62
+ const repeated = repeat(3, (index) => Text({ text: `Item ${index}` }));
63
+ const widgets = mapList(users, (user) => Text({ text: user.name }));
64
+ ```
65
+
66
+ `createList` provides data helpers:
67
+
68
+ ```javascript
69
+ const page = createList.paginate(users, 2, 20);
70
+ const matches = createList.search(users, "ada", ["name", "email"]);
71
+ const grouped = createList.groupBy(users, "role");
72
+ const sorted = createList.sort(users, "name", "asc");
73
+ ```
74
+
75
+ Array helpers include `shuffle`, `reverse`, `sort`, `unique`, and `chunk`.
76
+
77
+ ## Random values and ids
78
+
79
+ ```javascript
80
+ import { random, shortId, uuid } from "flet-box";
81
+
82
+ const userId = uuid();
83
+ const short = shortId();
84
+ const name = random.fullName();
85
+ const email = random.email();
86
+ const colorValue = random.hexColor();
87
+ ```
88
+
89
+ Use random helpers for demos and sample data. Do not use generated demo values as security credentials.
90
+
91
+ ## Strings and dates
92
+
93
+ ```javascript
94
+ import {
95
+ capitalizeWords,
96
+ formatDate,
97
+ relativeTime,
98
+ truncate,
99
+ } from "flet-box";
100
+
101
+ capitalizeWords("flet box");
102
+ truncate("A very long sentence", 10, "...");
103
+ formatDate(new Date(), "YYYY-MM-DD");
104
+ relativeTime("2026-01-01");
105
+ ```
106
+
107
+ ## Delays and retries
108
+
109
+ ```javascript
110
+ import { delay, retry, withMinDelay } from "flet-box";
111
+
112
+ await delay(500);
113
+ await retry(fetchData, 3, 1000);
114
+ await withMinDelay(fetchData(), 800);
115
+ ```
116
+
117
+ Use these helpers for loading states, demos, and recoverable network operations.
118
+
119
+ ## Device and dimensions
120
+
121
+ ```javascript
122
+ import { device, dimensions, height, width } from "flet-box";
123
+
124
+ if (device.isMobile()) {
125
+ console.log("Mobile layout");
126
+ }
127
+
128
+ console.log(dimensions.getWidth(), dimensions.getHeight());
129
+ console.log(width, height);
130
+ ```
131
+
132
+ Subscribe to changes:
133
+
134
+ ```javascript
135
+ const removeListener = dimensions.addListener(({ width, height }) => {
136
+ console.log(width, height);
137
+ });
138
+
139
+ removeListener();
140
+ ```
141
+
142
+ ## Themes and colors
143
+
144
+ ```javascript
145
+ import {
146
+ colors,
147
+ getColor,
148
+ getTheme,
149
+ setTheme,
150
+ toggleTheme,
151
+ } from "flet-box";
152
+
153
+ const primary = colors.primary;
154
+ const text = getColor("text");
155
+ setTheme("dark");
156
+ const current = getTheme();
157
+ toggleTheme();
158
+ ```
159
+
160
+ React to theme changes:
161
+
162
+ ```javascript
163
+ import { subscribeTheme } from "flet-box";
164
+
165
+ const unsubscribe = subscribeTheme((nextColors) => {
166
+ console.log(nextColors.primary);
167
+ });
168
+ ```
169
+
170
+ ## Clipboard
171
+
172
+ ```javascript
173
+ import { clipboard } from "flet-box";
174
+
175
+ clipboard.copy("Copied text");
176
+ const text = await clipboard.read();
177
+ ```
178
+
179
+ Browser permissions may be required for reading clipboard content.
180
+
181
+ ## Text input validation
182
+
183
+ ```javascript
184
+ import { TextInputValidator } from "flet-box";
185
+
186
+ TextInputValidator.isEmail("user@example.com");
187
+ TextInputValidator.onlyNumbers("abc123");
188
+ TextInputValidator.sanitize(userInput);
189
+ TextInputValidator.limitLength(userInput, 50);
190
+ ```
191
+
192
+ The `Input` widget can use these rules through its `validation` prop.
193
+
194
+ ## Markdown and code helpers
195
+
196
+ ```javascript
197
+ import {
198
+ escapeHtml,
199
+ generateHighlightedHtml,
200
+ markdownToWidgets,
201
+ } from "flet-box";
202
+
203
+ const content = markdownToWidgets("# Hello\n\nThis is **bold**");
204
+ const safe = escapeHtml(userText);
205
+ const highlighted = generateHighlightedHtml(code);
206
+ ```
207
+
208
+ Escape untrusted text before displaying it as HTML.
209
+
210
+ ## Media time helpers
211
+
212
+ ```javascript
213
+ import {
214
+ formatMediaProgress,
215
+ formatMediaTime,
216
+ getProgressPercent,
217
+ percentToSeconds,
218
+ } from "flet-box";
219
+
220
+ formatMediaTime(125); // 02:05
221
+ getProgressPercent(30, 120);
222
+ percentToSeconds(50, 120);
223
+ formatMediaProgress(30, 120);
224
+ ```
225
+
226
+ ## Choosing a utility
227
+
228
+ - Need spacing? Start with direct `padding`, `margin`, and `gap` props.
229
+ - Need reusable data? Use `createList`, `mapList`, or `range`.
230
+ - Need shared UI state? Read [State with `useState`](state.md).
231
+ - Need URL changes? Read [Routing](router.md).
232
+ - Need colors that follow the app theme? Use `colors` and `getColor`.
233
+ - Need browser information? Use `device`, `os`, and `dimensions`.
234
+
235
+ ---
236
+
237
+ ## Continue reading
238
+
239
+ - **Previous:** [Animation helpers](../tools/animation.md) — end of the tools chapter.
240
+ - **Next:** [The FletBox CLI](../cli/README.md) — Chapter 11
241
+ - **Index:** [Guides index](README.md) · [The FletBox Book](../README.md)
@@ -0,0 +1,163 @@
1
+ # Widget structure: one shape for every widget
2
+
3
+ Every widget in FletBox is a plain function that returns an `HTMLElement`, built
4
+ on top of the single rendering engine: [`src/widget-factory/`](../../src/widget-factory/).
5
+ This page is the **canonical structure** all widgets follow — existing and future —
6
+ so the library stays modular, predictable, and easy to review.
7
+
8
+ Reference implementation: [`src/widgets/QRCode.js`](../../src/widgets/QRCode.js).
9
+
10
+ ## The shape
11
+
12
+ ```javascript
13
+ /**
14
+ * @file MyWidget.js
15
+ * @description One paragraph: what the widget renders and how it behaves.
16
+ */
17
+
18
+ import { WidgetFactory } from "../widget-factory/index.js";
19
+ // import shared helpers (theme, composeUpdate, ...) — never a second engine.
20
+
21
+ // ---------------------------------------------------------------------------
22
+ // Module-level constants and pure helpers (no DOM, no side effects)
23
+ // ---------------------------------------------------------------------------
24
+
25
+ const WIDGET_PROP_KEYS = ["value", "onPress", /* ... */];
26
+
27
+ const normalize = (value) => /* pure transform */;
28
+
29
+ // ---------------------------------------------------------------------------
30
+ // Widget
31
+ // ---------------------------------------------------------------------------
32
+
33
+ /**
34
+ * JSDoc for every prop, its type and default.
35
+ * @returns {HTMLElement}
36
+ */
37
+ export const MyWidget = (props) => {
38
+ // 1. Destructure with defaults; keep the rest for the factory.
39
+ const { value = "", onPress, size = 200, ...rest } = props;
40
+
41
+ // 2. Early guards. Never leave a half-built element.
42
+ if (!value) return WidgetFactory({ widgetName: "MyWidget", ...rest });
43
+
44
+ // 3. Closure state / refs (private, mutable).
45
+ let currentValue = value;
46
+ let ref = null;
47
+
48
+ // 4. Exactly ONE factory root.
49
+ const container = WidgetFactory({
50
+ widgetName: "MyWidget",
51
+ ...defaults,
52
+ ...rest,
53
+ });
54
+
55
+ // 5. Children via the factory (`child`/`children`) or `appendChild`.
56
+ // Raw `createElement` only for what the factory cannot express (canvas...).
57
+
58
+ // 6. Public, reactive surface. Compose — never overwrite — `container.update`.
59
+ container.setValue = (v) => { currentValue = v; render(); };
60
+ container.getValue = () => currentValue;
61
+
62
+ // 7. Resources: every listener/timer/rAF/observer/subscription goes through
63
+ // onUnmount, and the disposer must be idempotent.
64
+ let disposed = false;
65
+ const dispose = () => {
66
+ if (disposed) return;
67
+ disposed = true;
68
+ // removeEventListener / clearTimeout / disconnect ...
69
+ };
70
+ container.onUnmount(dispose);
71
+
72
+ return container;
73
+ };
74
+
75
+ export default MyWidget;
76
+ ```
77
+
78
+ ## The rules
79
+
80
+ 1. **One root, one engine.** A widget returns a single element created by
81
+ `WidgetFactory`. Never hand-roll a parallel rendering path.
82
+ 2. **Module scope is pure.** Constants and helpers at the top of the file do no
83
+ DOM work and register no side effects.
84
+ 3. **Props in, element out.** Destructure with defaults, forward `...rest` to the
85
+ factory, guard early. A widget with no data returns a valid element (or a
86
+ documented controller object — see below).
87
+ 4. **`widgetName` labels the widget.** Pass `widgetName: "<Name>"` to the root
88
+ factory call so `Inspector`, `printWidgetCode`, and navigation helpers see the
89
+ real name instead of the capitalised HTML tag. (`name` is *not* reserved — it
90
+ is a public prop of `Icon`/`Avatar`.)
91
+ 5. **Compose `update`.** Keep widget state in the closure and route updates
92
+ through [`composeUpdate()`](../../src/utils/composeUpdate.js). Overwriting
93
+ `container.update` silently disables the factory's style/event reactivity.
94
+ 6. **No ad-hoc global styles.** Scope injected CSS with
95
+ `<style data-widget="<Name>">` or a per-instance adopted stylesheet
96
+ (`markdown-scope-N` pattern) and remove it on unmount. Never inject an
97
+ unscoped `<style>` tag into `document.head` yourself — `@keyframes` cannot be
98
+ scoped, so the only sanctioned global injection is the shared, idempotent
99
+ [`injectKeyframes()`](../../src/utils/styleInjector.js) helper.
100
+ 7. **Portals clean up after themselves.** Widgets that append to
101
+ `document.body` (dialogs, dropdowns, tooltips) must remove their node and
102
+ close over the parent's lifecycle via `onUnmount`.
103
+ 8. **`onUnmount` is the single cleanup hook.** Register disposers there; they can
104
+ run from more than one teardown path, so make them idempotent. Do not
105
+ monkey-patch `_cleanup`.
106
+ 9. **Public API is additive.** Expose behavior through named methods
107
+ (`updateValue`, `getValue`, ...) and reactive accessors. Never mutate
108
+ `container.update` or `container._cleanup`.
109
+ 10. **Complete the three surfaces.** Runtime file, export from
110
+ `src/widgets/index.js` **and** `src/index.js`, types in `src/index.d.ts`,
111
+ plus a doc page in `docs/widget/<Name>.md` with `basic`/`normal`/`full`
112
+ examples.
113
+ 11. **Flat, aliased CSS props — never `style:`.** FletBox has no `style` object:
114
+ pass CSS props directly (`backgroundColor`, `padding`, `flexDirection`,
115
+ `whiteSpace`, …) with aliases resolved by the factory. `style: { ... }` is
116
+ rejected with a warning (`processProps`), so it never silently half-applies.
117
+
118
+ ## Controller widgets
119
+
120
+ A few widgets manage transient UI that lives outside the tree (modals, sheets,
121
+ snackbars). They may return a **controller object** instead of an element, but
122
+ the exception is explicit and typed:
123
+
124
+ | Widget | Returns |
125
+ | --- | --- |
126
+ | `AlertDialog` | `{ open, close, modal }` |
127
+ | `SnackBar` | `{ close, show, getElement }` |
128
+ | `BottomSheet` | `{ open, close, toggle, destroy }` |
129
+ | `Modal` | controller instance (`open`/`close`/`updateContent`) |
130
+
131
+ Everything else returns an `HTMLElement`.
132
+
133
+ ## Adding a widget — checklist
134
+
135
+ 1. Copy the shape above into `src/widgets/<Name>.js`.
136
+ 2. Implement props with defaults and JSDoc; forward `...rest`.
137
+ 3. Pass `widgetName: "<Name>"` to the root factory call.
138
+ 4. Register every resource with an idempotent `onUnmount` disposer.
139
+ 5. Export from `src/widgets/index.js` and `src/index.js`.
140
+ 6. Add types and props to `src/index.d.ts` (regenerate docs with
141
+ `python3 scripts/generate_widget_docs.py`).
142
+ 7. Add `docs/widget/<Name>.md` with `basic`/`normal`/`full` examples.
143
+ 8. Verify:
144
+ ```bash
145
+ node --check src/widgets/<Name>.js
146
+ node scripts/check-widgets.mjs # static contract (no new violations)
147
+ npm run dev # then open the test harnesses:
148
+ # /tests/widget-contract.html — runtime contract
149
+ # /tests/smoke.html — instantiates every widget
150
+ # /tests/widget-factory.html — frozen engine regression suite
151
+ ```
152
+
153
+ ## Tooling
154
+
155
+ - `node scripts/check-widgets.mjs` — static contract checker. It compares the
156
+ code against `scripts/widget-contract-baseline.json`; the baseline records
157
+ pre-existing debt and must shrink as widgets are refactored. Adding a widget
158
+ to the baseline is never the fix.
159
+ - `node scripts/check-widgets.mjs --write-baseline` — re-snapshot after a batch
160
+ of fixes (only to *remove* entries in practice).
161
+ - `/tests/widget-contract.html` — runtime contract: every widget instantiates,
162
+ returns an element (or a documented controller), exposes `update()`, and
163
+ reports its real `_widgetName`.
@@ -0,0 +1,68 @@
1
+ # FletBox Server
2
+
3
+ FletBox Server is the backend toolkit for building APIs with Node.js. It gives you a simple route definition, automatic schemas, validation, authentication, security middleware, data tools, and generated API documentation.
4
+
5
+ It is a **separate package with its own repository** — [kuko53348/flet-box-server](https://github.com/kuko53348/flet-box-server) — because the frontend and the backend release independently. Nothing here is required to build a FletBox app; the docs live in this book so the whole stack is documented in one place.
6
+
7
+ ```bash
8
+ npm install flet-box-server
9
+ ```
10
+
11
+ Import the core from the package root, and each tool from its own module. The tools are deliberately not re-exported at the root: `pdf.js` pulls puppeteer, `sms.js` pulls twilio, `csv.js` pulls xlsx, and the speech modules need optional Google Cloud packages, so a single root import would force all of them to load.
12
+
13
+ ```javascript
14
+ import { Api, runServer } from "flet-box-server"; // core
15
+ import { SQLite } from "flet-box-server/tools/betterSqlite.js"; // one tool
16
+ ```
17
+
18
+ ## Start here
19
+
20
+ If this is your first backend, read [Start here](START_HERE.md).
21
+
22
+ ## Documentation map
23
+
24
+ - [Start here](START_HERE.md): create your first API step by step.
25
+ - [API and routes](api.md): define endpoints, handlers, parameters, and schemas.
26
+ - [Authentication and security](security.md): JWT, roles, sanitization, blocking, headers, and rate limits.
27
+ - [Database and services](data-services.md): where data lives (browser vs server), a dedicated SQLite API server example, cache, files, email, PDF, CSV, queues, and more.
28
+ - [Deployment](deployment.md): environment variables, production settings, Docker, and operational checks.
29
+
30
+ ## What the server does
31
+
32
+ - Defines routes with `Api()`.
33
+ - Runs on the native Node.js HTTP server or an Express adapter.
34
+ - Creates JSON responses automatically for returned objects.
35
+ - Generates schemas from request examples.
36
+ - Validates request bodies with `SchemaValidator`.
37
+ - Serves generated API documentation at `/docs`.
38
+ - Supports JWT authentication and role checks.
39
+ - Provides security headers, sanitization, malicious-input blocking, and rate limiting.
40
+ - Includes modules for SQLite, Redis, files, email, SMS, PDF, CSV/XLSX, WebSockets, queues, speech, translation, and logging.
41
+
42
+ ## Important production rule
43
+
44
+ The example server in `flet-box-server/app.js` is a test server. It disables some protections and contains a development admin account. Do not copy those values into production. Use `runSecureServer`, environment variables, a real database, a strong `JWT_SECRET`, and explicit CORS origins.
45
+
46
+ ## Minimal server
47
+
48
+ ```javascript
49
+ import { Api, runServer } from "flet-box-server";
50
+
51
+ const routes = Api({
52
+ "/": {
53
+ GET: () => ({ message: "Hello from FletBox Server" }),
54
+ },
55
+ });
56
+
57
+ runServer(routes, {
58
+ port: 3000,
59
+ docs: true,
60
+ });
61
+ ```
62
+
63
+ Then open:
64
+
65
+ ```text
66
+ http://localhost:3000/
67
+ http://localhost:3000/docs
68
+ ```
@@ -0,0 +1,121 @@
1
+ # Start here
2
+
3
+ This guide teaches the backend in small steps. You only need JavaScript and a terminal.
4
+
5
+ ## 1. Install
6
+
7
+ Inside `flet-box-server`:
8
+
9
+ ```bash
10
+ npm install
11
+ ```
12
+
13
+ The server requires Node.js and uses ES modules.
14
+
15
+ ## 2. Create one route
16
+
17
+ Create `server.js`:
18
+
19
+ ```javascript
20
+ import { Api, runServer } from "flet-box-server";
21
+
22
+ const routes = Api({
23
+ "/hello": {
24
+ GET: () => ({ message: "Hello" }),
25
+ },
26
+ });
27
+
28
+ runServer(routes, { port: 3000, docs: true });
29
+ ```
30
+
31
+ Start it:
32
+
33
+ ```bash
34
+ node server.js
35
+ ```
36
+
37
+ Test it:
38
+
39
+ ```bash
40
+ curl http://localhost:3000/hello
41
+ ```
42
+
43
+ ## 3. Understand the route
44
+
45
+ ```javascript
46
+ "/users/:id": {
47
+ GET: ({ id, query, req }) => ({
48
+ id,
49
+ filters: query,
50
+ userAgent: req.headers["user-agent"],
51
+ }),
52
+ }
53
+ ```
54
+
55
+ - `/users/:id` is the URL pattern.
56
+ - `id` comes from the URL.
57
+ - `query` contains values such as `?page=2`.
58
+ - `req` is the native request object.
59
+ - Returning an object sends JSON to the client.
60
+
61
+ ## 4. Accept JSON data
62
+
63
+ ```javascript
64
+ const routes = Api({
65
+ "/tasks": {
66
+ POST: {
67
+ handler: ({ title, completed }) => ({
68
+ title,
69
+ completed,
70
+ }),
71
+ example: {
72
+ title: "Learn FletBox Server",
73
+ completed: false,
74
+ },
75
+ },
76
+ },
77
+ });
78
+ ```
79
+
80
+ The `example` documents the expected body and can be used to generate a schema.
81
+
82
+ Request it with:
83
+
84
+ ```bash
85
+ curl -X POST http://localhost:3000/tasks \
86
+ -H "Content-Type: application/json" \
87
+ -d '{"title":"Learn FletBox Server","completed":false}'
88
+ ```
89
+
90
+ ## 5. Add protection
91
+
92
+ For a production-style default, use:
93
+
94
+ ```javascript
95
+ import { Api, runSecureServer } from "flet-box-server";
96
+
97
+ const routes = Api({
98
+ "/private": {
99
+ GET: () => ({ secret: "protected data" }),
100
+ },
101
+ });
102
+
103
+ runSecureServer(routes, {
104
+ port: 3000,
105
+ docs: true,
106
+ rateLimit: { max: 100, windowMs: 60_000 },
107
+ });
108
+ ```
109
+
110
+ Add authentication to routes that require a logged-in user. See [Authentication and security](security.md).
111
+
112
+ ## 6. Learn the normal workflow
113
+
114
+ 1. Define routes with `Api()`.
115
+ 2. Add `example` objects for request bodies.
116
+ 3. Add `responseExample` objects for documented responses.
117
+ 4. Add middleware such as authentication or roles.
118
+ 5. Start with `runSecureServer()`.
119
+ 6. Test with curl or your frontend.
120
+ 7. Open `/docs` to inspect generated documentation.
121
+ 8. Move secrets and configuration to environment variables.