@stonyx/orm 0.2.1-beta.9 → 0.2.1-beta.91

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 (175) hide show
  1. package/README.md +64 -6
  2. package/config/environment.js +37 -1
  3. package/dist/aggregates.d.ts +21 -0
  4. package/dist/aggregates.js +93 -0
  5. package/dist/attr.d.ts +2 -0
  6. package/dist/attr.js +22 -0
  7. package/dist/belongs-to.d.ts +11 -0
  8. package/dist/belongs-to.js +59 -0
  9. package/dist/cli.d.ts +22 -0
  10. package/dist/cli.js +148 -0
  11. package/dist/commands.d.ts +7 -0
  12. package/dist/commands.js +146 -0
  13. package/dist/db.d.ts +21 -0
  14. package/dist/db.js +180 -0
  15. package/dist/exports/db.d.ts +7 -0
  16. package/{src → dist}/exports/db.js +2 -4
  17. package/dist/has-many.d.ts +11 -0
  18. package/dist/has-many.js +58 -0
  19. package/dist/hooks.d.ts +75 -0
  20. package/dist/hooks.js +110 -0
  21. package/dist/index.d.ts +14 -0
  22. package/dist/index.js +34 -0
  23. package/dist/main.d.ts +46 -0
  24. package/dist/main.js +181 -0
  25. package/dist/manage-record.d.ts +13 -0
  26. package/dist/manage-record.js +123 -0
  27. package/dist/meta-request.d.ts +6 -0
  28. package/dist/meta-request.js +52 -0
  29. package/dist/migrate.d.ts +2 -0
  30. package/dist/migrate.js +57 -0
  31. package/dist/model-property.d.ts +9 -0
  32. package/dist/model-property.js +29 -0
  33. package/dist/model.d.ts +15 -0
  34. package/dist/model.js +18 -0
  35. package/dist/mysql/connection.d.ts +14 -0
  36. package/dist/mysql/connection.js +24 -0
  37. package/dist/mysql/migration-generator.d.ts +45 -0
  38. package/dist/mysql/migration-generator.js +254 -0
  39. package/dist/mysql/migration-runner.d.ts +12 -0
  40. package/dist/mysql/migration-runner.js +88 -0
  41. package/dist/mysql/mysql-db.d.ts +100 -0
  42. package/dist/mysql/mysql-db.js +425 -0
  43. package/dist/mysql/query-builder.d.ts +10 -0
  44. package/dist/mysql/query-builder.js +44 -0
  45. package/dist/mysql/schema-introspector.d.ts +19 -0
  46. package/dist/mysql/schema-introspector.js +257 -0
  47. package/dist/mysql/type-map.d.ts +21 -0
  48. package/dist/mysql/type-map.js +36 -0
  49. package/dist/orm-request.d.ts +38 -0
  50. package/dist/orm-request.js +475 -0
  51. package/dist/plural-registry.d.ts +4 -0
  52. package/dist/plural-registry.js +9 -0
  53. package/dist/postgres/connection.d.ts +15 -0
  54. package/dist/postgres/connection.js +32 -0
  55. package/dist/postgres/migration-generator.d.ts +45 -0
  56. package/dist/postgres/migration-generator.js +261 -0
  57. package/dist/postgres/migration-runner.d.ts +10 -0
  58. package/dist/postgres/migration-runner.js +87 -0
  59. package/dist/postgres/postgres-db.d.ts +119 -0
  60. package/dist/postgres/postgres-db.js +477 -0
  61. package/dist/postgres/query-builder.d.ts +27 -0
  62. package/dist/postgres/query-builder.js +98 -0
  63. package/dist/postgres/schema-introspector.d.ts +28 -0
  64. package/dist/postgres/schema-introspector.js +280 -0
  65. package/dist/postgres/type-map.d.ts +23 -0
  66. package/dist/postgres/type-map.js +56 -0
  67. package/dist/record.d.ts +75 -0
  68. package/dist/record.js +129 -0
  69. package/dist/relationships.d.ts +10 -0
  70. package/dist/relationships.js +41 -0
  71. package/dist/schema-helpers.d.ts +20 -0
  72. package/dist/schema-helpers.js +48 -0
  73. package/dist/serializer.d.ts +17 -0
  74. package/dist/serializer.js +136 -0
  75. package/dist/setup-rest-server.d.ts +1 -0
  76. package/dist/setup-rest-server.js +52 -0
  77. package/dist/standalone-db.d.ts +58 -0
  78. package/dist/standalone-db.js +142 -0
  79. package/dist/store.d.ts +62 -0
  80. package/dist/store.js +286 -0
  81. package/dist/timescale/query-builder.d.ts +43 -0
  82. package/dist/timescale/query-builder.js +115 -0
  83. package/dist/timescale/timescale-db.d.ts +45 -0
  84. package/dist/timescale/timescale-db.js +84 -0
  85. package/dist/transforms.d.ts +2 -0
  86. package/dist/transforms.js +17 -0
  87. package/dist/types/orm-types.d.ts +142 -0
  88. package/dist/types/orm-types.js +1 -0
  89. package/dist/utils.d.ts +7 -0
  90. package/dist/utils.js +17 -0
  91. package/dist/view-resolver.d.ts +8 -0
  92. package/dist/view-resolver.js +171 -0
  93. package/dist/view.d.ts +11 -0
  94. package/dist/view.js +18 -0
  95. package/package.json +57 -15
  96. package/src/aggregates.ts +109 -0
  97. package/src/{attr.js → attr.ts} +2 -2
  98. package/src/belongs-to.ts +90 -0
  99. package/src/cli.ts +183 -0
  100. package/src/{commands.js → commands.ts} +179 -170
  101. package/src/{db.js → db.ts} +55 -29
  102. package/src/exports/db.ts +7 -0
  103. package/src/has-many.ts +92 -0
  104. package/src/hooks.ts +151 -0
  105. package/src/{index.js → index.ts} +11 -2
  106. package/src/main.ts +229 -0
  107. package/src/manage-record.ts +161 -0
  108. package/src/{meta-request.js → meta-request.ts} +17 -14
  109. package/src/{migrate.js → migrate.ts} +9 -9
  110. package/src/model-property.ts +35 -0
  111. package/src/model.ts +21 -0
  112. package/src/mysql/{connection.js → connection.ts} +43 -28
  113. package/src/mysql/migration-generator.ts +337 -0
  114. package/src/mysql/{migration-runner.js → migration-runner.ts} +121 -110
  115. package/src/mysql/mysql-db.ts +543 -0
  116. package/src/mysql/{query-builder.js → query-builder.ts} +69 -64
  117. package/src/mysql/schema-introspector.ts +310 -0
  118. package/src/mysql/{type-map.js → type-map.ts} +42 -37
  119. package/src/{orm-request.js → orm-request.ts} +187 -108
  120. package/src/plural-registry.ts +12 -0
  121. package/src/postgres/connection.ts +48 -0
  122. package/src/postgres/migration-generator.ts +348 -0
  123. package/src/postgres/migration-runner.ts +115 -0
  124. package/src/postgres/postgres-db.ts +616 -0
  125. package/src/postgres/query-builder.ts +148 -0
  126. package/src/postgres/schema-introspector.ts +343 -0
  127. package/src/postgres/type-map.ts +61 -0
  128. package/src/record.ts +186 -0
  129. package/src/relationships.ts +54 -0
  130. package/src/schema-helpers.ts +59 -0
  131. package/src/serializer.ts +161 -0
  132. package/src/{setup-rest-server.js → setup-rest-server.ts} +18 -16
  133. package/src/standalone-db.ts +185 -0
  134. package/src/store.ts +373 -0
  135. package/src/timescale/query-builder.ts +174 -0
  136. package/src/timescale/timescale-db.ts +119 -0
  137. package/src/transforms.ts +20 -0
  138. package/src/types/mysql2.d.ts +49 -0
  139. package/src/types/orm-types.ts +146 -0
  140. package/src/types/pg.d.ts +32 -0
  141. package/src/types/stonyx-cron.d.ts +5 -0
  142. package/src/types/stonyx-events.d.ts +4 -0
  143. package/src/types/stonyx-rest-server.d.ts +16 -0
  144. package/src/types/stonyx-utils.d.ts +33 -0
  145. package/src/types/stonyx.d.ts +21 -0
  146. package/src/utils.ts +22 -0
  147. package/src/view-resolver.ts +211 -0
  148. package/src/view.ts +22 -0
  149. package/.claude/code-style-rules.md +0 -44
  150. package/.claude/hooks.md +0 -250
  151. package/.claude/index.md +0 -279
  152. package/.claude/usage-patterns.md +0 -217
  153. package/.github/workflows/ci.yml +0 -16
  154. package/.github/workflows/publish.yml +0 -51
  155. package/improvements.md +0 -139
  156. package/project-structure.md +0 -343
  157. package/src/belongs-to.js +0 -63
  158. package/src/has-many.js +0 -61
  159. package/src/hooks.js +0 -124
  160. package/src/main.js +0 -148
  161. package/src/manage-record.js +0 -118
  162. package/src/model-property.js +0 -29
  163. package/src/model.js +0 -9
  164. package/src/mysql/migration-generator.js +0 -188
  165. package/src/mysql/mysql-db.js +0 -320
  166. package/src/mysql/schema-introspector.js +0 -158
  167. package/src/record.js +0 -127
  168. package/src/relationships.js +0 -43
  169. package/src/serializer.js +0 -138
  170. package/src/store.js +0 -211
  171. package/src/transforms.js +0 -20
  172. package/src/utils.js +0 -12
  173. package/test-events-setup.js +0 -41
  174. package/test-hooks-manual.js +0 -54
  175. package/test-hooks-with-logging.js +0 -52
package/.claude/index.md DELETED
@@ -1,279 +0,0 @@
1
- # Stonyx-ORM Guide for Claude
2
-
3
- ## Detailed Guides
4
-
5
- - [Usage Patterns](usage-patterns.md) — Model definitions, serializers, transforms, CRUD, DB schema, persistence, access control, REST API, and include parameters
6
- - [Middleware Hooks System](hooks.md) — Before/after hooks for CRUD operations, halting, context object, change detection, and testing
7
- - [Code Style Rules](code-style-rules.md) — Strict prettier/eslint rules to apply across all Stonyx projects
8
-
9
- ---
10
-
11
- ## Project Overview
12
-
13
- **stonyx-orm** is a lightweight Object-Relational Mapping (ORM) library designed specifically for the Stonyx framework. It provides structured data modeling, relationship management, serialization, and persistence to JSON files, with optional REST API integration.
14
-
15
- ## Core Problem It Solves
16
-
17
- 1. **Data Modeling**: Clean, type-safe model definitions with attributes and relationships
18
- 2. **Data Serialization**: Transforms messy third-party data into structured model instances
19
- 3. **Relationship Management**: Automatic bidirectional relationships (hasMany, belongsTo)
20
- 4. **Data Persistence**: File-based JSON storage with auto-save
21
- 5. **REST API Generation**: Auto-generated RESTful endpoints with access control
22
- 6. **Data Transformation**: Custom type conversion and formatting
23
- 7. **Middleware Hooks**: Before/after hooks for all CRUD operations with halting capability
24
-
25
- ---
26
-
27
- ## Architecture Overview
28
-
29
- ### Key Components
30
-
31
- 1. **Orm** ([src/main.js](src/main.js)) - Singleton that initializes and manages the entire system
32
- 2. **Store** ([src/store.js](src/store.js)) - In-memory storage (nested Maps: `Map<modelName, Map<recordId, record>>`)
33
- 3. **Model** ([src/model.js](src/model.js)) - Base class for all models
34
- 4. **Record** ([src/record.js](src/record.js)) - Individual model instances
35
- 5. **Serializer** ([src/serializer.js](src/serializer.js)) - Maps raw data to model format
36
- 6. **DB** ([src/db.js](src/db.js)) - JSON file persistence layer
37
- 7. **Relationships** ([src/has-many.js](src/has-many.js), [src/belongs-to.js](src/belongs-to.js)) - Relationship handlers
38
- 8. **Include Logic** (inline in [src/orm-request.js](src/orm-request.js)) - Parses include query params, traverses relationships, collects and deduplicates included records
39
- 9. **Hooks** ([src/hooks.js](src/hooks.js)) - Middleware-based hook registry for CRUD lifecycle
40
- 10. **MySQL Driver** ([src/mysql/mysql-db.js](src/mysql/mysql-db.js)) - MySQL persistence, migrations, schema introspection. Loads records in topological order. `_rowToRawData()` converts TINYINT(1) → boolean, remaps FK columns, strips timestamps.
41
-
42
- ### Project Structure
43
-
44
- ```
45
- stonyx-orm/
46
- ├── src/
47
- │ ├── index.js # Main exports (includes hook functions)
48
- │ ├── main.js # Orm class
49
- │ ├── model.js # Base Model
50
- │ ├── record.js # Record instances
51
- │ ├── serializer.js # Base Serializer
52
- │ ├── store.js # In-memory storage
53
- │ ├── db.js # JSON persistence
54
- │ ├── attr.js # Attribute helper (Proxy-based)
55
- │ ├── has-many.js # One-to-many relationships
56
- │ ├── belongs-to.js # Many-to-one relationships
57
- │ ├── relationships.js # Relationship registry
58
- │ ├── manage-record.js # createRecord/updateRecord
59
- │ ├── model-property.js # Transform handler
60
- │ ├── transforms.js # Built-in transforms
61
- │ ├── hooks.js # Middleware hook registry
62
- │ ├── setup-rest-server.js # REST integration
63
- │ ├── orm-request.js # CRUD request handler with hooks + includes
64
- │ ├── meta-request.js # Meta endpoint (dev only)
65
- │ ├── migrate.js # JSON DB mode migration (file <-> directory)
66
- │ ├── commands.js # CLI commands (db:migrate-*, etc.)
67
- │ ├── utils.js # Pluralize wrapper for dasherized names
68
- │ ├── exports/
69
- │ │ └── db.js # Convenience re-export of DB instance
70
- │ └── mysql/
71
- │ ├── mysql-db.js # MySQL driver (CRUD persistence, record loading)
72
- │ ├── connection.js # mysql2 connection pool
73
- │ ├── query-builder.js # SQL builders (INSERT/UPDATE/DELETE/SELECT) with identifier validation
74
- │ ├── schema-introspector.js # Model-to-MySQL schema introspection
75
- │ ├── migration-generator.js # Schema diff and .sql migration generation
76
- │ ├── migration-runner.js # Migration apply/rollback with transactions
77
- │ └── type-map.js # ORM attr types -> MySQL column types (supports custom transform mysqlType)
78
- ├── config/
79
- │ └── environment.js # Default configuration
80
- ├── test/
81
- │ ├── integration/ # Integration tests
82
- │ ├── unit/ # Unit tests
83
- │ └── sample/ # Test fixtures
84
- │ ├── models/ # Example models
85
- │ ├── serializers/ # Example serializers
86
- │ ├── transforms/ # Custom transforms
87
- │ ├── access/ # Access control
88
- │ ├── db-schema.js # DB schema
89
- │ └── payload.js # Test data
90
- └── package.json
91
- ```
92
-
93
- ---
94
-
95
- ## Configuration
96
-
97
- Located in [config/environment.js](config/environment.js), overridable via environment variables:
98
-
99
- ```javascript
100
- config.orm = {
101
- paths: {
102
- model: './models',
103
- serializer: './serializers',
104
- transform: './transforms',
105
- access: './access'
106
- },
107
- db: {
108
- autosave: 'false',
109
- file: 'db.json',
110
- mode: 'file', // 'file' (single db.json) or 'directory' (one file per collection)
111
- directory: 'db', // directory name for collection files when mode is 'directory'
112
- saveInterval: 3600,
113
- schema: './config/db-schema.js'
114
- },
115
- restServer: {
116
- enabled: 'true',
117
- route: '/'
118
- }
119
- }
120
- ```
121
-
122
- ---
123
-
124
- ## Storage Modes
125
-
126
- The ORM supports two storage modes, configured via `db.mode`:
127
-
128
- - **`'file'`** (default): All data is stored in a single `db.json` file.
129
- - **`'directory'`**: Each collection is stored as a separate file in the configured directory — `{directory}/{collection}.json` (e.g., `db/animals.json`, `db/owners.json`). The main `db.json` is kept as a skeleton with empty arrays.
130
-
131
- **Migration CLI commands:**
132
- - `stonyx-db-file-to-directory` — Splits a single `db.json` into per-collection files in the directory.
133
- - `stonyx-db-directory-to-file` — Merges per-collection files back into a single `db.json`.
134
-
135
- **Mode validation:** On startup, the ORM warns if the configured mode doesn't match the actual file state (e.g., mode is `'file'` but a `db/` directory exists, or mode is `'directory'` but no directory is found).
136
-
137
- ---
138
-
139
- ## Design Patterns
140
-
141
- 1. **Singleton**: Orm, Store, DB classes
142
- 2. **Proxy**: `attr()` uses Proxies for type-safe access
143
- 3. **Registry**: Relationships in nested Maps
144
- 4. **Factory**: `createRecord()` function
145
- 5. **Observer**: Auto-save via Cron
146
- 6. **Middleware**: Hook system with halting capability
147
- 7. **Convention over Configuration**: Auto-discovery by naming
148
-
149
- **Naming Conventions:**
150
- - Models: `{PascalCase}Model` (e.g., `AnimalModel`)
151
- - Serializers: `{PascalCase}Serializer` (e.g., `AnimalSerializer`)
152
- - Transforms: Original filename (e.g., `animal.js`)
153
-
154
- ---
155
-
156
- ## Testing
157
-
158
- **Test Runner**: QUnit via `stonyx test` (auto-bootstraps and runs `test/**/*-test.js`)
159
-
160
- **Test Structure:**
161
- - **Integration**: [test/integration/orm-test.js](test/integration/orm-test.js) - Full pipeline test
162
- - **Unit**: [test/unit/transforms/](test/unit/transforms/) - Transform tests
163
- - **Sample**: [test/sample/](test/sample/) - Test fixtures
164
-
165
- **Key Test Data:**
166
- - [test/sample/payload.js](test/sample/payload.js) - Raw vs serialized data
167
- - Demonstrates transformation from messy external data to clean models
168
-
169
- ---
170
-
171
- ## Critical Files for Common Tasks
172
-
173
- **Understanding Core Behavior:**
174
- - [src/main.js](src/main.js) - Initialization flow
175
- - [src/store.js](src/store.js) - Record storage/retrieval
176
- - [src/manage-record.js](src/manage-record.js) - CRUD operations
177
-
178
- **Understanding Relationships:**
179
- - [src/relationships.js](src/relationships.js) - Registry system
180
- - [src/has-many.js](src/has-many.js) - One-to-many logic
181
- - [src/belongs-to.js](src/belongs-to.js) - Many-to-one logic
182
-
183
- **Understanding Data Flow:**
184
- - [src/serializer.js](src/serializer.js) - Raw → Model mapping
185
- - [src/model-property.js](src/model-property.js) - Transform application
186
- - [src/transforms.js](src/transforms.js) - Built-in transforms
187
-
188
- **Understanding REST API:**
189
- - [src/setup-rest-server.js](src/setup-rest-server.js) - Endpoint registration
190
- - [src/orm-request.js](src/orm-request.js) - Request handling with hooks
191
-
192
- **Understanding Hooks:**
193
- - [src/hooks.js](src/hooks.js) - Hook registry (beforeHooks, afterHooks Maps)
194
- - [src/orm-request.js](src/orm-request.js) - `_withHooks()` wrapper
195
-
196
- ---
197
-
198
- ## Key Insights
199
-
200
- **Strengths:**
201
- - Zero-config REST API generation
202
- - Clean declarative model definitions
203
- - Automatic relationship management
204
- - File-based (no database setup needed)
205
- - Flexible serialization for messy data
206
- - Middleware hooks with halting capability
207
-
208
- **Use Cases:**
209
- - Rapid prototyping
210
- - Small to medium applications
211
- - Third-party API consumption with normalization
212
- - Development/testing environments
213
- - Applications needing quick REST APIs
214
-
215
- **Dependencies:**
216
- - `stonyx` - Main framework (peer)
217
- - `@stonyx/utils` - File/string utilities
218
- - `@stonyx/events` - Pub/sub event system (event names initialized on startup; hooks use separate middleware-based registry)
219
- - `@stonyx/cron` - Scheduled tasks (used by DB for auto-save)
220
- - `@stonyx/rest-server` - REST API
221
- - `mysql2` - Optional peer dependency for MySQL mode
222
-
223
- ---
224
-
225
- ## Quick Reference
226
-
227
- **Import the ORM:**
228
- ```javascript
229
- import {
230
- Orm, Model, Serializer, attr, hasMany, belongsTo,
231
- createRecord, updateRecord, store,
232
- beforeHook, afterHook, clearHook, clearAllHooks
233
- } from '@stonyx/orm';
234
- ```
235
-
236
- **Initialize:**
237
- ```javascript
238
- const orm = new Orm({ dbType: 'json' });
239
- await orm.init();
240
- ```
241
-
242
- **Access Database:**
243
- ```javascript
244
- await Orm.db.save();
245
- ```
246
-
247
- **Common Operations:**
248
- ```javascript
249
- // Create
250
- const record = createRecord('modelName', data);
251
-
252
- // Read
253
- const record = store.get('modelName', id);
254
- const all = store.get('modelName');
255
-
256
- // Update
257
- updateRecord(record, newData);
258
-
259
- // Delete
260
- store.remove('modelName', id);
261
- ```
262
-
263
- **Register Hooks:**
264
- ```javascript
265
- // Before hook (can halt)
266
- const unsubscribe = beforeHook('create', 'animal', (ctx) => {
267
- if (invalid) return 400;
268
- });
269
-
270
- // After hook
271
- afterHook('update', 'animal', (ctx) => {
272
- console.log('Updated:', ctx.record.id);
273
- });
274
-
275
- // Cleanup
276
- unsubscribe(); // Remove specific hook
277
- clearHook('create', 'animal'); // Clear all hooks for operation
278
- clearAllHooks(); // Clear everything
279
- ```
@@ -1,217 +0,0 @@
1
- # Usage Patterns
2
-
3
- ## 1. Model Definition
4
-
5
- Models extend `Model` and use decorators for attributes and relationships:
6
-
7
- ```javascript
8
- // test/sample/models/animal.js
9
- import { Model, attr, belongsTo, hasMany } from '@stonyx/orm';
10
-
11
- export default class AnimalModel extends Model {
12
- // Attributes with type transforms
13
- type = attr('animal'); // Custom transform
14
- age = attr('number'); // Built-in transform
15
- size = attr('string');
16
-
17
- // Relationships
18
- owner = belongsTo('owner'); // Many-to-one
19
- traits = hasMany('trait'); // One-to-many
20
-
21
- // Computed properties
22
- get tag() {
23
- return `${this.owner.id}'s ${this.size} animal`;
24
- }
25
- }
26
- ```
27
-
28
- **Key Points:**
29
- - Use `attr(type)` for simple attributes
30
- - Use `belongsTo(modelName)` for many-to-one
31
- - Use `hasMany(modelName)` for one-to-many
32
- - Getters work as computed properties
33
- - Relationships auto-establish bidirectionally
34
-
35
- ## 2. Serializers (Data Transformation)
36
-
37
- Serializers map raw data paths to model properties:
38
-
39
- ```javascript
40
- // test/sample/serializers/animal.js
41
- import { Serializer } from '@stonyx/orm';
42
-
43
- export default class AnimalSerializer extends Serializer {
44
- map = {
45
- // Nested path mapping
46
- age: 'details.age',
47
- size: 'details.c',
48
- owner: 'details.location.owner',
49
-
50
- // Custom transformation function
51
- traits: ['details', ({ x:color }) => {
52
- const traits = [{ id: 1, type: 'habitat', value: 'farm' }];
53
- if (color) traits.push({ id: 2, type: 'color', value: color });
54
- return traits;
55
- }]
56
- }
57
- }
58
- ```
59
-
60
- **Key Points:**
61
- - `map` object defines field mappings
62
- - Supports nested paths (`'details.age'`)
63
- - Custom functions for complex transformations
64
- - Handlers receive raw data subset
65
-
66
- ## 3. Custom Transforms
67
-
68
- Transforms convert data types:
69
-
70
- ```javascript
71
- // test/sample/transforms/animal.js
72
- const codeEnumMap = { 'dog': 1, 'cat': 2, 'bird': 3 };
73
-
74
- export default function(value) {
75
- return codeEnumMap[value] || 0;
76
- }
77
- ```
78
-
79
- **Built-in Transforms:**
80
- - Type: `boolean`, `number`, `float`, `string`, `date`, `timestamp`
81
- - Math: `round`, `ceil`, `floor`
82
- - String: `trim`, `uppercase`
83
- - Utility: `passthrough`
84
-
85
- ## 4. CRUD Operations
86
-
87
- ```javascript
88
- import { createRecord, updateRecord, store } from '@stonyx/orm';
89
-
90
- // Create
91
- createRecord('owner', { id: 'bob', age: 30 });
92
-
93
- // Read
94
- const owner = store.get('owner', 'bob');
95
- const allOwners = store.get('owner');
96
-
97
- // Update
98
- updateRecord(owner, { age: 31 });
99
- // Or direct: owner.age = 31;
100
-
101
- // Delete
102
- store.remove('owner', 'bob');
103
- ```
104
-
105
- ## 5. Database Schema
106
-
107
- The DB schema is a Model defining top-level collections:
108
-
109
- ```javascript
110
- // test/sample/db-schema.js
111
- import { Model, hasMany } from '@stonyx/orm';
112
-
113
- export default class DBModel extends Model {
114
- owners = hasMany('owner');
115
- animals = hasMany('animal');
116
- traits = hasMany('trait');
117
- }
118
- ```
119
-
120
- ## 6. Persistence
121
-
122
- ```javascript
123
- import Orm from '@stonyx/orm';
124
-
125
- // Save to file
126
- await Orm.db.save();
127
-
128
- // Data auto-serializes to JSON file
129
- // Reload using createRecord with serialize:false, transform:false
130
- ```
131
-
132
- ## 7. Access Control
133
-
134
- ```javascript
135
- // test/sample/access/global-access.js
136
- export default class GlobalAccess {
137
- models = ['owner', 'animal']; // or '*' for all
138
-
139
- access(request) {
140
- // Deny specific access
141
- if (request.url.endsWith('/owner/angela')) return false;
142
-
143
- // Filter collections
144
- if (request.url.endsWith('/owner')) {
145
- return record => record.id !== 'angela';
146
- }
147
-
148
- // Grant CRUD permissions
149
- return ['read', 'create', 'update', 'delete'];
150
- }
151
- }
152
- ```
153
-
154
- ## 8. REST API (Auto-generated)
155
-
156
- ```javascript
157
- // Endpoints auto-generated for models:
158
- // GET /owners - List all
159
- // GET /owners/:id - Get one
160
- // POST /animals - Create
161
- // PATCH /animals/:id - Update (attributes and/or relationships)
162
- // DELETE /animals/:id - Delete
163
- ```
164
-
165
- **PATCH supports both attributes and relationships:**
166
- ```javascript
167
- // Update attributes only
168
- PATCH /animals/1
169
- { data: { type: 'animal', attributes: { age: 5 } } }
170
-
171
- // Update relationship only
172
- PATCH /animals/1
173
- { data: { type: 'animal', relationships: { owner: { data: { type: 'owner', id: 'gina' } } } } }
174
-
175
- // Update both
176
- PATCH /animals/1
177
- { data: { type: 'animal', attributes: { age: 5 }, relationships: { owner: { data: { type: 'owner', id: 'gina' } } } } }
178
- ```
179
-
180
- ## 9. Include Parameter (Sideloading)
181
-
182
- GET endpoints support sideloading related records with **nested relationship traversal**:
183
-
184
- ```javascript
185
- // Single-level includes
186
- GET /animals/1?include=owner,traits
187
-
188
- // Nested includes (NEW!)
189
- GET /animals/1?include=owner.pets,owner.company
190
-
191
- // Deep nesting (3+ levels)
192
- GET /scenes/e001-s001?include=slides.dialogue.character
193
-
194
- // Response structure (unchanged)
195
- {
196
- data: { type: 'animal', id: 1, attributes: {...}, relationships: {...} },
197
- included: [
198
- { type: 'owner', id: 'angela', ... },
199
- { type: 'animal', id: 7, ... }, // owner's other pets
200
- { type: 'animal', id: 11, ... }, // owner's other pets
201
- { type: 'company', id: 'acme', ... } // owner's company (if requested)
202
- ]
203
- }
204
- ```
205
-
206
- **How Nested Includes Work:**
207
- 1. Query param parsed into path segments: `owner.pets` -> `[['owner'], ['owner', 'pets'], ['traits']]`
208
- 2. `traverseIncludePath()` recursively traverses relationships depth-first
209
- 3. Deduplication still by type+id (no duplicates in included array)
210
- 4. Gracefully handles null/missing relationships at any depth
211
- 5. Each included record gets full `toJSON()` representation
212
-
213
- **Key Functions:**
214
- - `parseInclude()` - Splits comma-separated includes and parses nested paths
215
- - `traverseIncludePath()` - Recursively traverses relationship paths
216
- - `collectIncludedRecords()` - Orchestrates traversal and deduplication
217
- - All implemented in [src/orm-request.js](src/orm-request.js)
@@ -1,16 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- pull_request:
5
- branches: [dev, main]
6
-
7
- concurrency:
8
- group: ci-${{ github.head_ref || github.ref }}
9
- cancel-in-progress: true
10
-
11
- permissions:
12
- contents: read
13
-
14
- jobs:
15
- test:
16
- uses: abofs/stonyx-workflows/.github/workflows/ci.yml@main
@@ -1,51 +0,0 @@
1
- name: Publish to NPM
2
-
3
- on:
4
- repository_dispatch:
5
- types: [cascade-publish]
6
- workflow_dispatch:
7
- inputs:
8
- version-type:
9
- description: 'Version type'
10
- required: true
11
- type: choice
12
- options:
13
- - patch
14
- - minor
15
- - major
16
- custom-version:
17
- description: 'Custom version (optional, overrides version-type)'
18
- required: false
19
- type: string
20
- pull_request:
21
- types: [opened, synchronize, reopened]
22
- branches: [main]
23
- push:
24
- branches: [main]
25
-
26
- concurrency:
27
- group: ${{ github.event_name == 'repository_dispatch' && 'cascade-update' || format('publish-{0}', github.ref) }}
28
- cancel-in-progress: false
29
-
30
- permissions:
31
- contents: write
32
- id-token: write
33
- pull-requests: write
34
-
35
- jobs:
36
- publish:
37
- if: "!contains(github.event.head_commit.message, '[skip ci]')"
38
- uses: abofs/stonyx-workflows/.github/workflows/npm-publish.yml@main
39
- with:
40
- version-type: ${{ github.event.inputs.version-type }}
41
- custom-version: ${{ github.event.inputs.custom-version }}
42
- cascade-source: ${{ github.event.client_payload.source_package || '' }}
43
- secrets: inherit
44
-
45
- cascade:
46
- needs: publish
47
- uses: abofs/stonyx-workflows/.github/workflows/cascade.yml@main
48
- with:
49
- package-name: ${{ needs.publish.outputs.package-name }}
50
- published-version: ${{ needs.publish.outputs.published-version }}
51
- secrets: inherit