retold-data-service 2.0.8 → 2.0.10

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.
@@ -1,17 +1,36 @@
1
1
  {
2
2
  "sqltools.connections": [
3
- {
4
- "mysqlOptions": {
5
- "authProtocol": "default"
6
- },
7
- "previewLimit": 50,
8
- "server": "localhost",
9
- "port": 3306,
10
- "driver": "MariaDB",
11
- "name": "Local",
12
- "database": "bookstore",
13
- "username": "root",
14
- "password": "123456789"
15
- }
16
- ]
3
+ {
4
+ "mysqlOptions": {
5
+ "authProtocol": "default",
6
+ "enableSsl": "Disabled"
7
+ },
8
+ "ssh": "Disabled",
9
+ "previewLimit": 50,
10
+ "server": "localhost",
11
+ "port": 3306,
12
+ "driver": "MariaDB",
13
+ "name": "Local MariaDB Harness",
14
+ "database": "bookstore",
15
+ "username": "root",
16
+ "password": "123456789",
17
+ "group": "Retold Development"
18
+ },
19
+ {
20
+ "mysqlOptions": {
21
+ "authProtocol": "default",
22
+ "enableSsl": "Disabled"
23
+ },
24
+ "ssh": "Disabled",
25
+ "previewLimit": 50,
26
+ "server": "localhost",
27
+ "port": 31306,
28
+ "driver": "MariaDB",
29
+ "name": "Containerized MariaDB Harness",
30
+ "group": "Retold Development",
31
+ "database": "bookstore",
32
+ "username": "root",
33
+ "password": "123456789"
34
+ }
35
+ ]
17
36
  }
@@ -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/README.md CHANGED
@@ -1,86 +1,230 @@
1
1
  # Retold Data Service
2
2
 
3
- Provide a consistent back or mid-tier data service.
3
+ > An all-in-one Fable service that turns a Stricture schema into a complete REST API
4
+
5
+ Retold Data Service combines Meadow (data access), Orator (API server), and Meadow Endpoints (REST routes) into a single service provider. Point it at a compiled Stricture model and it auto-generates typed CRUD endpoints for every entity -- complete with filtering, pagination, soft deletes, and behavior injection hooks.
6
+
7
+ ## Features
8
+
9
+ - **Zero-Boilerplate REST** - Define your schema once, get full CRUD endpoints for every entity automatically
10
+ - **Provider-Agnostic** - Swap between MySQL, MSSQL, SQLite, or ALASQL without changing application code
11
+ - **Schema-Driven** - Stricture DDL compiles into a model that drives endpoint generation, validation, and defaults
12
+ - **Lifecycle Hooks** - `onBeforeInitialize`, `onInitialize`, and `onAfterInitialize` for custom startup logic
13
+ - **Behavior Injection** - Pre- and post-operation hooks on every CRUD operation for custom business logic
14
+ - **DAL Access** - Direct programmatic data access alongside the REST endpoints for server-side logic
15
+ - **Fable Service Provider** - First-class service in the Fable ecosystem with logging, configuration, and DI
16
+ - **Double-Init Protection** - Guards against accidental re-initialization
17
+
18
+ ## Quick Start
19
+
20
+ ```javascript
21
+ const libFable = require('fable');
22
+ const libRetoldDataService = require('retold-data-service');
23
+
24
+ const _Fable = new libFable({
25
+ APIServerPort: 8086,
26
+ MySQL: {
27
+ Server: '127.0.0.1',
28
+ Port: 3306,
29
+ User: 'root',
30
+ Password: 'secret',
31
+ Database: 'bookstore',
32
+ ConnectionPoolLimit: 20
33
+ },
34
+ MeadowConnectionMySQLAutoConnect: true
35
+ });
36
+
37
+ _Fable.serviceManager.addServiceType('RetoldDataService', libRetoldDataService);
38
+
39
+ _Fable.serviceManager.instantiateServiceProvider('RetoldDataService', {
40
+ StorageProvider: 'MySQL',
41
+ StorageProviderModule: 'meadow-connection-mysql',
42
+ FullMeadowSchemaPath: `${__dirname}/model/`,
43
+ FullMeadowSchemaFilename: 'MeadowModel-Extended.json'
44
+ });
45
+
46
+ _Fable.RetoldDataService.initializeService(
47
+ (pError) =>
48
+ {
49
+ if (pError)
50
+ {
51
+ return console.log('Error initializing data service:', pError);
52
+ }
53
+ console.log('REST API is running on port 8086');
54
+ });
55
+ ```
56
+
57
+ ## Installation
58
+
59
+ ```bash
60
+ npm install retold-data-service
61
+ ```
62
+
63
+ ## How It Works
64
+
65
+ Retold Data Service orchestrates the full Meadow stack into a single initialization sequence:
66
+
67
+ ```
68
+ Fable (Core)
69
+ └── Retold Data Service
70
+ ├── Orator (API Server)
71
+ │ └── Restify (HTTP Engine)
72
+ ├── Meadow (Data Access Layer)
73
+ │ ├── Schema (from compiled Stricture model)
74
+ │ ├── FoxHound (Query DSL)
75
+ │ └── Provider (MySQL / MSSQL / SQLite / ALASQL)
76
+ └── Meadow Endpoints (REST Routes)
77
+ ├── Create POST /1.0/Entity
78
+ ├── Read GET /1.0/Entity/:ID
79
+ ├── Reads GET /1.0/Entities/:Begin/:Cap
80
+ ├── Update PUT /1.0/Entity
81
+ ├── Delete DELETE /1.0/Entity/:ID
82
+ ├── Count GET /1.0/Entities/Count
83
+ ├── Schema GET /1.0/Entity/Schema
84
+ └── New GET /1.0/Entity/Schema/New
85
+ ```
86
+
87
+ ## Options
88
+
89
+ | Option | Default | Description |
90
+ |--------|---------|-------------|
91
+ | `StorageProvider` | `'MySQL'` | Database provider name |
92
+ | `StorageProviderModule` | `'meadow-connection-mysql'` | Node module for the provider |
93
+ | `FullMeadowSchemaPath` | `process.cwd() + '/model/'` | Path to the compiled schema |
94
+ | `FullMeadowSchemaFilename` | `'MeadowModel-Extended.json'` | Compiled model filename |
95
+ | `AutoStartOrator` | `true` | Start the HTTP server automatically |
96
+ | `APIServerPort` | `8080` | Port for the HTTP server |
97
+
98
+ ## SQLite Example
99
+
100
+ For embedded or test scenarios, use the in-memory SQLite provider:
101
+
102
+ ```javascript
103
+ const libMeadowConnectionSQLite = require('meadow-connection-sqlite');
104
+
105
+ const _Fable = new libFable({
106
+ APIServerPort: 8086,
107
+ SQLite: { SQLiteFilePath: ':memory:' }
108
+ });
109
+
110
+ _Fable.serviceManager.addServiceType('RetoldDataService', libRetoldDataService);
111
+ _Fable.serviceManager.addServiceType('MeadowSQLiteProvider', libMeadowConnectionSQLite);
112
+ _Fable.serviceManager.instantiateServiceProvider('MeadowSQLiteProvider');
113
+
114
+ _Fable.MeadowSQLiteProvider.connectAsync(
115
+ (pError) =>
116
+ {
117
+ _Fable.serviceManager.instantiateServiceProvider('RetoldDataService', {
118
+ StorageProvider: 'SQLite',
119
+ StorageProviderModule: 'meadow-connection-sqlite',
120
+ FullMeadowSchemaPath: `${__dirname}/model/`,
121
+ FullMeadowSchemaFilename: 'MeadowModel-Extended.json'
122
+ });
123
+
124
+ _Fable.RetoldDataService.initializeService(
125
+ (pError) =>
126
+ {
127
+ console.log('REST API running with in-memory SQLite');
128
+ });
129
+ });
130
+ ```
131
+
132
+ ## Behavior Injection
133
+
134
+ Add custom logic before or after any CRUD operation:
135
+
136
+ ```javascript
137
+ _Fable.MeadowEndpoints.Book.controller.BehaviorInjection.setBehavior(
138
+ 'Create-PreOperation',
139
+ (pRequest, pRequestState, fRequestComplete) =>
140
+ {
141
+ if (!pRequestState.RecordToCreate.Title)
142
+ {
143
+ pRequest.CommonServices.sendCodedResponse(
144
+ pRequestState.response, 400, 'Title is required');
145
+ return fRequestComplete(true);
146
+ }
147
+ return fRequestComplete(false);
148
+ });
149
+ ```
4
150
 
5
- ## Basic Usage
151
+ ## Lifecycle Hooks
6
152
 
7
- This library can run in any of three types of configurations:
153
+ Customize initialization by subclassing:
8
154
 
9
- * Configuration Driven
10
- * Managed via Backplane Endpoints
11
- * Hybrid (configuration plus endpoint)
12
-
13
- ## Configuration-Driven Mode
14
-
15
- The service looks for a `Retold` stanza in the configuration. For instance:
16
-
17
- ```
155
+ ```javascript
156
+ class MyDataService extends libRetoldDataService
18
157
  {
19
- ...
20
- "Retold": {
21
- "MeadowModel": "./meadow-schema-extended.json"
22
- },
23
- ...
158
+ onAfterInitialize(fCallback)
159
+ {
160
+ this.fable.log.info('Injecting custom behaviors...');
161
+ this.fable.MeadowEndpoints.Book.controller.BehaviorInjection
162
+ .setBehavior('Read-PostOperation', myCustomHook);
163
+ return fCallback();
164
+ }
24
165
  }
25
166
  ```
26
167
 
27
- The three auto-configured parameters are:
28
-
29
- * `MeadowModel`
30
- * `MeadowEntitySchema`
31
- * `StrictureDDL`
168
+ ## DAL Access
32
169
 
33
- The service tries to do the right thing with strings versus arrays -- you can pass an array of models or a single. Likewise, you can pass an array of schemas or a single. It also supports grabbing all files of a single folder with the `/*` suffix, and recursive with the `/**` suffix. When used in this fashion, only `.json` files are loaded from the folder(s).
170
+ Query data directly alongside the REST endpoints:
34
171
 
35
- ## Supplied Backplane Endpoints
172
+ ```javascript
173
+ let tmpQuery = _Fable.DAL.Book.query
174
+ .addFilter('Genre', 'Science Fiction')
175
+ .addSort({ Column: 'PublicationYear', Direction: 'Descending' })
176
+ .setCap(25)
177
+ .setBegin(0);
36
178
 
37
- ### Load a Meadow Model
38
-
39
- ```
40
- POST /BackPlane/${VERSION}/Load/MeadowModel
179
+ _Fable.DAL.Book.doReads(tmpQuery,
180
+ (pError, pQuery, pRecords) =>
181
+ {
182
+ console.log(`Found ${pRecords.length} sci-fi books`);
183
+ });
41
184
  ```
42
185
 
43
- This endpoint accepts a JSON blob of an entire Meadow model. It loads the entire model as a set of endpoints, and connects each endpoint to the default provider.
186
+ ## Backplane Endpoints
44
187
 
45
- ### Load a Meadow Entity Schema
188
+ For dynamic model loading at runtime, Retold Data Service provides backplane endpoints:
46
189
 
47
- ```
48
- POST /BackPlane/${VERSION}/Load/MeadowSchema
49
- ```
190
+ | Endpoint | Method | Description |
191
+ |----------|--------|-------------|
192
+ | `/BackPlane/:Version/Load/MeadowModel` | POST | Load a full Meadow model |
193
+ | `/BackPlane/:Version/Load/MeadowSchema` | POST | Load a Meadow entity schema |
194
+ | `/BackPlane/:Version/Load/StrictureDDL` | POST | Load and compile a Stricture DDL |
195
+ | `/BackPlane/:Version/Model/Primary/` | GET | Get the primary service model |
196
+ | `/BackPlane/:Version/Model/Composite/` | GET | Get composite models |
197
+ | `/BackPlane/:Version/Settings` | POST | Merge in provider settings |
198
+ | `/BackPlane/:Version/SetProvider/:Name` | GET | Set the default provider |
199
+ | `/BackPlane/:Version/SetProvider/:Name/:Entity` | GET | Set a per-entity provider |
50
200
 
51
- This endpoint accepts a JSON blob of an entire Meadow model. It loads the entire model as a set of endpoints, and connects each endpoint to the default provider.
201
+ ## Testing
52
202
 
53
- ### Load a DDL and Compile it
54
- ```
55
- POST /BackPlane/${VERSION}/Load/StrictureDDL
203
+ ```bash
204
+ npm test
56
205
  ```
57
206
 
58
- This endpoint loads a Stricture DDL, compiles it into the composite Entity schemas and loads them as endpoints.
207
+ Tests use an in-memory SQLite provider and require no external database server.
59
208
 
209
+ ## Documentation
60
210
 
61
- ### Access Primary Service Model and Composite Models
62
- ```
63
- GET /BackPlane/${VERSION}/Model/Primary/
64
- ```
65
-
66
- GET /BackPlane/${VERSION}/Model/Composite/
211
+ Detailed documentation is available in the `docs/` folder and can be served locally:
67
212
 
68
- ### Merge in Settings (to push default configurations for providers)
69
- ```
70
- POST /BackPlane/${VERSION}/Settings
213
+ ```bash
214
+ npx docsify-cli serve docs
71
215
  ```
72
216
 
73
- ### Set the Default Provider
74
- ```
75
- GET /BackPlane/${VERSION}/SetProvider/:ProviderName
76
- ```
77
-
78
- ### Set an Entity-Specific Provider
79
- ```
80
- GET /BackPlane/${VERSION}/SetProvider/:ProviderName/:Entity
81
- ```
217
+ ## Related Packages
82
218
 
219
+ - [meadow](https://github.com/stevenvelozo/meadow) - Data access and ORM
220
+ - [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) - Auto-generated REST endpoints
221
+ - [orator](https://github.com/stevenvelozo/orator) - API server abstraction
222
+ - [fable](https://github.com/stevenvelozo/fable) - Application services framework
83
223
 
224
+ ## License
84
225
 
226
+ MIT
85
227
 
228
+ ## Contributing
86
229
 
230
+ Pull requests are welcome. For details on our code of conduct, contribution process, and testing requirements, see the [Retold Contributing Guide](https://github.com/stevenvelozo/retold/blob/main/docs/contributing.md).
package/docs/.nojekyll ADDED
File without changes
package/docs/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # Retold Data Service
2
+
3
+ Retold Data Service is an all-in-one module that combines Fable, Meadow, Orator, and Meadow Endpoints into a single service. Given a compiled Stricture schema, it automatically creates a data access layer (DAL) and RESTful API endpoints for every entity in your model.
4
+
5
+ ## Features
6
+
7
+ - **Schema-Driven** — load a compiled Stricture model and get full CRUD endpoints for every table automatically
8
+ - **Pluggable Storage** — configure any Meadow-compatible provider (MySQL, SQLite, MSSQL, ALASQL) via options
9
+ - **Fable Service** — extends `fable-serviceproviderbase`, integrating with the Fable ecosystem for logging, configuration, and service management
10
+ - **Lifecycle Hooks** — override `onBeforeInitialize`, `onInitialize`, and `onAfterInitialize` for custom startup logic
11
+ - **Behavior Injection** — add pre- and post-operation hooks to any CRUD endpoint
12
+ - **DAL Access** — query your data directly through `fable.DAL.<Entity>` for programmatic access alongside the REST API
13
+ - **Auto-Start** — optionally start the Orator web server automatically on initialization
14
+
15
+ ## Quick Start
16
+
17
+ ```javascript
18
+ const libFable = require('fable');
19
+ const libRetoldDataService = require('retold-data-service');
20
+
21
+ const _Fable = new libFable({
22
+ Product: 'MyApp',
23
+ APIServerPort: 8086,
24
+ MySQL: {
25
+ Server: '127.0.0.1',
26
+ Port: 3306,
27
+ User: 'root',
28
+ Password: 'secret',
29
+ Database: 'mydb',
30
+ ConnectionPoolLimit: 20
31
+ },
32
+ MeadowConnectionMySQLAutoConnect: true
33
+ });
34
+
35
+ _Fable.serviceManager.addServiceType('RetoldDataService', libRetoldDataService);
36
+ _Fable.serviceManager.instantiateServiceProvider('RetoldDataService', {
37
+ FullMeadowSchemaPath: `${__dirname}/model/`,
38
+ FullMeadowSchemaFilename: 'MeadowModel-Extended.json',
39
+ StorageProvider: 'MySQL',
40
+ StorageProviderModule: 'meadow-connection-mysql',
41
+ AutoStartOrator: true
42
+ });
43
+
44
+ _Fable.RetoldDataService.initializeService(
45
+ (pError) =>
46
+ {
47
+ if (pError) return console.error('Startup failed:', pError);
48
+ console.log('Data service running on port 8086');
49
+ });
50
+ ```
51
+
52
+ ## Installation
53
+
54
+ ```bash
55
+ npm install retold-data-service
56
+ ```
57
+
58
+ ## Related Packages
59
+
60
+ | Package | Purpose |
61
+ |---------|---------|
62
+ | [fable](https://github.com/stevenvelozo/fable) | Core service framework |
63
+ | [meadow](https://github.com/stevenvelozo/meadow) | Data access layer and ORM |
64
+ | [foxhound](https://github.com/stevenvelozo/foxhound) | Query DSL for SQL generation |
65
+ | [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) | REST endpoint generation |
66
+ | [orator](https://github.com/stevenvelozo/orator) | API server abstraction |
67
+ | [stricture](https://github.com/stevenvelozo/stricture) | Schema definition DDL compiler |
68
+ | [retold-harness](https://github.com/stevenvelozo/retold-harness) | Application harness using Retold Data Service |
69
+
70
+ ## Testing
71
+
72
+ ```bash
73
+ npm test
74
+ ```
75
+
76
+ Tests run against an in-memory SQLite database and require no external services.
@@ -0,0 +1,13 @@
1
+ - Getting Started
2
+ - [Introduction](/)
3
+ - [Architecture](architecture.md)
4
+ - [Configuration](configuration.md)
5
+ - Usage
6
+ - [Initialization](initialization.md)
7
+ - [Endpoints](endpoints.md)
8
+ - [DAL Access](dal-access.md)
9
+ - [Behavior Injection](behavior-injection.md)
10
+ - Advanced
11
+ - [Lifecycle Hooks](lifecycle-hooks.md)
12
+ - [Storage Providers](storage-providers.md)
13
+ - [Schema Definition](schema-definition.md)
@@ -0,0 +1,94 @@
1
+ # Architecture
2
+
3
+ Retold Data Service orchestrates several Retold modules into a unified service that turns a schema into a running API.
4
+
5
+ ## Component Stack
6
+
7
+ ```
8
+ ┌─────────────────────────────────────────────┐
9
+ │ Your Application Code │
10
+ │ - Configure options │
11
+ │ - Override lifecycle hooks │
12
+ │ - Inject behaviors │
13
+ └──────────────────┬──────────────────────────┘
14
+
15
+ ┌──────────────────▼──────────────────────────┐
16
+ │ Retold Data Service │
17
+ │ - Loads Stricture model │
18
+ │ - Creates DAL per entity │
19
+ │ - Creates MeadowEndpoints per entity │
20
+ │ - Manages service lifecycle │
21
+ └──────────────────┬──────────────────────────┘
22
+
23
+ ┌──────────────────▼──────────────────────────┐
24
+ │ Orator (API Server) │
25
+ │ - HTTP server via Restify │
26
+ │ - Route registration │
27
+ │ - Request handling │
28
+ └──────────────────┬──────────────────────────┘
29
+
30
+ ┌──────────────────▼──────────────────────────┐
31
+ │ Meadow Endpoints (REST Layer) │
32
+ │ - CRUD route handlers │
33
+ │ - Behavior injection hooks │
34
+ │ - Session management │
35
+ │ - Authorization enforcement │
36
+ └──────────────────┬──────────────────────────┘
37
+
38
+ ┌──────────────────▼──────────────────────────┐
39
+ │ Meadow (Data Access) │
40
+ │ - Schema management │
41
+ │ - Query building via FoxHound │
42
+ │ - Provider-based query execution │
43
+ │ - Audit stamping and soft deletes │
44
+ └──────────────────┬──────────────────────────┘
45
+
46
+ ┌──────────────────▼──────────────────────────┐
47
+ │ Storage Provider │
48
+ │ MySQL │ SQLite │ MSSQL │ ALASQL │
49
+ └─────────────────────────────────────────────┘
50
+ ```
51
+
52
+ ## How It Works
53
+
54
+ 1. **Registration** — `RetoldDataService` is registered with Fable's service manager and instantiated with options
55
+ 2. **Server Setup** — Orator and its Restify service server are registered and configured
56
+ 3. **Initialization** — calling `initializeService()` triggers an ordered sequence:
57
+ - `onBeforeInitialize()` — your custom pre-initialization logic
58
+ - Orator web server start (if `AutoStartOrator` is true)
59
+ - Persistence engine initialization (loads the storage provider module)
60
+ - `onInitialize()` — your custom initialization logic
61
+ - Data endpoint initialization (loads model, creates DALs and endpoints)
62
+ - `onAfterInitialize()` — your custom post-initialization logic
63
+ 4. **Serving** — the Restify server listens for HTTP requests and routes them through Meadow Endpoints to the DAL
64
+
65
+ ## Key Objects
66
+
67
+ After initialization, these objects are available on the Fable instance:
68
+
69
+ | Object | Type | Description |
70
+ |--------|------|-------------|
71
+ | `fable.RetoldDataService` | Service | The data service instance |
72
+ | `fable.Orator` | Service | The Orator API server |
73
+ | `fable.OratorServiceServer` | Service | The Restify server |
74
+ | `fable.DAL.<Entity>` | Meadow | DAL for each entity in the model |
75
+ | `fable.MeadowEndpoints.<Entity>` | MeadowEndpoints | Endpoint controller for each entity |
76
+
77
+ ## Service Provider Pattern
78
+
79
+ Retold Data Service follows the Fable service provider pattern:
80
+
81
+ ```javascript
82
+ const libFableServiceProviderBase = require('fable-serviceproviderbase');
83
+
84
+ class RetoldDataService extends libFableServiceProviderBase
85
+ {
86
+ constructor(pFable, pOptions, pServiceHash)
87
+ {
88
+ super(pFable, pOptions, pServiceHash);
89
+ this.serviceType = 'RetoldDataService';
90
+ }
91
+ }
92
+ ```
93
+
94
+ This means it inherits logging, configuration access, and service lifecycle management from the base class.