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.
@@ -0,0 +1,128 @@
1
+ # Schema Definition
2
+
3
+ Retold Data Service loads a compiled Stricture schema model to create its entities and endpoints.
4
+
5
+ ## The Stricture DDL
6
+
7
+ Schemas are defined using Stricture's DDL syntax, then compiled into a JSON model that Retold Data Service understands.
8
+
9
+ ### DDL Example
10
+
11
+ ```
12
+ !Book
13
+ @IDBook
14
+ %GUIDBook
15
+ &CreateDate
16
+ #CreatingIDUser
17
+ &UpdateDate
18
+ #UpdatingIDUser
19
+ ^Deleted
20
+ &DeleteDate
21
+ #DeletingIDUser
22
+ $Title 200
23
+ $Type 32
24
+ $Genre 128
25
+ $ISBN 64
26
+ $Language 12
27
+ #PublicationYear
28
+
29
+ !Author
30
+ @IDAuthor
31
+ %GUIDAuthor
32
+ &CreateDate
33
+ #CreatingIDUser
34
+ &UpdateDate
35
+ #UpdatingIDUser
36
+ ^Deleted
37
+ &DeleteDate
38
+ #DeletingIDUser
39
+ $Name 200
40
+ ```
41
+
42
+ ### DDL Symbols
43
+
44
+ | Symbol | Meaning | Meadow Type |
45
+ |--------|---------|-------------|
46
+ | `!` | Table/entity name | — |
47
+ | `@` | Auto-increment ID | `AutoIdentity` |
48
+ | `%` | Auto GUID | `AutoGUID` |
49
+ | `&` | DateTime column | `CreateDate`, `UpdateDate`, `DeleteDate`, or `DateTime` |
50
+ | `#` | Numeric column | `Integer`, `CreateIDUser`, `UpdateIDUser`, `DeleteIDUser` |
51
+ | `$` | String column (with size) | `String` |
52
+ | `^` | Boolean column | `Deleted` or `Boolean` |
53
+ | `.` | Decimal column (with precision) | `Decimal` |
54
+ | `*` | Text column | `String` (large) |
55
+
56
+ ## Compiling the Model
57
+
58
+ Use Stricture to compile the DDL into JSON:
59
+
60
+ ```bash
61
+ npx stricture -i model/ddl/BookStore.ddl
62
+ ```
63
+
64
+ This produces a `MeadowModel-Extended.json` file containing the full model with:
65
+ - Column definitions per table
66
+ - Meadow schema per table (with `AutoIdentity`, `AutoGUID`, `CreateDate`, etc.)
67
+ - JSON Schema per table
68
+ - Default objects per table
69
+ - Authorization rules per table
70
+
71
+ ## Model JSON Structure
72
+
73
+ ```json
74
+ {
75
+ "Tables": {
76
+ "Book": {
77
+ "TableName": "Book",
78
+ "Columns": [...],
79
+ "MeadowSchema": {
80
+ "Scope": "Book",
81
+ "DefaultIdentifier": "IDBook",
82
+ "Schema": [
83
+ {"Column": "IDBook", "Type": "AutoIdentity"},
84
+ {"Column": "GUIDBook", "Type": "AutoGUID"},
85
+ {"Column": "Title", "Type": "String", "Size": "200"},
86
+ ...
87
+ ],
88
+ "DefaultObject": {
89
+ "IDBook": 0,
90
+ "Title": "",
91
+ ...
92
+ },
93
+ "Authorization": { ... }
94
+ }
95
+ },
96
+ "Author": { ... }
97
+ }
98
+ }
99
+ ```
100
+
101
+ ## Build Script
102
+
103
+ The test model includes a build script for compiling the DDL:
104
+
105
+ ```bash
106
+ npm run build-test-model
107
+ ```
108
+
109
+ This runs `cd test && npx stricture -i model/ddl/BookStore.ddl` to regenerate the compiled model from the DDL.
110
+
111
+ ## Schema Types Reference
112
+
113
+ | Type | Description | Auto-Managed |
114
+ |------|-------------|-------------|
115
+ | `AutoIdentity` | Auto-increment primary key | On Create (NULL/omit) |
116
+ | `AutoGUID` | Unique identifier | On Create (UUID generated) |
117
+ | `CreateDate` | Creation timestamp | On Create |
118
+ | `CreateIDUser` | Creator user ID | On Create |
119
+ | `UpdateDate` | Last update timestamp | On Create and Update |
120
+ | `UpdateIDUser` | Last updater user ID | On Create and Update |
121
+ | `Deleted` | Soft-delete flag | On Delete (set to 1) |
122
+ | `DeleteDate` | Deletion timestamp | On Delete |
123
+ | `DeleteIDUser` | Deleter user ID | On Delete |
124
+ | `String` | Text data | — |
125
+ | `Integer` | Numeric data | — |
126
+ | `Decimal` | Decimal data | — |
127
+ | `Boolean` | Boolean data | — |
128
+ | `DateTime` | Date/time data | — |
@@ -0,0 +1,109 @@
1
+ # Storage Providers
2
+
3
+ Retold Data Service supports any Meadow-compatible storage provider. The provider is configured through the `StorageProvider` and `StorageProviderModule` options.
4
+
5
+ ## Available Providers
6
+
7
+ | Provider | Module | Best For |
8
+ |----------|--------|----------|
9
+ | MySQL | `meadow-connection-mysql` | Production web applications |
10
+ | SQLite | `meadow-connection-sqlite` | Embedded apps, testing, single-server deployments |
11
+ | MSSQL | `meadow-connection-mssql` | Enterprise SQL Server environments |
12
+ | ALASQL | Built into Meadow | In-memory / browser-side usage |
13
+
14
+ ## MySQL Setup
15
+
16
+ MySQL is the default provider.
17
+
18
+ ```javascript
19
+ const settings = {
20
+ APIServerPort: 8086,
21
+ MySQL: {
22
+ Server: '127.0.0.1',
23
+ Port: 3306,
24
+ User: 'root',
25
+ Password: 'secret',
26
+ Database: 'mydb',
27
+ ConnectionPoolLimit: 20
28
+ },
29
+ MeadowConnectionMySQLAutoConnect: true
30
+ };
31
+
32
+ const _Fable = new libFable(settings);
33
+
34
+ _Fable.serviceManager.instantiateServiceProvider('RetoldDataService', {
35
+ StorageProvider: 'MySQL',
36
+ StorageProviderModule: 'meadow-connection-mysql',
37
+ FullMeadowSchemaPath: `${__dirname}/model/`,
38
+ FullMeadowSchemaFilename: 'MeadowModel-Extended.json'
39
+ });
40
+ ```
41
+
42
+ ## SQLite Setup
43
+
44
+ SQLite requires pre-registering the connection provider before creating the data service:
45
+
46
+ ```javascript
47
+ const libMeadowConnectionSQLite = require('meadow-connection-sqlite');
48
+
49
+ const settings = {
50
+ APIServerPort: 8086,
51
+ SQLite: { SQLiteFilePath: './data/app.db' }
52
+ };
53
+
54
+ const _Fable = new libFable(settings);
55
+
56
+ // Register and connect SQLite before creating the data service
57
+ _Fable.serviceManager.addServiceType('MeadowSQLiteProvider', libMeadowConnectionSQLite);
58
+ _Fable.serviceManager.instantiateServiceProvider('MeadowSQLiteProvider');
59
+
60
+ _Fable.MeadowSQLiteProvider.connectAsync(
61
+ (pError) =>
62
+ {
63
+ _Fable.serviceManager.instantiateServiceProvider('RetoldDataService', {
64
+ StorageProvider: 'SQLite',
65
+ StorageProviderModule: 'meadow-connection-sqlite',
66
+ FullMeadowSchemaPath: `${__dirname}/model/`,
67
+ FullMeadowSchemaFilename: 'MeadowModel-Extended.json'
68
+ });
69
+
70
+ _Fable.RetoldDataService.initializeService(callback);
71
+ });
72
+ ```
73
+
74
+ For in-memory testing, use `':memory:'` as the SQLite file path:
75
+
76
+ ```javascript
77
+ SQLite: { SQLiteFilePath: ':memory:' }
78
+ ```
79
+
80
+ ## MSSQL Setup
81
+
82
+ ```javascript
83
+ const settings = {
84
+ APIServerPort: 8086,
85
+ MSSQL: {
86
+ Server: '127.0.0.1',
87
+ Port: 1433,
88
+ User: 'sa',
89
+ Password: 'YourPassword123',
90
+ Database: 'mydb'
91
+ }
92
+ };
93
+
94
+ _Fable.serviceManager.instantiateServiceProvider('RetoldDataService', {
95
+ StorageProvider: 'MSSQL',
96
+ StorageProviderModule: 'meadow-connection-mssql',
97
+ FullMeadowSchemaPath: `${__dirname}/model/`,
98
+ FullMeadowSchemaFilename: 'MeadowModel-Extended.json'
99
+ });
100
+ ```
101
+
102
+ ## Changing the Provider at Runtime
103
+
104
+ After initialization, each entity's provider can be changed individually:
105
+
106
+ ```javascript
107
+ _Fable.DAL.Book.setProvider('MySQL');
108
+ _Fable.DAL.Author.setProvider('SQLite');
109
+ ```
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "retold-data-service",
3
- "version": "2.0.8",
3
+ "version": "2.0.10",
4
4
  "description": "Serve up a whole model!",
5
5
  "main": "source/Retold-Data-Service.js",
6
6
  "scripts": {
7
7
  "start": "node source/Retold-Data-Service.js",
8
- "coverage": "./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec",
9
- "test": "./node_modules/.bin/mocha -u tdd -R spec",
8
+ "coverage": "npx nyc --reporter=lcov --reporter=text-lcov npx mocha -- -u tdd -R spec",
9
+ "test": "npx mocha -u tdd -R spec",
10
10
  "build": "npx quack build",
11
11
  "build-test-model": "cd test && npx stricture -i model/ddl/BookStore.ddl",
12
12
  "docker-dev-build": "docker build ./ -f Dockerfile_LUXURYCode -t retold-data-service-image:local",
@@ -51,15 +51,19 @@
51
51
  },
52
52
  "homepage": "https://github.com/stevenvelozo/retold-data-service",
53
53
  "devDependencies": {
54
+ "chai": "^6.2.2",
55
+ "meadow-connection-sqlite": "file:../meadow-connection-sqlite",
56
+ "mocha": "^11.7.5",
54
57
  "quackage": "^1.0.41",
55
- "stricture": "^1.0.37"
58
+ "stricture": "^1.0.37",
59
+ "supertest": "^7.2.2"
56
60
  },
57
61
  "dependencies": {
58
62
  "fable": "^3.1.11",
59
63
  "fable-serviceproviderbase": "^3.0.15",
60
- "meadow": "^2.0.15",
64
+ "meadow": "file:../meadow",
61
65
  "meadow-connection-mysql": "^1.0.4",
62
- "meadow-endpoints": "^4.0.5",
66
+ "meadow-endpoints": "file:../meadow-endpoints",
63
67
  "orator": "^5.0.1",
64
68
  "orator-http-proxy": "^1.0.1",
65
69
  "orator-serviceserver-restify": "^2.0.4",
@@ -110,19 +110,28 @@ class RetoldDataService extends libFableServiceProviderBase
110
110
  {
111
111
  // 4. Create the DAL for each entry (e.g. it would be at _DAL.Movie for the Movie entity)
112
112
  let tmpDALEntityName = this.entityList[i];
113
- let tmpDALPackageObject = this.fullModel.Tables[tmpDALEntityName];
114
- // We no longer need to load it from a package file; it's all in the full model
115
- this.fable.log.info(`Initializing the ${tmpDALEntityName} DAL...`);
116
- this._DAL[tmpDALEntityName] = this._Meadow.loadFromPackageObject(tmpDALPackageObject.MeadowSchema);
117
- // 5. Tell this DAL object to use the specified storage provider
118
- this.fable.log.info(`...defaulting the ${tmpDALEntityName} DAL to use ${this.options.StorageProvider}`);
119
- this._DAL[tmpDALEntityName].setProvider(this.options.StorageProvider);
120
- // 6. Create a Meadow Endpoints class for this DAL
121
- this.fable.log.info(`...initializing the ${tmpDALEntityName} Meadow Endpoints to use ${this.options.StorageProvider}`);
122
- this._MeadowEndpoints[tmpDALEntityName] = libMeadowEndpoints.new(this._DAL[tmpDALEntityName]);
123
- // 8. Expose the meadow endpoints on Orator
124
- this.fable.log.info(`...mapping the ${tmpDALEntityName} Meadow Endpoints to Orator`);
125
- this._MeadowEndpoints[tmpDALEntityName].connectRoutes(this.fable.OratorServiceServer);
113
+ try
114
+ {
115
+ let tmpDALSchema = this.fullModel.Tables[tmpDALEntityName];
116
+ let tmpDALMeadowSchema = tmpDALSchema.MeadowSchema;
117
+
118
+ //let tmpDALPackageFile = `${this.options.DALMeadowSchemaPath}${this.options.DALMeadowSchemaPrefix}${tmpDALEntityName}${this.options.DALMeadowSchemaPostfix}.json`
119
+ //this.fable.log.info(`Initializing the ${tmpDALEntityName} DAL from [${tmpDALPackageFile}]...`);
120
+ this._DAL[tmpDALEntityName] = this._Meadow.loadFromPackageObject(tmpDALMeadowSchema);
121
+ // 5. Tell this DAL object to use the configured storage provider
122
+ this.fable.log.info(`...defaulting the ${tmpDALEntityName} DAL to use ${this.options.StorageProvider}`);
123
+ this._DAL[tmpDALEntityName].setProvider(this.options.StorageProvider);
124
+ // 6. Create a Meadow Endpoints class for this DAL
125
+ this.fable.log.info(`...initializing the ${tmpDALEntityName} Meadow Endpoints`);
126
+ this._MeadowEndpoints[tmpDALEntityName] = libMeadowEndpoints.new(this._DAL[tmpDALEntityName]);
127
+ // 8. Expose the meadow endpoints on Orator
128
+ this.fable.log.info(`...mapping the ${tmpDALEntityName} Meadow Endpoints to Orator`);
129
+ this._MeadowEndpoints[tmpDALEntityName].connectRoutes(this.fable.OratorServiceServer);
130
+ }
131
+ catch (pError)
132
+ {
133
+ this.fable.log.error(`Error initializing DAL and Endpoints for entity [${tmpDALEntityName}]: ${pError}`);
134
+ }
126
135
  }
127
136
 
128
137
  return fCallback();