@stonyx/orm 0.2.1-beta.9 → 0.2.1-beta.90
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/README.md +64 -6
- package/config/environment.js +37 -1
- package/dist/aggregates.d.ts +21 -0
- package/dist/aggregates.js +93 -0
- package/dist/attr.d.ts +2 -0
- package/dist/attr.js +22 -0
- package/dist/belongs-to.d.ts +11 -0
- package/dist/belongs-to.js +59 -0
- package/dist/cli.d.ts +22 -0
- package/dist/cli.js +148 -0
- package/dist/commands.d.ts +7 -0
- package/dist/commands.js +146 -0
- package/dist/db.d.ts +21 -0
- package/dist/db.js +180 -0
- package/dist/exports/db.d.ts +7 -0
- package/{src → dist}/exports/db.js +2 -4
- package/dist/has-many.d.ts +11 -0
- package/dist/has-many.js +58 -0
- package/dist/hooks.d.ts +62 -0
- package/dist/hooks.js +110 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +34 -0
- package/dist/main.d.ts +46 -0
- package/dist/main.js +181 -0
- package/dist/manage-record.d.ts +13 -0
- package/dist/manage-record.js +123 -0
- package/dist/meta-request.d.ts +6 -0
- package/dist/meta-request.js +52 -0
- package/dist/migrate.d.ts +2 -0
- package/dist/migrate.js +57 -0
- package/dist/model-property.d.ts +9 -0
- package/dist/model-property.js +29 -0
- package/dist/model.d.ts +15 -0
- package/dist/model.js +18 -0
- package/dist/mysql/connection.d.ts +14 -0
- package/dist/mysql/connection.js +24 -0
- package/dist/mysql/migration-generator.d.ts +45 -0
- package/dist/mysql/migration-generator.js +254 -0
- package/dist/mysql/migration-runner.d.ts +12 -0
- package/dist/mysql/migration-runner.js +88 -0
- package/dist/mysql/mysql-db.d.ts +100 -0
- package/dist/mysql/mysql-db.js +425 -0
- package/dist/mysql/query-builder.d.ts +10 -0
- package/dist/mysql/query-builder.js +44 -0
- package/dist/mysql/schema-introspector.d.ts +19 -0
- package/dist/mysql/schema-introspector.js +291 -0
- package/dist/mysql/type-map.d.ts +21 -0
- package/dist/mysql/type-map.js +36 -0
- package/dist/orm-request.d.ts +38 -0
- package/dist/orm-request.js +474 -0
- package/dist/plural-registry.d.ts +4 -0
- package/dist/plural-registry.js +9 -0
- package/dist/postgres/connection.d.ts +15 -0
- package/dist/postgres/connection.js +32 -0
- package/dist/postgres/migration-generator.d.ts +45 -0
- package/dist/postgres/migration-generator.js +261 -0
- package/dist/postgres/migration-runner.d.ts +10 -0
- package/dist/postgres/migration-runner.js +87 -0
- package/dist/postgres/postgres-db.d.ts +119 -0
- package/dist/postgres/postgres-db.js +477 -0
- package/dist/postgres/query-builder.d.ts +27 -0
- package/dist/postgres/query-builder.js +98 -0
- package/dist/postgres/schema-introspector.d.ts +29 -0
- package/dist/postgres/schema-introspector.js +314 -0
- package/dist/postgres/type-map.d.ts +23 -0
- package/dist/postgres/type-map.js +56 -0
- package/dist/record.d.ts +75 -0
- package/dist/record.js +129 -0
- package/dist/relationships.d.ts +10 -0
- package/dist/relationships.js +41 -0
- package/dist/serializer.d.ts +17 -0
- package/dist/serializer.js +136 -0
- package/dist/setup-rest-server.d.ts +1 -0
- package/dist/setup-rest-server.js +52 -0
- package/dist/standalone-db.d.ts +58 -0
- package/dist/standalone-db.js +142 -0
- package/dist/store.d.ts +62 -0
- package/dist/store.js +286 -0
- package/dist/timescale/query-builder.d.ts +43 -0
- package/dist/timescale/query-builder.js +115 -0
- package/dist/timescale/timescale-db.d.ts +45 -0
- package/dist/timescale/timescale-db.js +84 -0
- package/dist/transforms.d.ts +2 -0
- package/dist/transforms.js +17 -0
- package/dist/types/orm-types.d.ts +142 -0
- package/dist/types/orm-types.js +1 -0
- package/dist/utils.d.ts +7 -0
- package/dist/utils.js +17 -0
- package/dist/view-resolver.d.ts +8 -0
- package/dist/view-resolver.js +171 -0
- package/dist/view.d.ts +11 -0
- package/dist/view.js +18 -0
- package/package.json +57 -15
- package/src/aggregates.ts +109 -0
- package/src/{attr.js → attr.ts} +2 -2
- package/src/belongs-to.ts +90 -0
- package/src/cli.ts +183 -0
- package/src/{commands.js → commands.ts} +179 -170
- package/src/{db.js → db.ts} +55 -29
- package/src/exports/db.ts +7 -0
- package/src/has-many.ts +92 -0
- package/src/{hooks.js → hooks.ts} +41 -27
- package/src/{index.js → index.ts} +11 -2
- package/src/main.ts +229 -0
- package/src/manage-record.ts +161 -0
- package/src/{meta-request.js → meta-request.ts} +17 -14
- package/src/{migrate.js → migrate.ts} +9 -9
- package/src/model-property.ts +35 -0
- package/src/model.ts +21 -0
- package/src/mysql/{connection.js → connection.ts} +43 -28
- package/src/mysql/migration-generator.ts +337 -0
- package/src/mysql/{migration-runner.js → migration-runner.ts} +121 -110
- package/src/mysql/mysql-db.ts +543 -0
- package/src/mysql/{query-builder.js → query-builder.ts} +69 -64
- package/src/mysql/schema-introspector.ts +358 -0
- package/src/mysql/{type-map.js → type-map.ts} +42 -37
- package/src/{orm-request.js → orm-request.ts} +186 -108
- package/src/plural-registry.ts +12 -0
- package/src/postgres/connection.ts +48 -0
- package/src/postgres/migration-generator.ts +348 -0
- package/src/postgres/migration-runner.ts +115 -0
- package/src/postgres/postgres-db.ts +616 -0
- package/src/postgres/query-builder.ts +148 -0
- package/src/postgres/schema-introspector.ts +386 -0
- package/src/postgres/type-map.ts +61 -0
- package/src/record.ts +186 -0
- package/src/relationships.ts +54 -0
- package/src/serializer.ts +161 -0
- package/src/{setup-rest-server.js → setup-rest-server.ts} +18 -16
- package/src/standalone-db.ts +185 -0
- package/src/store.ts +373 -0
- package/src/timescale/query-builder.ts +174 -0
- package/src/timescale/timescale-db.ts +119 -0
- package/src/transforms.ts +20 -0
- package/src/types/mysql2.d.ts +49 -0
- package/src/types/orm-types.ts +146 -0
- package/src/types/pg.d.ts +32 -0
- package/src/types/stonyx-cron.d.ts +5 -0
- package/src/types/stonyx-events.d.ts +4 -0
- package/src/types/stonyx-rest-server.d.ts +16 -0
- package/src/types/stonyx-utils.d.ts +33 -0
- package/src/types/stonyx.d.ts +21 -0
- package/src/utils.ts +22 -0
- package/src/view-resolver.ts +211 -0
- package/src/view.ts +22 -0
- package/.claude/code-style-rules.md +0 -44
- package/.claude/hooks.md +0 -250
- package/.claude/index.md +0 -279
- package/.claude/usage-patterns.md +0 -217
- package/.github/workflows/ci.yml +0 -16
- package/.github/workflows/publish.yml +0 -51
- package/improvements.md +0 -139
- package/project-structure.md +0 -343
- package/src/belongs-to.js +0 -63
- package/src/has-many.js +0 -61
- package/src/main.js +0 -148
- package/src/manage-record.js +0 -118
- package/src/model-property.js +0 -29
- package/src/model.js +0 -9
- package/src/mysql/migration-generator.js +0 -188
- package/src/mysql/mysql-db.js +0 -320
- package/src/mysql/schema-introspector.js +0 -158
- package/src/record.js +0 -127
- package/src/relationships.js +0 -43
- package/src/serializer.js +0 -138
- package/src/store.js +0 -211
- package/src/transforms.js +0 -20
- package/src/utils.js +0 -12
- package/test-events-setup.js +0 -41
- package/test-hooks-manual.js +0 -54
- package/test-hooks-with-logging.js +0 -52
|
@@ -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)
|
package/.github/workflows/ci.yml
DELETED
|
@@ -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
|
package/improvements.md
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
# Code Improvements: @stonyx/orm
|
|
2
|
-
|
|
3
|
-
> Audited: 2026-02-09 | Auto-generated by project-docs-auditor
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Summary
|
|
8
|
-
|
|
9
|
-
The codebase is well-structured with clear separation of concerns and consistent patterns. The main areas for improvement are: a debug `console.log` left in production config, duplicated utility functions across multiple files, and documentation that has drifted from the actual code. The MySQL driver is well-tested and cleanly DI'd, but the JSON persistence side lacks equivalent test coverage.
|
|
10
|
-
|
|
11
|
-
**Findings by priority:**
|
|
12
|
-
| Priority | Count |
|
|
13
|
-
|----------|-------|
|
|
14
|
-
| High | 2 |
|
|
15
|
-
| Medium | 6 |
|
|
16
|
-
| Low | 5 |
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## High Priority
|
|
21
|
-
|
|
22
|
-
### [H1] Stray `console.log` in production config
|
|
23
|
-
- **Category:** Debug Leak
|
|
24
|
-
- **Files:** `config/environment.js`
|
|
25
|
-
- **Lines:** L57
|
|
26
|
-
- **Problem:** `console.log(MYSQL_HOST)` is left at the bottom of the environment config file. This will log the MySQL host (or `undefined`) on every application startup, leaking configuration details to stdout.
|
|
27
|
-
- **Suggestion:** Remove the `console.log(MYSQL_HOST)` line entirely.
|
|
28
|
-
- **Impact:** Eliminates unintended log noise and prevents leaking configuration values in production.
|
|
29
|
-
|
|
30
|
-
### [H2] Duplicated `getRelationshipInfo()` function
|
|
31
|
-
- **Category:** WET Code
|
|
32
|
-
- **Files:** `src/orm-request.js` (L18-28), `src/mysql/schema-introspector.js` (L6-14), `src/meta-request.js` (L33-34)
|
|
33
|
-
- **Problem:** The pattern of inspecting a function's `toString()` for `getRelationships('belongsTo',` or `getRelationships('hasMany',` is repeated in three separate files with slight variations. Each independently detects relationship type from a property.
|
|
34
|
-
- **Suggestion:** Extract a shared `getRelationshipInfo(property)` function into `src/relationships.js` (which already acts as the relationship utility module) and import it from all three consumers.
|
|
35
|
-
- **Impact:** Single source of truth for relationship detection. Changes to the detection pattern only need to happen in one place.
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Medium Priority
|
|
40
|
-
|
|
41
|
-
### [M1] Duplicated `getOrSet` helper
|
|
42
|
-
- **Category:** WET Code
|
|
43
|
-
- **Files:** `src/has-many.js` (imports from `@stonyx/utils/object`), `src/belongs-to.js` (L4-7)
|
|
44
|
-
- **Problem:** `belongs-to.js` defines its own local `getOrSet(map, key, defaultValue)` function identical to the one available from `@stonyx/utils/object` that `has-many.js` already imports.
|
|
45
|
-
- **Suggestion:** Replace the local `getOrSet` in `belongs-to.js` with `import { getOrSet } from '@stonyx/utils/object'`.
|
|
46
|
-
- **Impact:** Eliminates duplicated code and maintains consistency with `has-many.js`.
|
|
47
|
-
|
|
48
|
-
### [M2] Duplicated `getCollectionKeys()` and `getDirPath()`
|
|
49
|
-
- **Category:** WET Code
|
|
50
|
-
- **Files:** `src/db.js` (L42-61), `src/migrate.js` (L7-26)
|
|
51
|
-
- **Problem:** Both files contain identical `getCollectionKeys()` and `getDirPath()` functions. The migration module duplicated these from the DB class as standalone functions.
|
|
52
|
-
- **Suggestion:** Export these methods from `src/db.js` (or extract into a shared `src/db-utils.js`) and import them in `src/migrate.js`.
|
|
53
|
-
- **Impact:** Eliminates duplication and ensures migration logic always matches DB logic.
|
|
54
|
-
|
|
55
|
-
### [M3] `TYPES` array missing `pendingBelongsTo`
|
|
56
|
-
- **Category:** Bug Risk
|
|
57
|
-
- **Files:** `src/relationships.js` (L43)
|
|
58
|
-
- **Lines:** L43
|
|
59
|
-
- **Problem:** `export const TYPES = ['global', 'hasMany', 'belongsTo', 'pending']` is missing `'pendingBelongsTo'`, which is a relationship type initialized in `src/main.js` (L48). The `TYPES` array is used by `store.unloadAllRecords()` (L75) for cleanup, meaning `pendingBelongsTo` entries won't be cleaned up when unloading all records for a model.
|
|
60
|
-
- **Suggestion:** Add `'pendingBelongsTo'` to the `TYPES` array.
|
|
61
|
-
- **Impact:** Prevents potential stale pending belongsTo references when unloading all records for a model.
|
|
62
|
-
|
|
63
|
-
### [M4] `introspectModels` called repeatedly on every persist operation
|
|
64
|
-
- **Category:** Performance
|
|
65
|
-
- **Files:** `src/mysql/mysql-db.js` (L147, L193, L231)
|
|
66
|
-
- **Problem:** `_persistCreate`, `_persistUpdate`, and `_persistDelete` all call `this.deps.introspectModels()` on every single write operation. Schema introspection iterates all models, creates instances, and inspects properties. Since model schemas don't change at runtime, this is unnecessary repeated work.
|
|
67
|
-
- **Suggestion:** Cache the introspected schemas in `MysqlDB.init()` (or lazily on first access) and reuse the cached result in persist methods.
|
|
68
|
-
- **Impact:** Reduces CPU overhead on every write operation, especially significant with frequent CRUD activity.
|
|
69
|
-
|
|
70
|
-
### [M5] `startup()` also calls `introspectModels()` separately from `loadAllRecords()`
|
|
71
|
-
- **Category:** Performance
|
|
72
|
-
- **Files:** `src/mysql/mysql-db.js` (L69, L88)
|
|
73
|
-
- **Problem:** `startup()` calls `introspectModels()` at L69 for drift detection, but `loadAllRecords()` (called at L62 inside the migration-apply branch) also calls `introspectModels()` at L88. When migrations are applied, `introspectModels()` runs three times: once in `loadAllRecords` (via init), once in reloaded `loadAllRecords`, and once for drift check.
|
|
74
|
-
- **Suggestion:** Same as M4 — cache the result.
|
|
75
|
-
- **Impact:** Reduces redundant schema introspection calls during startup.
|
|
76
|
-
|
|
77
|
-
### [M6] No test coverage for JSON DB `save()` and `getRecord()` flows
|
|
78
|
-
- **Category:** Test Gap
|
|
79
|
-
- **Files:** `src/db.js`
|
|
80
|
-
- **Problem:** The JSON file persistence layer (`DB` class) lacks unit tests for its core `save()`, `getRecord()`, `getRecordFromDirectory()`, `getRecordFromFile()`, and `validateMode()` methods. The MySQL driver has thorough unit tests via dependency injection, but the JSON DB has no equivalent.
|
|
81
|
-
- **Suggestion:** Add unit tests for `src/db.js`, potentially using the same DI pattern used by `MysqlDB` to mock file operations.
|
|
82
|
-
- **Impact:** Increases confidence in the JSON persistence path, which is the default storage mode.
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## Low Priority
|
|
87
|
-
|
|
88
|
-
### [L1] Documentation references non-existent files
|
|
89
|
-
- **Category:** Stale Docs
|
|
90
|
-
- **Files:** `.claude/index.md` (L38-39), `.claude/personal/outline.md` (L1107)
|
|
91
|
-
- **Problem:** The `.claude/index.md` references `src/include-parser.js` and `src/include-collector.js` which don't exist — include parsing is inline in `src/orm-request.js`. The outline references `stonyx-bootstrap.cjs` which doesn't exist.
|
|
92
|
-
- **Suggestion:** Remove the `include-parser.js` and `include-collector.js` references from `.claude/index.md` and the `stonyx-bootstrap.cjs` reference from the outline. Update the architecture section to point to `src/orm-request.js` for include logic.
|
|
93
|
-
- **Impact:** Prevents confusion when navigating docs.
|
|
94
|
-
|
|
95
|
-
### [L2] Outdated version in outline doc
|
|
96
|
-
- **Category:** Stale Docs
|
|
97
|
-
- **Files:** `.claude/personal/outline.md` (L1076)
|
|
98
|
-
- **Problem:** Lists version as `0.1.0` but `package.json` shows `0.2.1-beta.1`.
|
|
99
|
-
- **Suggestion:** Update or remove the version reference. Since `package.json` is the source of truth, the docs shouldn't duplicate it.
|
|
100
|
-
- **Impact:** Minor — prevents stale version confusion.
|
|
101
|
-
|
|
102
|
-
### [L3] Outline docs missing `./commands` and `./hooks` package exports
|
|
103
|
-
- **Category:** Stale Docs
|
|
104
|
-
- **Files:** `.claude/personal/outline.md` (L884-889)
|
|
105
|
-
- **Problem:** The package.json `exports` section in the outline doc only shows `"."` and `"./db"`, but the actual `package.json` also exports `"./migrate"`, `"./commands"`, and `"./hooks"`.
|
|
106
|
-
- **Suggestion:** Update the outline's package.json section to match the actual exports.
|
|
107
|
-
- **Impact:** Minor — ensures docs reflect the full public API surface.
|
|
108
|
-
|
|
109
|
-
### [L4] Outline references old event-based system
|
|
110
|
-
- **Category:** Stale Docs
|
|
111
|
-
- **Files:** `.claude/index.md` (L204)
|
|
112
|
-
- **Problem:** States `@stonyx/events - Pub/sub event system (optional, not used for hooks)`. However, `@stonyx/events` is imported and `setup(eventNames)` is called in `src/main.js` (L91). The events are set up but the hooks system uses its own registry. This is confusing — events are initialized but the hooks use a separate middleware pattern.
|
|
113
|
-
- **Suggestion:** Clarify that `@stonyx/events` is still initialized for event names during ORM setup, but the actual hook dispatch uses the middleware-based system in `src/hooks.js`.
|
|
114
|
-
- **Impact:** Reduces confusion about the relationship between `@stonyx/events` and the hooks system.
|
|
115
|
-
|
|
116
|
-
### [L5] Manual test scripts in project root
|
|
117
|
-
- **Category:** Dead Code
|
|
118
|
-
- **Files:** `test-hooks-with-logging.js`, `test-events-setup.js`, `test-hooks-manual.js`
|
|
119
|
-
- **Problem:** Three manual test scripts remain in the project root from the hooks implementation. They were used to verify functionality when the test harness had linking issues, but are not part of the test suite and won't run via `npm test`.
|
|
120
|
-
- **Suggestion:** Either move them to `test/manual/` or remove them if the hooks implementation is considered stable and the test harness issues are resolved.
|
|
121
|
-
- **Impact:** Cleaner project root; reduces confusion about which test files are authoritative.
|
|
122
|
-
|
|
123
|
-
---
|
|
124
|
-
|
|
125
|
-
## Refactoring Roadmap
|
|
126
|
-
|
|
127
|
-
**Quick wins (do first):**
|
|
128
|
-
1. **H1** — Delete one line (`console.log(MYSQL_HOST)`) in config
|
|
129
|
-
2. **M1** — Replace local `getOrSet` in `belongs-to.js` with import
|
|
130
|
-
3. **M3** — Add `'pendingBelongsTo'` to `TYPES` array
|
|
131
|
-
|
|
132
|
-
**Medium effort:**
|
|
133
|
-
4. **H2** — Extract shared `getRelationshipInfo` into `relationships.js`
|
|
134
|
-
5. **M2** — Extract shared `getCollectionKeys`/`getDirPath` from `db.js`
|
|
135
|
-
|
|
136
|
-
**Longer term:**
|
|
137
|
-
6. **M4/M5** — Cache introspected schemas in MysqlDB
|
|
138
|
-
7. **M6** — Add DB unit tests
|
|
139
|
-
8. **L1-L4** — Documentation cleanup pass
|