retold 4.0.2 → 4.0.4
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.
- package/.claude/settings.local.json +37 -1
- package/README.md +112 -2
- package/docs/_sidebar.md +4 -1
- package/docs/architecture/architecture.md +2 -2
- package/docs/architecture/comprehensions.md +282 -0
- package/docs/architecture/fluid-models.md +355 -0
- package/docs/architecture/modules.md +3 -4
- package/docs/contributing.md +50 -0
- package/docs/modules/orator.md +0 -7
- package/docs/retold-catalog.json +3944 -878
- package/docs/retold-keyword-index.json +174010 -144308
- package/docs/testing.md +122 -0
- package/modules/Include-Retold-Module-List.sh +1 -1
- package/package.json +7 -4
- package/source/retold-manager/package.json +23 -0
- package/source/retold-manager/retold-manager.js +65 -0
- package/source/retold-manager/source/Retold-Manager-App.js +1532 -0
- package/source/retold-manager/source/Retold-Manager-ModuleCatalog.js +75 -0
- package/source/retold-manager/source/Retold-Manager-ProcessRunner.js +706 -0
- package/source/retold-manager/source/views/PictView-TUI-Checkout.js +45 -0
- package/source/retold-manager/source/views/PictView-TUI-Header.js +41 -0
- package/source/retold-manager/source/views/PictView-TUI-Layout.js +53 -0
- package/source/retold-manager/source/views/PictView-TUI-Status.js +45 -0
- package/source/retold-manager/source/views/PictView-TUI-StatusBar.js +41 -0
- package/source/retold-manager/source/views/PictView-TUI-Update.js +45 -0
- package/examples/quickstart/layer1/package-lock.json +0 -344
- package/examples/quickstart/layer2/package-lock.json +0 -4468
- package/examples/quickstart/layer3/package-lock.json +0 -1936
- package/examples/quickstart/layer4/package-lock.json +0 -13206
- package/examples/quickstart/layer5/package-lock.json +0 -345
- package/examples/todo-list/cli-client/package-lock.json +0 -418
- package/examples/todo-list/console-client/package-lock.json +0 -426
- package/examples/todo-list/server/package-lock.json +0 -6113
- package/examples/todo-list/web-client/package-lock.json +0 -12030
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# Fluid Models
|
|
2
|
+
|
|
3
|
+
In most application frameworks, a data model is a rigid artifact. You define it once in a migration file or a class, and it becomes the fixed skeleton of your application. Changing it means writing migration scripts, updating API contracts, rebuilding forms, and hoping nothing breaks.
|
|
4
|
+
|
|
5
|
+
Retold takes a different position: **the model is a living thing**. Data models are easy to describe, easy to mutate, and designed to flow through every layer of the stack — from a terse text definition, through database tables and API endpoints, all the way to browser form fields — adapting their shape at each layer without losing their identity.
|
|
6
|
+
|
|
7
|
+
## Describing a Model
|
|
8
|
+
|
|
9
|
+
The fastest way to describe a data model in Retold is Stricture's MicroDDL — a compact text notation where each line defines a column using a single-character sigil.
|
|
10
|
+
|
|
11
|
+
A classic order management system (think Northwind) might start like this:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
!Customer
|
|
15
|
+
@IDCustomer
|
|
16
|
+
%GUIDCustomer
|
|
17
|
+
$CompanyName 128
|
|
18
|
+
$ContactName 128
|
|
19
|
+
$ContactTitle 64
|
|
20
|
+
$Phone 24
|
|
21
|
+
$City 64
|
|
22
|
+
$Country 64
|
|
23
|
+
&CreateDate
|
|
24
|
+
#CreatingIDUser
|
|
25
|
+
&UpdateDate
|
|
26
|
+
#UpdatingIDUser
|
|
27
|
+
^Deleted
|
|
28
|
+
&DeleteDate
|
|
29
|
+
#DeletingIDUser
|
|
30
|
+
|
|
31
|
+
!Product
|
|
32
|
+
@IDProduct
|
|
33
|
+
%GUIDProduct
|
|
34
|
+
$ProductName 128
|
|
35
|
+
.UnitPrice 10,2
|
|
36
|
+
#UnitsInStock
|
|
37
|
+
~IDSupplier -> IDSupplier
|
|
38
|
+
&CreateDate
|
|
39
|
+
#CreatingIDUser
|
|
40
|
+
&UpdateDate
|
|
41
|
+
#UpdatingIDUser
|
|
42
|
+
^Deleted
|
|
43
|
+
&DeleteDate
|
|
44
|
+
#DeletingIDUser
|
|
45
|
+
|
|
46
|
+
!Order
|
|
47
|
+
@IDOrder
|
|
48
|
+
%GUIDOrder
|
|
49
|
+
~IDCustomer -> IDCustomer
|
|
50
|
+
&OrderDate
|
|
51
|
+
$ShipCity 64
|
|
52
|
+
$ShipCountry 64
|
|
53
|
+
&CreateDate
|
|
54
|
+
#CreatingIDUser
|
|
55
|
+
&UpdateDate
|
|
56
|
+
#UpdatingIDUser
|
|
57
|
+
^Deleted
|
|
58
|
+
&DeleteDate
|
|
59
|
+
#DeletingIDUser
|
|
60
|
+
|
|
61
|
+
!OrderDetail
|
|
62
|
+
@IDOrderDetail
|
|
63
|
+
%GUIDOrderDetail
|
|
64
|
+
~IDOrder -> IDOrder
|
|
65
|
+
~IDProduct -> IDProduct
|
|
66
|
+
.UnitPrice 10,2
|
|
67
|
+
#Quantity
|
|
68
|
+
.Discount 5,2
|
|
69
|
+
&CreateDate
|
|
70
|
+
#CreatingIDUser
|
|
71
|
+
&UpdateDate
|
|
72
|
+
#UpdatingIDUser
|
|
73
|
+
^Deleted
|
|
74
|
+
&DeleteDate
|
|
75
|
+
#DeletingIDUser
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The sigils are deliberate shorthand:
|
|
79
|
+
|
|
80
|
+
| Sigil | Type | Example |
|
|
81
|
+
|-------|------|---------|
|
|
82
|
+
| `!` | Table definition | `!Customer` |
|
|
83
|
+
| `@` | Auto-incrementing ID | `@IDCustomer` |
|
|
84
|
+
| `%` | GUID | `%GUIDCustomer` |
|
|
85
|
+
| `$` | String (with size) | `$CompanyName 128` |
|
|
86
|
+
| `#` | Integer | `#UnitsInStock` |
|
|
87
|
+
| `.` | Decimal (precision,scale) | `.UnitPrice 10,2` |
|
|
88
|
+
| `&` | DateTime | `&OrderDate` |
|
|
89
|
+
| `^` | Boolean | `^Deleted` |
|
|
90
|
+
| `~` | Foreign key | `~IDCustomer -> IDCustomer` |
|
|
91
|
+
| `*` | Text (unbounded) | `*Description` |
|
|
92
|
+
|
|
93
|
+
This is the entire data model for four related entities. No XML, no decorators, no class hierarchies. The definition is compact enough to hold in your head and quick enough to change on a whiteboard.
|
|
94
|
+
|
|
95
|
+
## One Definition, Many Shapes
|
|
96
|
+
|
|
97
|
+
From this single MicroDDL source, Stricture generates multiple representations:
|
|
98
|
+
|
|
99
|
+
```mermaid
|
|
100
|
+
graph LR
|
|
101
|
+
mddl["MicroDDL<br/><i>Source of truth</i>"]
|
|
102
|
+
meadow["Meadow Schema<br/><i>JSON column defs,<br/>defaults, validation</i>"]
|
|
103
|
+
mysql["MySQL Queries<br/><i>CREATE TABLE<br/>statements</i>"]
|
|
104
|
+
pict["Pict Config<br/><i>Form layouts,<br/>UI metadata</i>"]
|
|
105
|
+
auth["Authorization<br/><i>Role-based<br/>access rules</i>"]
|
|
106
|
+
|
|
107
|
+
mddl --> meadow
|
|
108
|
+
mddl --> mysql
|
|
109
|
+
mddl --> pict
|
|
110
|
+
mddl --> auth
|
|
111
|
+
|
|
112
|
+
style mddl fill:#f5f5f5,stroke:#bdbdbd,color:#333
|
|
113
|
+
style meadow fill:#fff3e0,stroke:#ffa726,color:#333
|
|
114
|
+
style mysql fill:#fff3e0,stroke:#ffa726,color:#333
|
|
115
|
+
style pict fill:#f3e5f5,stroke:#ab47bc,color:#333
|
|
116
|
+
style auth fill:#e3f2fd,stroke:#42a5f5,color:#333
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Each output is a different shape of the same logical model:
|
|
120
|
+
|
|
121
|
+
**Meadow Schema** — JSON column definitions that drive the ORM, query generation, default objects, and JSON Schema validation:
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"Scope": "Customer",
|
|
126
|
+
"DefaultIdentifier": "IDCustomer",
|
|
127
|
+
"Schema": [
|
|
128
|
+
{ "Column": "IDCustomer", "Type": "AutoIdentity" },
|
|
129
|
+
{ "Column": "GUIDCustomer", "Type": "AutoGUID" },
|
|
130
|
+
{ "Column": "CompanyName", "Type": "String", "Size": "128" },
|
|
131
|
+
{ "Column": "ContactName", "Type": "String", "Size": "128" },
|
|
132
|
+
{ "Column": "City", "Type": "String", "Size": "64" },
|
|
133
|
+
{ "Column": "CreateDate", "Type": "CreateDate" },
|
|
134
|
+
{ "Column": "UpdateDate", "Type": "UpdateDate" },
|
|
135
|
+
{ "Column": "Deleted", "Type": "Deleted" }
|
|
136
|
+
],
|
|
137
|
+
"DefaultObject": {
|
|
138
|
+
"IDCustomer": 0,
|
|
139
|
+
"GUIDCustomer": "",
|
|
140
|
+
"CompanyName": "",
|
|
141
|
+
"ContactName": "",
|
|
142
|
+
"City": ""
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**MySQL DDL** — CREATE TABLE statements ready to run against a database.
|
|
148
|
+
|
|
149
|
+
**Pict Configuration** — UI definitions for form views, list views, and record views — which fields to show, how to group them, what input types to use.
|
|
150
|
+
|
|
151
|
+
## The Model Changes Shape at Every Layer
|
|
152
|
+
|
|
153
|
+
Consider a modern social platform with Users, Posts, and Comments. Watch how the model's shape changes as it flows through the stack — and how Retold makes that natural rather than painful.
|
|
154
|
+
|
|
155
|
+
### At the Schema Layer
|
|
156
|
+
|
|
157
|
+
The MicroDDL is terse and structural:
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
!User
|
|
161
|
+
@IDUser
|
|
162
|
+
%GUIDUser
|
|
163
|
+
$UserName 64
|
|
164
|
+
$Email 256
|
|
165
|
+
$DisplayName 128
|
|
166
|
+
&CreateDate
|
|
167
|
+
#CreatingIDUser
|
|
168
|
+
&UpdateDate
|
|
169
|
+
#UpdatingIDUser
|
|
170
|
+
^Deleted
|
|
171
|
+
&DeleteDate
|
|
172
|
+
#DeletingIDUser
|
|
173
|
+
|
|
174
|
+
!Post
|
|
175
|
+
@IDPost
|
|
176
|
+
%GUIDPost
|
|
177
|
+
~IDUser -> IDUser
|
|
178
|
+
$Title 256
|
|
179
|
+
*Body
|
|
180
|
+
&PublishedDate
|
|
181
|
+
&CreateDate
|
|
182
|
+
#CreatingIDUser
|
|
183
|
+
&UpdateDate
|
|
184
|
+
#UpdatingIDUser
|
|
185
|
+
^Deleted
|
|
186
|
+
&DeleteDate
|
|
187
|
+
#DeletingIDUser
|
|
188
|
+
|
|
189
|
+
!Comment
|
|
190
|
+
@IDComment
|
|
191
|
+
%GUIDComment
|
|
192
|
+
~IDPost -> IDPost
|
|
193
|
+
~IDUser -> IDUser
|
|
194
|
+
*Body
|
|
195
|
+
&CreateDate
|
|
196
|
+
#CreatingIDUser
|
|
197
|
+
&UpdateDate
|
|
198
|
+
#UpdatingIDUser
|
|
199
|
+
^Deleted
|
|
200
|
+
&DeleteDate
|
|
201
|
+
#DeletingIDUser
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### At the Database Layer
|
|
205
|
+
|
|
206
|
+
Meadow consumes the schema and automatically handles audit columns. When you create a Post, you send:
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
{ Title: 'Hello World', Body: 'First post!', IDUser: 42 }
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Meadow merges your data with the schema's default object and fills in the audit columns:
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
{
|
|
216
|
+
IDPost: 0, // from defaults
|
|
217
|
+
GUIDPost: '8f14e45f-...', // auto-generated
|
|
218
|
+
Title: 'Hello World', // from your data
|
|
219
|
+
Body: 'First post!', // from your data
|
|
220
|
+
IDUser: 42, // from your data
|
|
221
|
+
PublishedDate: null, // from defaults
|
|
222
|
+
CreateDate: '2025-02-17 14:30:00', // auto-stamped
|
|
223
|
+
CreatingIDUser: 42, // auto-stamped from session
|
|
224
|
+
UpdateDate: '2025-02-17 14:30:00', // auto-stamped
|
|
225
|
+
UpdatingIDUser: 42, // auto-stamped from session
|
|
226
|
+
Deleted: 0 // from defaults
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
The schema knows which columns are audit columns by their type (`CreateDate`, `UpdateDate`, `Deleted`). Meadow inspects the schema on every operation — not just at startup — so changing the schema changes behavior immediately.
|
|
231
|
+
|
|
232
|
+
### At the Query Layer
|
|
233
|
+
|
|
234
|
+
FoxHound reads the schema to generate intelligent queries. If the schema includes a `Deleted` column with type `Deleted`, every read query automatically adds `WHERE Deleted = 0`. You never write that filter. The schema declares the intent; the query layer implements it.
|
|
235
|
+
|
|
236
|
+
```javascript
|
|
237
|
+
// You write:
|
|
238
|
+
_PostMeadow.doReads(_PostMeadow.query.addFilter('IDUser', 42), fCallback);
|
|
239
|
+
|
|
240
|
+
// FoxHound generates (simplified):
|
|
241
|
+
// SELECT * FROM Post WHERE IDUser = 42 AND Deleted = 0
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### At the API Layer
|
|
245
|
+
|
|
246
|
+
Meadow-Endpoints reads the same schema and generates a full REST API. The schema's authorization rules control who can do what:
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
GET /Posts → list (filtered by Deleted automatically)
|
|
250
|
+
GET /Post/42 → read single
|
|
251
|
+
POST /Post → create (audit columns auto-stamped)
|
|
252
|
+
PUT /Post → update (UpdateDate auto-stamped)
|
|
253
|
+
DEL /Post/42 → soft delete (sets Deleted = 1)
|
|
254
|
+
GET /Post/Schema → returns the live schema JSON
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
The `GET /Post/Schema` endpoint is important — it exposes the current schema to any client. This means the model is not hidden inside server code. It is a queryable, inspectable resource.
|
|
258
|
+
|
|
259
|
+
### At the UI Layer
|
|
260
|
+
|
|
261
|
+
Pict reads the schema through Manyfest descriptors and generates form fields. Each column gains UI metadata:
|
|
262
|
+
|
|
263
|
+
```javascript
|
|
264
|
+
{
|
|
265
|
+
Hash: 'Title',
|
|
266
|
+
Name: 'Post Title',
|
|
267
|
+
DataType: 'String',
|
|
268
|
+
PictForm: {
|
|
269
|
+
InputType: 'TextInput',
|
|
270
|
+
Section: 'PostDetails',
|
|
271
|
+
Row: 0
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
The same address notation — `Record.Title`, `AppData.Posts[0].Body` — works in templates, in code, and in form bindings. Manyfest provides safe navigation that never throws on missing paths, so the UI does not break when the model evolves.
|
|
277
|
+
|
|
278
|
+
## Runtime Mutation
|
|
279
|
+
|
|
280
|
+
The model is not frozen after compilation. Meadow schemas are live objects with independent, replaceable parts:
|
|
281
|
+
|
|
282
|
+
```javascript
|
|
283
|
+
// Load initial schema
|
|
284
|
+
_PostMeadow.loadFromPackage('./Post-Schema.json');
|
|
285
|
+
|
|
286
|
+
// Later, update just the column definitions
|
|
287
|
+
_PostMeadow.setSchema(updatedColumnArray);
|
|
288
|
+
|
|
289
|
+
// Or just the validation rules
|
|
290
|
+
_PostMeadow.setJsonSchema(updatedValidationSchema);
|
|
291
|
+
|
|
292
|
+
// Or just the default values
|
|
293
|
+
_PostMeadow.setDefault({ ...existingDefaults, NewField: 'default' });
|
|
294
|
+
|
|
295
|
+
// Or just the authorization policies
|
|
296
|
+
_PostMeadow.setAuthorizer(updatedAuthRules);
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Each part — column definitions, JSON Schema validation, default objects, authorization — can be modified independently. When you call `setSchema()`, the change propagates immediately to the database provider. Subsequent queries, creates, and updates use the new definition. There is no restart, no cache flush, no migration ceremony.
|
|
300
|
+
|
|
301
|
+
This matters for real applications. A bookstore that adds a `Price` column to its `Book` entity:
|
|
302
|
+
|
|
303
|
+
```javascript
|
|
304
|
+
// Existing schema
|
|
305
|
+
let schema = _BookMeadow.schema;
|
|
306
|
+
|
|
307
|
+
// Add the new column
|
|
308
|
+
schema.push({ Column: 'Price', Type: 'Decimal', Size: '10,2' });
|
|
309
|
+
|
|
310
|
+
// Update live
|
|
311
|
+
_BookMeadow.setSchema(schema);
|
|
312
|
+
_BookMeadow.setDefault({ ...existingDefaults, Price: 0.0 });
|
|
313
|
+
|
|
314
|
+
// All subsequent operations include Price
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
The database table still needs an `ALTER TABLE` — Retold does not run migrations for you. But the application layer adapts instantly. You can evolve the schema in code, test the new shape, and apply the database change when ready.
|
|
318
|
+
|
|
319
|
+
## Address-Based Access Across Layers
|
|
320
|
+
|
|
321
|
+
Manyfest provides the glue that makes model fluidity practical. Every piece of data in a Retold application is reachable through an address — a dot-notation string like `Record.Contact.Email` or `AppData.Posts[0].Title`.
|
|
322
|
+
|
|
323
|
+
```javascript
|
|
324
|
+
// Safe read — returns undefined if any part of the path is missing
|
|
325
|
+
let title = _Manyfest.getValueAtAddress(pRecord, 'Posts[0].Title');
|
|
326
|
+
|
|
327
|
+
// Safe write — creates intermediate objects as needed
|
|
328
|
+
_Manyfest.setValueAtAddress(pRecord, 'Posts[0].Title', 'Updated Title');
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
The same address notation works in Pict templates:
|
|
332
|
+
|
|
333
|
+
```
|
|
334
|
+
{~Data:Record.Title~}
|
|
335
|
+
{~Data:AppData.Posts[0].Title~}
|
|
336
|
+
{~Data:Bundle.Authors.ByID.42.Name~}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
And in form bindings, where the template address maps directly to a Manyfest descriptor, which maps to a Meadow column, which maps to a database field. One notation from top to bottom.
|
|
340
|
+
|
|
341
|
+
When the model changes shape — a field is renamed, a nested object is restructured, a new relationship is added — the address is the single point of update. Change the address in the Manyfest descriptor and every layer that references it adapts.
|
|
342
|
+
|
|
343
|
+
## Why This Matters
|
|
344
|
+
|
|
345
|
+
In a traditional framework, changing a data model means touching every layer: migration files, ORM classes, API serializers, validation schemas, form definitions, and template bindings. Each layer has its own notation for describing the same thing, and keeping them synchronized is the source of a large class of bugs.
|
|
346
|
+
|
|
347
|
+
Retold's approach is different:
|
|
348
|
+
|
|
349
|
+
- **One source** (MicroDDL) generates all layer-specific representations
|
|
350
|
+
- **One notation** (Manyfest addresses) accesses data everywhere
|
|
351
|
+
- **One schema object** (Meadow) drives queries, validation, defaults, and authorization
|
|
352
|
+
- **Live mutation** means the model evolves without restarts or redeployment ceremonies
|
|
353
|
+
- **Schema introspection** at operation time means changes take effect immediately
|
|
354
|
+
|
|
355
|
+
The model is not a static artifact that you deploy and forget. It is a fluid description that adapts to each layer's needs and evolves with your application.
|
|
@@ -30,7 +30,7 @@ An exhaustive list of every repository in the Retold suite, organized by group.
|
|
|
30
30
|
| [retold-harness](/meadow/retold-harness/) | `retold-harness` | Pre-built API harness with a bookstore demo (8 entities, 10,000+ records) |
|
|
31
31
|
| [meadow-integration](/meadow/meadow-integration/) | `meadow-integration` | Data integration tools for CSV import, schema mapping, and centralized formats |
|
|
32
32
|
|
|
33
|
-
## Orator — API Server (
|
|
33
|
+
## Orator — API Server (6 modules)
|
|
34
34
|
|
|
35
35
|
| Module | npm | Description |
|
|
36
36
|
|--------|-----|-------------|
|
|
@@ -39,7 +39,6 @@ An exhaustive list of every repository in the Retold suite, organized by group.
|
|
|
39
39
|
| [orator-static-server](/orator/orator-static-server/) | `orator-static-server` | Static file serving with MIME detection, default files, and subdomain routing |
|
|
40
40
|
| [orator-http-proxy](/orator/orator-http-proxy/) | `orator-http-proxy` | HTTP reverse proxy for forwarding requests to backend services |
|
|
41
41
|
| [tidings](/orator/tidings/) | `tidings` | Extensible reporting system for generating HTML, PDF, and other format reports |
|
|
42
|
-
| [orator-endpoint](/orator/orator-endpoint/) | `orator-endpoint` | Pluggable API endpoint base class for reusable route handlers |
|
|
43
42
|
| [orator-conversion](/orator/orator-conversion/) | `orator-conversion` | File format conversion endpoints for Orator service servers |
|
|
44
43
|
|
|
45
44
|
## Pict — MVC Tools (19 modules)
|
|
@@ -81,10 +80,10 @@ An exhaustive list of every repository in the Retold suite, organized by group.
|
|
|
81
80
|
|-------|-------|-------|
|
|
82
81
|
| Fable | 6 | Core ecosystem, DI, configuration, logging |
|
|
83
82
|
| Meadow | 12 | Data access, ORM, query DSL, schema, connectors |
|
|
84
|
-
| Orator |
|
|
83
|
+
| Orator | 6 | API server, HTTP, static files, proxy, reporting, conversion |
|
|
85
84
|
| Pict | 19 | MVC, views, templates, forms, grids, routing, docs, TUI |
|
|
86
85
|
| Utility | 4 | Build tools, manifests, docs, process supervision |
|
|
87
|
-
| **Total** | **
|
|
86
|
+
| **Total** | **47** | |
|
|
88
87
|
|
|
89
88
|
## GitHub Repositories
|
|
90
89
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Contributing to Retold
|
|
2
|
+
|
|
3
|
+
We welcome contributions to Retold and its modules. This guide covers the expectations and process for contributing.
|
|
4
|
+
|
|
5
|
+
## Code of Conduct
|
|
6
|
+
|
|
7
|
+
The Retold community values **empathy**, **equity**, **kindness**, and **thoughtfulness**. We expect all participants to treat each other with respect, assume good intent, and engage constructively. These values apply to all interactions: pull requests, issues, discussions, and code review.
|
|
8
|
+
|
|
9
|
+
## How to Contribute
|
|
10
|
+
|
|
11
|
+
### Pull Requests
|
|
12
|
+
|
|
13
|
+
Pull requests are the preferred method for contributing changes. To submit one:
|
|
14
|
+
|
|
15
|
+
1. Fork the module repository you want to change
|
|
16
|
+
2. Create a branch for your work
|
|
17
|
+
3. Make your changes, following the code style of the module you are editing
|
|
18
|
+
4. Ensure your changes have test coverage (see below)
|
|
19
|
+
5. Open a pull request against the module's main branch
|
|
20
|
+
|
|
21
|
+
**Submitting a pull request does not guarantee it will be accepted.** Maintainers review contributions for fit, quality, and alignment with the project's direction. A PR may be declined, or you may be asked to revise it. This is normal and not a reflection on the quality of your effort.
|
|
22
|
+
|
|
23
|
+
### Reporting Issues
|
|
24
|
+
|
|
25
|
+
If you find a bug or have a feature suggestion, open an issue on the relevant module's repository. Include enough detail to reproduce the problem or understand the proposal.
|
|
26
|
+
|
|
27
|
+
## Test Coverage
|
|
28
|
+
|
|
29
|
+
Every commit must include test coverage for the changes it introduces. Retold modules use Mocha in TDD style. Before submitting:
|
|
30
|
+
|
|
31
|
+
- **Write tests** for any new functionality or bug fixes
|
|
32
|
+
- **Run the existing test suite** with `npm test` and confirm all tests pass
|
|
33
|
+
- **Check coverage** with `npm run coverage` if the module supports it
|
|
34
|
+
|
|
35
|
+
Pull requests that break existing tests or lack coverage for new code will not be merged.
|
|
36
|
+
|
|
37
|
+
## Code Style
|
|
38
|
+
|
|
39
|
+
Follow the conventions of the module you are working in. The general Retold style is:
|
|
40
|
+
|
|
41
|
+
- **Tabs** for indentation, never spaces
|
|
42
|
+
- **Plain JavaScript** only (no TypeScript)
|
|
43
|
+
- **Allman-style braces** (opening brace on its own line)
|
|
44
|
+
- **Variable naming:** `pVariable` for parameters, `tmpVariable` for temporaries, `libSomething` for imports
|
|
45
|
+
|
|
46
|
+
When in doubt, match what the surrounding code does.
|
|
47
|
+
|
|
48
|
+
## Repository Structure
|
|
49
|
+
|
|
50
|
+
Each module is its own git repository. The [retold](https://github.com/stevenvelozo/retold) repository tracks module organization but does not contain module source code. Direct your pull request to the specific module repository where your change belongs.
|
package/docs/modules/orator.md
CHANGED
|
@@ -112,12 +112,6 @@ An extensible reporting system for generating HTML, PDF, and other format report
|
|
|
112
112
|
|
|
113
113
|
---
|
|
114
114
|
|
|
115
|
-
### [Orator-Endpoint](/orator/orator-endpoint/)
|
|
116
|
-
|
|
117
|
-
A base class for creating reusable, pluggable API endpoint handlers that can be shared across Orator applications.
|
|
118
|
-
|
|
119
|
-
**npm:** `orator-endpoint` · **Version:** 1.0.x
|
|
120
|
-
|
|
121
115
|
## Typical Setup
|
|
122
116
|
|
|
123
117
|
A standard API server combines Orator with Meadow-Endpoints:
|
|
@@ -161,5 +155,4 @@ This gives you a full REST API with Create, Read, Reads, Update, Delete, Undelet
|
|
|
161
155
|
| [orator-static-server](/orator/orator-static-server/) | Static file serving with MIME detection |
|
|
162
156
|
| [orator-http-proxy](/orator/orator-http-proxy/) | HTTP reverse proxy pass-through |
|
|
163
157
|
| [tidings](/orator/tidings/) | Reporting scaffolding for HTML/PDF output |
|
|
164
|
-
| [orator-endpoint](/orator/orator-endpoint/) | Reusable endpoint base class |
|
|
165
158
|
| [orator-conversion](/orator/orator-conversion/) | File format conversion endpoints |
|