retold-data-service 1.0.3 → 2.0.0
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/.vscode/launch.json +1 -1
- package/Dockerfile_LUXURYCode +2 -2
- package/debug/Harness.js +33 -28
- package/debug/bookstore-configuration.json +2 -1
- package/package.json +57 -70
- package/source/Retold-Data-Service.js +80 -83
- package/debug/bookstore-serve-meadow-endpoint-apis.js +0 -41
- package/debug/package-lock.json +0 -3999
- package/debug/package.json +0 -13
package/.vscode/launch.json
CHANGED
package/Dockerfile_LUXURYCode
CHANGED
|
@@ -56,8 +56,8 @@ RUN code-server --install-extension mtxr.sqltools-driver-mysql
|
|
|
56
56
|
RUN echo "...configuring mariadb (mysql) server..."
|
|
57
57
|
RUN sudo apt install default-mysql-server default-mysql-client -y
|
|
58
58
|
RUN sudo sed -i "s|bind-address|#bind-address|g" /etc/mysql/mariadb.conf.d/50-server.cnf
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
COPY ./debug/model/manual_scripts/MySQL-Security.sql /home/coder/MySQL-Configure-Security.sql
|
|
60
|
+
COPY ./debug/model/manual_scripts/MySQL-Laden-Entry.sh /usr/bin/MySQL-Laden-Entry.sh
|
|
61
61
|
RUN ( sudo mysqld_safe --skip-grant-tables --skip-networking & ) && sleep 5 && mysql -u root < /home/coder/MySQL-Configure-Security.sql
|
|
62
62
|
|
|
63
63
|
# Import the initial database
|
package/debug/Harness.js
CHANGED
|
@@ -3,33 +3,38 @@ const _Settings = require('./bookstore-configuration.json');
|
|
|
3
3
|
const libFable = require('fable');
|
|
4
4
|
|
|
5
5
|
_Fable = new libFable(_Settings);
|
|
6
|
+
|
|
6
7
|
_Fable.serviceManager.addAndInstantiateServiceType('RetoldDataService', require('../source/Retold-Data-Service.js'));
|
|
7
8
|
|
|
8
|
-
_Fable.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
9
|
+
_Fable.RetoldDataService.initializeService(
|
|
10
|
+
(pError) =>
|
|
11
|
+
{
|
|
12
|
+
_Fable.MeadowEndpoints.Book.controller.BehaviorInjection.setBehavior('Read-PostOperation',
|
|
13
|
+
(pRequest, pRequestState, fComplete) =>
|
|
14
|
+
{
|
|
15
|
+
// Get the join records
|
|
16
|
+
_Fable.DAL.BookAuthorJoin.doReads(_Fable.DAL.BookAuthorJoin.query.addFilter('IDBook', pRequestState.Record.IDBook),
|
|
17
|
+
(pJoinReadError, pJoinReadQuery, pJoinRecords)=>
|
|
18
|
+
{
|
|
19
|
+
let tmpAuthorList = [];
|
|
20
|
+
for (let j = 0; j < pJoinRecords.length; j++)
|
|
21
|
+
{
|
|
22
|
+
tmpAuthorList.push(pJoinRecords[j].IDAuthor);
|
|
23
|
+
}
|
|
24
|
+
if (tmpAuthorList.length < 1)
|
|
25
|
+
{
|
|
26
|
+
pRequestState.Record.Authors = [];
|
|
27
|
+
return fComplete();
|
|
28
|
+
}
|
|
29
|
+
else
|
|
30
|
+
{
|
|
31
|
+
_Fable.DAL.Author.doReads(_Fable.DAL.Author.query.addFilter('IDAuthor', tmpAuthorList, 'IN'),
|
|
32
|
+
(pReadsError, pReadsQuery, pAuthors)=>
|
|
33
|
+
{
|
|
34
|
+
pRequestState.Record.Authors = pAuthors;
|
|
35
|
+
return fComplete();
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
});
|
package/package.json
CHANGED
|
@@ -1,73 +1,60 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
2
|
+
"name": "retold-data-service",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Serve up a whole model!",
|
|
5
|
+
"main": "source/Retold-Data-Service.js",
|
|
6
|
+
"scripts": {
|
|
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",
|
|
10
|
+
"build": "npx quack build",
|
|
11
|
+
"docker-dev-build": "docker build ./ -f Dockerfile_LUXURYCode -t retold-data-service-image:local",
|
|
12
|
+
"docker-dev-run": "docker run -it -d --name retold-data-service-dev -p 44444:8080 -p 43306:3306 -p 48086:8086 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/retold-data-service\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" retold-data-service-image:local",
|
|
13
|
+
"docker-dev-shell": "docker exec -it retold-data-service-dev /bin/bash"
|
|
14
|
+
},
|
|
15
|
+
"mocha": {
|
|
16
|
+
"diff": true,
|
|
17
|
+
"extension": [
|
|
18
|
+
"js"
|
|
19
|
+
],
|
|
20
|
+
"package": "./package.json",
|
|
21
|
+
"reporter": "spec",
|
|
22
|
+
"slow": "75",
|
|
23
|
+
"timeout": "5000",
|
|
24
|
+
"ui": "tdd",
|
|
25
|
+
"watch-files": [
|
|
26
|
+
"source/**/*.js",
|
|
27
|
+
"test/**/*.js"
|
|
28
|
+
],
|
|
29
|
+
"watch-ignore": [
|
|
30
|
+
"lib/vendor"
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/stevenvelozo/retold-data-service.git"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"entity",
|
|
39
|
+
"behavior",
|
|
40
|
+
"api"
|
|
20
41
|
],
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"entity",
|
|
40
|
-
"behavior"
|
|
41
|
-
],
|
|
42
|
-
"author": "Steven Velozo <steven@velozo.com> (http://velozo.com/)",
|
|
43
|
-
"license": "MIT",
|
|
44
|
-
"bugs": {
|
|
45
|
-
"url": "https://github.com/stevenvelozo/retold-data-service/issues"
|
|
46
|
-
},
|
|
47
|
-
"homepage": "https://github.com/stevenvelozo/retold-data-service",
|
|
48
|
-
"devDependencies": {
|
|
49
|
-
"@babel/core": "^7.21.8",
|
|
50
|
-
"@babel/preset-env": "^7.21.5",
|
|
51
|
-
"browserify": "^17.0.0",
|
|
52
|
-
"chai": "4.3.7",
|
|
53
|
-
"gulp": "^4.0.2",
|
|
54
|
-
"gulp-babel": "^8.0.0",
|
|
55
|
-
"gulp-env": "^0.4.0",
|
|
56
|
-
"gulp-sourcemaps": "^3.0.0",
|
|
57
|
-
"gulp-terser": "^2.1.0",
|
|
58
|
-
"gulp-util": "^3.0.8",
|
|
59
|
-
"mocha": "10.2.0",
|
|
60
|
-
"nyc": "^15.1.0",
|
|
61
|
-
"vinyl-buffer": "^1.0.1",
|
|
62
|
-
"vinyl-source-stream": "^2.0.0"
|
|
63
|
-
},
|
|
64
|
-
"dependencies": {
|
|
65
|
-
"fable": "^3.0.46",
|
|
66
|
-
"fable-serviceproviderbase": "^3.0.4",
|
|
67
|
-
"meadow": "^2.0.5",
|
|
68
|
-
"meadow-connection-mysql": "^1.0.2",
|
|
69
|
-
"meadow-endpoints": "^4.0.2",
|
|
70
|
-
"orator": "^3.0.11",
|
|
71
|
-
"orator-serviceserver-restify": "^1.0.4"
|
|
72
|
-
}
|
|
42
|
+
"author": "Steven Velozo <steven@velozo.com> (http://velozo.com/)",
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/stevenvelozo/retold-data-service/issues"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://github.com/stevenvelozo/retold-data-service",
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"quackage": "^1.0.28"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"fable": "^3.0.112",
|
|
53
|
+
"fable-serviceproviderbase": "^3.0.12",
|
|
54
|
+
"meadow": "^2.0.15",
|
|
55
|
+
"meadow-connection-mysql": "^1.0.4",
|
|
56
|
+
"meadow-endpoints": "^4.0.5",
|
|
57
|
+
"orator": "^4.0.2",
|
|
58
|
+
"orator-serviceserver-restify": "^2.0.2"
|
|
59
|
+
}
|
|
73
60
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Retold Data Service
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* All-in-one add-ins for fable to provide endpoints.
|
|
5
5
|
*
|
|
6
6
|
* @author Steven Velozo <steven@velozo.com>
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
const libFableServiceProviderBase = require('fable-serviceproviderbase');
|
|
9
9
|
|
|
10
10
|
const libOrator = require('orator');
|
|
11
|
+
const libOratorServiceServerRestify = require('orator-serviceserver-restify');
|
|
12
|
+
|
|
11
13
|
const libMeadow = require('meadow');
|
|
12
14
|
const libMeadowEndpoints = require('meadow-endpoints');
|
|
13
15
|
|
|
@@ -15,7 +17,7 @@ const defaultDataServiceSettings = (
|
|
|
15
17
|
{
|
|
16
18
|
FullMeadowSchemaPath: `${process.cwd()}/model/`,
|
|
17
19
|
FullMeadowSchemaFilename: `Model-Extended.json`,
|
|
18
|
-
|
|
20
|
+
|
|
19
21
|
DALMeadowSchemaPath: `${process.cwd()}/model/meadow/`,
|
|
20
22
|
DALMeadowSchemaPrefix: `Model-MeadowSchema-`,
|
|
21
23
|
DALMeadowSchemaPostfix: ``,
|
|
@@ -34,97 +36,92 @@ class RetoldDataService extends libFableServiceProviderBase
|
|
|
34
36
|
|
|
35
37
|
this.options = this.fable.Utility.extend(defaultDataServiceSettings, this.options);
|
|
36
38
|
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// Orator is the (usually web) server
|
|
41
|
-
this.fable.Orator = new libOrator(this.fable, require('orator-serviceserver-restify'));
|
|
39
|
+
// Add the restify server provider and orator base class to fable
|
|
40
|
+
this.fable.serviceManager.addServiceType('OratorServiceServer', libOratorServiceServerRestify);
|
|
41
|
+
this.fable.serviceManager.addServiceType('Orator', libOrator);
|
|
42
42
|
|
|
43
|
-
//
|
|
44
|
-
this.fable.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
_Fable.serviceManager.addAndInstantiateServiceType('MeadowMySQLProvider', require('meadow-connection-mysql'));
|
|
59
|
-
|
|
60
|
-
this.fullModel = false;
|
|
61
|
-
this.entityList = false;
|
|
62
|
-
|
|
63
|
-
this.serviceInitialized = false;
|
|
64
|
-
|
|
65
|
-
if (this.options.AutoInitializeDataService)
|
|
66
|
-
{
|
|
67
|
-
this.fable.log.info(`The Retold Data Service is Auto Initializing itself`);
|
|
68
|
-
this.initializeService();
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (this.options.AutoStartOrator)
|
|
72
|
-
{
|
|
73
|
-
this.fable.log.info(`The Retold Data Service is Auto Starting Orator`);
|
|
74
|
-
this.fable.Orator.startWebServer(
|
|
75
|
-
(pError) =>
|
|
76
|
-
{
|
|
77
|
-
if (pError)
|
|
78
|
-
{
|
|
79
|
-
console.log(`Error auto-starting Orator: ${pError}`, pError);
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
});
|
|
43
|
+
// Initialize Restify
|
|
44
|
+
this.fable.serviceManager.instantiateServiceProvider('OratorServiceServer', this.options);
|
|
45
|
+
|
|
46
|
+
// Initialize Orator, which will automatically use the default `OratorServiceServer` service we just instantiated
|
|
47
|
+
this.fable.serviceManager.instantiateServiceProvider('Orator', this.options);
|
|
48
|
+
|
|
49
|
+
// TODO: This code will be much cleaner with meadow and meadow-endpoints as services
|
|
50
|
+
this._Meadow = libMeadow.new(_Fable);
|
|
51
|
+
|
|
52
|
+
// Create DAL objects for each table in the schema
|
|
53
|
+
// These will be unnecessary when meadow and meadow-endpoints are full fledged fable services
|
|
54
|
+
this._DAL = {};
|
|
55
|
+
this.fable.DAL = this._DAL;
|
|
56
|
+
this._MeadowEndpoints = {};
|
|
57
|
+
this.fable.MeadowEndpoints = this._MeadowEndpoints;
|
|
84
58
|
}
|
|
85
59
|
|
|
86
|
-
initializeService()
|
|
60
|
+
initializeService(fCallback)
|
|
87
61
|
{
|
|
88
62
|
if (this.serviceInitialized)
|
|
89
63
|
{
|
|
90
64
|
this.fable.log.error("Retold Data Service Application is being initialized but has already been initialized...");
|
|
65
|
+
return fCallback(new Error("Retold Data Service Application is being initialized but has already been initialized..."));
|
|
91
66
|
}
|
|
92
67
|
else
|
|
93
68
|
{
|
|
94
|
-
this.fable.log.info(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
69
|
+
this.fable.log.info(`The Retold Data Service is Auto Starting Orator`);
|
|
70
|
+
this.fable.Orator.startWebServer(
|
|
71
|
+
(pError) =>
|
|
72
|
+
{
|
|
73
|
+
if (pError)
|
|
74
|
+
{
|
|
75
|
+
console.log(`Error auto-starting Orator: ${pError}`, pError);
|
|
76
|
+
return fCallback(pError);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// TODO: Change this to an option (e.g. we might want to do ALASQL)
|
|
80
|
+
// Load the mysql connection for meadow if it doesn't exist yet
|
|
81
|
+
_Fable.serviceManager.addAndInstantiateServiceType('MeadowMySQLProvider', require('meadow-connection-mysql'));
|
|
82
|
+
|
|
83
|
+
this.fullModel = false;
|
|
84
|
+
this.entityList = false;
|
|
85
|
+
|
|
86
|
+
this.serviceInitialized = false;
|
|
87
|
+
|
|
88
|
+
this.fable.log.info("Retold Data Service Application is starting up...");
|
|
89
|
+
|
|
90
|
+
// Create DAL objects for each table in the schema
|
|
91
|
+
|
|
92
|
+
// 1. Load full compiled schema of the model from stricture
|
|
93
|
+
_Fable.log.info(`...loading full model stricture schema...`);
|
|
94
|
+
this.fullModel = require (`${this.options.FullMeadowSchemaPath}${this.options.FullMeadowSchemaFilename}`);
|
|
95
|
+
_Fable.log.info(`...full model stricture schema loaded.`);
|
|
96
|
+
|
|
97
|
+
// 2. Extract an array of each table in the schema
|
|
98
|
+
_Fable.log.info(`...getting entity list...`);
|
|
99
|
+
this.entityList = Object.keys(this.fullModel.Tables);
|
|
100
|
+
|
|
101
|
+
// 3. Enumerate each entry in the compiled model and load a DAL for that table
|
|
102
|
+
_Fable.log.info(`...initializing ${this.entityList.length} DAL objects and corresponding Meadow Endpoints...`);
|
|
103
|
+
for (let i = 0; i < this.entityList.length; i++)
|
|
104
|
+
{
|
|
105
|
+
// 4. Create the DAL for each entry (e.g. it would be at _DAL.Movie for the Movie entity)
|
|
106
|
+
let tmpDALEntityName = this.entityList[i];
|
|
107
|
+
let tmpDALPackageFile = `${this.options.DALMeadowSchemaPath}${this.options.DALMeadowSchemaPrefix}${tmpDALEntityName}${this.options.DALMeadowSchemaPostfix}.json`
|
|
108
|
+
_Fable.log.info(`Initializing the ${tmpDALEntityName} DAL from [${tmpDALPackageFile}]...`);
|
|
109
|
+
this._DAL[tmpDALEntityName] = this._Meadow.loadFromPackage(tmpDALPackageFile);
|
|
110
|
+
// 5. Tell this DAL object to use MySQL
|
|
111
|
+
_Fable.log.info(`...defaulting the ${tmpDALEntityName} DAL to use MySQL`);
|
|
112
|
+
this._DAL[tmpDALEntityName].setProvider('MySQL');
|
|
113
|
+
// 6. Create a Meadow Endpoints class for this DAL
|
|
114
|
+
_Fable.log.info(`...initializing the ${tmpDALEntityName} Meadow Endpoints to use MySQL`);
|
|
115
|
+
this._MeadowEndpoints[tmpDALEntityName] = libMeadowEndpoints.new(this._DAL[tmpDALEntityName]);
|
|
116
|
+
// 8. Expose the meadow endpoints on Orator
|
|
117
|
+
_Fable.log.info(`...mapping the ${tmpDALEntityName} Meadow Endpoints to Orator`);
|
|
118
|
+
this._MeadowEndpoints[tmpDALEntityName].connectRoutes(this.fable.Orator.webServer);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
this.serviceInitialized = true;
|
|
122
|
+
|
|
123
|
+
return fCallback(pError);
|
|
124
|
+
});
|
|
128
125
|
}
|
|
129
126
|
}
|
|
130
127
|
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
An example of Meadow Endpoints, Fable and Orator
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @license MIT
|
|
7
|
-
* @author <steven@velozo.com>
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
// Server Settings
|
|
11
|
-
let fStartServiceServer = (fInitializeCallback) =>
|
|
12
|
-
{
|
|
13
|
-
_Orator.initializeServiceServer(() =>
|
|
14
|
-
{
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// 100. Add a post processing hook to the Book DAL on single reads
|
|
18
|
-
/*
|
|
19
|
-
This post processing step will look for all book author joins then
|
|
20
|
-
load all appropriate authors and stuff them in the book record before
|
|
21
|
-
returning it.
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// Static site mapping
|
|
26
|
-
_Orator.log.info("...Mapping static route for web site...");
|
|
27
|
-
|
|
28
|
-
//_Orator.addStaticRoute(__dirname+'/../web/');
|
|
29
|
-
|
|
30
|
-
// Start the web server (ctrl+c to end it)
|
|
31
|
-
_Orator.startWebServer(
|
|
32
|
-
(pError) =>
|
|
33
|
-
{
|
|
34
|
-
fInitializeCallback(pError);
|
|
35
|
-
}
|
|
36
|
-
);
|
|
37
|
-
});
|
|
38
|
-
return _Orator;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
module.exports = fStartServiceServer;
|